Featured

Deploy OpenClaw in 60 seconds β€” 20% off logoDeploy OpenClaw in 60 seconds β€” 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger β†’
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger β†’
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free β†’
6,000+ web scrapers for your AI agent, start free logo6,000+ web scrapers for your AI agent, start free

Apify gives your agent live web data: 6,000+ prebuilt scrapers and actors, MCP-ready. Sign up free with $5 in usage credits.

Try Apify free β†’
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data β€” no proxies, no parsers, no maintenance.

Start building free β†’
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it β€” secured from day one.

Get it set up for you β†’
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free β†’
Reach 48,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here β†’

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

mcp-linkedin MCP server](https://glama.ai/mcp/servers/timkulbaev/mcp-linkedin/badges/score.svg)](https://glama.ai/mcp/servers/timkulbaev/mcp-linkedin) πŸ“‡ ☁️ - LinkedIn publishing, commenting, and reacting via Unipile API.

README.md

mcp-linkedin

An MCP server that lets AI assistants publish to LinkedIn on your behalf.

![mcp-linkedin MCP server](https://glama.ai/mcp/servers/timkulbaev/mcp-linkedin)

What it does

This is a Model Context Protocol (MCP) server that wraps the Unipile API to give AI assistants (Claude Code, Claude Desktop, or any MCP-compatible client) the ability to create posts, comments, and reactions on LinkedIn. The AI writes the content; this tool handles the publishing. All publishing actions default to preview mode β€” nothing goes live without explicit confirmation.

Features

  • 3 tools: publish, comment, react
  • Dry run by default (preview before publishing)
  • Auto-likes posts immediately after publishing
  • Media attachments (local files or URLs β€” images and video)
  • Company @mentions (auto-resolved via Unipile)
  • Works with Claude Code, Claude Desktop, and any MCP client

Prerequisites

  • Node.js 18+ β€” uses ES modules, node:test, and top-level await
  • Unipile account β€” Unipile is the service that connects to LinkedIn's API. Sign up, connect your LinkedIn account, and get your API key and DSN from the dashboard.

Installation

git clone https://github.com/timkulbaev/mcp-linkedin.git
cd mcp-linkedin
npm install

Configuration

Claude Code

Add to ~/.claude/mcp.json:

{
  "mcpServers": {
    "linkedin": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-linkedin/index.js"],
      "env": {
        "UNIPILE_API_KEY": "your-unipile-api-key",
        "UNIPILE_DSN": "apiXX.unipile.com:XXXXX"
      }
    }
  }
}

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "linkedin": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-linkedin/index.js"],
      "env": {
        "UNIPILE_API_KEY": "your-unipile-api-key",
        "UNIPILE_DSN": "apiXX.unipile.com:XXXXX"
      }
    }
  }
}

Restart Claude Code or Claude Desktop after editing the config.

Environment variables

| Variable | Required | Description | |----------|----------|-------------| | UNIPILE_API_KEY | Yes | Your Unipile API key (from the Unipile dashboard) | | UNIPILE_DSN | Yes | Your Unipile DSN (e.g. api16.unipile.com:14648) |

These are passed via the MCP config, not a .env file. The server reads them from process.env at startup.

Tools

linkedin_publish

Creates an original LinkedIn post.

dry_run defaults to true. Call with dry_run: true first to get a preview, then call again with dry_run: false to actually publish.

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | text | string | yes | β€” | Post body, max 3000 characters | | media | string[] | no | [] | Local file paths or URLs (jpg, png, gif, webp, mp4) | | mentions | string[] | no | [] | Company names to @mention (auto-resolved) | | dry_run | boolean | no | true | Preview without publishing |

Preview response (dry_run: true):

{
  "status": "preview",
  "post_text": "Hello LinkedIn!",
  "character_count": 16,
  "character_limit": 3000,
  "media": [],
  "mentions": [],
  "warnings": [],
  "ready_to_publish": true
}

