LinkedIn MCP Server
Click on "Deploy 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 Server search for data scientist jobs posted this week"
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 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.
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 |
|
Companies |
|
Jobs |
|
Session |
|
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+
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 chromiumAuthenticate once in a visible browser:
uv run linkedin-mcp-server --loginThe 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 --logoutMCP 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-serverEquivalent 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-serverFor local development, loopback-only HTTP is also available:
uv run linkedin-mcp-server \
--transport streamable-http \
--host 127.0.0.1 \
--port 8000Connect 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 .envConfiguration precedence is CLI arguments, existing environment variables, .env.local, .env,
then defaults.
Variable | Default | Purpose |
|
|
|
|
| Loopback HTTP bind address |
|
| HTTP port |
|
| HTTP endpoint path |
|
|
|
|
| Run without a visible browser |
|
| Browser action delay in milliseconds |
|
| Browser timeout in milliseconds |
|
| Browser viewport width |
|
| Browser viewport height |
| unset | Optional Chromium executable |
| unset | Optional browser user agent |
|
| 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;
stdiois 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 rootDevelopment
uv sync --locked --group dev
uv run pre-commit install
uv run ruff check .
uv run ruff format --check .
uv run pytest
uv buildBrowser-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 toolsclose_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
Scored across 8 tools
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.
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.
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.
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
Related MCP Connectors
LinkedIn API as MCP tools to retrieve profile data and publish content. Powered by HAPI MCP.
Real-time B2B professional profiles, company intelligence & jobs hosted MCP. OAuth or API key.
A hosted LinkedIn MCP server for your own account. Paste one address into Claude, ChatGPT, Cursor or n8n to read your inbox, send messages and invitations, and search people. Free to start. Not made by LinkedIn.
Public LinkedIn profiles as JSON: headline, company, experience, and education, via hosted MCP.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables LinkedIn API integration for managing profiles, posts, feed, connections, and sending messages through MCP-compatible clients.107 npmMIT
- AlicenseNot gradedqualityDmaintenanceMCP server for LinkedIn API integration. Enables authentication, profile access, connections, search, messaging, and feed management via OAuth2.MIT
- FlicenseNot gradedqualityDmaintenanceMCP server providing LinkedIn profile and page access via a stateless OAuth proxy, enabling Claude or MCP clients to interact with LinkedIn data.-
- AlicenseAqualityDmaintenanceEnables LinkedIn profile reads and post operations through a local-first MCP server, with OAuth token management and approval-friendly tools for OpenWorker.88 npm1MIT