linkedin-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@linkedin-mcpPost to LinkedIn: 'Hello from MCP!'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 v2Related MCP server: LinkedIn MCP Server
Step-by-Step Setup
STEP 1 — Create LinkedIn App
Click Create App
Fill in: App Name, LinkedIn Page (your company), App Logo
Click Create App
Go to Auth tab → note your Client ID and Client Secret
Under OAuth 2.0 settings → Authorized redirect URLs, add:
Local dev:
http://localhost:3000/auth/callbackProduction:
https://your-app.vercel.app/auth/callback
Go to Products tab → request access to:
Sign In with LinkedIn using OpenID Connect (instant approval)
Share on LinkedIn → gives you
w_member_socialscope (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 installSTEP 3 — Configure Environment
cp .env.example .envEdit .env:
LINKEDIN_CLIENT_ID=86xxxxxxxxxx
LINKEDIN_CLIENT_SECRET=WPxxxxxxxxxx
LINKEDIN_REDIRECT_URI=http://localhost:3000/auth/callback
PORT=3000STEP 4 — Build and Run Locally
npm run build
npm startServer starts at http://localhost:3000
Endpoints:
GET /health— health checkGET /auth/linkedin?user_id=YOUR_ID— start OAuth flowGET /auth/callback— LinkedIn redirects here automaticallyPOST /mcp— MCP endpoint for LLM tool calls
STEP 5 — Authenticate a LinkedIn Account
Open in browser:
http://localhost:3000/auth/linkedin?user_id=herbertThis 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 --prodAfter 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/mcpThat's your MCP URL.
Available MCP Tools
Tool | What it does |
| Check if a user is authenticated |
| Get profile info + LinkedIn person ID |
| Publish a post to LinkedIn |
| Fetch your recent posts |
| Get likes/comments on a 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 |
| Name, ID, photo | Instant |
| Email address | Instant |
| Post as yourself | Instant |
| Read company page posts | Manual review |
| Post as company page | Manual review |
| Impression/click analytics | Marketing partner only |
Token Expiry
Access tokens expire in 60 days
Refresh tokens expire in 365 days (if
offline_accessgranted)The server auto-refreshes tokens before they expire
This server cannot be installed
Maintenance
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
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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