Skip to main content
Glama
mcp-server-linkedin

mcp-server-linkedin

by Huzaifa-ali

Use Cases

  • Content Publishing: Draft and publish LinkedIn posts from your AI assistant without switching context.

  • Media Sharing: Upload images and videos alongside your posts in a single command.

  • Link Previews: Share articles with auto-generated link preview cards.

  • Multi-Format Workflow: Compose text-only updates, visual content, or article shares through one unified interface.

  • Account Management: Authenticate, check your profile, and manage your session without leaving your editor.

Built for developers and content creators who want their AI tools to publish directly to LinkedIn.


Quick Start

Prerequisites

  1. Python 3.10+

  2. LinkedIn App — Follow the step-by-step setup guide or the quick version below:

    • Create an app at LinkedIn Developer Portal

    • Products: "Share on LinkedIn" + "Sign In with LinkedIn using OpenID Connect"

    • OAuth 2.0 scopes: openid, profile, email, w_member_social

    • Redirect URL: http://localhost:3000/callback

Install

uvx mcp-server-linkedin

Or with pip:

pip install mcp-server-linkedin

Related MCP server: LinkedIn MCP Server

Configuration

Set these environment variables:

LINKEDIN_CLIENT_ID=your_client_id        # From LinkedIn Developer Portal
LINKEDIN_CLIENT_SECRET=your_secret_here  # From LinkedIn Developer Portal
LINKEDIN_REDIRECT_URI=http://localhost:3000/callback  # Optional, this is the default

Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "linkedin": {
      "command": "uvx",
      "args": ["mcp-server-linkedin"],
      "env": {
        "LINKEDIN_CLIENT_ID": "your_client_id",
        "LINKEDIN_CLIENT_SECRET": "your_secret_here"
      }
    }
  }
}
{
  "mcpServers": {
    "linkedin": {
      "command": "uvx",
      "args": ["mcp-server-linkedin"],
      "env": {
        "LINKEDIN_CLIENT_ID": "your_client_id",
        "LINKEDIN_CLIENT_SECRET": "your_secret_here"
      }
    }
  }
}

VS Code + Copilot

Add to .vscode/mcp.json in your workspace:

{
  "servers": {
    "linkedin": {
      "command": "uvx",
      "args": ["mcp-server-linkedin"],
      "env": {
        "LINKEDIN_CLIENT_ID": "your_client_id",
        "LINKEDIN_CLIENT_SECRET": "your_secret_here"
      }
    }
  }
}

Cursor

Add to .cursor/mcp.json in your project root:

{
  "mcpServers": {
    "linkedin": {
      "command": "uvx",
      "args": ["mcp-server-linkedin"],
      "env": {
        "LINKEDIN_CLIENT_ID": "your_client_id",
        "LINKEDIN_CLIENT_SECRET": "your_secret_here"
      }
    }
  }
}

Kiro

Add to .kiro/settings/mcp.json:

{
  "mcpServers": {
    "linkedin": {
      "command": "uvx",
      "args": ["mcp-server-linkedin"],
      "env": {
        "LINKEDIN_CLIENT_ID": "your_client_id",
        "LINKEDIN_CLIENT_SECRET": "your_secret_here"
      }
    }
  }
}

Claude Code

claude mcp add linkedin -- uvx mcp-server-linkedin

Then set LINKEDIN_CLIENT_ID and LINKEDIN_CLIENT_SECRET in your environment.

Windsurf

Add to your Windsurf MCP configuration:

{
  "mcpServers": {
    "linkedin": {
      "command": "uvx",
      "args": ["mcp-server-linkedin"],
      "env": {
        "LINKEDIN_CLIENT_ID": "your_client_id",
        "LINKEDIN_CLIENT_SECRET": "your_secret_here"
      }
    }
  }
}

Running from Source

Replace "command": "uvx", "args": ["mcp-server-linkedin"] with:

{
  "command": "uv",
  "args": ["--directory", "/path/to/mcp-server-linkedin", "run", "mcp-server-linkedin"]
}

