MCP server for LinkedIn — post text, images, videos, and articles via the official LinkedIn API
Server has 10 tools with complete descriptions and clear naming following verb_noun patterns (linkedin_auth, linkedin_post_text, etc.). Descriptions are LLM-optimized (50-200 chars range, averaging ~140 chars), explaining WHAT, WHEN, and prerequisites. Input schemas are present with type definitions and parameter descriptions. However, output schemas are not documented, LLMs cannot see what fields are returned. Error handling is minimal; no recovery guidance or actionable error messages visible in code. No tool annotations (readOnlyHint, destructiveHint) despite clear risk levels (WRITE, DESTRUCTIVE, READ_ONLY). Parameter validation rules not documented in descriptions (e.g., 'visibility' accepts PUBLIC or CONNECTIONS but no enum constraint visible). Missing idempotency guarantees for retry-safe operations.
Authenticate with LinkedIn using OAuth 2.0. Opens a browser window for the user to log in and authorize. Must be called BEFORE any other LinkedIn tool if the user is not yet authenticated. Only needs to be run once — the token is saved and lasts 2 months.
Delete an existing LinkedIn post. Use when the user wants to remove a post they previously published. Requires: the post URN/ID (e.g., urn:li:ugcPost:123456 or urn:li:share:123456). This action is irreversible.
Get aggregated analytics across ALL LinkedIn posts (total impressions, clicks, likes, comments, shares). NOTE: Currently requires Community Management API access (r_member_postAnalytics scope) which must be applied for separately. Returns instructions on how to gain access if not available.
Get analytics (impressions, clicks, likes, comments, shares) for a specific LinkedIn post. NOTE: Currently requires Community Management API access (r_member_postAnalytics scope) which must be applied for separately at developer.linkedin.com. Returns instructions on how to gain access if not available.
Get the currently authenticated LinkedIn user's profile: name, email, person URN, and profile picture URL. Use this to confirm who is logged in or to retrieve the user's identity. Requires prior authentication.
Output schemas not documented. LLMs cannot see what fields are returned by any tool (e.g., linkedin_get_profile returns name, email, person URN, profile picture URL but this is only in description text, not in a structured schema). This forces LLMs to guess field names for downstream operations.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk levels declared (READ_ONLY, WRITE, DESTRUCTIVE). linkedin_delete_post is marked DESTRUCTIVE but has no annotation to signal this to the LLM. linkedin_post_* tools are WRITE but lack idempotentHint guidance.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 56 | <=2025-11-25 | v2 |
Log out of LinkedIn by deleting the stored OAuth token. Use when the user wants to switch accounts or revoke access. After logout, linkedin_auth must be called again before using any other tools.
Publish a LinkedIn post with a link/article preview card. Use when the user wants to share a URL with an auto-generated preview (title, description, thumbnail). Best for sharing blog posts, news articles, or web pages. Requires: text commentary AND a URL. Optional: custom title, description, visibility (PUBLIC or CONNECTIONS).
Publish a LinkedIn post with an attached image. Use when the user wants to share a photo, infographic, screenshot, or any image file alongside text. Requires: text caption AND absolute file path to an image (JPEG, PNG, or GIF). Optional: visibility (PUBLIC or CONNECTIONS).
Publish a text-only post to LinkedIn. Use when the user wants to share a written update, thought, or announcement WITHOUT any image, video, or link preview. Requires: text content. Optional: visibility (PUBLIC or CONNECTIONS).
Publish a LinkedIn post with an attached video. Use when the user wants to share a video file (MP4, max 200 MB) alongside text. Requires: text caption AND absolute file path to a video file. Optional: visibility (PUBLIC or CONNECTIONS).
Parameter constraints not formalized as enums. 'visibility' parameter accepts PUBLIC or CONNECTIONS (documented in description text) but no enum constraint in schema. 'metric' and 'aggregation' in analytics tools similarly lack enum definitions, inviting hallucinated values.
No error handling or recovery guidance visible. Tools reference 'Community Management API access' requirement but do not document what error is returned if access is missing, or how to recover. No actionable error messages for invalid post_id, missing authentication, or API failures.
Idempotency not guaranteed for posting tools. linkedin_post_text, linkedin_post_image, linkedin_post_video, linkedin_post_article do not document whether repeated calls with identical parameters produce one post or multiple posts. Agents retry on ambiguous failures, non-idempotent tools risk duplicate posts.