LinkedIn MCP Server
📚 View Full Documentation & Installation Guides →
A comprehensive Model Context Protocol (MCP) server for LinkedIn API integration. Manage your LinkedIn profile, posts, connections, skills, education, certifications, and more through AI agents like Claude, ChatGPT, and other LLM applications.
🚀 Features
📱 Social Features
- Profile Management: Fetch and view your LinkedIn profile
- Posts & Engagement: Retrieve posts with engagement metrics, share new content
- Connections: Get and manage your professional network
- People Search: Find professionals by keywords
📝 Profile Management (18 Tools Total)
- Skills: Add and remove skills from your profile
- Work Experience: Add, update, and delete positions
- Education: Manage educational background
- Certifications: Add and remove professional certifications
- Publications: Manage your published works
- Languages: Add language proficiency to your profile
💻 Developer Experience
- Modern MCP SDK: Built with latest
McpServer API (v1.1.0+)
- OpenID Connect Support: Works with LinkedIn's modern OAuth 2.0 + OIDC authentication
- Full TypeScript support with strict type checking
- Comprehensive test suite: 67 test cases, 85%+ server coverage
- Zod schema validation for type safety and input validation
- Modern async/await patterns
- Extensive logging and error handling
- Latest dependencies (Vitest 4, Zod 4, MCP SDK 1.24+)
📋 Prerequisites
- Node.js >= 18.0.0
- LinkedIn Developer App (Client ID & Secret) or existing access token
- pnpm, npm, or yarn
📦 Installation
# Using pnpm (recommended)
pnpm install @pegasusheavy/linkedin-mcp
# Using npm
npm install @pegasusheavy/linkedin-mcp
# Using yarn
yarn add @pegasusheavy/linkedin-mcp
🔧 Configuration
Authentication Setup
This server requires LinkedIn API access. Choose your authentication method:
Option 1: Automatic OAuth Flow (Recommended) 🚀
The server automatically handles OAuth authentication when you don't have an access token.
Step 1: Create a LinkedIn App
- Go to LinkedIn Developers
- Click "Create App" and fill in the required information
- Note your Client ID and Client Secret
Step 2: Configure OAuth Settings
- In your app settings, go to "Auth" tab
- Add
http://localhost:50001/callback to "Authorized redirect URLs for your app"
- Request the following Products (in Products tab):
- Sign In with LinkedIn using OpenID Connect (required for profile access)
- Share on LinkedIn (required for posting)
Note: The server uses OpenID Connect scopes (openid, profile, email, w_member_social) which work with the standard "Sign In with LinkedIn" product. No special API access required!
Step 3: Configure Your MCP Client
The server receives configuration through environment variables from your MCP client:
For Claude Desktop:
Edit your Claude Desktop config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%\Claude\claude_desktop_config.json
- Linux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "@pegasusheavy/linkedin-mcp"],
"env": {
"LINKEDIN_CLIENT_ID": "your_client_id_here",
"LINKEDIN_CLIENT_SECRET": "your_client_secret_here"
}
}
}
}
For Cursor IDE:
In .cursor/mcp.json:
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "@pegasusheavy/linkedin-mcp"],
"env": {
"LINKEDIN_CLIENT_ID": "your_client_id_here",
"LINKEDIN_CLIENT_SECRET": "your_client_secret_here"
}
}
}
}
What Happens:
- First time the server starts, it detects no access token
- Automatically opens your browser to LinkedIn's authorization page
- You authorize the application once
- Token is cached in memory for the session
- Token is automatically refreshed when it expires (within the same session)
- Each new session requires re-authorization (secure, no disk storage)
Option 2: Manual Access Token
If you already have an access token:
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "@pegasusheavy/linkedin-mcp"],
"env": {
"LINKEDIN_ACCESS_TOKEN": "your_token_here"
}
}
}
}
Configuration Options
| Environment Variable | Required | Description |
|---|
LINKEDIN_CLIENT_ID | For OAuth | Your LinkedIn app client ID |
LINKEDIN_CLIENT_SECRET | For OAuth | Your LinkedIn app client secret |
LINKEDIN_REDIRECT_URI | Optional | OAuth callback URL (default: http://localhost:50001/callback) |
LINKEDIN_ACCESS_TOKEN | Alternative | Use existing token instead of OAuth |
LOG_LEVEL | Optional | Logging verbosity: debug, info, warn, error (default: info) |
Token Management
✨ Automatic Features:
- In-Memory Caching - Tokens cached in memory during the session
- Auto-Refresh - Expired tokens automatically refreshed within session
- Session-Based - Authenticate once per MCP client session
- No Disk Storage - Tokens never written to disk for maximum security
⚠️ Security Notes:
- Memory only - Tokens stored in process memory, never on disk
- Session scoped - Each new session requires re-authorization
- CSRF protection - State parameter validation prevents attacks
- Secure secrets - Client secrets never exposed to browser
- Auto-cleanup - Tokens cleared when server stops
🎯 Usage
Claude Desktop
The easiest way to use this MCP server is with Claude Desktop.
Quick Start with OAuth (Recommended)
-
Create a LinkedIn App (see Configuration above)
-
Configure Claude Desktop
Open your Claude Desktop configuration file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%\Claude\claude_desktop_config.json
- Linux:
~/.config/Claude/claude_desktop_config.json
Add this configuration with your LinkedIn app credentials:
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "@pegasusheavy/linkedin-mcp"],
"env": {
"LINKEDIN_CLIENT_ID": "your_client_id_here",
"LINKEDIN_CLIENT_SECRET": "your_client_secret_here"
}
}
}
}
-
Restart Claude Desktop
Completely quit and restart Claude Desktop.
-
Authorize on First Use
The first time Claude tries to use LinkedIn tools:
- A browser window will open to LinkedIn's authorization page
- Click "Allow" to authorize the application
- The token is cached and automatically refreshed
- All future uses work seamlessly without re-authorization
Alternative: Use an Existing Token
If you already have a LinkedIn access token:
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "@pegasusheavy/linkedin-mcp"],
"env": {
"LINKEDIN_ACCESS_TOKEN": "your_token_here"
}
}
}
}
Step 4: Verify Installation
Once Claude Desktop restarts, you should see the LinkedIn MCP server connected. You can verify by asking Claude:
"Can you show me my LinkedIn profile?"
"What are my recent LinkedIn posts?"
"Add TypeScript to my LinkedIn skills"
Claude will now have access to all 18 LinkedIn tools! 🎉
Other MCP Clients
Cursor IDE
Add to your Cursor MCP settings (accessible via Cursor Settings → Features → Model Context Protocol):
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "@pegasusheavy/linkedin-mcp"],
"env": {
"LINKEDIN_ACCESS_TOKEN": "your_linkedin_access_token_here"
}
}
}
}
Cline (VS Code Extension)
Add to your Cline MCP settings:
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "@pegasusheavy/linkedin-mcp"],
"env": {
"LINKEDIN_ACCESS_TOKEN": "your_linkedin_access_token_here"
}
}
}
}
Continue
Add to ~/.continue/config.json:
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "@pegasusheavy/linkedin-mcp"],
"env": {
"LINKEDIN_ACCESS_TOKEN": "your_linkedin_access_token_here"
}
}
}
}
As a Standalone Server (Advanced)
import { LinkedInMCPServer } from '@pegasusheavy/linkedin-mcp';
import { getConfig, validateConfig } from '@pegasusheavy/linkedin-mcp/config';
const config = getConfig();
validateConfig(config);
const server = new LinkedInMCPServer(config);
await server.start();
With MCP Client (Advanced)
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const transport = new StdioClientTransport({
command: 'linkedin-mcp',
});
const client = new Client({
name: 'my-app',
version: '1.0.0',
}, {
capabilities: {},
});
await client.connect(transport);
// List available tools
const tools = await client.listTools();
// Call a tool
const result = await client.callTool({
name: 'get_linkedin_profile',
arguments: {},
});
Using CLI
# Start the server
linkedin-mcp
# With environment variables
LINKEDIN_ACCESS_TOKEN=xxx linkedin-mcp
🛠️ Available Tools
Social & Content Tools
get_linkedin_profile
Get your LinkedIn profile information.
Arguments: None
Returns:
{
"id": "user-id",
"firstName": "John",
"lastName": "Doe",
"headline": "Software Engineer at Tech Corp",
"vanityName": "johndoe"
}
get_linkedin_posts
Get your recent LinkedIn posts with engagement metrics.
Arguments:
limit (number, optional): Maximum number of posts (default: 10)
get_linkedin_connections
Get your LinkedIn connections.
Arguments:
limit (number, optional): Maximum connections (default: 50)
share_linkedin_post
Share a new post on LinkedIn.
Arguments:
text (string, required): The post content
Returns:
{
"id": "post-id",
"url": "https://www.linkedin.com/feed/update/post-id"
}
search_linkedin_people
Search for people on LinkedIn.
Arguments:
keywords (string, required): Search keywords
limit (number, optional): Maximum results (default: 10)
Profile Management Tools
Skills
add_linkedin_skill - Add a skill to your profile
name (string, required): Skill name
delete_linkedin_skill - Remove a skill
skillId (string, required): Skill ID to delete
Work Experience
add_linkedin_position - Add a position
title (string, required): Job title
company (string, required): Company name
startYear (number, required): Start year
startMonth (number, optional): Start month (1-12)
endYear (number, optional): End year
endMonth (number, optional): End month
description (string, optional): Job description
current (boolean, optional): Is current position?
**`u