linkedin-mcp
Click on "Deploy 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-mcpread my last 20 LinkedIn messages and flag the ones that are recruiter outreach"
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-mcp is an unofficial LinkedIn CLI and MCP server in one Python
package. Every command and every MCP tool call the same shared core
(linkedin_mcp/core.py), so the two surfaces never drift apart.
It consolidates two prior tools into one:
linkedin-cli (by frizynn, MIT) — the Voyager-API read/write surface:
feed,search,profile,profile-posts,activity,post,react,unreact,save,unsave,comment. This repo forked that project and built on top of it.linkedin-agent — the CDP surface that drives your own already-logged-in Chrome for messaging, referrals, and posting:
doctor,classify,post-cdp,messages,referral. That project is now absorbed into this one.
It is built around a real LinkedIn web session (Voyager) or your own logged-in Chrome (CDP) — not OAuth. That makes it practical for personal automation, but session handling, browser behavior, and endpoint stability all matter.
What it does
Voyager API surface (a real session, requests/Playwright fallback):
Read the authenticated home feed, search people/posts, fetch a profile or its posts, inspect an activity, emit JSON for scripting.
Write: publish a post, react/unreact, save/unsave, comment — all through a Playwright browser-automation fallback.
CDP agent surface (your own already-open, already-logged-in Chrome, via own-chrome):
doctor— environment/session health check.classify— is an inbound message hiring-shaped, excluded, already-referred?post-cdp draft/post-cdp publish— lint-then-publish a feed post.messages read/messages send— read/reply in the open thread, with an optional file attachment.referral draft/referral send— draft/send a referral message with a resume attached, paced and deduped through a rate governor.
MCP server (linkedin-mcp serve): every command above as an MCP tool,
for Claude/Cursor/any MCP client.
Related MCP server: linkedin-mcp
Confirm gate — nothing sends without it
Every write/send/publish command requires an explicit --confirm (CLI) or
confirm: true (MCP tool). Two families, two mechanisms:
Voyager writes (
post,react,unreact,save,unsave,comment) refuse instantly —ConfirmRequiredError, nothing touched — without it.CDP agent writes (
post-cdp publish,messages send,referral send) still fill the browser compose box/composer as a preview, then refuse to click Send/Post —SendNotConfirmedError— without it.
Installation
git clone https://github.com/ml-lubich/linkedin-mcp.git
cd linkedin-mcp
uv tool install --force --from . linkedin-mcpInstalls two identical console scripts, linkedin and linkedin-mcp. If you
previously had the standalone tools installed, remove them so their command
names don't shadow this one:
uv tool uninstall linkedin-cli
uv tool uninstall linkedin-agentInstall Playwright's browser if you use the Voyager write fallback:
uv run playwright install chromiumQuick start (Voyager side)
export LINKEDIN_COOKIE_HEADER='li_at=...; JSESSIONID="ajax:..."; ...'
linkedin auth-status
linkedin feed --max 10
linkedin profile satyanadella
linkedin search "AI engineer" --max 10Quick start (CDP agent side)
Chrome must be listening on its debugging port (default 9222); quit Chrome
fully first, then (macOS, since Chrome 136+ ignores the flag on the default
profile):
open -a "Google Chrome" --args --remote-debugging-port=9222 --user-data-dir="$HOME/chrome-debug"linkedin doctor # environment/session check
linkedin messages read --limit 20 # read the open thread
linkedin messages send "thanks, that works" --confirm
linkedin post-cdp draft "shipped a small thing this week" # anti-cringe lint, no browser
linkedin post-cdp publish "shipped a small thing this week" --confirmConfig for the CDP side lives at ~/.config/linkedin-agent/config.toml
(unchanged from linkedin-agent — copy config.example.toml from that repo).
It holds the CDP port, your display name, the referral identity, and
exclusion lists. Nothing personal is hardcoded here.
MCP server
linkedin-mcp serve # stdio transportClaude Code / Cursor config:
{
"mcpServers": {
"linkedin": { "command": "linkedin-mcp", "args": ["serve"] }
}
}21 tools are exposed, one per CLI command (dashes/spaces -> underscores),
except serve (starts the server itself) and auth env (the one command
that reads a raw cookie value back out — never exposed as a tool; capture the
session with the auth_capture tool or linkedin auth capture instead).
tests/test_mcp_parity.py fails the build if a command and its tool ever
drift apart.
Authentication (Voyager side)
Resolved in this order:
LINKEDIN_COOKIE_HEADER(most reliable)LINKEDIN_LI_AT+LINKEDIN_JSESSIONIDBrowser cookie extraction (Chrome, Chromium, Brave, Edge, Firefox)
linkedin auth capture— CDP-based, for Chrome 127+, where its app-bound cookie encryption blocks #3. Polls a CDP-attached Chrome until logged in, then saves the cookie to~/.config/linkedin-mcp/cookies(mode0600). Never prints a cookie value.linkedin auth envis the one command that does, deliberately, to exportLINKEDIN_COOKIE_HEADER.
export LINKEDIN_LI_AT='AQ...'
export LINKEDIN_JSESSIONID='"ajax:123456789"'
export LINKEDIN_BROWSER='chrome'
export LINKEDIN_HEADLESS='1'
export LINKEDIN_PROXY='http://127.0.0.1:7890'
export LINKEDIN_CONFIG="$PWD/config.yaml"Commands
linkedin auth-status
linkedin auth capture
linkedin auth env
linkedin feed --max 20 --json
linkedin search "product manager" --max 10
linkedin profile satyanadella --json
linkedin profile-posts satyanadella --max 20
linkedin activity urn:li:activity:123
linkedin post "hello from linkedin-mcp" --confirm
linkedin react urn:li:activity:123 --type like --confirm
linkedin unreact urn:li:activity:123 --confirm
linkedin save urn:li:activity:123 --confirm
linkedin unsave urn:li:activity:123 --confirm
linkedin comment urn:li:activity:123 "nice post" --confirm
linkedin doctor
linkedin classify "InMail: Senior AI Engineer role" --name "Jordan Lee"
linkedin post-cdp draft "..."
linkedin post-cdp publish "..." --confirm
linkedin messages read --limit 40
linkedin messages send "..." --confirm
linkedin referral draft "Jordan Lee" "..." --headline "Talent @ Acme"
linkedin referral send "Jordan Lee" "<thread url>" --confirm
linkedin-mcp serveSkill
This repo ships one Codex/Claude skill in skills/linkedin-mcp/
covering command selection, the confirm gate, auth troubleshooting, and write
workflows for both surfaces.
Configuration (Voyager side)
The repository includes a sample config.yaml:
fetch:
count: 20
filter:
enabled: false
mode: "recent"
browser:
preferred: "chrome"
fallback_enabled: true
headless: true
rate_limit:
request_delay: 1.25
max_retries: 3
retry_base_delay: 3.0
write_delay_min: 1.5
write_delay_max: 4.0
timeout: 20.0Development
uv sync --extra dev
uv run playwright install chromiumRun checks (see docs/TESTING.md for the full gate):
uv run ruff check .
uv run pytest -q --cov=linkedin_mcpImportant notes
Unofficial, not affiliated with LinkedIn.
LinkedIn can change internal web endpoints without notice.
Session cookies are credentials. Treat them like passwords — never commit them, print them, or paste them into an issue/PR.
Never invent a referral target, resume, or pitch — they come only from config/env vars.
Do not use this for spam, scraping at abusive rates, or automating repeated posting/engagement loops.
Security and Privacy
See SECURITY.md for reporting guidance.
Contributing
Before opening a pull request, read CONTRIBUTING.md,
CODE_OF_CONDUCT.md, and SECURITY.md.
License
MIT. See LICENSE. Portions of this project originate from
frizynn/linkedin-cli (MIT).
This server cannot be deployed
Maintenance
Related MCP Connectors
LinkedIn API as MCP tools to retrieve profile data and publish content. Powered by HAPI MCP.
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
- linkedinOAuthio.reachium
LinkedIn campaigns, content, leads and inbox from your AI client. Scoped, revocable keys.
Managed LinkedIn MCP server for AI agents: search, connect, message and enrich on accounts you own.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables read-only extraction of LinkedIn profile data via MCP tools, using a local browser bridge for secure, authenticated access without exposing browser credentials.2MIT
- AlicenseAqualityBmaintenanceEnables LinkedIn API integration for managing profiles, posts, feed, connections, and sending messages through MCP-compatible clients.1010 npmMIT
- AlicenseNot gradedqualityBmaintenanceMCP server for AI-native LinkedIn prospecting. It enables lead research, audience building, conversation management, and controlled outreach actions such as messaging and publishing through an OAuth-protected remote endpoint.2MIT
- AlicenseAqualityBmaintenanceEnables MCP-compatible clients to read LinkedIn profiles, companies, and jobs, and to send connection requests after explicit confirmation, using interactive browser-based authentication instead of stored credentials.8MIT