LinkedIn & Sales NavigatorTeardown

Eleven LinkedIn MCP Servers, Read at a Pinned Commit

We read the source of 11 LinkedIn MCP servers, ours included, each at one pinned commit, and report what each actually does.

What we ranA source audit of 11 LinkedIn MCP servers - 10 open-source rivals plus Kairon's own - each read at one pinned commit on 2026-08-09 against six fixed questions: Sales Navigator, write actions, InMail, auth, setup cost, and where each one beats us. No server was installed or executed; every claim is a claim about source next to docs.

A LinkedIn MCP server lets an AI agent read LinkedIn and, in most cases, send invitations and messages from your account. Eleven exist that we could find and read. Which one you want turns on three things: whether it reaches Sales Navigator, whether you run it yourself, and what it costs you to start.

We read all eleven at a pinned commit on 2026-08-09 and checked six fixed questions against source and docs: Sales Navigator, write actions, InMail, auth, setup cost, and where each one wins.

We should say that plainly, not halfway down: we are Kairon, we build a LinkedIn MCP server ourselves, and it sits in this list on the same rows as everyone else's. Our own server has no public source — gh repo view heykairon/kairon returns isPrivate: true, licenseInfo: null — so you can read the other ten yourself and check our claims about them; you cannot do the same for our row, and we say where that costs you further down.

What each one lets you do, and what it costs to start

