MCP LINKEDIN B2 TECH

Model Context Protocol · LinkedIn Posts API — personal profile

Publish to LinkedIn
straight from Claude.

An MCP server that wires Claude into your personal LinkedIn profile — compose text, single-image or carousel posts of up to 20 images, see the exact preview before publishing, and send it with confirm=true. Idempotency and a daily ceiling prevent duplicates. Native LinkedIn login, no password stored here. Status: LIVE.

15 tools · personal profile · confirm gate · multi-tenant

LinkedIn Posts API — personal profile Nothing publishes without confirm=true Idempotency against duplicates Daily ceiling + 429 circuit breaker OAuth 2.1 + PKCE AES-256-GCM encrypted tokens Multi-tenant on Vercel LinkedIn Posts API — personal profile Nothing publishes without confirm=true Idempotency against duplicates Daily ceiling + 429 circuit breaker OAuth 2.1 + PKCE AES-256-GCM encrypted tokens Multi-tenant on Vercel
What it is

Your profile, operated in natural language

MCP LINKEDIN B2 TECH is a Model Context Protocol server that gives Claude real access to your personal LinkedIn profile — not a chatbot that pretends it posted, but typed calls into the LinkedIn Posts API.

Real connection

Claude talks to your personal profile

Composes hashtags, mentions and captions; publishes text, a single image, or a carousel of 2 to 20 images straight to the LinkedIn Posts API, with PUBLIC or CONNECTIONS visibility. Always as urn:li:person — the personal profile of the member who authorized, never a Company Page.

Preview before publishing

You see the exact text before LinkedIn does

preview_post_text composes and escapes LinkedIn's little text format without spending an API call. Every create_* is born with confirm=false — publishing and deleting always require an explicit confirm=true.

Status

LIVE in production

Multi-tenant deploy at mcp-linkedin-pi.vercel.app — an embedded OAuth 2.1 Authorization Server bridging to LinkedIn's native consent screen, tokens encrypted in Supabase, ephemeral state on Upstash.

What it already does

The complete tool catalog

15 tools grouped by function — from connection to publishing, from images to history. Everything below is implemented and live.

Connection & profile

4 tools
  • linkedin_token_statusValidates the stored credential against LinkedIn and reports days remaining on the 60-day token.
  • get_connected_profileThe member behind the credential, including the author_urn every post is published as.
  • linkedin_loginIn hosted mode, only reports connection state — the login happens inside the connector's own OAuth handshake.
  • linkedin_submit_callbackA no-op in hosted mode; exists for the local (stdio) development mode.

Publishing

6 · confirm=true
  • preview_post_textComposes and validates without publishing — zero calls to LinkedIn.
  • create_text_postPublishes a text post. confirm=false (default) behaves exactly like a preview.
  • create_image_postPublishes one image with a caption.
  • create_multi_image_postPublishes 2–20 images as one carousel post.
  • update_post_commentaryReplaces a published post's text in place (media and post type cannot change).
  • delete_postPermanently deletes a post. Confirm-gated, irreversible.

Media

2 tools
  • upload_image_from_urlPrimary path: the server fetches a public https:// URL and registers the image with LinkedIn in one step.
  • upload_imageSame, from inline base64 — for small or generated images only.

History & limits

3 tools
  • get_postReads back one post by URN. May return 403 on LinkedIn's self-serve tier — a LinkedIn-side ACL, not a failure here.
  • list_my_postsThe server's own publishing history — URN, status and a commentary excerpt. The reliable read path.
  • linkedin_usageToday's count against the daily ceiling, plus whether the 429 circuit breaker is open.

From draft to post: preview_post_textcreate_text_post with confirm=truelist_my_posts to check the history — with client_request_id guaranteeing a retry never duplicates.

Publishing safety model

Claude doesn't publish in your name on its own

A post is permanent and public — so every write goes through explicit barriers before it ever leaves the draft.

Nothing publishes without confirm=true

create_text_post, create_image_post, create_multi_image_post and delete_post are born with confirm=false — without it, it's always a preview, never a publish.

Personal profile only

Every post ships as urn:li:person. Publishing to a Company Page would need the w_organization_social scope and is out of scope — impossible to happen by accident.

Idempotency with client_request_id

A row is written before LinkedIn is ever called; retrying the same key replays the stored URN instead of duplicating the post, or returns needs_verification when the outcome is genuinely unknown.

Daily ceiling + 429 circuit breaker

A per-member counter (default 50/day) refuses over-limit publishes before LinkedIn ever sees them; a 429 opens a breaker for ~24h — we never retry automatically in that case.