Authentication

  1. Start your MCP client (Claude Desktop, Kiro, etc.)

  2. Ask: "Authenticate with LinkedIn"

  3. Browser opens → authorize the app → callback captured automatically

  4. Token saved to ~/.mcp-server-linkedin/token.json

  5. Token lasts 2 months. Re-run linkedin_auth when it expires.


Tools

Tool

Description

linkedin_auth

OAuth 2.0 browser-based authentication

linkedin_get_profile

Get your name, email, and person URN

linkedin_logout

Remove stored token

linkedin_post_text

Publish a text-only post

linkedin_post_image

Publish a post with an image

linkedin_post_video

Publish a post with a video (up to 200 MB)

linkedin_post_article

Publish a post with a link preview

linkedin_delete_post

Delete a post by ID

linkedin_get_post_stats

Get post analytics (requires Community Management API)

linkedin_get_all_stats

Get aggregated analytics (requires Community Management API)

Tool Details

Parameter

Type

Default

Description

text

string

required

Post content (up to ~3000 chars)

visibility

string

"PUBLIC"

"PUBLIC" or "CONNECTIONS"

Parameter

Type

Default

Description

text

string

required

Post caption

image_path

string

required

Absolute path to image (JPEG, PNG, GIF)

visibility

string

"PUBLIC"

"PUBLIC" or "CONNECTIONS"

Parameter

Type

Default

Description

text

string

required

Post caption

video_path

string

required

Absolute path to video (MP4, max 200 MB)

visibility

string

"PUBLIC"

"PUBLIC" or "CONNECTIONS"

Parameter

Type

Default

Description

text

string

required

Post commentary

url

string

required

Article URL (generates link preview)

title

string

""

Optional link preview title

description

string

""

Optional link preview description

visibility

string

"PUBLIC"

"PUBLIC" or "CONNECTIONS"

Parameter

Type

Default

Description

post_id

string

required

Post URN (e.g., urn:li:ugcPost:123456)


Architecture

src/mcp_server_linkedin/
├── config.py            # Constants, API URLs, settings dataclass
├── exceptions.py        # Typed exception hierarchy
├── server.py            # FastMCP entrypoint + tool registration
├── models/              # Frozen dataclass API response models
├── services/            # Async API client with connection pooling
├── tools/               # MCP tool implementations (validate → delegate → format)
│   ├── auth.py          # OAuth flow, profile, logout
│   ├── posting.py       # Text, image, video, article, delete
│   └── analytics.py     # Stubbed (pending API access)
└── utils/               # Token persistence

Rate Limits

Limit

Value

API requests per member per day

150

Token duration

2 months

Max video file size

200 MB

The server relays LinkedIn's rate limit errors clearly but does not enforce limits internally.


Security

  • Tokens stored locally at ~/.mcp-server-linkedin/token.json

  • No credentials in code — all secrets via environment variables

  • Official API only — uses w_member_social scope

  • Local OAuth callback — authorization code never leaves your machine

  • No data collection — this server sends nothing except LinkedIn API calls


Development

git clone https://github.com/Huzaifa-ali/mcp-server-linkedin.git
cd mcp-server-linkedin
uv sync --all-extras
pre-commit install
uv run mcp-server-linkedin                    # Run the server
uv run ruff check src/                        # Lint
uv run ruff format src/                       # Format
uv run mypy src/                              # Type check
uv run pytest                                 # Test

Test with MCP Inspector:

npx @modelcontextprotocol/inspector uv run mcp-server-linkedin

Contributing

See CONTRIBUTING.md for guidelines. In short:

  1. Fork the repo and create a feature branch

  2. Make your changes with type hints and docstrings

  3. Run pre-commit run --all-files (must pass)

  4. Open a pull request


License

MIT — see LICENSE.

Available Tools

10 tools
linkedin_authA

