Skip to main content
Glama
linkedin-mcp
by AriOliv

LinkedIn MCP

Unofficial Model Context Protocol server for LinkedIn — read your profile, network and connections, search people and jobs, and send messages from any MCP client (Claude, etc.).

It runs in two modes:

  • HTTP + OAuth 2.1 (recommended) — the server is an OAuth 2.1 authorization server for MCP clients and bridges to LinkedIn's real 3‑legged OAuth consent screen. Each user signs in on linkedin.com; the server never sees their password.

  • stdio — a local server that reads a LINKEDIN_ACCESS_TOKEN from the environment. Handy for a single user or quick testing.

This mirrors the auth architecture of @aol/ifood-mcp and @aol/uber-mcp, swapping their reverse‑engineered logins for LinkedIn's first‑class OAuth.


Tools

Tool

LinkedIn endpoint

Notes

linkedin_me

GET /v2/userinfo

Works with the default openid profile email scopes.

linkedin_network_stats

GET /v2/networkSizes/{urn}

Needs r_1st_connections_size.

linkedin_connections

GET /v2/connections

Needs an approved connections product.

linkedin_get_profile

GET /v2/people/{id}

Needs an approved profile product.

linkedin_search_people

GET /v2/search/people

Needs an approved search product.

linkedin_search_jobs

GET /v2/jobs/search

Needs an approved jobs product.

linkedin_send_message

POST /v2/messages

Needs w_member_social (messaging).

LinkedIn API access. Out of the box, a standard LinkedIn app only grants the OpenID Connect scopes (openid profile email), so linkedin_me works immediately. The other tools call endpoints that LinkedIn gates behind approved products (Sign In, Marketing, Talent Solutions, etc.). Until your app is approved for those, those tools will return 403 — this is a LinkedIn platform restriction, not a bug. Add the granted scopes to LINKEDIN_SCOPES once approved.


Related MCP server: Linkd MCP Server

Quick start (HTTP + OAuth)

1. Create a LinkedIn app

  1. Go to https://www.linkedin.com/developers/apps → Create app.

  2. Under Auth, copy the Client ID and Client Secret.

  3. Add your callback under Authorized redirect URLs: http://localhost:3000/login/callback (or PUBLIC_URL + /login/callback).

  4. Under Products, add Sign In with LinkedIn using OpenID Connect (and any others you need).

2. Configure

cp .env.example .env
# then edit .env:
#   MCP_JWT_SECRET=$(openssl rand -hex 32)
#   LINKEDIN_CLIENT_ID=...
#   LINKEDIN_CLIENT_SECRET=...
#   PUBLIC_URL=http://localhost:3000

3. Run

npm install
npm run build
npm run start:http      # or: npm run dev  (tsx watch)

Point your MCP client at http://localhost:3000/mcp. On first connect it runs the OAuth 2.1 flow, redirects you to LinkedIn to sign in, and then calls tools on your behalf.


Quick start (stdio)

cp .env.example .env
# set LINKEDIN_ACCESS_TOKEN=... (e.g. from the LinkedIn developer console token generator)
npm install && npm run build
npm start

MCP client config:

{
  "mcpServers": {
    "linkedin": {
      "command": "node",
      "args": ["/absolute/path/to/linkedin-mcpserver/build/index.js"],
      "env": { "LINKEDIN_ACCESS_TOKEN": "AQV..." }
    }
  }
}

How the OAuth bridge works

MCP client ──/authorize──▶ this server ──302──▶ /login ──▶ /login/start
                                                              │
                                                    302 ▼ linkedin.com/oauth/v2/authorization
                                              user signs in on LinkedIn
                                                              │
      /login/callback ◀──302 code&state──────────────────────┘
            │  exchange code → LinkedIn access + refresh token
            │  fetch /v2/userinfo → stable member id (sub)
            │  store tokens per‑user, mint an MCP auth code
            ▼
MCP client ──/token──▶ this server ──▶ HS256 JWT (audience‑bound to /mcp)
MCP client ──/mcp (Bearer JWT)──▶ tools call LinkedIn with the member's token
  • MCP access tokens are short‑lived HS256 JWTs signed with MCP_JWT_SECRET, audience‑bound to the /mcp resource (RFC 8707), with rotating refresh tokens.

  • Downstream LinkedIn tokens are refreshed transparently when the app is approved for refresh tokens; otherwise the user re‑authenticates.

  • All state is in memory (single process). Swap the stores in src/http/store.ts for Redis/DB to scale horizontally.


Environment

Var

Required

Default

Purpose

PORT

–

3000

HTTP port.

PUBLIC_URL

HTTP

http://localhost:PORT

URL the client + LinkedIn see.

MCP_JWT_SECRET

