Skip to main content
Glama
ashishtechsavvy

linkedin-mcp

LinkedIn MCP Server

MCP server for LinkedIn post management and analytics. Deploy on Vercel, connect to Claude or any MCP-compatible LLM.


Architecture

Claude / LLM
     │
     │ POST /mcp (JSON-RPC)
     ▼
LinkedIn MCP Server (Vercel)
     │
     │ OAuth 2.0 + Bearer token
     ▼
LinkedIn API v2

Related MCP server: LinkedIn MCP Server

Step-by-Step Setup

STEP 1 — Create LinkedIn App

  1. Go to https://developer.linkedin.com/apps

  2. Click Create App

  3. Fill in: App Name, LinkedIn Page (your company), App Logo

  4. Click Create App

  5. Go to Auth tab → note your Client ID and Client Secret

  6. Under OAuth 2.0 settings → Authorized redirect URLs, add:

    • Local dev: http://localhost:3000/auth/callback

    • Production: https://your-app.vercel.app/auth/callback

  7. Go to Products tab → request access to:

    • Sign In with LinkedIn using OpenID Connect (instant approval)

    • Share on LinkedIn → gives you w_member_social scope (instant)

    • Marketing Developer Platform → only if you need impression analytics (requires manual review)


STEP 2 — Clone and Install

git clone <your-repo>
cd linkedin-mcp-server
npm install

STEP 3 — Configure Environment

cp .env.example .env

Edit .env:

LINKEDIN_CLIENT_ID=86xxxxxxxxxx
LINKEDIN_CLIENT_SECRET=WPxxxxxxxxxx
LINKEDIN_REDIRECT_URI=http://localhost:3000/auth/callback
PORT=3000

STEP 4 — Build and Run Locally

npm run build
npm start

Server starts at http://localhost:3000

Endpoints:

  • GET /health — health check

  • GET /auth/linkedin?user_id=YOUR_ID — start OAuth flow

  • GET /auth/callback — LinkedIn redirects here automatically

  • POST /mcp — MCP endpoint for LLM tool calls


STEP 5 — Authenticate a LinkedIn Account

Open in browser:

http://localhost:3000/auth/linkedin?user_id=herbert

This redirects you to LinkedIn → you log in → LinkedIn redirects to your callback → token is stored.

Response you'll see:

{
  "success": true,
  "message": "LinkedIn authenticated for user herbert",
  "person_id": "abc123xyz",
  "expires_in_days": 60
}

Save the person_id — you'll need it when calling post tools.


STEP 6 — Deploy to Vercel

npm install -g vercel
vercel login

# Set secrets
vercel env add LINKEDIN_CLIENT_ID
vercel env add LINKEDIN_CLIENT_SECRET
vercel env add LINKEDIN_REDIRECT_URI  # set to https://your-app.vercel.app/auth/callback

# Deploy
npm run build
vercel --prod

After deploy, update your LinkedIn app's redirect URI to the production URL.


STEP 7 — Connect to Claude

In Claude.ai → Settings → Connectors → Add MCP Server:

URL: https://your-app.vercel.app/mcp

That's your MCP URL.


Available MCP Tools

Tool

What it does

linkedin_check_auth

Check if a user is authenticated

linkedin_get_profile

Get profile info + LinkedIn person ID

linkedin_create_post

Publish a post to LinkedIn

linkedin_get_my_posts

Fetch your recent posts

linkedin_get_post_analytics

Get likes/comments on a post

linkedin_delete_post

Delete a post you own


Example Claude Usage

Once connected, you can say:

"Check if user herbert is authenticated on LinkedIn"

"Post to LinkedIn as herbert: 'Excited to share our latest Oracle HCM implementation update...'"

"Get the last 5 LinkedIn posts for herbert and show me engagement"


Production: Replace In-Memory Token Store with Supabase

The current code stores tokens in memory (lost on restart). For production:

// src/services/linkedin.ts — replace storeToken/getToken with:

import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_KEY!
);

export async function storeToken(userId: string, token: LinkedInToken) {
  await supabase.from('linkedin_tokens').upsert({
    user_id: userId,
    access_token: token.access_token,
    refresh_token: token.refresh_token,
    expires_at: new Date(token.expires_at).toISOString(),
    person_id: token.person_id,
  });
}

export async function getToken(userId: string): Promise<LinkedInToken | undefined> {
  const { data } = await supabase
    .from('linkedin_tokens')
    .select('*')
    .eq('user_id', userId)
    .single();
  if (!data) return undefined;
  return {
    access_token: data.access_token,
    refresh_token: data.refresh_token,
    expires_at: new Date(data.expires_at).getTime(),
    person_id: data.person_id,
  };
}

Supabase table:

create table linkedin_tokens (
  user_id text primary key,
  access_token text not null,
  refresh_token text,
  expires_at timestamptz not null,
  person_id text,
  created_at timestamptz default now(),
  updated_at timestamptz default now()
);

LinkedIn API Scope Reference

Scope

What it unlocks

Approval

r_liteprofile

Name, ID, photo

Instant

r_emailaddress

Email address

Instant

w_member_social

Post as yourself

Instant

r_organization_social

Read company page posts

Manual review

rw_organization_admin

Post as company page

Manual review

r_ads_reporting

Impression/click analytics

Marketing partner only


Token Expiry

  • Access tokens expire in 60 days

  • Refresh tokens expire in 365 days (if offline_access granted)

  • The server auto-refreshes tokens before they expire

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ashishtechsavvy/linkedin-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server