linkedin-mcp-pro
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-mcp-profind me software engineer jobs at Microsoft"
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-pro
Open-source MCP server for LinkedIn. Profiles, search, jobs, posts, connections, messages. Self-hosted, ban-safe, MIT licensed.
Documentation
USAGE.md — practical examples, prompting tips, troubleshooting
docs/ARCHITECTURE.md — how the pieces fit together
docs/SAFETY.md — ban-prevention design and rationale
docs/CONTRIBUTING.md — how to contribute
CHANGELOG.md — version history
Related MCP server: LinkedIn Profile MCP Server
What is it?
linkedin-mcp-pro is a Model Context Protocol (MCP) server that exposes your LinkedIn account as 22 tools for any MCP-compatible client — while keeping you in control of how those tools act on your behalf.
22 tools, organized in 3 groups:
Group | Tools | Backend | Ban risk |
Reads (12) | profile lookup, search people/jobs/companies, feed, inbox, conversations, pending invitations | LinkedIn Voyager API (HTTP) | ⚪ None |
Writes (10) | connection requests, posts, comments, reactions, messages, accept/decline/withdraw invitations |
| 🟢 Hardened with safety layer |
Stats (2) | daily quota usage, audit log | Local SQLite | ⚪ None |
Why use it instead of SaaS alternatives?
linkedin-mcp-pro | SaaS (e.g. Zopto, Lemlist) | |
Cost | Free (your time to host) | $59-300/mo |
Data | Stays on your machine | Their servers |
Open source | ✅ MIT (audit it) | ❌ Closed |
Self-hostable | ✅ Docker / systemd / bare | ❌ |
Ban safety | Built-in (warmup, jitter, business hours) | Their responsibility |
Rate limits | You control (DB-enforced) | Their tier |
MCP integration | Any MCP client (Claude Desktop, Cursor, Windsurf, etc.) | Their dashboard |
Features
🛡️ Ban-safety (the focus)
Daily caps, DB-enforced (e.g. 20 connections, 2 posts, 30 messages)
Warm-up mode: Week 1: 5 conn/day, Week 2: 10, Week 3: 15, Week 4+: full caps
Business hours: actions only run in your configured window (default 9-20 UTC, Mon-Fri)
Jitter: 3-15 min random delay between actions (mimics human)
429 backoff: exponential cooldown on rate-limit responses
CAPTCHA detection: pauses all writes 24h, alerts you
Dry-run mode: every write tool accepts
dry_run=trueto previewAudit log: every action recorded with timestamp, target, status, detail
Pause on quota-exhaust: yellow zone (60%) warning, red (90%), exhausted (100%)
🔧 22 tools (full list)
Reads (no ban risk)
get_my_profile,get_person_profilesearch_people,search_jobs,search_companiesget_job_details,get_company_profile,get_company_employeesget_feed,get_inbox,get_conversationget_pending_invitations
Writes (safety-enforced)
send_connection_request(with optional personalized note)create_post(text + optional media URL)delete_postcomment_on_postreact_to_post(LIKE, CELEBRATE, INSIGHTFUL, etc.)send_messageaccept_invitation,decline_invitation,withdraw_invitation
Stats
get_daily_stats(quota used/limit/zone per action)get_audit_log(recent actions with status)
📊 Storage
SQLite for quotas, queue, audit log, session state
Browser profile persisted at
data/browser-profile/(Patchright)No external DB required
Retention: audit log auto-pruned at 90 days (configurable)
Installation
Prerequisites
Python 3.11+ (tested on 3.13)
Node.js 20+ and npm (for
agent-browserCLI)LinkedIn account with
li_atcookie (see Getting your cookie)
Option A: pip install (recommended)
# 1. Install agent-browser (Rust CLI for write actions)
npm install -g agent-browser
agent-browser install --with-deps
# 2. Install linkedin-mcp-pro
git clone https://github.com/your-org/linkedin-mcp-pro
cd linkedin-mcp-pro
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
cp .env.example .env
# Edit .env with your LI_AT (and optionally JSESSIONID)
linkedin-mcp-healthOption B: Docker
git clone https://github.com/your-org/linkedin-mcp-pro
cd linkedin-mcp-pro
cp .env.example .env
# Edit .env with your LI_AT
docker compose up -d
docker compose logs -f linkedin-mcp-proOption C: systemd (production)
See systemd/linkedin-mcp-pro.service.
sudo cp systemd/linkedin-mcp-pro.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now linkedin-mcp-pro
sudo systemctl status linkedin-mcp-proConfiguration
All config is via environment variables (or .env file). See .env.example for the full reference.
Minimum (reads only)
LI_AT=your-li_at-value-hereRecommended (reads + writes)
LI_AT=your-li_at-value-here
DAILY_LIMIT_CONNECTION_REQUESTS=20
DAILY_LIMIT_POSTS=2
BUSINESS_HOURS_START=9
BUSINESS_HOURS_END=20
WARMUP_ENABLED=trueProduction (use file-based secrets)
LI_AT_FILE=/etc/linkedin-mcp-pro/li_at
JSESSIONID_FILE=/etc/linkedin-mcp-pro/jsessionidGetting your li_at cookie
Open https://www.linkedin.com in Chrome/Firefox and log in
Open DevTools (F12 or Cmd+Opt+I)
Go to Application tab → Cookies →
https://www.linkedin.comFind the
li_atcookie, double-click its value, copyPaste into
.envasLI_AT=...
For browser-based writes, you also need a working browser session — Patchright will use this cookie to bootstrap.
Optional but recommended: copy the JSESSIONID cookie too (improves API reliability).
Usage with Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"linkedin": {
"command": "uvx",
"args": ["--from", "/absolute/path/to/linkedin-mcp-pro", "linkedin-mcp-pro"],
"env": {
"LI_AT_FILE": "/etc/linkedin-mcp-pro/li_at"
}
}
}
}Or if installed via pip install -e .:
{
"mcpServers": {
"linkedin": {
"command": "linkedin-mcp-pro",
"env": {
"LI_AT_FILE": "/etc/linkedin-mcp-pro/li_at"
}
}
}
}Example: a daily workflow (Roman Urdu / English mix)
"Mujhe 20 recruiters ko LinkedIn pe connect request bhejne hain, 1 post karo, aur 5 jobs search karo 'AI engineer' in San Francisco."
The MCP client will:
Call
search_jobs(keywords="AI engineer", location="San Francisco", limit=5)(read)Call
create_post(text="...", visibility="PUBLIC", dry_run=false)(write, safety-checked)Call
send_connection_request(public_id="recruiter1", note="...")× 20 (writes, jittered, capped)
You can preview any write by passing dry_run=true:
"Show me what the next connection request would look like."
→ send_connection_request(public_id="recruiter1", note="...", dry_run=true)
Architecture
See docs/ARCHITECTURE.md for the full design.
┌──────────────────────────────────────────────────┐
│ linkedin-mcp-pro (Python 3.13) │
┌──────────────┐ ┌──────────────┐ ┌────────┐ │
│ Voyager API │ │ agent-browser│ │ Safety │ │
│ (reads + │ │ (writes: │ │ Layer │ │
│ fast data) │ │ connect/ │ │ +queue │ │
│ │ │ post/ │ │ +audit │ │
│ │ │ message) │ │ log │ │
└──────┬───────┘ └──────┬───────┘ └───┬────┘ │
│ │ │ │ │
│ └────────┬────────┴──────────────┘ │
│ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ SQLite (./data/linkedin-mcp-pro.db) │ │
│ │ - daily_quotas - action_queue │ │
│ │ - audit_log - session_state │ │
│ └──────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘Safety in depth
See docs/SAFETY.md for the full ban-prevention design.
The key insight: rate limits are signals, not bugs. If LinkedIn says "slow down", we want to slow down — not blast through. Every write tool goes through SafetyGuard.enforce() which checks:
Business hours — never outside your configured window
Daily quota — hard cap from DB, with warm-up ramp
429 backoff — exponential, with consecutive-count multiplier
CAPTCHA — never auto-resolve, hard pause 24h + alert
Audit — every action recorded, regardless of outcome
Development
# Install with dev deps
pip install -e ".[dev]"
# Run tests
pytest
# Lint
ruff check linkedin_mcp/
ruff format linkedin_mcp/
# Type check
mypy linkedin_mcp/Project layout
linkedin-mcp-pro/
├── linkedin_mcp/
│ ├── __init__.py
│ ├── config.py # env loading, validation
│ ├── db.py # SQLite (quotas, queue, audit)
│ ├── safety.py # SafetyGuard
│ ├── server.py # MCP server, 22 tools
│ ├── cli.py # health, stats commands
│ ├── api/ # Voyager HTTP client (reads)
│ ├── browser/ # agent-browser client (writes)
│ └── tools/ # (future) tool-specific helpers
├── data/ # runtime: db, browser profile
├── tests/
│ ├── test_api.py
│ ├── test_browser.py
│ ├── test_safety.py
│ └── test_db.py
├── docs/
│ ├── ARCHITECTURE.md
│ ├── SAFETY.md
│ └── CONTRIBUTING.md
├── examples/
│ └── claude_desktop_config.json
├── systemd/
│ └── linkedin-mcp-pro.service
├── pyproject.toml
├── .env.example
├── LICENSE # MIT
└── README.mdContributing
We welcome PRs. See docs/CONTRIBUTING.md for guidelines.
Especially wanted:
More test coverage (current focus: tools, safety)
Documentation improvements
LinkedIn Voyager endpoint discovery (the API is undocumented)
New write tools (e.g. skill endorsement, post scheduling)
⚖️ Legal & Ethics
This tool automates a third-party service (LinkedIn). By using it:
You agree to LinkedIn's Terms of Service
You acknowledge that automation may violate LinkedIn's TOS and risk account restrictions
You are solely responsible for your usage
The authors disclaim all liability for account actions
We do not encourage spam, unsolicited outreach, or any activity that violates LinkedIn's fair-use policies. Use responsibly.
License
MIT © 2026 linkedin-mcp-pro contributors
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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/horizonbymuneeb/linkedin-mcp-pro'
If you have feedback or need assistance with the MCP directory API, please join our Discord server