Everything you need to install, run, and troubleshoot the tool.
What it does
Screen Leads turns a browser tab you have open on a profile into a structured lead. It screenshots your screen, scrolls, runs the images through Claude vision, and saves normalised leads to a local database you browse from the dashboard.
It is screen-capture only — it reads pixels already on your screen and never contacts the target site's servers. LinkedIn profile pages are the first supported site.
Quick start
Run it on your own machine, in a terminal:
cd path/to/screen-leads
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
export ANTHROPIC_API_KEY=sk-ant-...
python main.py
Then open http://127.0.0.1:8000. Next time,
skip the install steps — just activate the venv, set the key, and run
python main.py.
ANTHROPIC_API_KEY in the environment (or an
ant auth login profile). The key is only used to call Claude for extraction.Permissions by OS
| OS | Grant this |
|---|---|
| macOS | System Settings → Privacy & Security → Screen Recording and Accessibility for your terminal/app. Quit and reopen the terminal after granting. Automation permission for the browser enables exact URL detection. |
| Windows | Usually none. pip install uiautomation enables native URL detection. |
| Linux | Use an X11 session. Wayland can't capture or scroll via
mss/pyautogui — switch to X11 or use the desktop screenshot portal. |
Using it
- Open a LinkedIn profile in your normal browser. To capture email/phone, open the Contact info panel first — those only appear there, and often not at all.
- Click Start. A short countdown appears so you can focus the browser window.
- The tool scrolls, screenshots, extracts, and saves the lead, then waits for you to open the next profile.
Dashboard controls
| Control | Effect |
|---|---|
| Start | Begins a run: countdown → detect front tab → capture loop. |
| Pause | Freezes the loop between ticks; leads already saved stay. |
| Resume | Continues a paused run. |
| Stop | Ends the run and closes the run record. |
The event line under the header shows live status; the cards show funnel-stage
counts (NEW → ENRICHED → CONTACT_FOUND → EXPORTED).
Troubleshooting
Run stops immediately with "not a supported site / not a profile page"
The front tab wasn't a LinkedIn /in/… profile. Open a profile and Start again.
To keep polling instead of stopping, set SCREEN_LEADS_ON_INVALID_PAGE=wait.
"Screen capture failed" or blank/black screenshots
macOS Screen Recording permission isn't granted (or the terminal wasn't restarted after granting). On Linux, you're likely on Wayland — switch to an X11 session.
Page doesn't scroll during capture
macOS Accessibility permission isn't granted, or the profile window isn't focused. Capture still runs; you just get fewer distinct sections.
Authentication / API key errors
ANTHROPIC_API_KEY isn't set in the same terminal running python main.py.
Re-run the export line, or use ant auth login.
Name captured but no email/phone
Expected — contact details live behind LinkedIn's Contact info panel and are
often not shown. Open that panel before capture; the lead stays at ENRICHED until
contact data is found.
Wrong window captured
Keep the profile tab frontmost. Increase SCREEN_LEADS_START_DELAY to give yourself
more time to switch after Start.
Configuration
All optional; set as environment variables (or in a .env file — see
.env.example).
| Variable | Default | Purpose |
|---|---|---|
ANTHROPIC_API_KEY | — | Required. Claude API key. |
SCREEN_LEADS_MODEL | claude-opus-4-8 | Vision model (use claude-sonnet-5 to cut cost). |
SCREEN_LEADS_START_DELAY | 5 | Grace seconds before first capture (0 = off). |
SCREEN_LEADS_AUTO_NEXT | true | After each capture, click a "Next" control, scroll to top, and continue. |
SCREEN_LEADS_NEXT_LOAD_PAUSE | 2.5 | Seconds to wait for the next page to load after clicking Next. |
SCREEN_LEADS_MAX_AUTO_NEXT | 25 | Safety cap on auto-advances per run. |
SCREEN_LEADS_SCROLL_STEPS | 6 | Screenshots per profile. |
SCREEN_LEADS_SCROLL_AMOUNT | 800 | Scroll distance per step. |
SCREEN_LEADS_SCROLL_PAUSE | 0.8 | Settle time (s) after each scroll. |
SCREEN_LEADS_WATCH_INTERVAL | 2.0 | Loop tick (s). |
SCREEN_LEADS_ON_INVALID_PAGE | stop | stop or wait on a non-target page. |
SCREEN_LEADS_HOST / _PORT | 127.0.0.1 / 8000 | Server bind address. |
Adding a site
- Create
ai/recipes/<site>.pyimplementingSiteRecipe(matches,extraction_schema,extraction_prompt,to_canonical). - Register it in
ai/recipes/__init__.py.
The capture loop and guard are recipe-driven, so nothing else changes.
Compliance
Automated scraping of LinkedIn violates its Terms of Service. This tool is built for low-volume, human-in-the-loop use on profiles you manually open and are allowed to view. Keep pacing conservative and use it accordingly.