MCP server for LinkedIn — post to LinkedIn from Claude, upload images, and manage company pages via natural language.
Server has 9 well-named tools with complete descriptions and input schemas. All tools follow verb_noun naming (linkedin_get_*, linkedin_create_*, etc.). Descriptions are detailed (100-250 chars) and explain prerequisites (scope requirements). Input parameters have types and descriptions. However, output schemas are not documented, LLMs cannot predict response structure for downstream chaining. Error handling is minimal; no recovery guidance or actionable error messages visible. Missing idempotency hints on write operations. No batch variants despite tools like linkedin_list_posts that agents might call in loops.
Create a new post on LinkedIn on behalf of a member or organization. Supports text-only posts, image posts (after uploading via linkedin_upload_image), and article/link posts. Post length is capped at 3000 characters. Requires scope: w_member_social (for member posts) or w_organization_social (for org posts)
Delete a LinkedIn post by its URN. Requires scope: w_member_social
Get the total number of LinkedIn members following an organization page. Requires scope: rw_organization_admin
Retrieve a LinkedIn organization (company) page by its numeric ID or vanity name. Without admin access, returns public fields: id, localizedName, vanityName, localizedWebsite, primaryOrganizationType, locations, and logoV2. With admin access (rw_organization_admin scope), returns additional fields like description, industries, staffCountRange, foundedOn, and specialties. Requires scope: rw_organization_admin
Retrieve a LinkedIn post by its URN. NOTE: Reading posts requires the r_member_social scope for member posts or r_organization_social for org posts. These scopes require LinkedIn approval and are not available to all developers. If you only have w_member_social, use linkedin_create_post and linkedin_list_posts instead. Requires scope: r_member_social or r_organization_social
Output schemas not documented. LLMs cannot predict response structure (fields, types, nested objects) for downstream tool chaining. E.g., linkedin_get_profile returns 'sub' field but this is not documented, forcing agents to guess or fail when passing it to linkedin_create_post.
Error handling lacks recovery guidance. handleApiError() in linkedin-client.ts returns generic messages like 'Error: Bad request' without actionable next steps. LLMs cannot self-correct or know whether to retry, ask user, or abort.
Destructive operations (linkedin_delete_post, linkedin_update_post) lack confirmation or dry-run support. Agents can irreversibly delete posts without a safety gate.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 59 | 2025-06-18+ | v2 |
Retrieve the authenticated LinkedIn member's profile information via the OIDC userinfo endpoint. Returns the member's name, profile picture, email address, and locale. Requires scopes: openid, profile, email
List posts by a member or organization. Requires scope: r_member_social (for member posts) or r_organization_social (for org posts)
Update the text and/or visibility of a LinkedIn post. Requires scope: w_member_social
Upload an image to LinkedIn and get an image URN to use when creating an image post. This is a two-step process handled automatically: 1. Initialize the upload via /rest/images to get a pre-signed upload URL 2. PUT the image binary to that URL After upload, use the returned image URN as image_asset_urn in linkedin_create_post. Requires scope: w_member_social
linkedin_list_posts accepts limit (1-50) and offset but does not document total count or next_cursor in response. Agents cannot determine if more results exist or how to paginate efficiently.
Tool descriptions mention scope requirements but do not declare them as formal permission metadata. No pattern:scope-declaration visible in tool registration.