Universal LinkedIn MCP Server
Universal LinkedIn MCP Server
A production-grade Model Context Protocol (MCP) server that connects your AI assistant (Claude, Grok, Cursor, Antigravity) to LinkedIn with human-like stealth browser automation, mathematical account boundary guardrails, and zero official API restrictions.
đź’ˇ Why This Exists: The Problem & The Solution
❌ The Problem
The Closed API Wall: LinkedIn's official Developer APIs are gated behind enterprise partner programs (LinkedIn Marketing Developer Platform / LinkedIn Talent Solutions). Solo builders, freelancers, and AI agent developers cannot obtain write access to publish posts, send connection invites, or update profiles programmatically.
The Anti-Bot Ban Trap: Standard automation tools (Puppeteer, Selenium, raw Chromium binaries) trigger LinkedIn's bot detection checkpoints within minutes. They broadcast
navigator.webdriver = true, lack persistent cookie management, type at robotic speeds, and fail when presented with 2FA or CAPTCHAs, resulting in instant account restrictions.The LLM Safety & Prompt-Injection Hazard: Giving an autonomous LLM browser access is dangerous. Without rigid guardrails, prompt injections can trick an AI into editing unintended accounts, scraping unauthorized targets, or blasting spam across your professional network.
Desktop vs. Cloud AI Fragmentation: Desktop AI tools (Claude Desktop, Cursor) communicate over local
stdio, whereas web-based cloud AI (like Grok.com) run on remote servers and cannot access your local browser or session without secure tunneling and CORS support.
âś… The Solution
Full 29-Tool Platform Without API Keys: Provides your AI with complete human capabilities—profile editing, rich posting (with images/PDFs), interactive polls, inbox history, connection management, analytics, and executive intelligence briefings.
Native Google Chrome Stealth Engine: Uses your computer's real, native Google Chrome installation rather than generic Chromium binaries. Strips automation markers (
navigator.webdriver), introduces human typing delay jitter, and executes natural Bezier-curve mouse movements.Passwordless, 2FA-Friendly Session Management: Never asks for or stores your plaintext LinkedIn password. You log in interactively once through your real browser, solve any 2FA challenge, and the encrypted session state is saved locally to
~/.linkedin_mcp. Built-in keep-alive telemetry extends LinkedIn's 30-day sliding activity window automatically.Mathematical Account Boundaries: Profile mutation tools (
update_my_headline,update_my_about,add_experience, etc.) do not accept a target profile parameter. They are hardcoded to/in/me. It is mathematically impossible for an AI to modify an external profile.Universal Multi-Transport Architecture: Runs locally via
stdiousing zero-cloneuvx, or remotely viastreamable-http/ssewith full CORS support and a 1-click Cloudflare Tunnel script for Grok.com.
Related MCP server: LinkedIn Buddy
đź“‹ Prerequisites
Before setting up, make sure your computer has:
Google Chrome: Installed and functioning normally.
Python 3.10 or higher: python.org/downloads
uv(Fast Python Package Runner):Windows (PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
⚡ Step 1: One-Time Interactive Authentication
You only need to log in once. The server saves your session state to ~/.linkedin_mcp so your AI assistants remain authenticated across restarts.
Open your terminal and run:
uvx --from git+https://github.com/ChimbuezeDavid/linkedin-mcp python -c "import asyncio; from linkedin_mcp.tools.auth import linkedin_start_login; asyncio.run(linkedin_start_login())"What happens:
A real Google Chrome browser window will open automatically.
Enter your LinkedIn credentials and complete 2FA / verification if prompted.
Once your LinkedIn home feed loads, the tool automatically verifies your identity, saves your encrypted cookies, and closes the browser.
Your terminal will display:
Active session verified for <Your Name>.
🔌 Step 2: Connect to Your AI Assistant
Choose your setup below based on whether you are using a Desktop AI Client (Claude, Cursor, Antigravity) or a Cloud Web AI (Grok.com).
Option A: Desktop AI Clients (Zero-Clone via uvx)
You do not need to download or clone this repository. Your AI client will execute it directly using uvx.
1. Claude Desktop
Add this snippet to your claude_desktop_config.json:
Windows:
%APPDATA%\Claude\claude_desktop_config.jsonmacOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"linkedin": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/ChimbuezeDavid/linkedin-mcp",
"linkedin-mcp"
]
}
}
}2. Antigravity
Open your Antigravity MCP settings (mcp_config.json or Settings > MCP):
{
"mcpServers": {
"linkedin": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/ChimbuezeDavid/linkedin-mcp",
"linkedin-mcp"
]
}
}
}3. Cursor & Windsurf
Add to .cursor/mcp.json or your global Cursor settings:
{
"mcpServers": {
"linkedin": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/ChimbuezeDavid/linkedin-mcp",
"linkedin-mcp"
]
}
}
}4. Claude Code CLI
Run directly from your terminal:
claude mcp add linkedin uvx --from git+https://github.com/ChimbuezeDavid/linkedin-mcp linkedin-mcpOption B: Cloud Web-Based AI (Grok.com)
Cloud-based AI assistants (like grok.com/connectors) cannot connect to localhost. They need a public, encrypted tunnel with CORS and Streamable HTTP support.
We include a pre-configured 1-click startup script that starts the MCP server in Streamable HTTP mode on port 8765 and launches a Cloudflare Tunnel.
Step 1: Run the Grok Connector Script
Clone the repository and run the script:
git clone https://github.com/ChimbuezeDavid/linkedin-mcp.git
cd linkedin-mcpOn Windows (PowerShell):
powershell -ExecutionPolicy Bypass -File .\run_for_grok.ps1On macOS / Linux:
# Terminal 1: Launch MCP server in Streamable HTTP mode uv run linkedin-mcp --transport streamable-http --port 8765 # Terminal 2: Expose via Cloudflare Tunnel cloudflared tunnel --url http://127.0.0.1:8765
Step 2: Configure Grok.com
Copy the public tunnel URL displayed in your terminal (e.g.
https://example-subdomain.trycloudflare.com).Go to grok.com/connectors in your browser.
Click Add Custom MCP Server:
Name:
LinkedIn MCPURL:
https://example-subdomain.trycloudflare.com/mcp(⚠️ Important: you must append/mcpto the end of the URL)
Click Save and start chatting with Grok!
Why /mcp instead of /sse? Cloudflare quick tunnels do not support persistent Server-Sent Events (SSE) due to proxy buffering, but work seamlessly with Streamable HTTP (/mcp). The server includes built-in CORS middleware to ensure seamless communication with grok.com.
Option C: Local Development Setup
If you want to contribute or modify the codebase locally:
git clone https://github.com/ChimbuezeDavid/linkedin-mcp.git
cd linkedin-mcp
uv syncTo configure your AI client to point to your local code:
{
"mcpServers": {
"linkedin": {
"command": "uv",
"args": [
"--directory",
"<ABSOLUTE_PATH_TO_LINKEDIN_MCP>",
"run",
"linkedin-mcp"
]
}
}
}🛠️ Available MCP Tools (29 Tools)
All tools operate strictly within the authenticated account boundary and enforce @require_auth.
Category | Tool Name | Key Arguments | Description |
Auth & Keep-Alive |
| (none) | Inspects session validity, active account identity, and sliding-window age. |
|
| Opens an interactive Chrome window for 1-click sign-in and 2FA. | |
| (none) | Clears stored session tokens, local cookies, and cached profile data. | |
| (none) | Performs a silent heartbeat to extend the 30-day session sliding window. | |
Self-Profile |
| (none) | Retrieves your authenticated profile details (name, headline, bio, experience). |
(Hard-Locked to |
|
| Updates your headline under your name. |
|
| Updates your About / bio summary text. | |
|
| Adds an academic credential to your profile. | |
|
| Adds a job or role to your Experience section. | |
|
| Adds a skill to your Skills section (with suggestion auto-selection). | |
|
| Adds a project to your Projects section. | |
|
| Configures "Open to work" career preferences. | |
|
| Updates client services and offerings on your profile. | |
Browsing & Search |
|
| Searches LinkedIn for professionals with connection degree badges (1st/2nd/3rd). |
|
| Reads any member's public/network profile details in read-only mode. | |
Feed, Posts & Polls |
|
| Reads recent posts from your personal home feed. |
|
| Publishes a post authored by your account, optionally attaching image/PDF. | |
|
| Publishes an interactive poll to your feed (2-4 options, custom duration). | |
|
| Comments on a post as your authenticated profile. | |
Analytics & Insights |
|
| Retrieves impressions, reactions, and comments for your recent posts. |
| (none) | Retrieves private profile view counts and viewer demographics. | |
Direct Messaging |
|
| Lists recent direct message threads in your inbox. |
|
| Reads complete message history and replies for a specific thread. | |
|
| Dispatches a direct message from your account. | |
Network Growth |
|
| Sends a connection invitation with an optional personalized note. |
| (none) | Lists incoming connection invitations received by your account. | |
|
| Accepts or ignores a pending connection invitation. | |
Agentic Skills |
|
| Generates a daily executive digest: inbox, invitations, analytics & feed trends. |
| (none) | Audits completeness across 6 sections and gives an actionable score & tips. |
đź§Ş Automated Testing & Verification
The repository includes a comprehensive unit test suite verifying boundary constraints, security invariants, parameter validation, and session health calculation:
uv run python -m unittest discover testsExpected output:
Ran 12 tests in 0.015s
OKđź”’ Security & Privacy Invariants
Zero Plaintext Password Exposure: The server never prompts for, reads, or stores your LinkedIn password.
Local Storage Only: All session state, cookies, and identity caches are saved strictly to your local machine at
~/.linkedin_mcp. No external telemetry or cloud servers are used.Mathematical Impossibility of Impersonation: Self-profile editing tools are hard-coded to navigate to
/in/me/. There is notarget_profile_urlparameter, preventing prompt-injected LLMs from altering other members' profiles.
đź“„ License
MIT License. See LICENSE for details. Authored with ❤️ by Chimbueze (David) Okoroji.
Available Tools
29 toolsadd_educationA
Add an education credential to your own LinkedIn profile.
Security Notice: Strictly locked to your authenticated account (/in/me).
Args: school: Name of university or school (e.g. 'Afe Babalola University'). degree: Degree type (e.g. 'Bachelor of Science - BSc'). field_of_study: Major or area of study (e.g. 'Computer Science', 'Data Analysis'). start_month: Starting month (e.g. 'September'). start_year: Starting year (e.g. '2020'). end_month: Graduation or ending month (e.g. 'June'). end_year: Graduation or ending year (e.g. '2024'). grade: GPA or honors (optional). activities: Clubs, societies, sports (optional). description: Notes, courses, or achievements (optional).
Inputs: school (required), grade, degree, end_year, +6 more. Returns: result
add_experienceA
Add a work position or experience to your own LinkedIn profile.
Security Notice: Strictly locked to your authenticated account (/in/me).
Args: title: Job title (e.g. 'Full-Stack AI Engineer'). company: Company or organization name (e.g. 'AltSchool Africa'). employment_type: 'Full-time', 'Part-time', 'Contract', 'Internship', 'Freelance'. location: City or region (e.g. 'Lagos, Nigeria'). location_type: 'On-site', 'Hybrid', or 'Remote'. is_current: Whether you currently work in this role (default: True). start_month: Start month (e.g. 'January'). start_year: Start year (e.g. '2024'). end_month: End month (if not current). end_year: End year (if not current). description: Role accomplishments and responsibilities.
Inputs: title (required), company (required), end_year, location, +7 more. Returns: result
add_projectA
Add a project to your own LinkedIn profile under Projects.
Security Notice: Strictly locked to your authenticated account (/in/me).
Args: title: Project title or name (e.g. 'Argus Agent', 'NairaPulse AI'). description: Description of the project, architecture, tech stack, and achievements. url: Link to project demo or repository (optional). start_month: Starting month (e.g. 'January'). start_year: Starting year (e.g. '2024'). end_month: Ending month (optional). end_year: Ending year (optional).
Inputs: title (required), url, end_year, end_month, +3 more. Returns: result
add_skillA
Add a skill to your own LinkedIn profile.
Security Notice: Strictly locked to your authenticated account (/in/me).
Args: skill_name: The name of the skill (e.g. 'Model Context Protocol (MCP)', 'Python', 'FastAPI').
Inputs: skill_name (required). Returns: result
analyze_profile_strengthA
Audit your profile completeness, section strength, and generate actionable recommendations to optimize LinkedIn discoverability.
Inputs: no named parameters. Returns: result
check_login_statusA
Check LinkedIn authentication status and inspect the active user's identity details.
Inputs: no named parameters. Returns: result
comment_on_postA
Leave a comment on a LinkedIn post as your authenticated account.
Args: post_url: The URL of the post. comment_text: The comment text to publish.
Inputs: post_url (required), comment_text (required). Returns: result
create_pollA
Create and publish an interactive poll to your LinkedIn feed.
Args: question: The question for the poll (up to 140 chars). options: List of poll answer options (minimum 2, maximum 4 options, each up to 30 chars). duration: Duration for the poll to run: '1_day', '3_days', '1_week', or '2_weeks' (default: '1_week').
Inputs: options (required), question (required), duration. Returns: result
create_postA
Publish a post to your LinkedIn feed authored exclusively by your profile, optionally attaching an image or document.
Args: text: The text content of your post. media_path: Optional path to an image (.png, .jpg) or document (.pdf) to attach.
Inputs: text (required), media_path. Returns: result
get_conversation_messagesA
Read full message history and replies for a specific conversation in your inbox.
Args: recipient_name: Name or keyword matching the conversation partner. limit: Maximum number of recent messages to retrieve (default: 10, max: 30).
Inputs: recipient_name (required), limit. Returns: result
get_feedA
Read recent posts from your personal LinkedIn home feed.
Args: limit: Number of posts to read (default: 5, max: 15).
Inputs: limit. Returns: result
get_my_profileA
Retrieve full profile details for your own authenticated LinkedIn profile.
Security Notice: This tool can only read your own profile information.
Inputs: no named parameters. Returns: result
get_network_briefingB
Synthesize a complete daily intelligence briefing: unread messages, pending invitations, post analytics, and top feed trends.
Args: limit: Number of feed items and recent posts to include in the briefing (default: 5).
Inputs: limit. Returns: result
get_pending_invitationsA
List pending incoming connection invitations received by your account.
Inputs: no named parameters. Returns: result
get_post_analyticsA
Retrieve engagement metrics (impressions, reactions, comments, reposts) for recent posts authored by your account.
Args: limit: Maximum number of recent posts to analyze (default: 5, max: 15).
Inputs: limit. Returns: result
get_profile_viewsA
Retrieve private profile view analytics and viewer demographics for your account.
Inputs: no named parameters. Returns: result
list_conversationsA
List recent direct message conversations from your authenticated inbox.
Args: limit: Maximum conversations to retrieve (default: 10, max: 20).
Inputs: limit. Returns: result
logoutA
Clear all stored LinkedIn session credentials, cookies, and local profile caches.
Inputs: no named parameters. Returns: result
manage_invitationA
Accept or ignore a pending incoming connection invitation.
Args: sender_name: Name of the person whose invitation to manage. action: Either 'accept' or 'ignore' (default: 'accept').
Inputs: sender_name (required), action. Returns: result
refresh_sessionB
Test and extend the active LinkedIn session validity with sliding window keep-alive telemetry.
Inputs: no named parameters. Returns: result
search_peopleA
Search for professionals on LinkedIn through your authenticated account.
Args: keywords: Search term (e.g. name, title, skills). location: Optional location filter (e.g. 'San Francisco', 'United Kingdom'). current_company: Optional current company name. limit: Maximum results to retrieve (default: 10, max: 25).
Inputs: keywords (required), limit, location, current_company. Returns: result
send_connection_requestA
Send a connection invitation to a professional from your authenticated account.
Args: profile_url: Profile URL of the member to connect with. custom_note: Optional personalized message (up to 300 characters).
Inputs: profile_url (required), custom_note. Returns: result
send_messageA
Send a direct message to a LinkedIn member from your authenticated account.
Args: recipient_profile_url: Profile URL of the recipient. message_text: The message body to send.
Inputs: message_text (required), recipient_profile_url (required). Returns: result
start_loginA
Open an interactive browser window to sign in to LinkedIn, solve 2FA, and save the session.
Args: timeout_seconds: Maximum time in seconds to wait for sign-in (default: 300).
Inputs: timeout_seconds. Returns: result
update_job_preferencesA
Configure your 'Open to work' job preferences on LinkedIn.
Security Notice: Strictly locked to your authenticated account (/in/me).
Args: job_titles: List of target job titles (e.g. ['AI Engineer', 'Full-Stack Developer']). location_types: Workplace modes: ['On-site', 'Hybrid', 'Remote']. locations: Target cities or countries (e.g. ['Nigeria', 'United Kingdom']). employment_types: Types of work: ['Full-time', 'Part-time', 'Contract', 'Internship'].
Inputs: locations, job_titles, location_types, employment_types. Returns: result
update_my_aboutA
Update the About / summary section on your own LinkedIn profile.
Security Notice: Strictly locked to your authenticated account.
Args: summary: New bio/summary text for your About section.
Inputs: summary (required). Returns: result
update_my_headlineA
Update the headline on your own LinkedIn profile.
Security Notice: Strictly locked to your authenticated account. Does not accept any other profile target.
Args: headline: New headline text to display under your name.
Inputs: headline (required). Returns: result
update_my_servicesA
Configure or update client services listed on your own LinkedIn profile.
Security Notice: Strictly locked to your authenticated account (/in/me).
Args: services_to_add: List of service names to add (e.g. ['Custom Software Development', 'Web Development']). services_to_remove: List of service names to remove (e.g. ['Graphic Design']). description: Summary of client offerings and experience (up to 500 characters).
Inputs: description, services_to_add, services_to_remove. Returns: result
view_profileA
View another LinkedIn member's profile as your authenticated user (strictly read-only).
Args: profile_url: The member's profile URL or vanity username.
Inputs: profile_url (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 29 tools
Most tools have clearly distinct purposes (e.g., add_education vs add_experience, get_my_profile vs view_profile). Some overlap exists between get_network_briefing and get_feed/get_pending_invitations, but descriptions clarify their roles, so misselection is unlikely.
All tools use snake_case and follow a consistent verb_noun pattern (get, update, add, create, send, list, etc.). Even 'logout' fits the style as a single-word verb. No mixing of conventions or inconsistent styles.
29 tools is above the typical 15-25 range, but the server aims to cover a broad LinkedIn surface (auth, profile, feed, messaging, connections, analytics). While heavy, it is not absurdly excessive, and each tool serves a distinct purpose. Still, it feels slightly over-scoped.
The server covers core LinkedIn workflows well: profile editing, posting, messaging, connections, and analytics. However, there are notable gaps: no update or delete operations for education/experience/skills (only add), no post deletion or editing, and no ability to remove connections. These missing lifecycle operations could cause dead ends for agents.
Related MCP Connectors
Managed LinkedIn MCP server for AI agents: search, connect, message and enrich on accounts you own.
LinkedIn MCP with 47 tools: post, comment, DM and run comment-to-DM automations inside your limits.
Hosted LinkedIn MCP server on your own account: 35 tools for search, profiles, inbox, posts, pages.
The all-in-one LinkedIn MCP server: six outbound specialists for LinkedIn and email.
Related MCP Servers
- AlicenseAqualityDmaintenanceFully featured MCP server that provides automation tools for LinkedIn, supporting browser-based scraping and API-based operations for content management, media uploads, and reactions.64MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for LinkedIn automation that enables AI agents to perform LinkedIn actions (search, inbox, feed, jobs, etc.) safely with human-like evasion and two-phase commit preview.4 npm3MIT
- AlicenseNot gradedqualityDmaintenanceAI-powered LinkedIn automation server for content generation, profile/company data extraction, and connection request automation, integrating with MCP clients like Claude Desktop.MIT
- AlicenseNot gradedqualityCmaintenanceMCP 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