linkedin-mcp
Enables Claude to manage your LinkedIn account and pages (post, schedule, read feed, comments) by driving a real local Chrome browser under your logged-in session.
README
LinkedIn MCP Server · Claude Code plugin
A local MCP server (TypeScript + Playwright) that lets Claude manage your own LinkedIn account and the Company/showcase Pages you admin — post, schedule, read the feed, and read/reply to comments — by driving a real local Chrome under your existing logged-in web session.
Ships as a Claude Code plugin: the MCP server, six slash commands, and a skill that teaches Claude the safe-use rules. Install with two commands — see Install.
⚠️ Read this first — Terms of Service & risk
- This automates the LinkedIn website. It does not use the official LinkedIn API.
- Automating LinkedIn web browsing violates the LinkedIn User Agreement and can get your account rate-limited, restricted, or banned.
- Use it for your own account, at low volume, for actions you initiate. Do not bulk-post, scrape, or run it across many accounts.
- Run it locally only — your own machine, your own residential IP, a headed (visible) browser. Never run it in the cloud, in Docker, or on a datacenter IP: that fingerprint is exactly what LinkedIn flags.
- Provided as-is, no warranty. You accept the risk.
Requirements
- Node.js ≥ 22.5 (uses the built-in
node:sqlite— no native build step). - Google Chrome installed (Playwright drives your system Chrome via
channel: "chrome"; no separate browser download).
Install as a Claude Code plugin
The repo is its own single-plugin marketplace:
/plugin marketplace add HDHNezherParking-cum-Y638-Intl-Ltd/linkedin-mcp
/plugin install linkedin@linkedin-mcp
Then, in order:
/linkedin:setup # installs npm deps + compiles src/ → dist/ (once, ~30s)
/linkedin:login # opens Chrome; you sign in by hand
/linkedin:setup is optional — the server bootstraps itself on its first tool call — but running
it up front keeps that first call from stalling behind an npm install.
If Chrome isn't found, either install Google Chrome, or run
npx playwright install chromiumand delete thechannel: 'chrome'option insrc/browser.ts.
Slash commands
| Command | What it does |
|---|---|
/linkedin:setup |
Install dependencies and build the bundled server. Idempotent. |
/linkedin:login |
Check the session; open a browser to sign in if needed. |
/linkedin:post |
Draft a post, show it for approval, publish to your profile or a Page. |
/linkedin:schedule |
Queue / list / cancel scheduled posts. |
/linkedin:comments |
Read comments on a post and draft replies. |
/linkedin:doctor |
Diagnose runtime, build, session, and selector drift. |
The bundled linkedin-account skill loads automatically when a conversation turns to
LinkedIn: tool ordering, the approve-before-publishing rule, the local-scheduler caveat, volume
limits, and where to repair selectors.
Or: register the server directly (no plugin)
Claude Desktop (claude_desktop_config.json) or a project .mcp.json, after
npm install && npm run build:
{
"mcpServers": {
"linkedin": {
"command": "node",
"args": ["/absolute/path/to/linkedin-mcp/dist/index.js"]
}
}
}
First run — log in once
- Run
/linkedin:login(or call thelinkedin_logintool). A real Chrome window opens. - Log in by hand (2FA, email, and device checkpoints all work — you're driving).
- Your session is saved to
~/.linkedin-mcp/session/and reused on later runs. linkedin_session_statusconfirms you're logged in.
Re-run linkedin_login whenever the session expires (LinkedIn's li_at cookie lasts weeks to
months; there's no fixed TTL).
Tools
| Tool | What it does |
|---|---|
linkedin_login |
Open a headed browser and wait for you to log in manually. No password stored. |
linkedin_session_status |
Report whether you're logged in; warn if page selectors have drifted. |
create_post |
Publish a text post to your personal profile. |
schedule_post |
Queue a post for a future time (local scheduler — see caveat). |
list_scheduled_posts |
List queued posts and their status. |
cancel_scheduled_post |
Cancel a still-pending scheduled post. |
list_my_posts |
List your recent posts (their refs feed read_post_comments). |
read_post_comments |
Read comments on a post (URL or activity/share URN). |
reply_to_comment |
Reply to a comment. |
list_pages |
List Company/showcase Pages surfaced to your account. |
create_page_post |
Publish a post as a Page you admin. |
read_feed |
Light snapshot of your home feed. |
Scheduling — how it works (and its limit)
schedule_post writes to a local SQLite queue (~/.linkedin-mcp/schedule.sqlite). A background
worker polls and publishes each post at its due time via the browser.
It fires only while this server process is running. If your machine is off or the server isn't running at the scheduled time, the post goes out on the next poll after the server is running again. This is a local scheduler, not LinkedIn's native one.
Configuration
All optional — set as environment variables, or in a .env file. Two are loaded, later wins:
~/.linkedin-mcp/.env (use this when installed as a plugin — a plugin's own directory is a cache
that updates overwrite) and ./.env (repo-local, for development). See
.env.example.
| Env | Default | Meaning |
|---|---|---|
LINKEDIN_MCP_HOME |
~/.linkedin-mcp |
Root for session + scheduler state. |
LINKEDIN_SESSION_DIR |
$LINKEDIN_MCP_HOME/session |
Persistent Chrome profile (your logged-in session). |
LINKEDIN_DB_PATH |
$LINKEDIN_MCP_HOME/schedule.sqlite |
Scheduler database. |
LINKEDIN_HEADLESS |
false |
Run non-login actions headless. Login is always headed. |
LINKEDIN_LOGIN_TIMEOUT_SEC |
300 |
How long login waits for you. |
LINKEDIN_POLL_MS |
30000 |
Scheduler poll interval. |
LINKEDIN_PACING_MS |
400,1200 |
Randomized delay between UI steps (min,max). |
Security & secrets
- No password is ever read, stored, or logged — login is interactive in a real browser.
- Your session cookies and the scheduler DB live in
~/.linkedin-mcp/, outside the repo and outside the plugin cache (so a plugin update never wipes your login, and no project directory ever ends up holding your cookies). Treat~/.linkedin-mcp/session/like a password — anyone with it can act as you on LinkedIn. .gitignorecoverssession/,data/,.env,*.sqlite,dist/,node_modules/.
Selector maintenance (expect this)
LinkedIn's markup changes constantly. Every LinkedIn selector lives in one file:
src/linkedin/selectors.ts. When a tool errors with
"update src/linkedin/selectors.ts", or linkedin_session_status warns that a selector drifted,
fix the locator there — nowhere else. The comment / feed / page selectors are best-effort and
may need a live tuning pass against your account the first time you use those tools.
Known limitations
- The exact URL of a new post isn't always captured (LinkedIn doesn't reliably expose it).
read_feed,list_pages, and comment parsing are best-effort and sensitive to DOM changes.- Replying as a Page isn't supported (LinkedIn doesn't reliably expose the identity switcher in reply boxes).
- Text posts only — no media/video upload.
- Not the official API; no analytics, messaging, or connection management.
Development
npm run typecheck # tsc --noEmit
npm run build # compile to dist/
npm test # node:test — scheduler + validation + plugin manifests (no browser, no network)
npm run smoke # boot the server in-memory and list tools (no LinkedIn contact)
npm run dev # run from source via tsx
The scheduler is unit-tested with the browser mocked (the worker takes an injectable poster).
test/plugin.test.ts guards the packaging: the manifests parse, the paths they reference exist,
and every MCP tool pre-allowed in a command is one the server actually registers.
Live LinkedIn flows are verified manually — never in CI (needs a real session and would violate ToS).
Plugin layout
| Path | Role |
|---|---|
.claude-plugin/plugin.json |
Plugin manifest (name, version, author). |
.claude-plugin/marketplace.json |
Makes this repo a single-plugin marketplace. |
.mcp.json |
Registers the bundled stdio server via ${CLAUDE_PLUGIN_ROOT}. |
scripts/launch.mjs |
Bootstrap: installs + compiles if missing or stale, then starts the server in-process. |
commands/*.md |
The /linkedin:* slash commands. |
skills/linkedin-account/SKILL.md |
Safe-use rules Claude loads on LinkedIn topics. |
A marketplace install is a plain git clone — no node_modules, no dist/ — which is why
launch.mjs builds on first run. It compares the newest mtime under src/ against dist/, so a
plugin update rebuilds automatically. All its output goes to stderr; stdout is the MCP channel.
Opening this repo as a Claude Code project will surface the root
.mcp.jsonas a project server. Decline it —${CLAUDE_PLUGIN_ROOT}only expands in plugin scope. Registerdist/index.jsby absolute path instead (see above).
License
MIT — see LICENSE.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。