HTTP

–

HS256 key (≥32 chars). openssl rand -hex 32.

LINKEDIN_CLIENT_ID

HTTP

–

LinkedIn app client id.

LINKEDIN_CLIENT_SECRET

HTTP

–

LinkedIn app client secret.

LINKEDIN_SCOPES

–

openid profile email

OAuth scopes to request.

LINKEDIN_REDIRECT_URI

–

PUBLIC_URL/login/callback

OAuth callback override.

LINKEDIN_ACCESS_TOKEN

stdio

–

Token for stdio mode.

LINKEDIN_API_BASE

–

https://api.linkedin.com

API host override.

LINKEDIN_VERSION

–

–

LinkedIn-Version header (YYYYMM) for /rest.


Layout

src/
  index.ts                 stdio server + tool catalog + executeTool + TokenProvider
  http-server.ts           remote MCP server (Streamable HTTP + OAuth 2.1)
  http/
    provider.ts            LinkedInOAuthProvider (OAuthServerProvider, HS256 JWTs)
    login-router.ts        /login → LinkedIn consent → /login/callback
    linkedin-auth.ts       LinkedIn OAuth client (authorize / token / userinfo)
    session-provider.ts    per-user token lookup + transparent refresh
    store.ts               in-memory OAuth + downstream token stores

Scripts

Script

Action

npm run build

Compile to build/.

npm run start:http

Run the HTTP/OAuth server.

npm start

Run the stdio server.

npm run dev

tsx watch the HTTP server.

npm run dev:stdio

tsx watch the stdio server.

npm run typecheck

tsc --noEmit.

License

MIT. See LICENSE.

Available Tools

7 tools
linkedin_connectionsC

List the member's 1st-degree connections (paginated). Requires an approved connections product/scope.

Inputs: count, start.

linkedin_get_profileA

Retrieve a member profile by person id (publicId or numeric/URN id). Requires an approved profile product/scope.

Inputs: personId (required).

linkedin_meA

Get the authenticated member's profile via OpenID Connect (sub, name, email, locale, picture). Works with the openid profile email scopes.

Inputs: no named parameters.

linkedin_network_statsA

Get the member's network size (1st-degree connection count). Requires the r_1st_connections_size product/scope.

Inputs: personUrn.

linkedin_search_jobsA

Search job postings by keywords / location / company / job type. Requires an approved jobs product/scope.

Inputs: jobType, keywords, location, companies.

linkedin_search_peopleC

Search member profiles by keywords / location / company / industry. Requires an approved search product/scope.

Inputs: keywords, location, industries, currentCompany.

linkedin_send_messageA

Send a message to a connection. Requires the w_member_social (messaging) product/scope.

Inputs: messageBody (required), recipientUrn (required), subject.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 7 tools

    Disambiguation5/5

    Each tool has a distinct purpose: self-profile, profile by ID, search people, search jobs, send messages, connections list, and network size. Although 'me' and 'get_profile' both retrieve profiles, one is self and the other is arbitrary, so there is no ambiguity. The two search tools clearly target different resources.

    Naming Consistency4/5

    All tools share the 'linkedin_' prefix, which is consistent. However, the pattern after the prefix varies: some use bare nouns (me, connections, network_stats) while others use verb_noun (search_people, search_jobs, send_message, get_profile). This is a minor inconsistency but still predictable and readable.

    Tool Count5/5

    With 7 tools, the server is well-scoped for a LinkedIn integration. Each tool covers a core functionality area without unnecessary bloat, falling well within the typical 3-15 range for a focused server.

    Completeness4/5

    The tool surface covers the most common LinkedIn actions: viewing profiles, searching people and jobs, messaging, and managing connections. Missing capabilities like posting updates or managing connection requests are noticeable but not critical, as the core workflows are covered.

    Maintenance

    ActivityStale
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      A Model Context Protocol server that enables seamless interaction with LinkedIn for job applications, profile retrieval, feed browsing, and resume analysis through natural language commands.
      36
      -
    • A
      license
      A
      quality
      D
      maintenance
      An unofficial Model Context Protocol server that enables programmatic access to LinkedIn data through tools like user search, company search, profile enrichment, and contact retrieval.
      7
      45 npm
      3
      ISC
    • F
      license
      Not graded
      quality
      D
      maintenance
      A comprehensive Model Context Protocol server that enables AI assistants to interact with LinkedIn APIs for profile management, content creation, networking, messaging, and analytics.
      2
      -
    • A
      license
      A
      quality
      F
      maintenance
      An unofficial Model Context Protocol server that provides LinkedIn tools for searching users, enriching profiles, retrieving contact information, and conducting deep research through natural language interfaces.
      5
      13 npm
      5
      MIT