"Write actions" means the server can send an invite or a message, not just read a profile. "Sales Navigator" means it operates against /sales/* search and lead tooling, not the consumer search box. Both change what a server is for — read-only research versus something that can contact a stranger on your behalf.

ServerStars (2026-08-09)Sales NavigatorWrite actionsInMailTo run it
stickerdaniel/linkedin-mcp-server3,063noyesnouvx mcp-server-linkedin@latest, free, needs your own logged-in browser session
eliasbiondo/linkedin-mcp-server174nononoclone + uv sync + --login, free, browser session
felipfr/linkedin-mcpserver80noyesyesclone + npm install + build, needs your own LinkedIn Developer app
quinnjr/linkedin-mcp63noyesno (roadmap only)npx @pegasusheavy/linkedin-mcp, needs your own Developer app (OAuth + OIDC)
alinaqi/mcp-linkedin-server53noyes (like, comment)noclone + pip install, free, browser login, cookies encrypted to disk
Dishant27/linkedin-mcp-server52noyesyes (undocumented)clone + npm run build, needs a Developer app (client_credentials OAuth)
LaGrowthMachine/gtm-system32yesyesnoone-line installer, hosted, browser OAuth to an LGM account
globodai-group/mcp-linkedin-sales-navigator6yesyesyesnpm install, needs an active Sales Navigator subscription plus a real logged-in browser
bhaktatejas922/unipile-linkedin-mcp2yesyesyesuvx unipile-linkedin-mcp, needs a Unipile account and API key
CassiaResearch/openclaw-unipile3yesyesyesplugin-marketplace install, needs a Unipile account and API key
Kairon (ours)0 (private repo)yesyesyesKairon account, a paid plan, a connected seat, hosted OAuth — no self-host path

Stars and commits are what we read on 2026-08-09; the category leader alone moved from 2,835 to 3,063 stars in the nineteen days before that, so treat every count here as a snapshot, not a fact that holds still.

Where each one wins

All ten beat us at something, and a features table would have hidden every one of these:

  • stickerdaniel reads through your own already-logged-in browser, so results reflect exactly what your account can see, no data broker in the middle — plus it's free, and its get_sidebar_profiles, get_saved_jobs, get_feed, and search_posts tools cover LinkedIn surfaces (recommendation modules, your own feed) that a campaign-first product like ours doesn't try to touch.
  • eliasbiondo returns typed, section-by-section JSON — pull experience without paying the scrape cost for recommendations too — inside a hexagonal codebase where the domain layer has zero external dependencies, which makes it unusually easy for a third party to audit exactly what touches their credentials.
  • felipfr keeps the whole path from tool call to api.linkedin.com in code you can read — 15 TypeScript source files, 39,491 bytes, measured from the tree at commit d87e7f3 on 2026-08-09 — and your token never passes through any third party's server, ours included.
  • quinnjr does something we did not see in the other ten: 13 of its 18 tools add, update, and delete your own profile's skills, positions, education, certifications, publications, and languages through LinkedIn's official API. Reading all eleven at the commits named above, the rest either read other people's profiles or contact them; this is the one that edits yours.
  • alinaqi is a single 712-line file a person can read start to finish in an afternoon — the whole trust surface fits in one sitting, self-hosted, nothing leaves your laptop.
  • Dishant27 is the same pitch as felipfr at a similar size: an MIT shim against LinkedIn's documented v2 REST API, OAuth2 and bearer tokens, no browser and no cookie handling anywhere in its source.
  • LaGrowthMachine, reading its repository at the pinned commit, isn't mainly a tool surface — it's the Claude Skills (boolean search grammar, Sales Navigator filter enums, campaign playbooks) that layer live data on top of a standalone reference pack. execute_bigquery_query gives an agent arbitrary SQL over LGM's own send/reply warehouse instead of fixed report shapes, and campaign-challenger benchmarks a new draft against the account's own history and rewrites it in place.
  • globodai states outright, in its own auth module's header comment, that it "does NOT store or handle credentials directly" — every session lives in Chrome via CDP, a persistent profile, or a cookie file you supply, never in the server's code.
  • bhaktatejas922 puts Unipile's raw Sales Navigator filters — tenure range, seniority level, company headcount — directly on the tool call, no ICP or campaign object standing between the agent and the filter.
  • openclaw-unipile, per its README and plugin config at the pinned commit, exposes its pacing model as inspectable config — daily/weekly/monthly send caps, jitter, working-hours windows, all named fields — plus a linkedin_check_budget tool that simulates whether a batch of invites would pass before you send it, and duplicate-message hashing that blocks resending the same text by accident.
  • Kairon does the one thing that matters most for Sales Navigator specifically: search_sales_navigator needs no Sales Navigator seat on the calling account. The tool's own description states it falls back to shared capacity, and a comment in the source records this fixing a real regression where an earlier version of the code wrongly downgraded to keyword search for exactly that reason (apps/api/src/channel-actions/channel-action.tools.ts, lines 379–407).

What "no Sales Navigator" actually took to establish

Six of the eleven answer "no" to Sales Navigator, and none by omission alone — each was checked in source and docs, not assumed. eliasbiondo's repo, for instance, was checked with:

grep -rniE "sales.?nav|salesnavigator|sales navigator" .

run on 2026-08-09 across all 54 files in the tarball at commit 34d277c180ab4726a67d991494baf294e52230e9 — source, README, CONTRIBUTING, LICENSE, pyproject.toml, uv.lock. Zero matches, grep exit code 1. That's the standard every "no" above was held to: a full-tree grep plus a read of every tool registration, not a glance at a README's feature list.

What broke between the README and the code

Three servers on this list say one thing in prose and do another in source, at the pinned commits we read:

quinnjr/linkedin-mcp's README states, twice, under "Token Management" and "Security Notes": "No Disk Storage — Tokens never written to disk" and "Memory only — Tokens stored in process memory, never on disk." The source at commit e9c69d1c4b860b019dd77f4451f8cb709e67dc25 does the opposite: oauth-manager.ts writes TOKEN_FILE = tokens.json under ~/.config/linkedin-mcp with fs.writeFileSync(..., { mode: 0o600 }) and restores it on the next launch — the reverse of what the README states in two separate places.

alinaqi/mcp-linkedin-server's get_linkedin_profile, at commit 2fbdf3220b4b98607871dfa469c70050ffc55d89, has no return statement on its success path — it returns a dict only inside the "profile not found" branch, otherwise it falls off the end. Its own test file asserts validation errors for a bad email or short password that don't exist anywhere in the function it tests.

Dishant27/linkedin-mcp-server registers a tool named the generic send-message, but src/client.ts hardcodes messageType: 'INMAIL' in the request body behind it — the tool sends InMail specifically, and nothing in the README or the tool's own description says so.

Not one of these is a claim about whether the servers work — we did not install or execute any of them, by design. They are claims about what the source says next to what the docs say, at the commit named for each.

Where the difference between remote and local actually bites

Seven of the eleven are programs you run yourself — four scrape through your own browser session, three call LinkedIn's official API with a Developer app you register — so the cost is a git clone and one login, nothing else. Two more run locally too, but reach LinkedIn through a paid third party, Unipile. That leaves two where the MCP server itself lives on someone else's infrastructure: LaGrowthMachine's, and ours. Of the eleven we read, Kairon was the sole one whose source is not published. A remote MCP server already trades a local server's zero HTTP surface for an OAuth deployment to get right. Ours adds two trades on top of that. You are trusting code you cannot read. And if app.heykairon.com goes down, this server goes with it. The other ten, as far as we could see reading them, carry no such dependency on us.

That is not a small caveat, and it is not the last. In an earlier audit of our own server we ran a real tools/list call against it and counted how many of its 40 tools carried a ToolAnnotations object — the machine-readable flags (readOnlyHint, destructiveHint) a client can use to decide when to interrupt a human before a tool fires. The count was zero out of 40, at commit e026b4e7, checked 2026-07-21. inmail_send — a tool that contacts a real person and spends a credit — carried the same empty annotations object as a tool that only reads a profile. We haven't re-run that probe for this piece, so we don't know whether it's still 0/40 today; we're citing it as a standing, dated finding, not a fresh one.

Picking one

If you already keep LinkedIn open in a real, logged-in browser and want free and self-hosted, read stickerdaniel or eliasbiondo first — the difference between them is a monolithic tool surface versus opt-in, section-by-section data. If what you want is Sales Navigator and InMail without holding a seat yourself, wired into a campaign layer instead of called one tool at a time, that's what we built — read the caveats above before you take our word for the part you can't read yourself. If you already pay for Sales Navigator and want the filters exposed raw with nothing else in the way, bhaktatejas922 or globodai get you there fastest, and every line either one runs is a line you can read first. And if you want your agent editing your own profile — skills, positions, certifications — quinnjr was the sole server we found doing it, reading all eleven at the commits named above — disk-storage claim aside.

Whichever you pick, the thing that restricts a LinkedIn account is not the one most of these tools let you configure. We got rate-limited with every daily cap respected, and the trigger was how fast the calls went out — the numbers are here, along with what our own fix still does not cover.