Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@LinkedIn MCPShow me my LinkedIn profile"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
๐ LinkedIn MCP
LinkedIn for AI assistants โ structured data via a real, stealth browser session
๐ CI
๐ npm version
๐ MIT License
๐ TypeScript
๐ MCP
๐ Glama score
Give Claude, Cursor, and any MCP client access to LinkedIn โ profiles, people/job/company search, feed, messaging, and your network โ as clean structured JSON.
22 tools ยท reads + gated writes (connect, message, post, react, comment) ยท a real safety layer (daily caps, human pacing, circuit breaker) ยท 166 tests.
โ ๏ธ Automating LinkedIn violates its User Agreement and can get an account restricted. No tool is ban-proof โ and this one says so up front. Use a secondary account; read Account safety and DISCLAIMER.md first.
Why this exists
LinkedIn's internal Voyager API (the one its own web app uses) returns rich, structured JSON โ but it sits behind Cloudflare bot-management, which rejects plain HTTP requests (a stateless fetch or curl gets stuck in an endless redirect, even with a valid cookie). The only reliable way to read LinkedIn data programmatically in 2026 is from inside a real browser that clears the challenge.
This project's approach:
Drive a real Chrome via patchright (an undetected Playwright fork) so Cloudflare's challenge is solved with a genuine browser fingerprint.
Query Voyager from inside the authenticated page โ same-origin, the exact network path LinkedIn's own SPA uses โ structured JSON, not scraped DOM text.
That last point is the edge over DOM-scraping tools: in-page API calls are locale-independent and resilient to UI redesigns, so they don't break on a moved CSS selector or a translated label.
Related MCP server: LinkedIn MCP Server
โจ What's good here
๐งฉ Structured JSON | In-page Voyager API calls return normalized data, shaped into compact objects โ not brittle innerText scraping. |
โ๏ธ Writes are API calls, not button-clicking |
|
๐ก๏ธ Safety layer built in | Serial queue, human-paced jittered delays, per-action daily budgets, account warmup ramp, and a circuit breaker that hard-stops on any checkpoint/captcha. (Risk reduction โ not a safety guarantee.) |
๐ฅ One warm session | A single persistent browser per process (cookies + Cloudflare clearance survive restarts). Explicit |
๐ Locale-independent | API + embedded-JSON parsing, not English-only DOM selectors โ survives UI redesigns and translations. |
๐ Local & private | Session stored under |
How it compares
DOM-scraping LinkedIn MCPs | This | |
Reads | scraped page text (brittle, locale-bound) | structured API JSON |
Writes (connect/message/post) | click rendered buttons (break on sticky navbars, dialog races, localized labels) | direct Voyager |
Write feedback | "clicked it" โ hope | structured status (ok / duplicate / restricted / quota_exhausted / โฆ) |
Resilience | breaks on UI tweaks / translations | API + embedded-JSON, locale-proof |
Safety (caps, pacing, circuit breaker) | none | โ built-in, 166 tests |
Zombie browser processes | common | โ reaped on close |
Language | Python | TypeScript + official MCP SDK |
We hit LinkedIn's own API from inside the challenge-passed browser โ reads and writes โ so you get the structured response and a real status, not parsed HTML and a hopeful click. (Shipping checklist + launch notes: LAUNCH.md.)
๐ฆ Status
Full transparency โ exactly where every piece stands (and what's still alpha):
Area | State |
Stealth browser engine (patchright) | โ built, live-proven |
In-page Voyager fetch (the core mechanism) | โ live-verified (returns structured JSON) |
Safety layer (queue / pacer / budgets / circuit-breaker) | โ built, 166 unit tests |
Profile โ | โ live-verified |
Feed / notifications โ | โ live-verified |
Jobs / messaging โ | โ live-verified |
People / companies โ | โ live-verified |
Network โ | โ |
Session โ | โ |
Write tools โ | โ
all 5 endpoints captured + live-verified on a burner; gated ( |
22 tools. typecheck + 166 tests green.
Login is headful, the server is headless. The one-time --login opens a real
Chrome window (to clear Cloudflare and let you solve any captcha/2FA). After that
the persistent profile carries the clearance, so the server runs headless โ
verified returning live data. Use a residential IP; datacenter/VPN IPs are
often pre-flagged by Cloudflare regardless of headless vs headful.
๐ Quick start
1. Log in once (opens a real Chrome window โ sign in, solve any captcha/2FA):
npx -y linkedin-mcp-tools@latest --loginNeeds Google Chrome installed (or run npx patchright install chrome once). Your
session โ Cloudflare clearance and all โ persists to ~/.linkedin-mcp/profile/.
2. Point your MCP client at it. Claude Desktop / Cursor / Claude Code config:
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "linkedin-mcp-tools@latest"]
}
}
}Then just ask: "Get my LinkedIn profile and summarize my experience" or "Find 5 recruiters at Google."
git clone https://github.com/devag7/linkedin-mcp.git
cd linkedin-mcp
npm install
npm run setup:browser # installs the Chrome patchright drives
npm run login # log in once
npm run spike # verify: fetches your profile as JSON
npm run build # produces dist/MCP config: "command": "node", "args": ["/absolute/path/to/dist/index.js"].
Headless / server deployment
The one-time --login needs a window; the server then runs headless (verified
returning live data). Run --login on a machine with a display (or via VNC),
copy ~/.linkedin-mcp/profile/ to your server, and run there:
LINKEDIN_HEADLESS=true npx -y linkedin-mcp-tools@latest # no display neededUse a residential IP โ datacenter/VPN IPs are frequently pre-flagged by Cloudflare regardless of headless vs headful.
๐ก๏ธ Account safety
Read this. Automating LinkedIn violates its User Agreement and can get your account restricted or banned โ no tool can prevent that, including this one. The built-in safety features (daily caps, human pacing, warmup, circuit breaker) reduce risk; they do not eliminate it.
Defaults err conservative:
Connections 20/day, messages 50/day, likes+comments 50/day combined, follows 30/day โ combined write cap 150/24h.
Profile views 80/day, searches 30/day.
New-account warmup ramp over the first weeks; pending-invite ceiling and acceptance-rate pauses.
Reads paced 4โ12s apart, writes 45โ150s, with long breaks and a working-hours gate.
A circuit breaker stops automatically on any checkpoint, captcha, or "unusual activity" page โ and never tries to solve one.
Recommendations: use a secondary/throwaway account, run from a residential IP, warm it up slowly. See DISCLAIMER.md for the full legal/ToS notice.
โ๏ธ Configuration
Variable | Default | Description |
|
| Server runs headless. |
| โ | Explicit Chrome binary path (else patchright's). |
|
| Persistent browser profile. |
|
| Close the browser after this idle time (0 disables). |
|
| Serial by default; >1 is ban-risky. |
|
|
|
๐ Development
npm run dev # run from source (stdio)
npm run typecheck
npm test # vitest (safety layer + smoke)
npm run build๐ License
MIT โ see LICENSE. Not affiliated with LinkedIn. Use at your own risk; see DISCLAIMER.md.
Made by Dev Agarwalla
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/devag7/linkedin-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