Publish response (dry_run: false):

{
  "status": "published",
  "post_id": "7437514186450104320",
  "post_text": "Hello LinkedIn!",
  "posted_at": "2026-03-11T15:06:04.849Z",
  "auto_like": "liked"
}

After publish, save the post_id and construct the post URL: `` https://www.linkedin.com/feed/update/urn:li:activity:{post_id}/ ``

---

linkedin_comment

Posts a comment on an existing LinkedIn post.

dry_run defaults to true.

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | post_url | string | yes | β€” | LinkedIn post URL or raw URN (urn:li:activity:... or urn:li:ugcPost:...) | | text | string | yes | β€” | Comment text | | dry_run | boolean | no | true | Preview without posting |

---

linkedin_react

Reacts to a LinkedIn post. This action is immediate β€” there is no dry_run.

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | post_url | string | yes | β€” | LinkedIn post URL or raw URN | | reaction_type | string | no | "like" | One of: like, celebrate, support, love, insightful, funny |

---

How it works

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚           mcp-linkedin            β”‚
AI Assistant  ──►   β”‚                                  β”‚
(via MCP stdio)     β”‚  Posts/Comments/Reactions  ──►  Unipile API  ──►  LinkedIn
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • The AI assistant calls tools via MCP's JSON-RPC protocol over stdio
  • Calls Unipile API which handles LinkedIn OAuth β€” no token management needed

Safe publishing workflow

The dry_run default exists to prevent accidental publishing. The intended flow:

  1. AI calls the tool with dry_run: true (the default)
  2. You see the preview: final text, character count, media validation, resolved mentions, warnings
  3. You confirm or ask for changes
  4. AI calls again with dry_run: false
  5. Post goes live

dry_run is true by default. The AI cannot publish without explicitly setting it to false, which requires going through the preview step first.

Media handling

  • Pass local file paths (/path/to/image.jpg) or URLs (https://example.com/img.png)
  • URLs are downloaded to /tmp/mcp-linkedin-media/ and cleaned up after publish (whether it succeeds or fails)
  • Supported formats: jpg, jpeg, png, gif, webp (images), mp4 (video)
  • Each file is validated before upload: must exist, be non-empty, and be a supported type
  • Failed files appear in the preview's media array with "valid": false and an error message

Company @mentions

  • Pass company names as strings: mentions: ["Microsoft", "OpenAI"]
  • The server slugifies each name and looks it up via Unipile's LinkedIn company search
  • Resolved companies are injected as {{0}}, {{1}} placeholders in the post text β€” LinkedIn renders these as clickable @mentions
  • If a company name appears in the post text, it gets replaced in place; if not, the placeholder is appended
  • Unresolved names appear as warnings in the preview. The post can still be published without them.

Testing

npm test       # 28 unit tests, zero extra dependencies (Node.js built-in test runner)
npm run lint   # Biome linter

Project structure

mcp-linkedin/
  index.js                    Entry point (stdio transport)
  package.json
  src/
    server.js                 MCP server and tool registration
    unipile-client.js         Unipile API wrapper (posts, comments, reactions)
    media-handler.js          URL download and file validation
    tools/
      publish.js              linkedin_publish handler
      comment.js              linkedin_comment handler
      react.js                linkedin_react handler
  tests/
    unit.test.js              28 unit tests

Getting a Unipile account

  1. Sign up for a Unipile account
  2. In the dashboard, connect your LinkedIn account
  3. Copy your API key and DSN from the dashboard settings
  4. Paste them into the MCP config (see Configuration above)

Unipile has a free tier that covers basic usage.

License

MIT β€” see LICENSE.

Credits

Built by Timur Kulbaev. Uses the Model Context Protocol by Anthropic and the Unipile API.

See related servers & alternatives β†’

Related MCP servers

Browse all β†’

Related guides

Hand-picked reading to help you choose and use AI & ML servers.