Skip to main content
ClaudeWave

Typed, policy-enforced Python MCP server for authorized LinkedIn visible-UI capabilities

MCP ServersOfficial Registry0 stars0 forksPythonApache-2.0Updated today
Install in Claude Code / Claude Desktop
Method: UVX (Python) · linkedin-mcp
Claude Code CLI
claude mcp add linkedin -- uvx linkedin-mcp
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "linkedin": {
      "command": "uvx",
      "args": ["linkedin-mcp"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Use cases

MCP Servers overview

# LinkedIn MCP Server

<!-- mcp-name: io.github.prakharagarwal-dev/linkedin-mcp-server -->

[![CI](https://github.com/prakharagarwal-dev/linkedin-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/prakharagarwal-dev/linkedin-mcp-server/actions/workflows/ci.yml)
[![CodeQL](https://github.com/prakharagarwal-dev/linkedin-mcp-server/actions/workflows/codeql.yml/badge.svg)](https://github.com/prakharagarwal-dev/linkedin-mcp-server/actions/workflows/codeql.yml)
[![PyPI](https://img.shields.io/pypi/v/linkedin-mcp-local.svg)](https://pypi.org/project/linkedin-mcp-local/)
[![Python 3.12–3.13](https://img.shields.io/badge/Python-3.12%E2%80%933.13-3776AB.svg?logo=python&logoColor=white)](https://www.python.org/)
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)

A standalone Python MCP server that exposes narrow, typed LinkedIn capabilities
through the visible LinkedIn web UI.

> [!IMPORTANT]
> This is an unofficial, beta project. It is not affiliated with, endorsed by,
> or sponsored by LinkedIn. LinkedIn is a trademark of LinkedIn Corporation.
> Visible-UI automation can stop working when LinkedIn changes its interface and
> may cause checkpoints, restrictions, or other account consequences. You are
> responsible for complying with applicable terms, laws, consent requirements,
> and organizational policies. Do not use this project for spam, deceptive
> activity, high-volume extraction, or bypassing access controls.

This repository is the LinkedIn harness, not an agent runtime. LangGraph,
schedulers, ranking, memory, and natural-language planning belong in clients
that call this server. Agents never receive cookies, arbitrary browser control,
generic navigation, JavaScript execution, or unrestricted network access.

Version `0.14.1` has no database, migration, Docker-service, keyring, or
application-state dependency. It uses one local Playwright Chromium profile to
preserve the LinkedIn login and keeps capability execution state only for the
lifetime of one server process.

## Runtime model

```text
LangGraph / Codex / another MCP client
                  |
          stdio or loopback HTTP
                  |
          typed MCP capabilities
                  |
      bounded asyncio.Queue (one worker)
                  |
     policy -> executor -> page objects
                  |
    one persistent Playwright context
                  |
       visible linkedin.com surfaces
```

The server owns:

- official MCP Python SDK transport and typed Pydantic contracts;
- one bounded in-process queue and one capability worker;
- one account-scoped persistent Playwright Chromium context;
- internal navigation pacing and per-operation safety bounds;
- exact-host, surface, scope, and effect authorization;
- visible page extraction and field-level evidence;
- expiring, filter-bound continuation cursors for collection reads;
- immutable prepare/confirm/execute envelopes for writes;
- process-local request replay, evidence, action drafts, and idempotency.

It has no dependency on LangGraph, Temporal, `startup-scanner`, PostgreSQL,
RabbitMQ, Redis, or another LinkedIn MCP implementation.

## What survives a restart

| Data | Location | Lifetime |
| --- | --- | --- |
| LinkedIn cookies and browser preferences | local Chromium profile | across restarts |
| Managed Chromium binaries | local Playwright browser cache | across package environments |
| Explicit post/message assets | configured local asset directory | user managed |
| Calls and request replay | memory | current process only |
| Evidence resources | memory | current process only |
| Action drafts and attempts | memory | current process only |
| Execution idempotency keys | memory | current process only |
| Queue and pacing history | memory | current process only |
| Collection cursors, seen identities, and invitation snapshots | memory | current process only |

The browser profile is sensitive authentication material. Its directory is
created with owner-only permissions on supported POSIX systems. Never commit,
copy, log, or share it.

Because operation state is intentionally ephemeral:

- read retries deduplicate only while the same server process is alive;
- `linkedin://sources/{source_id}` must be read before that process exits;
- a prepare and its matching execute call must use the same process;
- after a hard process interruption during a write, inspect LinkedIn's visible
  state before preparing any new action. Never blindly retry the old execute
  request.

LangGraph should checkpoint workflow history, cross-run deduplication,
notifications, rankings, and conversations outside this server.

## MCP surface

| MCP primitive | Purpose |
| --- | --- |
| `linkedin.server.status` | Non-secret runtime metadata |
| `linkedin.capabilities.list` | Installed capabilities and policy status |
| `linkedin.session.status` | Browser setup, profile, authentication, and pause state |
| `linkedin.jobs.search` | Cursor-paged current Jobs search with optional keywords, Any time by default, and every current account-visible filter |
| `linkedin.jobs.get` | Expanded JD, header metadata, application method, and hiring team for a numeric job ID |
| `linkedin.people.search` | Bounded People search with every current account-visible filter |
| `linkedin.people.get` | Selected or all visible member-profile sections |
| `linkedin.companies.search` | Cursor-paged Company search with keywords and every current native filter: headquarters, industry, all eight size buckets, job listings, and first-degree connection presence |
| `linkedin.companies.get` | Exact Company Overview plus About, including all visible structured About fields and field evidence |
| `linkedin.posts.search` | Post search with every current visible filter, including live videos, followed authors, and Author Keywords |
| `linkedin.posts.get` | Exact post read with fully expanded text, typed current media/link/poll variants, engagement and visibility, field evidence, completeness coverage, and bounded repost-original resolution |
| `linkedin.posts.comments.list` | Top-level comments and nested replies |
| `linkedin.posts.create.prepare` / `.execute` | Nine current personal composer modes: text/link, edited images, video, document, poll, celebration, event, existing-job hiring, and expert request; plus audience/group, comment control, brand partnership, eligible collaborators, and scheduling |
| `linkedin.posts.comment.prepare` / `.execute` | Top-level comment or exact-thread reply with text/emoji/link, exact mentions, one photo, or one exact GIF |
| `linkedin.posts.reaction.prepare` / `.execute` | Set, change, remove, or no-op any current post/comment reaction: Like, Celebrate, Support, Love, Insightful, or Funny |
| `linkedin.invitations.list` | Exact sent view or deduplicated union of every current received invitation view |
| `linkedin.connections.list` | Cursor-page and sort the existing first-degree connection inventory |
| `linkedin.connections.search` | Search established first-degree connections with first-degree enforced by the server |
| `linkedin.invitations.send.prepare` / `.execute` | Connection invitation with optional note |
| `linkedin.invitations.accept.prepare` / `.execute` | Accept an exact received invitation |
| `linkedin.invitations.ignore.prepare` / `.execute` | Ignore an exact received connection request |
| `linkedin.messaging.search` | Cursor-paged recipient/message-keyword search across Focused, Other, Archived, or Spam with exactly one optional Jobs, Unread, Connections, InMail, or Starred filter |
| `linkedin.messaging.conversation.get` | Bounded reverse-virtualized one-to-one history with incoming/outgoing messages, visible attachments, replies, edits, reactions, and explicit completeness |
| `linkedin.messaging.message.prepare` / `.execute` | Exact-recipient text/emoji, current desktop image/file, exact KLIPY GIF, or exact-message reply with hash-locked confirmation and visible postconditions |
| `linkedin://sources/{source_id}` | Evidence captured by the current process |

Every operation accepts a caller-owned `context_id` and `request_id`. Direct
detail reads do not require a prior search. The server constructs bounded,
canonical LinkedIn targets from validated job IDs, profile slugs, company
slugs, post references, comment references, and conversation references.

### Collection pagination

Every LinkedIn search or list tool accepts `page_size` (1–100) and an optional
opaque `cursor`. Omit `cursor` for the first page, then copy
`pagination.next_cursor` into the next call with a new `request_id`. A terminal
page has `pagination.has_more=false`.

Cursors are process-local, single-use, expire after 15 minutes by default, and
are bound to the account, capability, and semantic filters that created them.
Changing `page_size` between pages is allowed; changing the search target,
query, sort, direction, or filters is rejected as `invalid_cursor`. The server
rescans a bounded live prefix and removes stable identities already returned,
so `consistency=live_deduplicated` prevents duplicates but does not claim a
frozen LinkedIn snapshot. `truncated=true` means an internal safety or cursor
state bound ended the scan and no further cursor is issued.

`linkedin.invitations.list` uses a stronger contract. A single-filter call
captures and exactly reconciles that view against LinkedIn's visible count.
Received `all` is server-defined because the latest UI has no reliable All
control: it reconciles Focused, Other, Verified, Mutual Connections, Your
Company, and Your School separately, then deduplicates their stable invitation
identities. Coverage reports the per-view counts, their membership sum, the
overlap removed, and the exact unique snapshot count. Continuations slice that
immutable process-local snapshot without reopening LinkedIn and report
`consistency=captured_snapshot`. A quiet list, physical bottom, loader state,
or end message can never substitut
automationlinkedinmcpmodel-context-protocolplaywrightpython

What people ask about linkedin-mcp-server

What is prakharagarwal-dev/linkedin-mcp-server?

+

prakharagarwal-dev/linkedin-mcp-server is mcp servers for the Claude AI ecosystem. Typed, policy-enforced Python MCP server for authorized LinkedIn visible-UI capabilities It has 0 GitHub stars and was last updated today.

How do I install linkedin-mcp-server?

+

You can install linkedin-mcp-server by cloning the repository (https://github.com/prakharagarwal-dev/linkedin-mcp-server) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is prakharagarwal-dev/linkedin-mcp-server safe to use?

+

prakharagarwal-dev/linkedin-mcp-server has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.

Who maintains prakharagarwal-dev/linkedin-mcp-server?

+

prakharagarwal-dev/linkedin-mcp-server is maintained by prakharagarwal-dev. The last recorded GitHub activity is from today, with 0 open issues.

Are there alternatives to linkedin-mcp-server?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy linkedin-mcp-server to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: prakharagarwal-dev/linkedin-mcp-server
[![Featured on ClaudeWave](https://claudewave.com/api/badge/prakharagarwal-dev-linkedin-mcp-server)](https://claudewave.com/repo/prakharagarwal-dev-linkedin-mcp-server)
<a href="https://claudewave.com/repo/prakharagarwal-dev-linkedin-mcp-server"><img src="https://claudewave.com/api/badge/prakharagarwal-dev-linkedin-mcp-server" alt="Featured on ClaudeWave: prakharagarwal-dev/linkedin-mcp-server" width="320" height="64" /></a>

More MCP Servers

linkedin-mcp-server alternatives