Skip to content

lucasygu/lockedout

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lockedout — LinkedIn from the command line

Node CLI for reading LinkedIn profiles via a persistent stealth Chromium session. Built on Patchright. No API keys, no cookie copying — just lockedout login once, then scrape from your terminal.

Easiest way to get started

Paste this to your AI agent (Claude Code, Cursor, Codex, Windsurf, OpenClaw, etc.):

"Install the @lucasygu/lockedout LinkedIn CLI tool via npm. Then run lockedout login to sign in once, and lockedout status to verify. Repo: https://github.com/lucasygu/lockedout"

The agent will install the CLI, walk you through the one-time browser sign-in, and verify the session. After that, try: "Pull this person's LinkedIn profile and summarize their career trajectory" — the agent will run lockedout profile <slug> --json, parse the sections, and produce a structured summary.

Install

npm install -g @lucasygu/lockedout

Requires Node.js >= 22. Supports macOS, Linux, Windows.

First run note. The first lockedout login downloads ~150 MB of Chromium into the shared Patchright/Playwright cache (~/Library/Caches/ms-playwright/ on macOS, ~/.cache/ms-playwright/ on Linux). It's a one-time cost — subsequent runs are instant. Already have Playwright installed? It'll be a no-op; we share the cache.

After installing, run lockedout login to sign in (2FA / captcha OK). The CLI persists your session at ~/.lockedout/profile/ so you don't have to log in again until LinkedIn flags it.

Why this exists

Cookie-only LinkedIn tools (@bcharleson/linkedincli, tomquirk/linkedin-api) get sessions revoked within 1–2 calls. LinkedIn's BrowserGate / APFC fingerprint header is generated by ~2.7 MB of JS that has to run in a real browser — you can't fake it, copy it, or replay it. The only architecture that works in 2026 is "be a real browser." That's what lockedout is.

What you can do

  • Profile read — pull anyone's LinkedIn profile sections (experience, education, skills, etc.) as structured JSON
  • Session-aware scraping — uses your real LinkedIn session via a stealth Chromium profile; no API keys
  • Built-in safety — jittered delays defeat LinkedIn's "heartbeat" detection, daily quotas cap your exposure, automatic cooldown engages on rate-limit signals
  • AI-agent-first — auto-installs as a Claude Code skill (/lockedout); JSON output is designed for LLM parsing

Quick start

# One-time browser sign-in (downloads Chromium on first run)
lockedout login

# Verify the session is alive
lockedout status

# Read a profile (defaults to main_profile section only)
lockedout profile satyanadella --json

# Read multiple sections
lockedout profile satyanadella --sections experience,education,skills --json

# See today's quota usage
lockedout usage

# When something breaks — run this first
lockedout doctor

# Check / clear cooldown
lockedout cooldown status
lockedout cooldown clear

Commands

