An MCP server that posts to LinkedIn gives your AI assistant one tool call — create_post — instead of an OAuth app, a Community Management API application, a 60-day token refresh loop and a two-step image upload. Here is the config, the tool list, and an honest account of what the direct LinkedIn route costs you if you skip it.
Add this to Claude Desktop and restart it:
1{
2 "mcpServers": {
3 "outstand": {
4 "command": "npx",
5 "args": ["mcp-remote", "https://mcp.outstand.so/mcp",
6 "--header", "Authorization: Bearer ost_your_key"]
7 }
8 }
9}That is the whole install. The rest of this page is what you get, and why LinkedIn in particular is the platform you least want to integrate by hand.
Prerequisites
Two things, both of which take about a minute.
- An Outstand API key. Keys are prefixed
ost_. The MCP endpoint also supports one-click OAuth if you would rather not paste a key into a config file — point your client at the connector URL and authorise in the browser. - A connected LinkedIn account. Connect it once through Outstand's OAuth flow. The assistant never sees LinkedIn credentials; it sees an account identifier.
There is no separate LinkedIn developer app, no app review, and no scope request. That work has already happened on the other side of the MCP server.
The config, for each client
The endpoint is https://mcp.outstand.so/mcp in every case. What changes is how each client wants it declared.
Claude Code
Claude Code takes it as a single command — no file editing:
1claude mcp add --transport http outstand https://mcp.outstand.so/mcp \
2 --header "Authorization: Bearer ost_your_key"If you would rather commit it to the repo so your whole team picks it up, put this in .mcp.json at the project root:
1{
2 "mcpServers": {
3 "outstand": {
4 "type": "http",
5 "url": "https://mcp.outstand.so/mcp",
6 "headers": {
7 "Authorization": "Bearer ost_your_key"
8 }
9 }
10 }
11}Claude Desktop
Claude Desktop connects to remote servers through the mcp-remote bridge, so the config is a command/args pair rather than a URL:
1{
2 "mcpServers": {
3 "outstand": {
4 "command": "npx",
5 "args": ["mcp-remote", "https://mcp.outstand.so/mcp",
6 "--header", "Authorization: Bearer ost_your_key"]
7 }
8 }
9}Cursor
Cursor (and Windsurf) use the same shape as Claude Desktop:
1{
2 "mcpServers": {
3 "outstand": {
4 "command": "npx",
5 "args": ["mcp-remote", "https://mcp.outstand.so/mcp",
6 "--header", "Authorization: Bearer ost_your_key"]
7 }
8 }
9}Restart the client after editing the file. If the server connected, the assistant will list create_post and list_social_accounts among its tools.
The tools you get
The server exposes 28 tools across 12 platforms — X, LinkedIn, Instagram, Facebook, Threads, TikTok, YouTube, Bluesky, Pinterest, Google Business, Vimeo and Reddit. The ones that matter for LinkedIn:
Tool | What it does |
|---|---|
| Lists connected accounts. Call it first — posts target accounts by encoded ID or exact username, and only connected accounts can be published to |
| Publishes or schedules a post to one or more accounts |
| Edits a scheduled post before it goes out |
| Reads posts you have created through the API |
| Per-account engagement for a published post |
| Comment threads on a published post |
| Two-step upload: |
| Current post count against your plan |
create_post takes one required argument, accounts — an array of encoded account IDs or exact usernames. Everything else is optional:
content— the post text for a single-container post.containers— for threads and carousels. Each container after the first is published as a reply.scheduledAt— an ISO 8601 datetime. It must be within 30 days. A later value is rejected outright and no post is created, rather than being silently clamped.- Per-platform override objects for Instagram, TikTok, Threads, YouTube, Google Business, Pinterest, Vimeo, Reddit and Facebook.
Worth noticing what is *not* in that last list: there is no LinkedIn override object. LinkedIn takes text, media and a schedule, and that is the whole surface. Reddit, by contrast, requires a subreddit and a title before it will accept anything. The platforms differ enormously in how much configuration they demand, and LinkedIn is on the simple end — once you are past its approval gate.
A worked example
"Post this to LinkedIn on Thursday at 9am." What the assistant actually does:
11. list_social_accounts { "network": "linkedin" }
2 -> [{ "id": "acc_9Xk2...", "username": "outstand-so", "network": "linkedin" }]
3
42. create_post {
5 "accounts": ["acc_9Xk2..."],
6 "content": "We shipped scheduled posting through the MCP server today...",
7 "scheduledAt": "2026-09-17T09:00:00Z"
8 }
9 -> { "id": "pst_4Qm7...", "status": "scheduled" }Two calls. The first is not optional — account IDs are opaque encoded strings, so the assistant has to look one up rather than construct it. Later, on the same post:
13. get_post_analytics { "post_id": "pst_4Qm7..." }
2 -> per-account likes, comments, shares, views, impressions,
3 reach and engagement rate, plus aggregated totalsOne caveat that will save you a bug report: engagement fields the platform does not expose come back as 0, and the names of those fields are listed in platform_specific.unavailable_fields. Check that array before you report a zero as a real count.
Why LinkedIn specifically is hard to integrate directly
Every platform has friction. LinkedIn's is unusual in that most of it happens *before* you write any code.
Posting to a Company Page requires approval. Personal-profile posting is self-serve through the Share on LinkedIn product and the w_member_social scope. Posting as an organisation needs the Community Management API, and LinkedIn's own documentation is blunt about who qualifies:
At this time, our Community Management APIs are only available to registered legal organizations for commercial use cases only.
That is an application, a review, and a real chance of rejection — before your first successful request. Budget calendar time for it, not engineering time.
Tokens expire on a 60-day clock. LinkedIn's 3-legged OAuth access tokens are short-lived by the standards of a scheduler that is supposed to run unattended. You need programmatic refresh, and you need to handle the case where refresh fails and a human has to re-authorise. This is the single most common way a hand-rolled LinkedIn integration dies quietly.
Images are a separate API. The Posts API does not accept image bytes. You call the Images API to initialise an upload, PUT the bytes to the returned URL, wait for the asset to become available, then reference its URN in the post. Three round trips for one image, each with its own failure mode.
The API is versioned monthly. Requests carry a LinkedIn-Version header, and versions age out. An integration you ship and forget will break on a schedule.
None of this is a reason not to build directly — if LinkedIn is the only platform you need and you are posting at volume, owning the integration is defensible. It is a reason to know the bill before you commit to it. We costed that out in detail in LinkedIn API pricing: the fee is $0, and the price is approval, refresh loops and version churn.
Extending past LinkedIn
The reason to route LinkedIn through MCP rather than build it is usually that LinkedIn is not the only platform. The same create_post call takes an array of accounts, so adding X, Bluesky and Threads to a LinkedIn post is a longer accounts array — not three more OAuth apps, three more token lifecycles and three more upload flows. The per-platform quirks that remain are expressed as optional config objects on the one call.
If you want the same setup for other assistants or platforms, the MCP server page has the connector details, and these MCP servers covers the wider landscape.
*Last verified: September 2026, against LinkedIn's developer documentation on Microsoft Learn, Anthropic's Claude Code MCP documentation, and Outstand's live tool schemas.*