Skip to main content
Glama
LinkedIn Custom MCP Server

LinkedIn Custom MCP Server

LinkedIn MCP Server

PyPI version Python 3.10+ License: MIT

A powerful Model Context Protocol (MCP) server that enables AI agents like Claude to interact seamlessly with LinkedIn's professional network. Built with FastMCP for high performance and reliability.

What is This?

This MCP server bridges the gap between AI assistants and LinkedIn, allowing them to:

  • Create and manage LinkedIn posts with text and images

  • Comment on posts and engage with content

  • Access profile information

  • Search for companies, jobs, and people

  • Automate LinkedIn interactions through natural language

Perfect for professionals who want to leverage AI to manage their LinkedIn presence efficiently.

Related MCP server: LinkedIn MCP Server

Features

Core Capabilities

  • Secure Authentication - OAuth 2.0 flow with access token management

  • Content Creation - Publish text posts and image posts

  • Content Management - Update and delete posts

  • Engagement - Comment on posts and manage comments

  • Profile Access - Retrieve authenticated user profile information

  • Company Intelligence - Search and view company profiles

  • Job Discovery - Search job postings and view details

  • People Search - Find professionals on LinkedIn

Built With

  • FastMCP - Modern Python MCP framework

  • httpx - Async HTTP client for API calls

  • Pydantic - Data validation and settings management

  • OAuth 2.0 - Industry-standard authentication

Installation

The fastest way to get started:

uvx linkedin-mcp-server

Option 2: Using pip

Install from PyPI:

pip install linkedin-mcp-server

Option 3: From Source

For development or customization:

git clone https://github.com/SARAMALI15792/LinkedIn_mcp_custom_server.git
cd LinkedIn_mcp_custom_server
pip install -e .

Quick Start Guide

Step 1: Create LinkedIn App

  1. Go to LinkedIn Developer Portal

  2. Click "Create app"

  3. Fill in required information:

    • App name: Choose a descriptive name

    • LinkedIn Page: Associate with your page or create one

    • App logo: Upload a logo (optional but recommended)

  4. Request access to these products:

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

    • Share on LinkedIn (instant approval)

  5. In the "Auth" tab:

    • Add Redirect URL: http://localhost:8000

    • Copy your Client ID

    • Copy your Client Secret

Step 2: Configure Environment

Create a .env file in your working directory:

LINKEDIN_CLIENT_ID=your_client_id_here
LINKEDIN_CLIENT_SECRET=your_client_secret_here
LINKEDIN_REDIRECT_URI=http://localhost:8000

Security Note: Never commit the .env file to version control. It's already in .gitignore.

Step 3: Configure Claude Desktop

Edit your Claude Desktop configuration file:

Windows: %APPDATA%\Claude\claude_desktop_config.json macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Linux: ~/.config/Claude/claude_desktop_config.json

Add the LinkedIn MCP server:

{
  "mcpServers": {
    "linkedin": {
      "command": "uvx",
      "args": ["linkedin-mcp-server"]
    }
  }
}

If installed via pip:

{
  "mcpServers": {
    "linkedin": {
      "command": "linkedin-mcp-server"
    }
  }
}

For local development:

{
  "mcpServers": {
    "linkedin": {
      "command": "python",
      "args": ["-m", "linkedin_mcp_server"],
      "env": {
        "LINKEDIN_CLIENT_ID": "your_client_id",
        "LINKEDIN_CLIENT_SECRET": "your_client_secret",
        "LINKEDIN_REDIRECT_URI": "http://localhost:8000"
      }
    }
  }
}

Step 4: Authenticate with LinkedIn

  1. Restart Claude Desktop

  2. In Claude, type: "Generate LinkedIn login URL"

  3. Copy and open the URL in your browser

  4. Sign in to LinkedIn and authorize the application

  5. You'll be redirected to http://localhost:8000/?code=...

  6. Copy the code parameter value from the URL

  7. In Claude, type: "Exchange this code: [paste the code]"

  8. Done! You're now authenticated.

Your access token is automatically saved to .env and will be used for all future requests.

Usage Examples

Authentication

User: "Generate LinkedIn login URL"
Claude: [Provides OAuth URL with instructions]

User: "Exchange this code: AQTvqXXXXXXXXXXX"
Claude: "Success! Access Token saved. Expires in 5183999 seconds."

Creating Posts

Text Post:

User: "Post to LinkedIn: Excited to announce the launch of our new AI-powered LinkedIn MCP server! Check it out on GitHub."
Claude: [Creates post and returns post URN]

Post with Image:

User: "Post this image to LinkedIn with caption 'Team celebration': C:/Users/photos/team.jpg"
Claude: [Uploads image and creates post with caption]

