Open-source MCP server for LinkedIn. Give Claude and any MCP-compatible AI agent access to profiles, companies, jobs, and messages.
# MCP Server for LinkedIn
An MCP server that connects AI assistants like Claude to LinkedIn through your own logged-in browser session. Look up profiles and companies, send messages, manage your inbox, or search for jobs. All browser actions run locally on your machine.
> This is an independent open-source project, not affiliated with, authorized by, endorsed by, or sponsored by LinkedIn or Microsoft. LinkedIn is a trademark of LinkedIn Corporation and is used here only to identify the service this software interacts with.
LinkedIn MCP Sponsor
> This MCP server is supported by [**Unipile**](https://golink.onl/unipile-link). Unipile is the fully managed cloud option for developers: a hosted LinkedIn API for Classic, Sales Navigator, and Recruiter that handles auth, sessions, and infrastructure for you.
[Try Unipile free for 7 days →](https://golink.onl/unipile-free-trial)
---
## Installation Methods - LinkedIn MCP Server
| Tool | Description |
|------|-------------|
| `get_person_profile` | Get profile info with explicit section selection (experience, education, interests, honors, languages, certifications, skills, projects, contact_info, posts) |
| `get_my_profile` | Get the authenticated user's own LinkedIn profile (same sections as get_person_profile) |
| `connect_with_person` | Send a connection request or accept an incoming one, with optional note |
| `get_sidebar_profiles` | Extract profile URLs from sidebar recommendation sections ("More profiles for you", "Explore premium profiles", "People you may know") on a profile page |
| `get_inbox` | List recent conversations from the LinkedIn messaging inbox |
| `get_conversation` | Read a specific messaging conversation by username or thread ID |
| `search_conversations` | Search messages by keyword |
| `send_message` | Compose/send a new message to a LinkedIn user (requires confirmation; profile-based targeting may open a separate DM instead of replying in an existing thread — see #483) |
| `get_company_profile` | Extract company information with explicit section selection (posts, jobs); about-section references may include a `company_urn` entry carrying the numeric id used by LinkedIn's people-search `currentCompany` URL facet |
| `get_company_posts` | Get recent posts from a company's LinkedIn feed |
| `search_companies` | Search for companies on LinkedIn by keywords |
| `get_company_employees` | List employees at a company from the /people/ page, with optional keyword filter |
| `search_jobs` | Search for jobs with keywords and location filters |
| `get_saved_jobs` | List job postings saved by the authenticated user |
| `search_people` | Search for people by keywords, location, connection degree (1st/2nd/3rd), and current company |
| `get_job_details` | Get detailed information about a specific job posting |
| `get_feed` | Get recent posts from the authenticated user's home feed |
| `search_posts` | Search posts/content globally by keyword (the "Posts" tab) with an optional recency filter (past-24h/past-week/past-month); returns unordered candidate permalinks in references |
| `close_session` | Close browser session and clean up resources |
## uvx Setup (Recommended)
**Prerequisites:** [Install uv](https://docs.astral.sh/uv/getting-started/installation/).
### Installation
**Client Configuration**
```json
{
"mcpServers": {
"mcp-server-linkedin": {
"command": "uvx",
"args": ["mcp-server-linkedin@latest"],
"env": { "UV_HTTP_TIMEOUT": "300" }
}
}
}
```
The `@latest` tag turns on automatic updates, which keep the server working with LinkedIn's current page structure. The server starts quickly, prepares the shared Patchright Chromium browser cache in the background under `~/.linkedin-mcp/patchright-browsers`, and opens a LinkedIn login browser window on the first tool call that needs authentication.
AI agent? Get a quick confirmation from the user before enabling automatic updates.
> [!NOTE]
> Early tool calls may return a setup/authentication-in-progress error until browser setup or login finishes. If you prefer to create a session explicitly, run `uvx mcp-server-linkedin@latest --login`.
### uvx Setup Help
Configuration
Transport modes
- **Default (stdio)**: Standard communication for local MCP servers
- **Streamable HTTP**: For a web-based MCP server
- If no transport is specified, the server defaults to `stdio`
- An interactive terminal without explicit transport shows a chooser prompt
CLI options
**Session:**
- `--login` - Open a browser to sign in and save the session
- `--import-from-browser [BROWSER]` - Reuse a session from a locally signed-in Chromium browser (`chrome`, `chromium`, `brave`, `edge`, `arc`, `vivaldi`, `helium`, `yandex`, `whale`, `auto`). Bare flag picks `auto`, the most recently used browser with a live LinkedIn session.
- `--auto-import` / `--no-auto-import` - Import a session from a signed-in local browser on the first tool call that needs one, before falling back to manual login (default: on). Skipped in Docker, behind a proxy, and on a non-loopback HTTP bind. On macOS the keychain may prompt once.
- `--logout` - Clear the stored session
- `--login-viewer` - Docker only: show the `--login` browser at a token-protected URL on port 6080 (see [Authentication](#authentication))
- `--user-data-dir PATH` - Browser profile directory (default: ~/.linkedin-mcp/profile). Rotating or clearing a session deletes this directory *and its parent*, which holds the stored cookies and derived profiles.
- `--claim-profile-root` - Take over a profile directory the server will not claim on its own, such as one whose parent already holds other files. Needed once per directory.
**Transport:**
- `--transport {stdio,streamable-http}` - Force the transport mode (default: stdio)
- `--host HOST` / `--port PORT` / `--path PATH` - HTTP server address (defaults: 127.0.0.1, 8000, /mcp)
**Timeouts:**
- `--timeout MS` - Timeout for a single page operation (default: 5000)
- `--tool-timeout SECONDS` - Timeout for a whole tool call (default: 180). Raise it for heavy scrapes, slow networks, or a cold-start browser.
- `--login-timeout SECONDS` - How long the login browser waits for you to finish signing in (default: 1800; 0 = no limit). `--login-viewer` ends the session after 30 minutes either way.
- `--login-inline-wait SECONDS` - How long a tool call waits for a login to finish before telling the model to retry (default: 25, max 45; 0 = return at once)
**Shared browser:**
- `--browser-wait SECONDS` - How long to wait for another server process to hand over the shared browser (default: 25, max 45; 0 = report busy at once). Only matters with several MCP clients running at once.
- `--browser-min-hold SECONDS` - Shortest time this process keeps the shared browser before handing it over (default: 20). Clamped to 3 seconds below `--browser-wait`, so raise that one along with it. Higher means fewer browser restarts but longer waits for other clients.
- `--browser-idle-timeout SECONDS` - Close an idle browser and release the profile after this long without a tool call (default: 600; 0 = keep it open)
**Browser:**
- `--no-headless` - Show the browser window (useful for debugging)
- `--chrome-path PATH` - Path to a Chrome/Chromium executable
- `--proxy-server URL` - Route browser traffic through a proxy, as `scheme://host:port`. Set it up **before** `--login`; see [Using a proxy](#using-a-proxy).
**Other:**
- `--log-level {DEBUG,INFO,WARNING,ERROR}` - Logging level (default: WARNING)
Import a session from your everyday browser
If you are already signed into LinkedIn in Chrome, Chromium, Brave, Edge, Arc, Vivaldi, Helium, Yandex, or Naver Whale, you can skip the manual `--login` step and reuse that session:
```bash
# Auto-pick the most recently used browser with a live LinkedIn session
uvx mcp-server-linkedin@latest --import-from-browser
# Or target a specific browser
uvx mcp-server-linkedin@latest --import-from-browser brave
```
This reads the browser's LinkedIn cookies, validates them against your feed, and saves them to `~/.linkedin-mcp/profile/`, the same place `--login` writes to. Notes:
- With several signed-in browsers, the most recently used live LinkedIn session is tried first. If LinkedIn rejects it (revoked or remote-logged-out), the next most recent is tried automatically; the first the server accepts is imported. There is no prompt to pick. Pass a browser name to target one specifically.
- On macOS the OS keychain may prompt to allow access to the browser's Safe Storage. Close the source browser first for the most reliable read.
- Cookies protected by Chrome 127+ app-bound encryption (`v20`) cannot be decrypted without OS elevation; in that case use `--login` instead.
- Imported cookies match a real login's on-disk set. The local server reads them back in full from the saved profile; the Docker bridge narrows to the same minimal auth subset it uses for a normal session.
HTTP mode and debugging
**Basic Usage Examples:**
```bash
# Run with debug logging
uvx mcp-server-linkedin@latest --log-level DEBUG
```
**HTTP Mode Example (for web-based MCP clients):**
```bash
uvx mcp-server-linkedin@latest --transport streamable-http --host 127.0.0.1 --port 8080 --path /mcp
```
Runtime server logs are emitted by FastMCP/Uvicorn.
Tool calls are serialized to protect the shared LinkedIn browser session, both
within one server process and across separate ones. If you run several MCP
clients at once, each starts its own server process, and only one of them uses
the browser at a time; the others wait briefly and take over as soon as it
finishes a call. A client that waits too long gets a "browser is busy" message
and can simply retry. Use `--log-level DEBUG` to see the wait/acquire/release
logs.
This covers processes on the same machine and in the same runtime. It does not
extend between the host and a Docker container sharing the same
`~/.linkedin-mcp` directory, so do not run `--login` or `--logout` on the host
while a container is running.
**Test with mcp inspector:**
1. Install and run mcp inspector ```bunx @modelcontextprotocol/inspector```
2. Click pre-filled token url to open the inspector in your browser
3. Select `Streamable HTTP` as `Transport Type`
4. Set `URL` to `http://localhost:8080/mcp`
5. Connect
6. Test tools
❗ Troubleshooting
Installation issues
- Ensure you have uv installed: `curl -LsSf https://astral.sh/uv/install.sh | sh`
- Check uv version: `uv --version` (should be 0.4.0 or higher)
- On first run, `uvx` downloads all Python dependencies. On slow connections, uv's default 30s HTTP timeout may be too short. The recommended config above already sets `UV_HTTP_TIMEOUT=300` (seconds) to avoid this.
- *Windows, `DLL load failed while importing _greenlet`*: move to greenlet 3.5.5 or newer, whose published Windows wheels carry the C++ runtime inside the extension again. A fresh `uvx` run resolves that on