An MCP server that lets AI assistants publish to LinkedIn on your behalf.
mcp-linkedin
An MCP server that lets AI assistants publish to LinkedIn on your behalf.
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
└────────────────────────
Tools (3)
linkedin_publishCreates an original LinkedIn post with optional media and mentions.linkedin_commentPosts a comment on an existing LinkedIn post.linkedin_reactReacts to a LinkedIn post with a specific reaction type.Environment Variables
UNIPILE_API_KEYrequiredYour Unipile API key from the Unipile dashboardUNIPILE_DSNrequiredYour Unipile DSN (e.g. api16.unipile.com:14648)Configuration
{"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"}}}}