Command Palette

Search for a command to run...

UnylyUnyly
Browse all

timkulbaev/mcp-linkedin

FreeNot checked

LinkedIn publishing, commenting, and reacting via Unipile API. Dry-run by default, SKILL.md included, CLI-first design for AI automation workflows.

GitHubEmbed

About

LinkedIn publishing, commenting, and reacting via Unipile API. Dry-run by default, SKILL.md included, CLI-first design for AI automation workflows.

README

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

mcp-linkedin MCP server

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 accountUnipile 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.

from github.com/timkulbaev/mcp-linkedin

Installing timkulbaev/mcp-linkedin

This server has no published package — it is built from source. Open the repository and follow its README.

▸ github.com/timkulbaev/mcp-linkedin

FAQ

Is timkulbaev/mcp-linkedin MCP free?

Yes, timkulbaev/mcp-linkedin MCP is free — one-click install via Unyly at no cost.

Does timkulbaev/mcp-linkedin need an API key?

No, timkulbaev/mcp-linkedin runs without API keys or environment variables.

Is timkulbaev/mcp-linkedin hosted or self-hosted?

Self-hosted: the server runs locally on your machine via the install command above.

How do I install timkulbaev/mcp-linkedin in Claude Desktop, Claude Code or Cursor?

Open timkulbaev/mcp-linkedin on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

LibreOffice Tools

Enables AI agents to read, write, and edit Office documents via LibreOffice with token-efficient design. Supports multiple formats including DOCX, XLSX, PPTX, a

passerbyflutterby passerbyflutter

dannote/figma-use

Full Figma control: create shapes, text, components, set styles, auto-layout, variables, export. 80+ tools.

dannoteby dannote

Logo.dev

Search and retrieve company logos by brand or domain. Customize size, format, and theme to match your design needs. Accelerate design, prototyping, and content

NOVA-3951by NOVA-3951

Design Inspiration Server

Searches top design platforms like Dribbble and Behance to provide UI inspiration, color palettes, and layout patterns via the Serper API. It allows users to re

YonasValentinby YonasValentin

PIX4Dmatic

Enables GUI automation for controlling PIX4Dmatic on Windows through MCP. Supports launching, focusing, capturing screenshots, sending hotkeys, clicking UI elem

jangjo123by jangjo123

Figma

Extract design specs and assets

Figmaby Figma

mcp-dockmaster

An Open-Sourced UI to install and manage MCP servers for Windows, Linux and macOS.

by Community

ariekogan/ateam-mcp

Build, validate, and deploy multi-agent AI solutions on the ADAS platform. Design skills with tools, manage solution lifecycle, and connect from any AI environm

ariekoganby ariekogan

thinkchainai/mcpbundles

MCP Bundles: Create custom bundles of tools and connect providers with OAuth or API keys. Use one MCP server across thousands of integrations, with programmatic

thinkchainaiby thinkchainai

arikusi/nakkas

MCP server that turns AI into an SVG artist. One rendering engine with JSON config, AI controls all design parameters. CSS @keyframes + SMIL animations, 16+ ele

arikusiby arikusi

Compare timkulbaev/mcp-linkedin with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All design MCPs