Managing Content

Update a Post:

User: "Update post urn:li:share:7289123456789 to say: Updated announcement..."
Claude: [Deletes old post and creates new one with updated text]

Delete a Post:

User: "Delete my post urn:li:share:7289123456789"
Claude: [Deletes the post permanently]

Engagement

Comment on Posts:

User: "Comment on post urn:li:share:7289123456789: Great insights, thanks for sharing!"
Claude: [Posts comment and returns comment URN]

View Comments:

User: "Show comments on post urn:li:share:7289123456789"
Claude: [Retrieves and displays all comments]

Profile Information

User: "What's my LinkedIn email address?"
Claude: [Retrieves profile and shows email]

User: "Show me my LinkedIn profile"
Claude: [Displays profile information: name, email, picture URL, etc.]

Company Research

User: "Search for companies: Microsoft"
Claude: [Returns list of matching companies]

User: "Get details for company urn:li:organization:1035"
Claude: [Shows company profile information]
User: "Find remote Python developer jobs"
Claude: [Searches and displays matching job postings]

User: "Search for Machine Learning Engineer positions in San Francisco"
Claude: [Returns relevant job listings]

User: "Get details for job urn:li:job:123456789"
Claude: [Shows detailed job information]
User: "Search for AI researchers at Stanford"
Claude: [Returns matching professionals]

Available Tools

Tool Name

Description

Read-Only

Destructive

linkedin_get_oauth_url

Generate OAuth 2.0 authorization URL

Yes

No

linkedin_exchange_code

Exchange auth code for access token

No

No

linkedin_get_my_profile

Get authenticated user's profile

Yes

No

linkedin_get_member_profile

Get member profile by URN

Yes

No

linkedin_create_post

Create text post

No

No

linkedin_create_image_post

Create post with image

No

No

linkedin_update_post

Update existing post (via delete + create)

No

Yes

linkedin_delete_post

Delete post permanently

No

Yes

linkedin_get_recent_posts

List recent posts

Yes

No

linkedin_create_comment

Comment on content

No

No

linkedin_get_post_comments

Get comments on post

Yes

No

linkedin_delete_comment

Delete comment permanently

No

Yes

linkedin_get_company_profile

Get company details by URN

Yes

No

linkedin_search_companies

Search for companies

Yes

No

linkedin_search_jobs

Search job postings

Yes

No

linkedin_get_job_details

Get job details by URN

Yes

No

linkedin_search_people

Search for people

Yes

No

Understanding LinkedIn URNs

LinkedIn uses URNs (Uniform Resource Names) to identify resources:

  • Person: urn:li:person:AbC123XyZ

  • Post/Share: urn:li:share:7289123456789

  • Comment: urn:li:comment:(ugcPost:7289123456789,7289987654321)

  • Organization: urn:li:organization:1035

  • Job: urn:li:job:123456789

When Claude returns a URN, you can use it to reference that resource in other commands.

API Permissions and Limitations

Available Permissions

This server requests these OAuth scopes:

  • openid - OpenID Connect authentication

  • profile - Access to profile information

  • email - Access to email address

  • w_member_social - Create posts and comments

Known Limitations

Some LinkedIn API features require additional permissions that are restricted to approved partners:

Restricted Read Operations:

  • r_member_social - Read user's posts (rarely granted to third-party apps)

  • Marketing Developer Platform - Advanced company/people search

  • Talent Solutions - Advanced job search features

What This Means:

  • Creating posts: Works perfectly

  • Deleting posts: Works perfectly

  • Reading your own posts: May not work (requires restricted permission)

  • Advanced search: May require approval for Marketing/Talent APIs

Why? LinkedIn restricts these APIs to protect user privacy and control third-party access to their platform.

Project Structure

linkedin-mcp-server/
├── linkedin_mcp_server/          # Main package
│   ├── __init__.py               # Package initialization
│   ├── __main__.py               # CLI entry point
│   ├── server.py                 # MCP server with 18 tool definitions
│   ├── config.py                 # Configuration with pydantic-settings
│   ├── utils.py                  # Shared HTTP client utilities
│   └── tools/                    # Tool implementations
│       ├── auth.py               # OAuth 2.0 authentication flow
│       ├── profile.py            # Profile retrieval operations
│       ├── post.py               # Post and comment operations
│       ├── company.py            # Company search and profiles
│       ├── job.py                # Job search operations
│       └── search.py             # People search functionality
├── pyproject.toml                # Package metadata and dependencies
├── requirements.txt              # Pinned dependencies
├── README.md                     # This file
├── claude.md                     # Claude integration guide
├── LICENSE                       # MIT License
└── get_profile.py                # Example standalone script

