linkedin-mcp-server

stickerdanielApache-2.0活跃维护

把 LinkedIn 的人脉、公司、职位和消息接入 Claude 等 MCP 兼容 AI 代理,让智能体能直接读取和操作领英数据。

Open-source MCP server for LinkedIn. Give Claude and any MCP-compatible AI agent access to profiles, companies, jobs, and messages.

v4.29.0发布于 2026-10-31 19:17 UTC4,170star +31 / 7 天739fork同步于 2026-11-10 17:40 UTC

怎么上手

由 README 提炼,执行前请确认
uvx mcp-server-linkedin@latest
uvx mcp-server-linkedin@latest --login
硬件要求按 README 说明

README 未说明显存或 GPU 要求;需要本地安装 Chromium 系浏览器(可用 --chrome-path 指定路径),纯 CPU 环境即可运行。

有 Docker 镜像
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

把 LinkedIn 的个人主页、公司、职位和消息接入 Claude 等 MCP 兼容 AI 代理的开源 MCP 服务器

把 LinkedIn 的人脉、公司、职位和消息接入 Claude 等 MCP 兼容 AI 代理,让智能体能直接读取和操作领英数据。

核心能力

  • 复用本地浏览器已登录的 LinkedIn 会话,无需另存账号密码
  • 提供读取个人主页、调研公司、搜索职位、管理会话与好友请求的工具
  • 支持 stdio 与 streamable-http 两种传输模式
  • 用 Patchright Chromium 后台准备共享浏览器缓存,多客户端可共享浏览器
  • 支持从 Chrome、Edge、Brave 等本地 Chromium 浏览器导入会话

容易踩的坑

