Skip to main content
Glama
LinkedIn MCP Server

LinkedIn MCP Server

LinkedIn MCP Server

A local Model Context Protocol server that exposes structured LinkedIn profile, company, and job data to MCP-compatible clients. It uses a persistent Patchright browser session, so you authenticate interactively instead of storing a LinkedIn password in an environment variable.

WARNING

LinkedIn may restrict automated access, and use of this project may be subject to LinkedIn's terms and account limitations. Use it responsibly with your own account. This project is not affiliated with or endorsed by LinkedIn.

Features

Area

MCP tools

People

get_person_profile, search_people, send_connection_request

Companies

get_company_profile, get_company_posts

Jobs

get_job_details, search_jobs

Session

close_browser

Profile reads can include experience, education, interests, honors, languages, contact information, and posts. Company reads can include about information, posts, and jobs. Job search supports date, type, experience, workplace, Easy Apply, and sorting filters.

Connection requests are deliberately constrained: the tool accepts an exact profile slug, previews the current state by default, requires confirm=true to write, and never includes a note.

Related MCP server: linkedin-mcp-server

Requirements

  • Python 3.12+

  • uv

  • A LinkedIn account

The project uses pyproject.toml and uv.lock; a requirements.txt file is intentionally not needed.

Setup

git clone https://github.com/aarnav-hariramani/linkedin-mcp.git
cd linkedin-mcp
uv sync --locked
uv run patchright install chromium

Authenticate once in a visible browser:

uv run linkedin-mcp-server --login

The default profile is stored at ~/.linkedin-mcp-server/browser-data. It contains sensitive session cookies and must never be committed or shared.

Check or clear the saved session:

uv run linkedin-mcp-server --status
uv run linkedin-mcp-server --logout

MCP client configuration

Use the absolute path to your clone. For Codex:

codex mcp add linkedin -- uv --directory /absolute/path/to/linkedin-mcp-server run linkedin-mcp-server

Equivalent JSON configuration for clients such as Claude Desktop or Cursor:

{
  "mcpServers": {
    "linkedin": {
      "command": "uv",
      "args": [
        "--directory",
        "/absolute/path/to/linkedin-mcp-server",
        "run",
        "linkedin-mcp-server"
      ]
    }
  }
}

Restart the MCP client after changing its configuration.

Running directly

The recommended local transport is stdio:

uv run linkedin-mcp-server

For local development, loopback-only HTTP is also available:

uv run linkedin-mcp-server \
  --transport streamable-http \
  --host 127.0.0.1 \
  --port 8000

Connect to http://127.0.0.1:8000/mcp. The server rejects non-loopback HTTP bindings.

Configuration

Copy the documented template only when you need to override defaults:

cp .env.example .env

Configuration precedence is CLI arguments, existing environment variables, .env.local, .env, then defaults.

Variable

Default

Purpose

LINKEDIN_TRANSPORT

stdio

stdio or streamable-http

LINKEDIN_HOST

127.0.0.1

Loopback HTTP bind address

LINKEDIN_PORT

8000

HTTP port

LINKEDIN_PATH

/mcp

HTTP endpoint path

LINKEDIN_LOG_LEVEL

WARNING

DEBUG, INFO, WARNING, or ERROR

LINKEDIN_HEADLESS

true

Run without a visible browser

LINKEDIN_SLOW_MO

0

Browser action delay in milliseconds

LINKEDIN_TIMEOUT

10000

Browser timeout in milliseconds

LINKEDIN_VIEWPORT_WIDTH

1280

Browser viewport width

LINKEDIN_VIEWPORT_HEIGHT

720

Browser viewport height

LINKEDIN_CHROME_PATH

unset

Optional Chromium executable

LINKEDIN_USER_AGENT

unset

Optional browser user agent

LINKEDIN_USER_DATA_DIR

~/.linkedin-mcp-server/browser-data

Persistent browser profile

No username, password, cookie, API key, or token belongs in .env.

Safety model

  • Browser navigation is limited to HTTPS LinkedIn hosts.

  • Raw page HTML is not returned through MCP tools.

  • Persistent profiles are created with restrictive permissions and a marker used for safe logout.

  • HTTP transport is local-only; stdio is preferred.

  • All profile slugs, job IDs, and search input are validated.

  • Writes require explicit confirmation.

See SECURITY.md for handling local session data and reporting vulnerabilities.

Architecture

src/linkedin_mcp_server/
├── domain/       # Models, parsers, validation, and domain errors
├── ports/        # Browser, authentication, and configuration interfaces
├── application/  # Scrape, search, session, and connection use cases
├── adapters/
│   ├── driven/   # Patchright browser, profile auth, environment config
│   └── driving/  # CLI, FastMCP server, tools, serialization
└── container.py  # Dependency composition root

