How to post to LinkedIn from Claude
Five lines of JSON, one API key, and Claude can draft, preflight and schedule LinkedIn posts without you opening a browser tab. Here is the exact setup — plus the four things that trip up the first attempt.
Claude cannot post to LinkedIn by itself. It has no network access to your account and no credentials for it — which is correct, and not something you want to change.
What it can do is call tools, and an MCP server can hold the LinkedIn connection on its behalf. Once one is connected, drafting and scheduling a LinkedIn post is a sentence in a conversation you were already having. Setup takes about five minutes, most of which is the OAuth click-through.
Before you start
- Claude Desktop installed (or a Claude.ai account, for the hosted route below).
- Node.js on your machine —
npxneeds it. Nothing gets installed permanently. - A PostMCP account with LinkedIn connected. The free plan covers 20 posts a month and needs no card.
Step 1 — connect LinkedIn and mint a key
- 1Authorise LinkedIn
In the dashboard, add LinkedIn as a channel. This runs LinkedIn’s own OAuth 2.0 sign-in — you approve the permissions on linkedin.com, and an encrypted access token comes back. No password is ever handled by anything but LinkedIn.
- 2Create an API key
From the same dashboard. Keys look like
pmcp_sec_…and are bound to the workspace they were issued from, so a bare key is enough unless you run several workspaces. - 3Keep it somewhere sensible
The key goes into a local config file in the next step. Treat it like any other publishing credential — anything holding it can post as you.
Step 2 — add the server to Claude Desktop
Open Claude Desktop’s config file. On macOS it is at ~/Library/Application Support/Claude/claude_desktop_config.json; on Windows, %APPDATA%\Claude\claude_desktop_config.json. If the file does not exist, create it.
{
"mcpServers": {
"postmcpai": {
"command": "npx",
"args": ["-y", "@postmcpai/server"],
"env": {
"POSTMCPAI_API_KEY": "pmcp_sec_your_key_here"
}
}
}
}Save, then quit Claude Desktop completely and reopen it — a window reload is not enough, because the server is spawned at startup. When it comes back, the tools icon in the composer should list sixteen publishing tools.
Step 3 — prove the connection with a read
Do not start by asking it to publish. Start with something that cannot touch your feed:
“What social accounts do I have connected?”
Claude calls get_connected_accounts, and you get back your LinkedIn profile with the profileId it will use to target you. That single call proves the whole chain — key valid, server running, backend reachable, LinkedIn connected — before anything is at stake.
Step 4 — draft, preflight, publish
Now the real thing. A prompt that works well in practice names the outcome and the constraints, and leaves the copy to Claude:
“Draft a LinkedIn post about the analytics dashboard we shipped today — first person, no hashtags, under 1,200 characters. Preflight it, show me the copy, and do not publish until I say so.”
Claude writes the copy, calls preflight_post to check limits and cost, and stops. You read it, ask for a rewrite of the second paragraph, and then say publish. That last instruction triggers create_post with publishImmediately, and Claude comes back with the live URL.
To schedule instead, say when — and say where:
“Schedule it for Tuesday at 9am IST.”
Claude.ai instead of Claude Desktop
Claude.ai runs in a browser and cannot spawn a local process, so the stdio route above does not apply. It needs a hosted server speaking streamable HTTP. The same npm package does this — setting a PORT switches transports:
export POSTMCPAI_API_KEY="pmcp_sec_your_key_here" export PORT=3000 npx -y @postmcpai/server
Deploy that anywhere that runs Node — Render, Railway, Fly.io — then add it in Claude.ai as a custom connector, pointing at https://your-host/mcp?apikey=pmcp_sec_…. Claude discovers the tools over the URL. Full detail is on the Claude integration page.
The four things that go wrong
- 1The timezone was left implicit
Scheduling defaults to UTC. “9am” for an IST-based account means 14:30 local. Name the zone every single time a wall-clock hour matters.
- 2The client was reloaded, not restarted
MCP servers are spawned at client startup. Quit fully and reopen after editing the config.
- 3The LinkedIn token expired
Posts stop appearing with no obvious error. Ask “does anything need reconnecting?” — that runs
get_account_healthand names the dead connections. - 4Everything was approved on autopilot
Approve reads permanently; keep the prompt on
create_postandpublish_post_now. The approval dialog shows the exact copy about to go out, which is the last cheap place to catch a bad draft.
Beyond LinkedIn
Nothing above is LinkedIn-specific — the same server covers X, Facebook, Instagram, Threads, Bluesky and YouTube Shorts. Once it is connected, “post this to LinkedIn and X, but rewrite the X version to fit 280 characters” is one instruction, and Claude handles the per-network variants itself.
If you would rather work from a calendar than a chat window, the LinkedIn post scheduler is the same queue with a UI on top — the two views stay in sync, because they are the same posts.
Frequently asked questions
- Can Claude post to LinkedIn directly?
- Not on its own — Claude has no built-in LinkedIn access. It can post through an MCP server that holds the LinkedIn connection. You add the server to Claude Desktop with a small JSON block, or connect a hosted one to Claude.ai as a remote connector, and LinkedIn publishing tools appear in Claude’s tool list.
- Do I have to give Claude my LinkedIn password?
- No, and you should never do that. LinkedIn is authorised through its own OAuth 2.0 sign-in on the publishing service, which stores an encrypted access token. Claude never sees the token or the password — it only sees tool names, the arguments it chose, and the results.
- Does this work with Claude.ai in the browser, or only Claude Desktop?
- Both. Claude Desktop uses the local stdio transport — a command entry in its config file. Claude.ai needs a hosted server speaking streamable HTTP, which you add as a remote connector by URL. The same package does both; setting a PORT switches modes.
- Will Claude post without asking me?
- Claude asks for approval before running a mutating tool the first time, showing you the exact arguments. Read-only tools are safe to approve permanently; keep the approval prompt on create_post and publish_post_now if you want a human check before anything reaches your feed.
- Can it schedule posts for a specific time zone?
- Yes, but you have to say so. Always include the timezone in your instruction — “Tuesday 9am IST”, not just “Tuesday 9am”. The backend defaults to UTC, so an unqualified 9:00 for an India-based account publishes at 14:30 local.