Skip to main content
Glama
Universal LinkedIn MCP Server

Universal LinkedIn MCP Server

Universal LinkedIn MCP Server

Model Context Protocol Python 3.10+ Tools: 29 CI License: MIT

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

  1. 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.

  2. 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.

  3. 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.

  4. 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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. Universal Multi-Transport Architecture: Runs locally via stdio using zero-clone uvx, or remotely via streamable-http / sse with 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:

  1. Google Chrome: Installed and functioning normally.

  2. Python 3.10 or higher: python.org/downloads

  3. 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:

  1. A real Google Chrome browser window will open automatically.

  2. Enter your LinkedIn credentials and complete 2FA / verification if prompted.

  3. Once your LinkedIn home feed loads, the tool automatically verifies your identity, saves your encrypted cookies, and closes the browser.

  4. 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.json

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Linux: ~/.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-mcp

Option 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-mcp
  • On Windows (PowerShell):

    powershell -ExecutionPolicy Bypass -File .\run_for_grok.ps1
  • On 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

  1. Copy the public tunnel URL displayed in your terminal (e.g. https://example-subdomain.trycloudflare.com).

  2. Go to grok.com/connectors in your browser.

  3. Click Add Custom MCP Server:

    • Name: LinkedIn MCP

    • URL: https://example-subdomain.trycloudflare.com/mcp (⚠️ Important: you must append /mcp to the end of the URL)

  4. Click Save and start chatting with Grok!

TIP

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 sync

To 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

check_login_status

(none)

Inspects session validity, active account identity, and sliding-window age.

start_login

timeout_seconds

Opens an interactive Chrome window for 1-click sign-in and 2FA.

logout

(none)

Clears stored session tokens, local cookies, and cached profile data.

refresh_session

(none)

Performs a silent heartbeat to extend the 30-day session sliding window.

Self-Profile

get_my_profile

(none)

Retrieves your authenticated profile details (name, headline, bio, experience).

(Hard-Locked to /in/me)

update_my_headline

headline

Updates your headline under your name.

update_my_about

summary

Updates your About / bio summary text.

add_education

school, degree, field_of_study, start_year, end_year, ...

Adds an academic credential to your profile.

add_experience

title, company, employment_type, location, description, ...

Adds a job or role to your Experience section.

add_skill

skill_name

Adds a skill to your Skills section (with suggestion auto-selection).

add_project

title, description, url, start_year, end_year

Adds a project to your Projects section.

update_job_preferences

job_titles, location_types, locations, employment_types

Configures "Open to work" career preferences.

update_my_services

services_to_add, services_to_remove, description

Updates client services and offerings on your profile.

Browsing & Search

search_people

keywords, location, current_company, limit

Searches LinkedIn for professionals with connection degree badges (1st/2nd/3rd).

view_profile

profile_url

Reads any member's public/network profile details in read-only mode.

Feed, Posts & Polls

get_feed

limit

Reads recent posts from your personal home feed.

create_post

text, media_path (optional)

Publishes a post authored by your account, optionally attaching image/PDF.

create_poll

question, options, duration

Publishes an interactive poll to your feed (2-4 options, custom duration).

comment_on_post

post_url, comment_text

Comments on a post as your authenticated profile.

Analytics & Insights

get_post_analytics

limit

Retrieves impressions, reactions, and comments for your recent posts.

get_profile_views

(none)

Retrieves private profile view counts and viewer demographics.

Direct Messaging

list_conversations

limit

Lists recent direct message threads in your inbox.

get_conversation_messages

recipient_name, limit

Reads complete message history and replies for a specific thread.

send_message

recipient_profile_url, message_text

Dispatches a direct message from your account.

Network Growth

send_connection_request

profile_url, custom_note

Sends a connection invitation with an optional personalized note.

get_pending_invitations

(none)

Lists incoming connection invitations received by your account.

manage_invitation

sender_name, action

Accepts or ignores a pending connection invitation.

Agentic Skills

get_network_briefing

limit

Generates a daily executive digest: inbox, invitations, analytics & feed trends.

analyze_profile_strength

(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 tests

Expected 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 no target_profile_url parameter, 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 tools
add_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

    A3.7/5.0

    Scored across 29 tools

    Disambiguation4/5

    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.

    Naming Consistency5/5

    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.

    Tool Count3/5

    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.

    Completeness3/5

    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

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Fully featured MCP server that provides automation tools for LinkedIn, supporting browser-based scraping and API-based operations for content management, media uploads, and reactions.
      6
      4
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP 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 npm
      3
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      MCP 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.
      2
      MIT