Tenant is never an argument

In hosted mode, the tenant comes only from the MCP credential, derived from your OpenID Connect login. LinkedIn tokens AES-256-GCM encrypted; refresh tokens stored only as hashes.

Media boundary against SSRF

URL uploads require https, reject redirects and internal/reserved addresses, pin the validated IP and verify the image's magic bytes instead of trusting Content-Type.

How to connect

Up and running in minutes

Hosted, multi-tenant server, zero setup: add the connector, authorize with your LinkedIn account and Claude is already composing and publishing for you — always previewed first.

Zero setup

Hosted — mcp-linkedin-pi.vercel.app

Add the connector in Claude and authorize with your LinkedIn account. Nothing to install; the login runs entirely on LinkedIn's own consent screen.

  1. Add the connector. In claude.ai → Customize → Connectors → + → Add custom connector, paste the URL below. On Team/Enterprise accounts, an Owner adds it under Organization settings → Connectors.
    # Connector URL
    https://mcp-linkedin-pi.vercel.app/api/mcp
  2. Authorize on LinkedIn's screen. Click Connect — you're redirected to LinkedIn's own consent screen (OAuth 2.1 with PKCE). Sign in with the account you want to publish from and approve.
  3. Confirm. Ask Claude to run linkedin_token_status and get_connected_profile — they show the connected member and how many days remain on the token.
First steps

What to ask Claude

Real requests the server resolves end to end — nothing publishes without confirm=true.

  1. Preview.
    # you, in the chat:
    "Draft a LinkedIn post announcing I
     shipped MCP LinkedIn, with the
     hashtag #buildinpublic"
    # → preview_post_text, zero calls to LinkedIn
  2. Publish it.
    "Publish it"
    # → create_text_post with confirm=true
  3. Check it.
    "List my most recent posts published
     through this MCP"
    # → list_my_posts (own source of truth)

Frequently asked questions

Still have a question? Write to bruno@b2tech.io.

How much does it cost?
MCP LinkedIn is an exclusive benefit for Claude Code Architect students — access to the hosted connector is unlocked for students only. Not a student yet? Check out the training at claude-code.b2tech.io.
Is it safe? Can Claude publish without me reviewing it?
No. Every create_text_post, create_image_post and create_multi_image_post is born with confirm=false by default — without confirm=true, the call behaves like a preview and nothing gets published. preview_post_text shows the exact text before any call to LinkedIn, and delete_post also requires an explicit confirm=true.
Does it publish to my Company Page or my personal profile?
Your personal profile only. Every post is authored as urn:li:person — the member who authorized the login. Publishing to a Company Page would need a different scope (w_organization_social) and a different approval path; that's out of scope for this server.
Do I need to install anything?
No. The hosted, multi-tenant connector lives at mcp-linkedin-pi.vercel.app — just add it in claude.ai and log in with your LinkedIn account; authentication runs entirely through LinkedIn's own native OAuth 2.1 flow, with PKCE.
Does the login expire?
Yes, but it rarely needs your attention. LinkedIn issues a 60-day token with no programmatic refresh — roughly every two months you reconnect the connector. With your session active and the same scopes, LinkedIn normally skips the consent screen, so reconnection is effectively one click. linkedin_token_status shows how many days remain.
Where do my tokens live?
The LinkedIn token is AES-256-GCM encrypted in a Supabase project. The tenant comes from your OpenID Connect identifier and is never an argument to any tool. Every MCP client call uses a short-lived (8h) ES256 JWT signed by the server — a separate credential from the LinkedIn 60-day token.
Is there a limit on how many posts I can publish per day?
Yes — a per-member daily ceiling (default 50 posts) refuses over-limit publishes before LinkedIn ever sees them. If LinkedIn returns a 429, a circuit breaker opens for about 24h — in that case we never retry automatically, because LinkedIn's cooldown is a flat window, not a gradual throttle.
How do I avoid duplicate posts if my automation fails and retries?
Pass client_request_id (for example, daily-2026-08-22) on any create. A row is written before LinkedIn is ever called, so retrying the same key replays the already-published post instead of duplicating it — or reports needs_verification when an earlier attempt's outcome is genuinely unknown, rather than blindly retrying.
Get started

Stop copy-pasting into LinkedIn.
Ask Claude to draft, review and publish.

Text, single image or carousel — always previewed first, confirm=true to publish or delete, idempotency against duplicates, and a daily ceiling that protects you from any runaway automation.

15 tools · native LinkedIn login · multi-tenant on Vercel