Command Description
login Open Chromium, sign in to LinkedIn manually. Cookies persist to ~/.lockedout/profile/.
status Headless probe that checks if the saved session is still valid.
logout Wipe the local session (rm -rf ~/.lockedout/).
profile <username> Scrape a person profile. Accepts a slug (satyanadella) or full URL.
doctor End-to-end self-diagnostic — run this first when something breaks. Supports --json and --quick.
usage Show today's scrape count, daily cap, and cooldown status.
cooldown status Show remaining cooldown time.
cooldown clear Clear an active cooldown (use only if you're confident it was overcautious).

Profile options

Option Description Default
--sections <list> Comma-separated sections to fetch main_profile only
--max-scrolls <n> Max scroll attempts per section page 5
--json JSON output false
--pretty Human-readable text true
--force Bypass the daily quota cap false

Available sections: main_profile, experience, education, interests, honors, languages, certifications, skills, projects, posts.

⚠️ Rate-limit safety. LinkedIn detects automation behaviorally — uniform delays between actions are the #1 signal. lockedout jitters every wait (1.5–3.5s nav, 0.3–0.8s scroll), caps actions at 40/day (50 in the first 14 days post-install), and auto-engages a 30-min cooldown on any rate-limit or auth signal. Override with --force only when you accept the risk. Industry data: ~23% of LinkedIn automation users hit account restrictions within 90 days; these guards are designed to keep you out of that bucket.

Troubleshooting

Always start with: lockedout doctor (or lockedout doctor --json for tooling). It runs 8 checks across Node, Patchright, Chromium, profile, session, quota, cooldown, and the skill symlink — most "doesn't work" reports resolve at this step. If doctor is green and a scrape still fails, the problem is on LinkedIn's side, not the skill.

Problem Solution
Anything unexpected — start here lockedout doctor
Auth: LinkedIn requires interactive re-authentication Run lockedout login. A 30-min cooldown will auto-engage; lockedout cooldown clear after re-login if you want to scrape immediately.
Cooldown active: N min remaining Wait it out, or lockedout cooldown clear if the trigger was a known false positive.
Daily cap reached: N/N. Resets in ~Xh Wait for UTC reset, or use --force for one more scrape if needed.
Setting up Chromium (one-time, ~150 MB)... Normal first-run download — wait for it to complete.
Chromium install failed (exit N) Run npx patchright install chromium manually to see the underlying error.
lockedout profile returns mostly empty sections Likely a soft rate-limit on that account. Check lockedout cooldown status. If clean, wait an hour and retry.
Skills section returns just headers Known v0.3.0 limitation — LinkedIn's new skills UI needs a "Show all" tab click that's not yet implemented.
lockedout status returns logged_in: false Session expired or LinkedIn rotated cookies. Run lockedout login again.

How it works

Layer What we use Why
Browser Patchright — stealth-patched Playwright fork Removes --enable-automation, adds --disable-blink-features=AutomationControlled, blocks Runtime.enable / Console.enable leaks. Necessary but not sufficient — see below.
Session Persistent Chromium profile at ~/.lockedout/profile/ LinkedIn's own JS generates lidc, bcookie, bscookie, liap, and the APFC fingerprint header; we don't fake any of it.
Chromium Lazy-downloaded on first login We don't bundle (npm has a 250 MB hard cap; Chromium is 280 MB). We don't postinstall-download (slow, hostile UX). First login triggers npx patchright install chromium; subsequent runs reuse the shared cache.
Extraction innerText from rendered DOM, not CSS selectors Resilient to LinkedIn's frequent UI churn. The output is loosely structured text per section, ideal for LLM downstream parsing.
Anti-detection Jitter + daily quota + cooldown Static fingerprint defeat (Patchright) is necessary but doesn't address behavioral patterns. lockedout adds randomized delays, a 40/day cap, and auto-engaged cooldowns. See docs/rate-limiting.md.

AI agent integration

Claude Code

Auto-registers as a skill at install time via the postinstall hook (which symlinks ~/.claude/skills/lockedout to the npm package). After npm install -g @lucasygu/lockedout, the /lockedout slash command is available immediately.

Use the slash command directly:

/lockedout profile satyanadella
/lockedout status
/lockedout usage

Or give Claude Code natural-language tasks:

  • "Pull Satya Nadella's career history from LinkedIn and summarize the timeline"
  • "Compare these three profiles' education sections"
  • "Check today's scrape budget before starting batch lookups"
  • "Walk me through the first-time login flow"

Claude Code combines multiple commands, parses the JSON, and produces structured analysis — driven by the SKILL.md instructions inside the package.

Acknowledgments

  • stickerdaniel/linkedin-mcp-server (Apache-2.0) — the Python MCP server we ported to Node/TypeScript. The innerText-extraction strategy, the auth-barrier and rate-limit detection, the persistent-profile design — all credit to the upstream maintainers.
  • Patchright by Kaliiiiiiiiii-Vinyzu — the stealth-patched Playwright fork that makes any of this possible. Maintained as the modern replacement for the (dead since 2023) puppeteer-extra-stealth.

Disclaimer

LinkedIn's Terms of Service prohibit automated access to the platform. Per 2025–2026 industry data (Salesflow, Salesloop, Connectsafely.ai, others), approximately 23% of users running LinkedIn automation tools hit an account restriction within 90 days. lockedout adds jittered delays, daily quotas, and an automatic cooldown circuit-breaker to reduce that risk, but cannot eliminate it.

Use responsibly:

  • One personal account per machine. Do not use lockedout on accounts you can't afford to lose.
  • Read docs/rate-limiting.md before any bulk operation.
  • This project is not affiliated with LinkedIn.

License

MIT © 2026 Lucas Gu

About

Node CLI for LinkedIn via a persistent stealth Patchright browser session. Survives LinkedIn's BrowserGate fingerprint scoring.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors