Model Context Protocol · LinkedIn Posts API — personal profile
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.
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.
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_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.
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.
15 tools grouped by function — from connection to publishing, from images to history. Everything below is implemented and live.
author_urn every post is published as.confirm=false (default) behaves exactly like a preview.https:// URL and registers the image with LinkedIn in one step.From draft to post: preview_post_text → create_text_post with confirm=true → list_my_posts to check the history — with client_request_id guaranteeing a retry never duplicates.
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.
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.
Add the connector in Claude and authorize with your LinkedIn account. Nothing to install; the login runs entirely on LinkedIn's own consent screen.
# Connector URL https://mcp-linkedin-pi.vercel.app/api/mcp
linkedin_token_status and get_connected_profile — they show the connected member and how many days remain on the token.Real requests the server resolves end to end — nothing publishes without confirm=true.
# you, in the chat: "Draft a LinkedIn post announcing I shipped MCP LinkedIn, with the hashtag #buildinpublic" # → preview_post_text, zero calls to LinkedIn
"Publish it"
# → create_text_post with confirm=true"List my most recent posts published
through this MCP"
# → list_my_posts (own source of truth)Still have a question? Write to bruno@b2tech.io.
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.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.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.linkedin_token_status shows how many days remain.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.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