Development

uv sync --locked --group dev
uv run pre-commit install
uv run ruff check .
uv run ruff format --check .
uv run pytest
uv build

Browser-backed integration testing requires a separately authenticated local session. Unit tests and CI must not depend on real credentials.

See CONTRIBUTING.md for the contribution workflow.

Acknowledgments

This project is built on top of eliasbiondo/linkedin-mcp-server by Elias Biondo, which provided the original hexagonal architecture, Patchright-based browser automation, and read-only profile, company, and job scraping tools. This fork adds the send_connection_request write tool, additional navigation and session-safety hardening, and test coverage on top of that foundation.

License

MIT. See LICENSE. Original copyright retained; see the LICENSE file for details.

Available Tools

8 tools
close_browserA

Close the browser instance and release resources. Credentials are preserved.

Inputs: no named parameters. Returns: object

get_company_postsB

Get recent posts from a company's LinkedIn feed.

Args: company_name: LinkedIn company name (e.g., 'google', 'stripe', 'openai')

Inputs: company_name (required). Returns: object

get_company_profileA

Get a specific company's LinkedIn profile.

Args: company_name: LinkedIn company name (e.g., 'google', 'stripe', 'openai') sections: Comma-separated list of extra sections to scrape. The about page is always included. Available sections: posts, jobs Default (None) scrapes only the about page.

Inputs: company_name (required), sections. Returns: object

get_job_detailsB

Get job details for a specific job posting on LinkedIn.

Args: job_id: LinkedIn job ID (e.g., '3912045678', '4108763210')

Inputs: job_id (required). Returns: object

get_person_profileA

Get a specific person's LinkedIn profile.

Args: linkedin_username: LinkedIn username (e.g., 'satyanadella', 'jeffweiner08') sections: Comma-separated list of extra sections to scrape. The main profile page is always included. Available sections: experience, education, interests, honors, languages, contact_info, posts Default (None) scrapes only the main profile page.

Inputs: linkedin_username (required), sections. Returns: object

search_jobsA

Search for jobs on LinkedIn.

Returns job_ids that can be passed to get_job_details for full info.

Args: keywords: Search keywords (e.g., 'backend developer', 'devops engineer') location: Optional location filter (e.g., 'Austin', 'Singapore') max_pages: Maximum number of result pages to load (1-10, default 3) date_posted: Filter by posting date (past_hour, past_24_hours, past_week, past_month) job_type: Filter by job type, comma-separated (full_time, part_time, contract, temporary, volunteer, internship, other) experience_level: Filter by experience level, comma-separated (internship, entry, associate, mid_senior, director, executive) work_type: Filter by work type, comma-separated (on_site, remote, hybrid) easy_apply: Only show Easy Apply jobs (default false) sort_by: Sort results (date, relevance)

Inputs: keywords (required), sort_by, job_type, location, +5 more. Returns: object

search_peopleB

Search for people on LinkedIn.

Args: keywords: Search keywords (e.g., 'product manager', 'ML engineer at Meta') location: Optional location filter (e.g., 'London', 'Berlin')

Inputs: keywords (required), location. Returns: object

send_connection_requestA

Preview or send a LinkedIn connection request without a note. The default confirm=false performs no write and reports whether the profile is ready, already connected, or already pending. Set confirm=true only after verifying the exact profile. This tool never adds a note.

Args: linkedin_username: Exact LinkedIn profile username/slug. confirm: Must be true to actually send the invitation.

Inputs: linkedin_username (required), confirm. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 8 tools

    Disambiguation4/5

    Each tool targets a distinct resource (people, companies, jobs, browser lifecycle), and search vs. detail operations are clearly separated. Minor overlap exists where get_company_profile can fetch posts via sections, duplicating get_company_posts.

    Naming Consistency5/5

    All tools follow a consistent snake_case verb_noun pattern: search_*, get_*, send_*, close_*. The naming is predictable and makes the resource and action immediately clear.

    Tool Count5/5

    Eight tools is a well-scoped set for a LinkedIn API covering people, companies, jobs, and connection actions. Each tool serves a distinct purpose without bloat.

    Completeness4/5

    The main workflows are covered: search people, view profiles, send connection requests, search jobs, get job details, and view company info/posts. Minor gaps exist, such as no company search, no connection request with a note, and no direct 'view my profile' tool.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables LinkedIn API integration for managing profiles, posts, feed, connections, and sending messages through MCP-compatible clients.
      10
      7 npm
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server for LinkedIn API integration. Enables authentication, profile access, connections, search, messaging, and feed management via OAuth2.
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      MCP server providing LinkedIn profile and page access via a stateless OAuth proxy, enabling Claude or MCP clients to interact with LinkedIn data.
      -