首次工具调用可能返回认证进行中的错误,需等浏览器准备或登录完成;默认 HTTP 绑定 127.0.0.1:8000 路径 /mcp,改端口需显式传 --host/--port;--logout 或轮换会话会删除 profile 目录及其父目录,注意别放重要文件。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v4.29.0
  1. v4.29.0最新正式版2026-10-31 · 2026-10-31 19:17 UTC

    Highlights

    • Stable error codes. Failed calls name a code in _meta that clients can branch on. (#1390 by @benjamin-di)
    • Usage rules at connect. Clients get the usage rules as MCP server instructions. (#1402 by @mvanhorn)
    • Crashed pages recover. A crashed page is replaced instead of failing every later call. (#1382 by @benjamin-di)

    Features

    • A failed tool call now says when LinkedIn answered HTTP 429 or 999 during it. (#1264 by @shbernal)
    • MCPB bundle settings can point the server at your own Chrome or Chromium executable. (#1303 by @kumiDa)
    • search_jobs reports why paging stopped, so a caller knows whether more results may exist. (#1323 by @shbernal)
    • dismiss_job dismisses a job from job search so later searches no longer show it. (#1326 by @shbernal)
    • New get_easy_apply_form tool reads an Easy Apply form's questions without answering. (#1343 by @shbernal)
    • New archive_conversation tool archives a messaging thread by its id, InMail included. (#1354 by @shbernal)
    • get_person_profile and get_my_profile can now read a profile's volunteering section. (#1357 by @JaiPi)
    • search_posts can filter by content type, such as uploaded documents. (#1377 by @sunnycho100)
    • Failed tool calls name a stable error code in _meta, beside the unchanged message. (#1390 by @benjamin-di)
    • Add get_session_status, which reports the saved session without opening a browser. (#1392 by @benjamin-di)
    • The server now sends its usage rules to MCP clients as server instructions. (#1402 by @mvanhorn)
    • get_feed pairs a post's permalink with its text excerpt and URN when its markup has one. (#1409 by @letya999)
    • Ctrl+V (Cmd+V on a Mac) in the Docker login viewer pastes plain text. (#1414)
    • search_people refuses a plain-text location and filters by a numeric geo URN id instead. (#722 by @BasitS-hash)
    • search_jobs reports no_matching_jobs when LinkedIn's redesigned search matches nothing. (#1363 by @shbernal)
    • A crashed browser page is now shut down and replaced instead of failing every later call. (#1382 by @benjamin-di)
    • Raise fastmcp to 4.1.3, fixing the M2M OAuth advisory GHSA-vqqp-x5qm-5qp4. (#1408 by @letya999)
    • Sidebar "Show all" links off LinkedIn are skipped, and diagnostics hide proxy credentials. (#1417)

    Install or update

    [!TIP] New here? The README covers setup.

    Update with uvx

    Clients configured with mcp-server-linkedin@latest pick up v4.29.0 on their next start. To pin this release, use `mcp-server-l

  2. v4.28.02026-10-23 · 2026-10-23 06:18 UTC
    查看更新说明

    Highlights

    • Claude Code and Cursor plugins. Install the server and its agent skill in one step. (#1296)
    • Proxy credentials stay private. Search errors no longer quote them. (#1375)
    • Checkpoints ask for a login. A checkpoint reached mid-call no longer waits 30 s. (#1379)

    Features

    • Cursor Marketplace plugin adds one-click install and the linkedin-mcp agent skill. (#1268 by @minhhung2556)
    • A shared browser process that stops responding is now named, with its pid, in the error. (#1295)
    • Claude Code plugin with the same server and skill as the Codex plugin. (#1296)
    • The Codex, Claude Code and Cursor plugins now start the latest server release. (#1322)
    • Trace directories left behind by killed servers are now removed after 14 days. (#1297)
    • Tool calls answered in full are no longer reported as possibly lost. (#1298)
    • A newer server now retires an older shared browser that uses other settings. (#1301)
    • Browser setup on a busy Mac no longer fails after Chromium installed successfully. (#1302)
    • Clients differing only in login settings share one browser; EAGER_FULL_CHROMIUM is gone. (#1304)
    • A message confirmed just before the deadline is no longer reported as unconfirmed. (#1305)
    • Listing resources or prompts no longer fails while the shared browser is unavailable. (#1311)
    • Shared browser startup refuses a file swapped for a named pipe instead of hanging. (#1317)
    • Tool calls no longer keep failing on a shared browser built with an incompatible MCP. (#1327)
    • A call whose answer was lost no longer reports that the shared browser stopped running. (#1337)
    • On a busy Mac, a cleanly closed browser no longer reports that it may still be running. (#1368)
    • On a busy Mac, a crashed server's browser is now closed and its profile released. (#1370)
    • search_people and search_posts no longer show proxy credentials quoted in an error. (#1375)
    • A security checkpoint reached mid-call now asks for a new login instead of a 30 s wait. (#1379)

    Install or update

    [!TIP] New here? The README covers setup.

    Update with uvx

    Clients configured with mcp-server-linkedin@latest pick up v4.28.0 on their next start. To pin this release, use [email protected] instead.

    Update with the MCP Bundle

    For Claude Desktop, download linkedin-mcp-server-v4.28.0.mcpb and open it to install or update. Bundles do

  3. v4.27.02026-10-10 · 2026-10-10 02:12 UTC
    查看更新说明

    Highlights

    • Multi-line messages. send_message sends line breaks and empty lines as one message. (#1224)
    • Apply links. get_job_apply_url returns the apply type and the employer's link. (#1035 by @shbernal)
    • Sessions recover. A profile that lost its cookies gets them back before any page. (#1251)

    Features

    • get_job_apply_url says how a posting takes applications and gives the employer's URL. (#1035 by @shbernal)
    • get_saved_jobs takes a stage to read in-progress, applied and archived tracker jobs. (#1058 by @shbernal)
    • send_message now sends multi-line messages as one message, keeping empty lines. (#1224)
    • send_message reports the thread a confirmed message landed in, or null on compose. (#1243)
    • get_job_details adds apply: {type} for postings applied to or closed. (#1249 by @shbernal)
    • A browser install no longer fails when its helper processes end late under load. (#1220)
    • A profile locked under another host name now says which lock files to remove, and when. (#1228)
    • A browser install whose size limit was exceeded is now refused even if it exits cleanly. (#1229)
    • The CLI now says that Ctrl+Z does not pause a browser download. (#1230)
    • Logout no longer deletes a session another client signed in with while it waited. (#1231)
    • A lost shared browser now tells clients to reconnect instead of an internal error. (#1232)
    • send_message now reports an unconfirmed send instead of a bare timeout error. (#1233)
    • A cancelled job search no longer keeps scrolling its results in the shared page. (#1234)
    • Tools now refuse a page that ended up off LinkedIn instead of reading it as LinkedIn's. (#1235)
    • A browser that stopped is shut down, and the next tool call starts a new one. (#1240)
    • A feed navigation is timed from the request, and one that is never sent still ends. (#1245)
    • get_job_apply_url reads an Easy Apply that LinkedIn now renders as a button. (#1250 by @shbernal)
    • A profile that opens without its saved cookies loads them before the first page. (#1251)
    • Exclude new-message compose destinations from conversation references and thread IDs. (#1255 by @ihuzaifashoukat)
    • search_jobs keeps the pages it has when a slow page reaches the end of its time budget. (#1261 by @shbernal)

    Install or update

    [!TIP] New here? The README covers setup.

    Update with uvx

    Clients confi

  4. v4.26.22026-10-03 · 2026-10-03 19:54 UTC
    查看更新说明

    Breaking Changes

    • Python imports move from linkedin_mcp_server.scraping to linkedin_mcp_server.linkedin. (#1189)
    • Every Python name containing "scrap" is renamed, keywords too; error context: read_*. (#1190)
    • --status now says another process holds the browser profile instead of failing. (#1191)
    • On Windows, closing the shared daemon's browser no longer breaks its next browser start. (#1201)
    • Send messages and return profile_urn again on LinkedIn's redesigned profile page. (#1214 by @stevenmcsorley)

    Install or update

    [!TIP] New here? The README covers setup.

    Update with uvx

    Clients configured with mcp-server-linkedin@latest pick up v4.26.2 on their next start. To pin this release, use [email protected] instead.

    Update with the MCP Bundle

    For Claude Desktop, download linkedin-mcp-server-v4.26.2.mcpb and open it to install or update. Bundles do not update themselves, so repeat this for every release.

    Update with Docker

    docker pull stickerdaniel/linkedin-mcp-server:latest
    

    Use the 4.26.2 tag instead of latest to pin this release.


    Contributors: @stevenmcsorley (first contribution 🎉), @stickerdaniel

    Full Changelog: https://github.com/stickerdaniel/linkedin-mcp-server/compare/v4.26.1...v4.26.2

  5. v4.26.12026-09-28 · 2026-09-28 20:55 UTC
    查看更新说明

    Bug Fixes

    • send_message reports "Press Enter to Send" and explains how to switch that setting. (#1109 by @Ymx1ZQ)
    • Keep an open chat overlay from blocking connect_with_person invitations. (#1110 by @Ymx1ZQ)
    • Avoid needless browser setup when Patchright versions share the cache. (#1162)
    • Recover browser setup when Windows AppContainer grants block the default temp directory. (#1163)

    Install or update

    [!TIP] New here? The README covers setup.

    Update with uvx

    Clients configured with mcp-server-linkedin@latest pick up v4.26.1 on their next start. To pin this release, use [email protected] instead.

    Update with the MCP Bundle

    For Claude Desktop, download linkedin-mcp-server-v4.26.1.mcpb and open it to install or update. Bundles do not update themselves, so repeat this for every release.

    Update with Docker

    docker pull stickerdaniel/linkedin-mcp-server:latest
    

    Use the 4.26.1 tag instead of latest to pin this release.


    Contributors: @Ymx1ZQ, @stickerdaniel

    Full Changelog: https://github.com/stickerdaniel/linkedin-mcp-server/compare/v4.26.0...v4.26.1

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    MCP Server for LinkedIn

    Give your AI agents access to LinkedIn through your own browser session. Read profiles, research companies, find jobs, and manage conversations and connection requests.

    This is an independent open-source project, not affiliated with LinkedIn or Microsoft. LinkedIn is a trademark of LinkedIn Corporation, used here only to identify the service this software interacts with.

    Running LinkedIn agents in production? LinkupAPI is the hosted outreach API built for scale, across LinkedIn Classic, Sales Navigator, and Recruiter, plus email, WhatsApp, and iMessage.

    Try LinkupAPI free →

    Cadenza is the single hosted MCP server for all your LinkedIn needs. It covers Classic, Sales Navigator, and Recruiter with 100+ actions, each within limits you set. Works on web, desktop, and mobile.

    Use code FOUNDING20 for 20% off your first year. Try Cadenza →

    This MCP server is supported by Unipile. 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 →

    Zernio gives your agents official APIs for every social channel. Post, reply, and run ads on Instagram, TikTok, X, YouTube, Threads, and more, through one API or MCP server.

    Try Zernio free →


    Installation Methods - LinkedIn MCP Server

    uvx Install MCP Bundle Codex Plugin Claude Code Plugin Cursor Plugin Docker

    ToolDescription
    get_person_profileRead profile sections: experience, education, skills, projects, volunteering, posts.
    get_my_profileRead your own profile, with the same section selection as other profiles.
    connect_with_personSend a connection request with an optional note, or accept an incoming one.
    get_sidebar_profilesFind recommended profile links, including people you may know.
    get_inboxList recent inbox conversations, with links to open individual threads.
    get_conversationRead a conversation's messages using a LinkedIn username or thread ID.
    search_conversationsSearch messages by keyword and return links to matching conversation threads.
    archive_conversationArchive a conversation by thread ID; a repeat call reports it already archived.
    send_messageSend after confirmation; profile targets may open a new DM (#483).
    reply_to_conversationReply inside an existing thread or InMail by thread ID. Sends after confirmation.
    get_company_profileRead company information, with optional sections for posts and open jobs.
    get_company_postsRead recent posts from a company's feed, with links to the original posts.
    search_companiesFind companies by keyword and return links to their LinkedIn profiles.
    get_company_employeesFind company employees, optionally filtered by name, title, or skill.
    search_jobsFind job postings by keyword and location, with job IDs for reading details.
    get_saved_jobsList your saved job postings, with job IDs for looking up their details.
    dismiss_jobDismiss a job from job search so later searches no longer show it. Irreversible.
    search_peopleFind people by keyword, location, connection degree, and current company.
    get_job_detailsRead a job posting's description, requirements, and company details.
    get_job_apply_urlCheck whether a job uses Easy Apply or links to an employer's application.
    get_easy_apply_formRead an Easy Apply form's fields, options and prefilled values. Never submits.
    get_feedRead recent posts from your home feed, with links to the original posts.
    search_postsSearch posts by keyword, optionally filtered by recency or content type.
    get_session_statusCheck your saved login and browser state without opening a browser.
    close_sessionClose the shared browser session without deleting your saved login.

    Setup with uvx (Recommended)

    Prerequisites: Install uv.

    Installation

    Add to your MCP client's mcpServers configuration

    {
      "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 and prepares the shared Patchright Chromium browser cache in the background under ~/.linkedin-mcp/patchright-browsers. On the first tool call that needs authentication, it reuses a LinkedIn session from a signed-in local browser if it finds one, and otherwise opens a LinkedIn login browser window.

    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.

    Setup Help

    • 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

    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, coccoc, opera, opera_gx, 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)
    • --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 calls that read many pages, 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.

    Other:

    • --log-level {DEBUG,INFO,WARNING,ERROR} - Logging level (default: WARNING)

    If you are already signed into LinkedIn in Chrome, Chromium, Brave, Edge, Arc, Vivaldi, Helium, Yandex, Naver Whale, Cốc Cốc, Opera, or Opera GX, you can skip the manual --login step and reuse that session:

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

    Basic Usage Examples:

    # Run with debug logging
    uvx mcp-server-linkedin@latest --log-level DEBUG
    

    HTTP Mode Example (for web-based MCP clients):

    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
    • 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 its own; an environment that pins its dependencies needs uv lock --upgrade-package greenlet. Only greenlet 3.3.1 through 3.5.4 need MSVCP140.dll, which neither the python.org installer nor the uv-managed builds carry, and a greenlet built from source can need it at any version. Where the version cannot be moved, the Microsoft Visual C++ Redistributable supplies that DLL. Reported as greenlet#525, fixed in greenlet#526.
    • Browser profile is stored at ~/.linkedin-mcp/profile/
    • Managed browser downloads are cached at ~/.linkedin-mcp/patchright-browsers/
    • The browser cache keeps growing: a server upgrade can bring a new Chromium revision, and Patchright keeps the old one for as long as any installed version still references it. uvx keeps one archive per version you have ever run, so every one of them holds such a reference and the old revisions stay. The server logs a warning naming the revisions it is holding and how much space they take. To reclaim it, stop every LinkedIn MCP Server instance, delete ~/.linkedin-mcp/patchright-browsers/, and let the next launch download the current browser.
    • Make sure you have only one active LinkedIn session at a time
    • LinkedIn may require a login confirmation in the LinkedIn mobile app for --login
    • LinkedIn may show a captcha challenge during login. Run uvx mcp-server-linkedin@latest --login which opens a browser where you can solve it manually.
    • Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout: --timeout 10000 or TIMEOUT=10000 (milliseconds, default 5000).
    • Entire tool calls timing out (e.g. multi-section profiles, cold-start Chromium, slow containers): increase the per-tool execution timeout: --tool-timeout 300 or TOOL_TIMEOUT=300 (seconds, default 180).
    • First tool call with no session: if a locally logged-in browser has a live LinkedIn session, the server auto-imports it (see AUTO_IMPORT_FROM_BROWSER / --auto-import) instead of forcing a manual login. On macOS the keychain may prompt once for Safe Storage access. If no importable browser session exists, it falls back to opening a login window and waits up to LOGIN_INLINE_WAIT seconds (default 25, max 45; --login-inline-wait) so a quick sign-in resolves in one call. If the wait elapses, the tool returns a pending signal and the model retries in about 30 seconds. Neither the auto-import nor the inline wait applies under Docker or when the server is bound to a non-loopback HTTP host. Create the session on the host with --login, or use the explicit Docker --login --login-viewer command.
    • Users on slow connections may need higher values for either.
    • If tool calls answer "No valid LinkedIn session is available in Docker" on a machine that is not a container, the runtime was misdetected. This happened on Linux hosts running a Docker daemon for unrelated services. Set LINKEDIN_MCP_CONTAINER=false to override the detection; true forces the opposite.
    • If Chrome is installed in a non-standard location, use --chrome-path /path/to/chrome
    • Can also set via environment variable: CHROME_PATH=/path/to/chrome
    • On macOS and Linux the browser must be at least as new as the one that last opened your profile, and the server refuses the launch otherwise. (Not on Windows: a browser there cannot be asked its version without starting one, so the check is off.) An older browser can silently drop stores a newer one wrote, the saved session among them, and the failure then looks exactly like an expired login. The message names both versions. Going back to the bundled Chromium after running a newer Chrome once is the usual way to meet this; either run the newer browser again, whichever one that was, or run --login, which moves the stored session aside and signs in fresh with the browser you have. --logout also clears it but discards the old session instead of keeping it recoverable, and it asks for confirmation on the terminal, so it is not usable from a server an MCP client started.
    • Only Chrome, Chromium and Chrome for Testing are compared this way. Forks number themselves differently (Vivaldi is on 7.x, Edge's build number sits far below Chrome's under the same major), so pointing CHROME_PATH at one turns the check off rather than producing a refusal nothing could satisfy.

    Claude Desktop MCP Bundle (formerly DXT)

    Prerequisites: Claude Desktop.

    Installation

    1. Download the latest .mcpb artifact from releases
    2. Click the downloaded .mcpb file to install it into Claude Desktop
    3. Call any LinkedIn tool

    On startup, the MCP Bundle prepares the shared Patchright Chromium browser cache in the background. On the first tool call that needs authentication, the server reuses a LinkedIn session from a signed-in local browser if it finds one, and otherwise opens a LinkedIn login browser window.

    [!NOTE] Early tool calls may return a setup/authentication-in-progress error until browser setup or login finishes. Retry the tool call once the browser download or sign-in completes.

    Setup Help

    • Claude Desktop starts the bundle immediately; browser setup continues in the background
    • If the Patchright Chromium browser is still downloading, retry the tool after a short wait
    • Managed browser downloads are shared under ~/.linkedin-mcp/patchright-browsers/
    • The browser cache keeps growing: Patchright keeps an old Chromium revision for as long as any installed version still references it, so an upgrade can leave both on disk. The server logs a warning naming what it holds. To reclaim the space, stop every LinkedIn MCP Server instance, delete ~/.linkedin-mcp/patchright-browsers/, and let the next launch download the current browser.
    • Windows, the bundle exits with DLL load failed while importing _greenlet: install the Microsoft Visual C++ Redistributable, or reinstall a bundle pinning greenlet 3.5.5 or newer, whose published Windows wheels carry the C++ runtime inside the extension again. A bundle pinning greenlet 3.3.1 through 3.5.4 needs MSVCP140.dll from that redistributable, which neither the python.org installer nor the uv-managed builds carry, and a greenlet built from source can need it at any version. The server names this itself on startup, and only after checking that the loader cannot produce that DLL. Reported as greenlet#525, fixed in greenlet#526.
    • Make sure you have only one active LinkedIn session at a time
    • LinkedIn may require a login confirmation in the LinkedIn mobile app for --login
    • LinkedIn may show a captcha challenge during login. Run uvx mcp-server-linkedin@latest --login which opens a browser where you can solve captchas manually. See the uvx setup for prerequisites.
    • Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout: --timeout 10000 or TIMEOUT=10000 (milliseconds, default 5000).
    • Entire tool calls timing out (e.g. multi-section profiles, cold-start Chromium, slow containers): increase the per-tool execution timeout: --tool-timeout 300 or TOOL_TIMEOUT=300 (seconds, default 180).
    • First tool call with no session: if a locally logged-in browser has a live LinkedIn session, the server auto-imports it (see AUTO_IMPORT_FROM_BROWSER / --auto-import) instead of forcing a manual login. On macOS the keychain may prompt once for Safe Storage access. If no importable browser session exists, it falls back to opening a login window and waits up to LOGIN_INLINE_WAIT seconds (default 25, max 45; --login-inline-wait) so a quick sign-in resolves in one call. If the wait elapses, the tool returns a pending signal and the model retries in about 30 seconds. Neither the auto-import nor the inline wait applies under Docker or when the server is bound to a non-loopback HTTP host. Create the session on the host with --login, or use the explicit Docker --login --login-viewer command.
    • Users on slow connections may need higher values for either.
    • Set Chrome executable in the extension's settings to a Chrome, Chromium or Chrome for Testing binary, such as /usr/bin/google-chrome. Leave it blank to keep the bundled Chromium. It sets CHROME_PATH, described under Custom Chrome path in the uvx setup help.
    • This is the fix when tool calls refuse to open the profile because a newer browser last opened it: point the setting at that newer browser instead of signing in again.
    • If tool calls answer "No valid LinkedIn session is available in Docker" on a machine that is not a container, the runtime was misdetected. This happened on Linux hosts running a Docker daemon for unrelated services. Set LINKEDIN_MCP_CONTAINER=false to override the detection; true forces the opposite.

    Codex Plugin

    Prerequisites: Codex and uv.

    Installation

    Run in a terminal

    codex plugin marketplace add stickerdaniel/linkedin-mcp-server
    codex plugin add linkedin-mcp-server@linkedin-mcp-server
    

    The plugin runs the latest server release. On the first tool call that needs authentication, the server reuses a LinkedIn session from a signed-in local browser or opens a login window.

    [!NOTE] Early tool calls may return a setup/authentication-in-progress error until browser setup or login finishes. Retry the tool call once the browser download or sign-in completes.

    Claude Code Plugin

    Prerequisites: Claude Code and uv.

    Installation

    Run in a terminal

    claude plugin marketplace add stickerdaniel/linkedin-mcp-server
    claude plugin install linkedin-mcp-server@linkedin-mcp-server
    

    The plugin runs the latest server release. On the first tool call that needs authentication, the server reuses a LinkedIn session from a signed-in local browser or opens a login window.

    [!NOTE] Early tool calls may return a setup/authentication-in-progress error until browser setup or login finishes. Retry the tool call once the browser download or sign-in completes.

    Cursor Plugin

    Prerequisites: Cursor and uv on your PATH.

    Installation

    From the Cursor Marketplace: open Customize in the sidebar, search for LinkedIn MCP, and choose Install. The plugin bundles the LinkedIn skill.

    One-click MCP install (server only, without the skill):

    Add to Cursor

    Both run the latest server release. On the first tool call that needs authentication, the server reuses a LinkedIn session from a signed-in local browser or opens a login window.

    [!NOTE] Early tool calls may return a setup/authentication-in-progress error until browser setup or login finishes. Retry the tool call once the browser download or sign-in completes.

    Setup with Docker

    Prerequisites: Make sure Docker is installed and running.

    Authentication

    Log in once. The container opens a LinkedIn login browser that you drive from your own browser tab.

    macOS / Linux:

    # Create the directory first so the container can save your session into it
    mkdir -p ~/.linkedin-mcp
    docker run -it --rm \
      -v ~/.linkedin-mcp:/home/pwuser/.linkedin-mcp \
      -p 127.0.0.1:6080:6080 \
      stickerdaniel/linkedin-mcp-server:latest \
      --login --login-viewer
    

    PowerShell (Windows):

    $sessionDir = Join-Path $env:USERPROFILE ".linkedin-mcp"
    New-Item -ItemType Directory -Force -Path $sessionDir | Out-Null
    docker run -it --rm `
      -v "${sessionDir}:/home/pwuser/.linkedin-mcp" `
      -p 127.0.0.1:6080:6080 `
      stickerdaniel/linkedin-mcp-server:latest `
      --login --login-viewer
    

    Open the full URL the command prints (it carries the access token) and sign in. Ctrl+V (Cmd+V on a Mac) pastes plain ASCII text, such as a password from your password manager, into the login browser. The viewer closes itself afterwards; let the command exit on its own so the session is stored completely. It gives up after 30 minutes.

    Keep the same host directory mounted at /home/pwuser/.linkedin-mcp on every later docker run, otherwise the server cannot find the session.

    Add to your MCP client's mcpServers configuration

    macOS / Linux (absolute path in JSON):

    {
      "mcpServers": {
        "mcp-server-linkedin": {
          "command": "docker",
          "args": [
            "run", "--rm", "-i",
            "-v", "/absolute/path/to/.linkedin-mcp:/home/pwuser/.linkedin-mcp",
            "stickerdaniel/linkedin-mcp-server:latest"
          ]
        }
      }
    }
    

    Spell that first path out in full. A client runs docker directly rather than through a shell, so a leading ~ reaches Docker unexpanded and it refuses the mount.

    PowerShell (Windows): use a forward-slash JSON path. A backslash path like C:\Users\Alice\.linkedin-mcp fails JSON parsing because \U is an invalid escape. Use C:/Users/Alice/.linkedin-mcp instead, replacing Alice with your username.

    {
      "mcpServers": {
        "mcp-server-linkedin": {
          "command": "docker",
          "args": [
            "run", "--rm", "-i",
            "-v", "C:/Users/Alice/.linkedin-mcp:/home/pwuser/.linkedin-mcp",
            "stickerdaniel/linkedin-mcp-server:latest"
          ]
        }
      }
    }
    

    [!NOTE] In PowerShell, ~ is not expanded inside a composite Docker -v argument. Use C:/Users/<you>/.linkedin-mcp or build the path with $env:USERPROFILE\.linkedin-mcp before passing it to Docker.

    [!NOTE] Sessions expire over time. When tool calls start asking for authentication, repeat the login command above, or run uvx mcp-server-linkedin@latest --login on the host.

    Setup Help

    • 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

    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 (ignored in Docker). On macOS the keychain may prompt once.
    • --logout - Clear the stored session and every profile derived from it
    • --login-viewer - With --login, show the login browser at a token-protected URL on port 6080. Needs the profile mount from 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 calls that read many pages, 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:

    • --chrome-path PATH - Path to a Chrome/Chromium executable (rarely needed in Docker)
    • --proxy-server URL - Route browser traffic through a proxy, as scheme://host:port. Set it up before --login; see Using a proxy.

    Other:

    • --log-level {DEBUG,INFO,WARNING,ERROR} - Logging level (default: WARNING)

    [!NOTE] Plain --login still has no visible window in Docker. Add --login-viewer and publish 127.0.0.1:6080:6080 only for the one-shot login command. Docker is already headed by default, so --no-headless changes nothing. The experimental --daemon is ignored in Docker because its owner can outlive the virtual display.

    HTTP Mode Example (for web-based MCP clients):

    Bash / macOS / Linux:

    docker run -it --rm \
      -v ~/.linkedin-mcp:/home/pwuser/.linkedin-mcp \
      -p 127.0.0.1:8080:8080 \
      stickerdaniel/linkedin-mcp-server:latest \
      --transport streamable-http --host 0.0.0.0 --port 8080 --path /mcp
    

    PowerShell (Windows):

    $sessionDir = Join-Path $env:USERPROFILE ".linkedin-mcp"
    docker run -it --rm `
      -v "${sessionDir}:/home/pwuser/.linkedin-mcp" `
      -p 127.0.0.1:8080:8080 `
      stickerdaniel/linkedin-mcp-server:latest `
      --transport streamable-http --host 0.0.0.0 --port 8080 --path /mcp
    

    Both halves of that are needed, and they do different jobs. --host 0.0.0.0 makes the server reachable inside the container: a process bound to 127.0.0.1 in there cannot be reached through a published port at all. The 127.0.0.1: in front of -p is what limits it outside, to this machine. Drop that prefix and Docker publishes on every interface, which puts an endpoint with no authentication on your network. The server cannot tell the two apart, so it warns either way.

    Loopback publishing limits this to the machine, not to the container. Other containers on the same host can still reach it through host.docker.internal wherever that name resolves, which is the default on Docker Desktop and OrbStack but not on native Linux Docker.

    Runtime server logs are emitted by FastMCP/Uvicorn.

    The HTTP server answers requests addressed to localhost or to the address it is bound to, and refuses others with 421. That is what stops a website you merely visit from pointing a domain at this server and using your LinkedIn session through your own browser.

    Reaching the server by any other name is refused, including a machine name on your network and the public name in front of a reverse proxy. Either have the proxy rewrite the upstream Host to the backend address, or name the host you serve it under:

    FASTMCP_HTTP_ALLOWED_HOSTS='["mcp.example"]'
    

    That permits exactly that name and keeps refusing everything else. The endpoint still has no authentication, so anything reachable beyond your own machine belongs behind something that provides it.

    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
    • Make sure Docker is installed
    • Check if Docker is running: docker ps
    • Permission errors on ~/.linkedin-mcp: an older rootful Docker run may have created the directory as root. Fix it with sudo chown -R "$(id -u):$(id -g)" ~/.linkedin-mcp.
    • Make sure you have only one active LinkedIn session at a time
    • LinkedIn may require a login confirmation in the LinkedIn mobile app for --login
    • LinkedIn may show a captcha challenge during login. Run uvx mcp-server-linkedin@latest --login which opens a browser where you can solve captchas manually. See the uvx setup for prerequisites.
    • If Docker auth becomes stale after you re-login on the host, restart Docker once so it can fresh-bridge from the new source session generation.
    • Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout: --timeout 10000 or TIMEOUT=10000 (milliseconds, default 5000).
    • Entire tool calls timing out (e.g. multi-section profiles, cold-start Chromium, slow containers): increase the per-tool execution timeout: --tool-timeout 300 or TOOL_TIMEOUT=300 (seconds, default 180).
    • First tool call with no session: if a locally logged-in browser has a live LinkedIn session, the server auto-imports it (see AUTO_IMPORT_FROM_BROWSER / --auto-import) instead of forcing a manual login. On macOS the keychain may prompt once for Safe Storage access. If no importable browser session exists, it falls back to opening a login window and waits up to LOGIN_INLINE_WAIT seconds (default 25, max 45; --login-inline-wait) so a quick sign-in resolves in one call. If the wait elapses, the tool returns a pending signal and the model retries in about 30 seconds. Neither the auto-import nor the inline wait applies under Docker or when the server is bound to a non-loopback HTTP host. Create the session on the host with --login, or use the explicit Docker --login --login-viewer command.
    • Users on slow connections may need higher values for either.
    • If tool calls answer "No valid LinkedIn session is available in Docker" on a machine that is not a container, the runtime was misdetected. This happened on Linux hosts running a Docker daemon for unrelated services. Set LINKEDIN_MCP_CONTAINER=false to override the detection; true forces the opposite.
    • If Chrome is installed in a non-standard location, use --chrome-path /path/to/chrome
    • Can also set via environment variable: CHROME_PATH=/path/to/chrome
    • On macOS and Linux the browser must be at least as new as the one that last opened your profile, and the server refuses the launch otherwise. (Not on Windows: a browser there cannot be asked its version without starting one, so the check is off.) An older browser can silently drop stores a newer one wrote, the saved session among them, and the failure then looks exactly like an expired login. The message names both versions. Going back to the bundled Chromium after running a newer Chrome once is the usual way to meet this; either run the newer browser again, whichever one that was, or run --login, which moves the stored session aside and signs in fresh with the browser you have. --logout also clears it but discards the old session instead of keeping it recoverable, and it asks for confirmation on the terminal, so it is not usable from a server an MCP client started.
    • Only Chrome, Chromium and Chrome for Testing are compared this way. Forks number themselves differently (Vivaldi is on 7.x, Edge's build number sits far below Chrome's under the same major), so pointing CHROME_PATH at one turns the check off rather than producing a refusal nothing could satisfy.
    • In the documented Docker setup this check does not apply. The container never opens the profile you created with --login; it derives its own from your cookies, and by default rebuilds that from scratch on every start, so there is nothing for an older image to downgrade. With EXPERIMENTAL_PERSIST_DERIVED_RUNTIME the derived profile is kept, and an image tag that moves backwards then throws it away and re-derives it, again with nothing for you to do. The check matters on the host, where the server opens that profile directly. Not during --login itself, which moves the old profile aside before it starts a browser and so can never trip it.

    Using a proxy

    LinkedIn scores the address a session signs in from. Your account's usual IP address is the safe one. You should use a proxy in your country when the server cannot use it: a VPS, another country, or a second account that must not share the first one's address.

    With a paid provider, use a sticky residential session that holds one address (never per-request rotation). A WireGuard full tunnel or Tailscale exit node on your home network works when the server should use your usual home address.

    Setup Help

    • Set the proxy up before --login. Moving an existing session to a new address triggers a LinkedIn checkpoint. That includes a session from --import-from-browser, which was created on your real address.
    • --proxy-server scheme://host:port or PROXY_SERVER, with http, https, socks4 or socks5. Only browser traffic is routed, not the MCP transport.
    • Pass credentials through PROXY_USERNAME and PROXY_PASSWORD, or include them in PROXY_SERVER using the combined http://user:pass@host:port form. The combined form is not accepted by the --proxy-server CLI option.
    • PROXY_BYPASS=localhost,127.0.0.1,::1 reaches local targets directly. With a proxy set, Chromium routes localhost through it too.
    • Chromium cannot authenticate to a SOCKS proxy, so credentials require an http(s) endpoint. If your provider only offers authenticated SOCKS5, run a local relay that holds the credentials and point the server at that.
    • A wrong proxy password shows up as a timeout or a failed sign-in, because Chromium retries the authentication challenge until the page times out. If sessions stop working right after you add a proxy, check the proxy credentials first.
    • Auto-import is skipped while a proxy is configured: the imported session would move from your real address to the proxy. Use --login.
    • Inside a container 127.0.0.1 is the container itself, so a relay on the host is host.docker.internal; native Linux Docker also needs --add-host=host.docker.internal:host-gateway.

    Setup from Source (Develop & Contribute)

    Contributions are welcome. See CONTRIBUTING.md for architecture guidelines and checklists. Search existing issues first, then use the issue forms for anything new. AI agents follow the issue-packet skill.

    Prerequisites: Git and uv installed

    Installation

    Run in a terminal

    # 1. Clone repository
    git clone https://github.com/stickerdaniel/linkedin-mcp-server
    cd linkedin-mcp-server
    
    # 2. Install UV package manager (if not already installed)
    curl -LsSf https://astral.sh/uv/install.sh | sh
    
    # 3. Install dependencies
    uv sync
    uv sync --group dev
    
    # 4. Install pre-commit hooks
    uv run pre-commit install
    
    # 5. Start the server
    uv run -m linkedin_mcp_server
    

    Setup Help

    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, coccoc, opera, opera_gx, 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.
    • --status - Check whether the stored session is valid, then exit
    • --logout - Clear the stored session
    • --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 calls that read many pages, 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)
    • --slow-mo MS - Delay between browser actions (default: 0, useful for debugging)
    • --viewport WxH - Viewport size (default: 1280x720). Applies to windowless mode only; a headed launch uses the real window size.
    • --chrome-path PATH - Path to a Chrome/Chromium executable
    • --installer-temp-dir PATH - Existing directory for browser installation temporary files (environment: INSTALLER_TEMP_DIR).
    • --proxy-server URL - Route browser traffic through a proxy, as scheme://host:port. Set it up before --login; see Using a proxy.

    Other:

    • --log-level {DEBUG,INFO,WARNING,ERROR} - Logging level (default: WARNING)
    • --help - Show help

    Note: Most CLI options have environment variable equivalents. See .env.example for details.

    HTTP Mode Example (for web-based MCP clients):

    uv run -m linkedin_mcp_server --transport streamable-http --host 127.0.0.1 --port 8000 --path /mcp
    

    Claude Desktop:

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

    stdio is used by default for this config.

    • Make sure you have only one active LinkedIn session at a time
    • LinkedIn may require a login confirmation in the LinkedIn mobile app for --login
    • LinkedIn may show a captcha challenge during login. The --login command opens a browser where you can solve it manually.
    • Use --no-headless to watch the browser when a tool returns wrong or missing data
    • Add --log-level DEBUG to see more detailed logging
    • Browser profile is stored at ~/.linkedin-mcp/profile/
    • Managed browser downloads are cached at ~/.linkedin-mcp/patchright-browsers/, shared with the uvx and MCP Bundle installations
    • The browser cache keeps growing: Patchright keeps an old Chromium revision for as long as any installed version still references it, and a uv archive or a second worktree is such a reference. The server logs a warning naming what it holds. To reclaim the space, stop every LinkedIn MCP Server instance, delete ~/.linkedin-mcp/patchright-browsers/, and let the next launch download the current browser.
    • Use --logout to clear the profile and start fresh
    • Check Python version: python --version (should be 3.12.4+)
    • Reinstall Patchright: uv run patchright install chromium
    • Reinstall dependencies: uv sync --reinstall
    • Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout: --timeout 10000 or TIMEOUT=10000 (milliseconds, default 5000).
    • Entire tool calls timing out (e.g. multi-section profiles, cold-start Chromium, slow containers): increase the per-tool execution timeout: --tool-timeout 300 or TOOL_TIMEOUT=300 (seconds, default 180).
    • First tool call with no session: if a locally logged-in browser has a live LinkedIn session, the server auto-imports it (see AUTO_IMPORT_FROM_BROWSER / --auto-import) instead of forcing a manual login. On macOS the keychain may prompt once for Safe Storage access. If no importable browser session exists, it falls back to opening a login window and waits up to LOGIN_INLINE_WAIT seconds (default 25, max 45; --login-inline-wait) so a quick sign-in resolves in one call. If the wait elapses, the tool returns a pending signal and the model retries in about 30 seconds. Neither the auto-import nor the inline wait applies under Docker or when the server is bound to a non-loopback HTTP host. Create the session on the host with --login, or use the explicit Docker --login --login-viewer command.
    • Users on slow connections may need higher values for either.
    • If tool calls answer "No valid LinkedIn session is available in Docker" on a machine that is not a container, the runtime was misdetected. This happened on Linux hosts running a Docker daemon for unrelated services. Set LINKEDIN_MCP_CONTAINER=false to override the detection; true forces the opposite.
    • If Chrome is installed in a non-standard location, use --chrome-path /path/to/chrome
    • Can also set via environment variable: CHROME_PATH=/path/to/chrome
    • On macOS and Linux the browser must be at least as new as the one that last opened your profile, and the server refuses the launch otherwise. (Not on Windows: a browser there cannot be asked its version without starting one, so the check is off.) An older browser can silently drop stores a newer one wrote, the saved session among them, and the failure then looks exactly like an expired login. The message names both versions. Going back to the bundled Chromium after running a newer Chrome once is the usual way to meet this; either run the newer browser again, whichever one that was, or run --login, which moves the stored session aside and signs in fresh with the browser you have. --logout also clears it but discards the old session instead of keeping it recoverable, and it asks for confirmation on the terminal, so it is not usable from a server an MCP client started.
    • Only Chrome, Chromium and Chrome for Testing are compared this way. Forks number themselves differently (Vivaldi is on 7.x, Edge's build number sits far below Chrome's under the same major), so pointing CHROME_PATH at one turns the check off rather than producing a refusal nothing could satisfy.

    [!IMPORTANT] FAQ

    Is this safe to use? Will I get banned? This tool controls a real browser session; it doesn't exploit undocumented APIs or bypass authentication. LinkedIn's User Agreement prohibits automated access, and accounts using automated tools can be restricted or banned. Use at your own risk; there is no guarantee of account safety. If you encounter any issues, let me know in the Discussions.

    What if my agents execute too many actions? Tool calls run sequentially through a queue. You are responsible for the volume of automation you run; use it sparingly and prompt your agents responsibly.

    Contributors

    Thanks to everyone who has contributed code, bug reports and fixes.

    Acknowledgements

    Built with FastMCP and Patchright.

    Use in accordance with LinkedIn's User Agreement. Automated access may violate LinkedIn's terms and can lead to account restrictions. This tool is for personal use only and comes with no warranty of any kind.

    License

    This project is licensed under the Apache 2.0 license.

    Building on this project is welcome! See the license for terms and the NOTICE for attribution.