Development

Setting Up Development Environment

# Clone repository
git clone https://github.com/SARAMALI15792/LinkedIn_mcp_custom_server.git
cd LinkedIn_mcp_custom_server

# Install with dev dependencies
pip install -e ".[dev]"

Running Tests

pytest tests/

Code Quality

# Format code
black linkedin_mcp_server/

# Lint
ruff check linkedin_mcp_server/

# Type checking
mypy linkedin_mcp_server/

Running Locally

# Using module syntax
python -m linkedin_mcp_server

# Using installed command
linkedin-mcp-server

Troubleshooting

Authentication Issues

Problem: "Error: LINKEDIN_CLIENT_ID not configured" Solution: Create .env file with your LinkedIn app credentials

Problem: "Unauthorized (401)" errors Solution: Your access token expired. Re-authenticate using the OAuth flow

Problem: "Error exchanging code: invalid code" Solution: Authorization codes expire quickly. Generate a new OAuth URL and try again

API Errors

Problem: "Forbidden (403)" errors Solution: Your LinkedIn app may lack required permissions. Check your app's products in the Developer Portal

Problem: "r_member_social permission required" Solution: This permission is restricted. LinkedIn rarely grants it to third-party apps. Focus on write operations instead

Problem: Can't search companies/jobs/people Solution: These APIs may require Marketing/Talent Solutions products which need LinkedIn approval

Connection Issues

Problem: MCP server not connecting in Claude Desktop Solution:

  1. Verify claude_desktop_config.json syntax is valid JSON

  2. Check that the command path is correct

  3. Restart Claude Desktop

  4. Check Claude Desktop logs for error messages

Problem: ".env file not found" Solution: Create .env file in the same directory where Claude Desktop runs the server, or specify environment variables in the config

Security Best Practices

  1. Never commit credentials - .env is in .gitignore for a reason

  2. Rotate tokens regularly - Re-authenticate periodically for security

  3. Use HTTPS in production - Update redirect URI to HTTPS for production apps

  4. Minimum permissions - Only request scopes you actually need

  5. Review app access - Regularly check LinkedIn's "Apps" section in settings

Contributing

Contributions are welcome! Here's how:

  1. Fork the repository

  2. Create a feature branch: git checkout -b feature/amazing-feature

  3. Make your changes

  4. Run tests: pytest tests/

  5. Format code: black linkedin_mcp_server/

  6. Commit: git commit -m 'Add amazing feature'

  7. Push: git push origin feature/amazing-feature

  8. Open a Pull Request

Contribution Guidelines

  • Follow existing code style (Black formatter, 100 char line length)

  • Add tests for new features

  • Update documentation as needed

  • Keep commits focused and atomic

  • Write clear commit messages

Roadmap

Future enhancements being considered:

  • Token refresh flow implementation

  • Webhook support for real-time notifications

  • Enhanced error handling and retry logic

  • Pagination support for search results

  • Bulk operations for efficiency

  • Analytics and insights (if API access granted)

  • Connection management features

  • Message sending (if Messaging API access granted)

FAQ

Q: Why can't I read my own posts? A: The r_member_social permission required to read posts is restricted by LinkedIn. Most third-party apps cannot access this feature.

Q: How long do to access tokens last? A: LinkedIn controls token expiration. Typically tokens last for 60 days, but this can vary. You'll need to re-authenticate when tokens expire.

Q: Can I use this for multiple LinkedIn accounts? A: Currently, the server is designed for single-user authentication. Each .env file holds one access token.

Q: Is this officially supported by LinkedIn? A: No, this is a community project. It uses LinkedIn's public APIs but is not officially endorsed by LinkedIn.

Q: Can I use this commercially? A: Yes, the MIT license allows commercial use. However, check LinkedIn's terms of service and API usage policies.

Q: Why do some searches return empty results? A: Search APIs may require additional LinkedIn products (Marketing/Talent) that need approval. Also, API access varies by account type.

Support

Resources

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Built with:

  • FastMCP - For the excellent MCP framework

  • Model Context Protocol - For enabling AI-agent integrations

  • LinkedIn API - For providing professional networking capabilities

  • Claude - For inspiring and testing this integration

Author

SARAM ALI


Built with care for the AI and LinkedIn communities | Report Issues | Contribute | Star on GitHub

Available Tools

17 tools
linkedin_create_commentCreate CommentB

Create a comment on a LinkedIn share, article, or video. Args: object_urn: The URN of the content to comment on (e.g., 'urn:li:share:123'). text: The text of the comment.

Inputs: object_urn (required), text (required). Returns: result

