LinkedIn MCP Server
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 MCP Servershare a post about my new certification"
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
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
McpServerAPI (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+)
Related MCP server: LinkedIn Custom MCP Server
π 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/callbackto "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,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.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.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 |
| For OAuth | Your LinkedIn app client ID |
| For OAuth | Your LinkedIn app client secret |
| Optional | OAuth callback URL (default: |
| Alternative | Use existing token instead of OAuth |
| Optional | Logging verbosity: |
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.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.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 keywordslimit(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 titlecompany(string, required): Company namestartYear(number, required): Start yearstartMonth(number, optional): Start month (1-12)endYear(number, optional): End yearendMonth(number, optional): End monthdescription(string, optional): Job descriptioncurrent(boolean, optional): Is current position?
update_linkedin_position - Update an existing position
positionId(string, required): Position IDAll other fields optional
delete_linkedin_position - Remove a position
positionId(string, required): Position ID
Education
add_linkedin_education - Add education
schoolName(string, required): School namedegree(string, optional): Degree namefieldOfStudy(string, optional): Field of studystartYear,startMonth,endYear,endMonth(optional)grade(string, optional): GPA or gradeactivities(string, optional): Activities and societies
delete_linkedin_education - Remove education
educationId(string, required): Education ID
Certifications
add_linkedin_certification - Add a certification
name(string, required): Certification nameauthority(string, required): Issuing organizationlicenseNumber(string, optional): License numberstartYear,startMonth,endYear,endMonth(optional)url(string, optional): Certificate URL
delete_linkedin_certification - Remove a certification
certificationId(string, required): Certification ID
Publications
add_linkedin_publication - Add a publication
name(string, required): Publication namepublisher(string, optional): Publisher nameyear,month,day(optional): Publication datedescription(string, optional): Descriptionurl(string, optional): Publication URL
delete_linkedin_publication - Remove a publication
publicationId(string, required): Publication ID
Languages
add_linkedin_language - Add a language
name(string, required): Language nameproficiency(string, optional): ELEMENTARY, LIMITED_WORKING, PROFESSIONAL_WORKING, FULL_PROFESSIONAL, NATIVE_OR_BILINGUAL
delete_linkedin_language - Remove a language
languageId(string, required): Language ID
For detailed examples and usage patterns, see PROFILE_MANAGEMENT.md.
π§ͺ Development
Setup
# Clone the repository
git clone https://github.com/pegasusheavy/linkedin-mcp.git
cd linkedin-mcp
# Install dependencies
pnpm install
# Set environment variables for testing
export LINKEDIN_CLIENT_ID="your_client_id"
export LINKEDIN_CLIENT_SECRET="your_client_secret"
# Or use an existing access token
export LINKEDIN_ACCESS_TOKEN="your_token"Running Tests
# Run all tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run tests with coverage
pnpm test:coverage
# Type checking
pnpm run type-check
# Linting
pnpm run lintBuilding
# Build the project
pnpm run build
# Run in development mode
pnpm run devπ Test Coverage
This project maintains high test coverage:
Lines: 85%+
Functions: 100%
Branches: 72%+
Statements: 85%+
Total Tests: 67
pnpm test:coverageποΈ Architecture
src/
βββ index.ts # Entry point and CLI
βββ server.ts # MCP server implementation (18 tools)
βββ config.ts # Configuration management
βββ logger.ts # Logging utilities
βββ types.ts # TypeScript type definitions
βββ linkedin-client.ts # LinkedIn API client (OpenID Connect + legacy support)
βββ oauth-manager.ts # OAuth 2.0 flow management
βββ oauth-service.ts # OAuth token exchange service
βββ *.test.ts # Unit tests (67 tests)π€ Contributing
Contributions are welcome! Please follow these steps:
Fork the repository
Create a feature branch (
git checkout -b feature/amazing-feature)Make your changes
Add tests for new functionality
Ensure tests pass (
pnpm test)Commit your changes (
git commit -m 'Add amazing feature')Push to the branch (
git push origin feature/amazing-feature)Open a Pull Request
Please read CONTRIBUTING.md for details on our code of conduct and development process.
π License
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright (c) 2025-2026 Pegasus Heavy Industries
π Security
Best Practices
Never commit API keys or tokens to version control
Use environment variables for all sensitive configuration
Rotate access tokens regularly
Follow the principle of least privilege for API scopes
Review the Security Policy for reporting vulnerabilities
π API Documentation
OAuth Scopes
The server requests the following OpenID Connect scopes:
Scope | Purpose |
| OpenID Connect authentication |
| Access to name and profile picture |
| Access to email address |
| Create, modify, and delete posts |
These scopes are available with the standard "Sign In with LinkedIn using OpenID Connect" product - no special API access required!
LinkedIn API Rate Limits
LinkedIn imposes rate limits on API calls. The server handles rate limiting gracefully and provides informative error messages.
Error Handling
All tools return errors in a consistent format:
{
"content": [{
"type": "text",
"text": "Error: Descriptive error message"
}],
"isError": true
}π Examples
Example 1: Building Your Profile
// Add education
await client.callTool({
name: 'add_linkedin_education',
arguments: {
schoolName: 'Stanford University',
degree: 'Master of Science',
fieldOfStudy: 'Computer Science',
startYear: 2020,
endYear: 2022,
},
});
// Add current position
await client.callTool({
name: 'add_linkedin_position',
arguments: {
title: 'Senior Software Engineer',
company: 'Pegasus Heavy Industries',
startYear: 2022,
startMonth: 6,
current: true,
description: 'Building AI-powered solutions',
},
});
// Add skills
await client.callTool({ name: 'add_linkedin_skill', arguments: { name: 'TypeScript' } });
await client.callTool({ name: 'add_linkedin_skill', arguments: { name: 'AI/ML' } });Example 2: Share a Post
const result = await client.callTool({
name: 'share_linkedin_post',
arguments: {
text: 'π Excited to announce our new LinkedIn MCP server! Full profile management through AI agents. #opensource #typescript #ai',
},
});Example 3: Search and Analyze
// Search for people
const people = await client.callTool({
name: 'search_linkedin_people',
arguments: {
keywords: 'software engineer typescript AI',
limit: 20,
},
});
// Get your posts analytics
const posts = await client.callTool({
name: 'get_linkedin_posts',
arguments: { limit: 10 },
});π Acknowledgments
π Support
π¬ Issues: GitHub Issues
π Documentation: Wiki
π Website: Pegasus Heavy Industries
πΊοΈ Roadmap
LinkedIn Company Pages support
LinkedIn Groups integration
Advanced search filters and saved searches
Bulk operations support
Message management (InMail)
Recommendations management
Profile views analytics
Web dashboard for monitoring
Docker container support
Migration toMcpServerhigh-level APIβ Completed in v1.1.0OpenID Connect authentication supportβ Completed in v1.3.0
π Changelog
See CHANGELOG.md for a list of changes.
Made with β€οΈ by Pegasus Heavy Industries
Empowering AI agents to manage professional networks
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
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/quinnjr/linkedin-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server