Authenticate with LinkedIn using OAuth 2.0. Opens a browser window for the user to log in and authorize. Must be called BEFORE any other LinkedIn tool if the user is not yet authenticated. Only needs to be run once — the token is saved and lasts 2 months.

Inputs: no named parameters. Returns: result

linkedin_delete_postA

Delete an existing LinkedIn post. Use when the user wants to remove a post they previously published. Requires: the post URN/ID (e.g., urn:li:ugcPost:123456 or urn:li:share:123456). This action is irreversible.

Inputs: post_id (required). Returns: result

linkedin_get_all_statsA

Get aggregated analytics across ALL LinkedIn posts (total impressions, clicks, likes, comments, shares). NOTE: Currently requires Community Management API access (r_member_postAnalytics scope) which must be applied for separately. Returns instructions on how to gain access if not available.

Inputs: metric, end_date, start_date, aggregation. Returns: result

linkedin_get_post_statsB

Get analytics (impressions, clicks, likes, comments, shares) for a specific LinkedIn post. NOTE: Currently requires Community Management API access (r_member_postAnalytics scope) which must be applied for separately at developer.linkedin.com. Returns instructions on how to gain access if not available.

Inputs: post_id (required), metric, end_date, start_date, +1 more. Returns: result

linkedin_get_profileA

Get the currently authenticated LinkedIn user's profile: name, email, person URN, and profile picture URL. Use this to confirm who is logged in or to retrieve the user's identity. Requires prior authentication.

Inputs: no named parameters. Returns: result

linkedin_logoutA

Log out of LinkedIn by deleting the stored OAuth token. Use when the user wants to switch accounts or revoke access. After logout, linkedin_auth must be called again before using any other tools.

Inputs: no named parameters. Returns: result

linkedin_post_articleA

Publish a LinkedIn post with a link/article preview card. Use when the user wants to share a URL with an auto-generated preview (title, description, thumbnail). Best for sharing blog posts, news articles, or web pages. Requires: text commentary AND a URL. Optional: custom title, description, visibility (PUBLIC or CONNECTIONS).

Inputs: url (required), text (required), title, visibility, +1 more. Returns: result

linkedin_post_imageA

Publish a LinkedIn post with an attached image. Use when the user wants to share a photo, infographic, screenshot, or any image file alongside text. Requires: text caption AND absolute file path to an image (JPEG, PNG, or GIF). Optional: visibility (PUBLIC or CONNECTIONS).

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

linkedin_post_textA

Publish a text-only post to LinkedIn. Use when the user wants to share a written update, thought, or announcement WITHOUT any image, video, or link preview. Requires: text content. Optional: visibility (PUBLIC or CONNECTIONS).

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

linkedin_post_videoA

Publish a LinkedIn post with an attached video. Use when the user wants to share a video file (MP4, max 200 MB) alongside text. Requires: text caption AND absolute file path to a video file. Optional: visibility (PUBLIC or CONNECTIONS).

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

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 10 tools

    Disambiguation5/5

    Each tool targets a distinct action: authentication, profile retrieval, logout, various post types (text, image, video, article), deletion, and post stats. No overlapping functionality.

    Naming Consistency5/5

    All tools follow a consistent 'linkedin_verb_noun' pattern in snake_case (e.g., linkedin_post_text, linkedin_get_profile). Minor exception: linkedin_auth omits a noun but is still clear.

    Tool Count5/5

    With 10 tools, the set covers authentication, profile, posting (four types), deletion, and two levels of stats. Each tool serves a clear purpose, and no tool seems redundant or out of place.

    Completeness3/5

    Covers core posting and basic profile/stats, but notable gaps exist: no ability to list or edit posts, no comment operations, and stats tools require special API access not guaranteed. For a content-focused toolset, updates and retrieval would be expected.

    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
      A
      quality
      C
      maintenance
      Enables AI agents to publish posts, images, comments, and reactions to LinkedIn as the authenticated user, with built-in safety features like daily budgets and deduplication.
      9
      18 npm
      1
      Apache 2.0