linkedin_create_image_postCreate Image PostB

Create a post with an image. Args: text: Post caption. image_source: Local file path or public URL of the image. visibility: 'PUBLIC' or 'CONNECTIONS'.

Inputs: text (required), image_source (required), visibility. Returns: result

linkedin_create_postCreate Feed PostA

Create a new text-based update on the user LinkedIn feed. Args: text: The content of the post. visibility: 'PUBLIC' or 'CONNECTIONS'.

Inputs: text (required), visibility. Returns: result

linkedin_delete_commentDelete CommentC

Delete a specific comment. Args: comment_urn: The URN of the comment to delete. object_urn: The URN of the parent post/object.

Inputs: comment_urn (required), object_urn (required). Returns: result

linkedin_delete_postDelete PostA

Delete a LinkedIn post by its URN (e.g., 'urn:li:share:123').

Inputs: post_urn (required). Returns: result

linkedin_exchange_codeExchange Auth CodeB

Exchange the browser-provided authorization code for a persistent access token.

Inputs: code (required). Returns: result

linkedin_get_company_profileGet Company ProfileA

Fetch a company's profile information by its URN (e.g., 'urn:li:organization:123').

Inputs: company_urn (required). Returns: result

linkedin_get_job_detailsGet Job DetailsB

Fetch details for a specific job posting by its URN.

Inputs: job_urn (required). Returns: result

linkedin_get_member_profileGet Member ProfileA

Fetch a specific member's profile by their URN (e.g., 'urn:li:person:123').

Inputs: member_urn (required). Returns: result

linkedin_get_my_profileGet My ProfileA

Fetch the authenticated user's profile information (Name, Email, Picture).

Inputs: no named parameters. Returns: result

linkedin_get_oauth_urlGet LinkedIn Auth URLA

Generate the LinkedIn OAuth 2.0 authorization URL for browser login.

Inputs: no named parameters. Returns: result

linkedin_get_post_commentsGet CommentsB

Get comments for a specific post/share.

Inputs: object_urn (required). Returns: result

linkedin_get_recent_postsGet Recent PostsA

List the user's recent posts (Requires 'r_member_social' permission).

Inputs: no named parameters. Returns: result

linkedin_search_companiesSearch CompaniesB

Search for companies on LinkedIn by keywords.

Inputs: keywords (required). Returns: result

linkedin_search_jobsSearch JobsB

Search for jobs on LinkedIn by keywords and optional location.

Inputs: keywords (required), location. Returns: result

linkedin_search_peopleSearch PeopleC

Search for people on LinkedIn by keywords.

Inputs: keywords (required). Returns: result

linkedin_update_postUpdate PostA

Update a post's text. ⚠️ Warning: This deletes the old post and creates a new one with a new ID, as LinkedIn does not support editing published posts via API.

Inputs: post_urn (required), text (required), visibility. Returns: result

Tool Schema Changelog

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

    TDQS

    A3.7/5.0

    Scored across 17 tools

    Disambiguation5/5

    Every tool has a clearly distinct purpose targeting specific LinkedIn resources and actions. For example, linkedin_create_post, linkedin_create_image_post, and linkedin_create_comment handle different content types, while search tools (companies, jobs, people) and get tools (profile, post details) are well-separated. No tools appear to overlap in functionality.

    Naming Consistency5/5

    All tools follow a consistent 'linkedin_verb_noun' pattern with snake_case throughout. The verbs are appropriate and predictable (e.g., create, delete, get, search, update), and nouns clearly indicate the resource (e.g., post, comment, profile). There are no deviations in naming conventions.

    Tool Count4/5

    With 17 tools, the count is slightly high but reasonable for a comprehensive LinkedIn API server covering posts, comments, profiles, companies, jobs, and OAuth. It includes core CRUD operations and search functionalities, though it might benefit from slight consolidation in some areas like OAuth-related tools.

    Completeness4/5

    The tool set provides strong coverage for LinkedIn's social and professional features, including create, read, update, delete for posts and comments, profile fetching, and searches. Minor gaps include lack of tools for liking/reacting to content or managing connections, but agents can perform core workflows effectively without dead ends.

    Maintenance

    ActivityInactive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      C
      maintenance
      Enables AI agents to manage LinkedIn profiles, posts, connections, skills, education, and certifications through the LinkedIn API.
      18
      176 npm
      64
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Enables AI agents with read/write access to LinkedIn API, including profile, posts, media, organizations, comments, reactions, and analytics.
      20
      7 npm
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Allows AI agents to authenticate with LinkedIn and share posts or links via the Model Context Protocol.
      2
      89 npm
      MIT