LinkedIn MCP Server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@LinkedIn MCP Servercreate a LinkedIn post about our new product launch"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
LinkedIn MCP Server (Python)
A Model Context Protocol server that lets any MCP client — Amazon Quick, Amazon Q, Claude Desktop, Cline, Continue — publish and manage LinkedIn content in natural language: create posts (text, image, multi-image, video, document, article, poll), upload media, edit/delete, comment, and reshare on a self-serve token. Reactions, engagement reads, and company-Page tools are also built in, gated behind opt-in flags because LinkedIn requires partner approval for them.
By default the server advertises the 10 tools that work on a self-serve token; the 7 partner-scoped tools stay hidden until you opt in (see Feature tiers).
Built with Python + FastMCP, plain LinkedIn REST, and OAuth 2.0. Runs over stdio (local) or streamable HTTP (hosted) from the same codebase.
Unofficial integration. Not affiliated with LinkedIn. Use within LinkedIn's API Terms.
Amazon Quick Desktop vs Amazon Quick Web — read this first
Amazon Quick comes in two forms with different MCP requirements:
Surface | Transport it needs | How to run this server |
Amazon Quick Desktop (native app) | Local connector (runs a command) or remote HTTP | Run over stdio (default). Add as a Local connector. |
Amazon Quick Web (browser / cloud, aka Quick Suite) | Remote only — streamable HTTP / SSE over HTTPS; stdio not supported | Run over HTTP and host it (e.g. behind Bedrock AgentCore Runtime), then add as a remote MCP connector. |
Every other MCP client — Amazon Q Developer CLI, Claude Desktop, Cline, Continue — runs the default stdio server locally, exactly like Quick Desktop.
The transport is a single env var (LINKEDIN_MCP_TRANSPORT=stdio|http) — no code
change between the two.
Related MCP server: Postoria MCP Server
Feature tiers (what your token can actually reach)
The server advertises 10 tools by default — exactly the ones that work on a self-serve token. The other 7 are built in full but hidden behind two default-off flags, because LinkedIn requires partner approval for the scopes they need. Flip a flag only once your app is approved for that program; otherwise those tools would only return a ScopeError.
Flag | Default | Adds | Needs |
(none) | — | the 10 self-serve tools below |
|
|
| 3 reaction/metadata tools | Community Management ( |
|
| 4 organization tools | Marketing/Org scopes + Page admin role |
Tool count: default 10 → +SOCIAL_FEED 13 → +ORG 14 → both 17.
✅ Self-serve — advertised by default (10 tools)
Scopes openid profile email w_member_social, granted instantly by adding the
Sign In with LinkedIn (OIDC) and Share on LinkedIn products to your app.
Tool | What it does |
| Your name, email, picture, and person URN |
| Text / image / multi-image / video / document / article post |
| Poll post (2–4 options, 1/3/7/14-day) |
| Reshare an existing post with commentary |
| Edit a post's text |
| Delete a post |
| Upload an image → image URN |
| Upload a video → video URN |
| Upload a PDF/document → document URN |
| Comment on a post / reply to a comment |
⚠️ Community Management — gated behind LINKEDIN_ENABLE_SOCIAL_FEED (3 tools)
Need w_member_social_feed (reactions) / r_member_social_feed (metadata, which
LinkedIn marks Restricted — granted to select developers only). Plain
w_member_social is not sufficient — these endpoints return 403 until your
app is approved for the Community Management API.
Tool | What it does | Scope |
| Add a reaction to a post/comment |
|
| Remove your reaction |
|
| Like/comment counts + reaction summary |
|
🏢 Organization — gated behind LINKEDIN_ENABLE_ORG (4 tools)
Need Marketing Developer Platform approval or a Page admin role
(rw_organization_admin, r_organization_social). Fully implemented; until
approved they return a clear ScopeError.
Tool | What it does |
| Look up a company Page by org ID |
| Find a Page by its URL slug |
| Follower statistics for a Page |
| Pages you can administer |
Posting as an organization also works through linkedin_create_post — pass an
urn:li:organization:... author URN (needs w_organization_social + a Page role).
Clear errors, not opaque failures. Every tool is wrapped so a LinkedIn error comes back as a structured
{error, status, linkedin_response, hint}dict — a missing-scope 403 names the exact permission required instead of failing silently.
No native scheduling. LinkedIn's public Posts API only accepts
lifecycleState: PUBLISHED. Scheduling must live in your own layer.
Install
git clone <this-repo>
cd linkedin-mcp-server
python3 -m venv .venv && source .venv/bin/activate
pip install -e .Get a LinkedIn access token (quickest path)
Create a Company Page (LinkedIn requires every app to be linked to one): linkedin.com/company/setup/new.
Create an app at the Developer Portal linked to that Page.
Products tab → request access to Sign In with LinkedIn using OpenID Connect and Share on LinkedIn (both auto-approved).
Auth tab → add redirect URL
https://www.linkedin.com/developers/tools/oauth/redirect(for the token generator) andhttp://localhost:8765/callback(for this server's interactive login).Generate a token at the token generator with scopes
openid profile email w_member_social(expires in 60 days), or let this server run the interactive login (see Config below).
Configure
Copy .env.example → .env, or set the vars in your MCP client. Two auth modes:
Bring your own token (simplest / headless): set
LINKEDIN_ACCESS_TOKEN.Interactive OAuth (PKCE): set
LINKEDIN_CLIENT_ID(+LINKEDIN_CLIENT_SECRETif your app is confidential). The server opens a browser on first use and caches the token at~/.linkedin-mcp/token.json.
Partner-scoped tool groups are off by default. Once LinkedIn approves your app
for the relevant program, set LINKEDIN_ENABLE_SOCIAL_FEED=true (reactions /
social metadata) and/or LINKEDIN_ENABLE_ORG=true (organization tools) to make
them appear. See Feature tiers.
Client setup
Amazon Quick Desktop (Local connector)
Desktop App → Customize → Connectors → Create → Create local connector → Local:
Command:
/absolute/path/to/.venv/bin/pythonArguments:
-m linkedin_mcp.serverEnvironment variables:
LINKEDIN_ACCESS_TOKEN= your token
Amazon Quick Web (browser / cloud, remote HTTP)
Host the server with LINKEDIN_MCP_TRANSPORT=http behind an HTTPS endpoint
(e.g. Bedrock AgentCore Runtime). Then in the Quick console →
Connectors → Model Context Protocol (MCP) → set the MCP server endpoint
to your https://.../mcp URL and pick an auth method (No Auth / OAuth / S2S).
Amazon Q Developer CLI
q mcp add --name linkedin \
--command /absolute/path/to/.venv/bin/python \
--args '["-m", "linkedin_mcp.server"]'
# then set LINKEDIN_ACCESS_TOKEN in the environment / agent configClaude Desktop / Cline / Continue
{
"mcpServers": {
"linkedin": {
"command": "/absolute/path/to/.venv/bin/python",
"args": ["-m", "linkedin_mcp.server"],
"env": { "LINKEDIN_ACCESS_TOKEN": "paste-your-token-here" }
}
}
}Try it
"What's my LinkedIn profile?" → returns your name, email, and person URN. "Post on LinkedIn: Excited to share our new MCP server!" "Upload ~/pic.png and post it with the caption 'Launch day 🚀'." "Reshare urn:li:share:123 with the note 'This is great.'" "Delete my last post."
Development
pip install -e ".[dev]"
pytest # LinkedIn calls are mocked with respx — no network, no tokenArchitecture
src/linkedin_mcp/
server.py FastMCP app + stdio|http transport
config.py env-driven config
auth.py OAuth 2.0 PKCE loopback flow + token cache + env fallback
client.py REST client: versioned headers, URN encoding, media upload, error mapping
errors.py AuthError / ScopeError / APIError + tool_safe (structured-error wrapper)
tools/
profile.py whoami
posts.py create / poll / reshare / update / delete
media.py image / video / document upload
social.py comment (always) + react / unreact / social metadata (LINKEDIN_ENABLE_SOCIAL_FEED)
organizations.py company tools, gated behind LINKEDIN_ENABLE_ORGLicense
MIT
Available Tools
10 toolslinkedin_commentA
Comment on a post, or reply to a comment.
Scope: w_member_social.
Args:
actor_urn: Who is commenting (urn:li:person:... or org URN).
object_urn: The post URN being commented on.
text: The comment body.
parent_comment_urn: If replying to a comment, that comment's URN.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| actor_urn | Yes | ||
| object_urn | Yes | ||
| parent_comment_urn | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden. It usefully names the required OAuth scope ('w_member_social'), but says nothing about the fact that this creates publicly visible content, whether duplicate comments are allowed, rate limits, or failure behavior for an invalid URN.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the one-line purpose, then scope, then a clean arg list. Slightly redundant that the args list restates parameter names already in the schema, but every line is short and earns its place for an undocumented schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter mutation tool with no annotations and no output schema, the description covers the auth scope and all parameters, which is the essential core. It stops short of return value, error semantics, and visibility consequences, so an agent knows how to call it but not fully what to expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: all four parameters are explained with meaning ('Who is commenting', 'The post URN being commented on', 'The comment body', 'If replying to a comment'). It even gives a format exemplar (`urn:li:person:...`), though it omits that parent_comment_urn defaults to null.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource pair ('Comment on a post') and adds a second distinct mode ('reply to a comment'), which an agent can immediately distinguish from siblings like linkedin_create_post or linkedin_reshare_post. The scope line and arg list reinforce exactly what the tool operates on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance, no exclusions, and no named alternative (e.g. when to comment vs reshare vs post). The only routing hint is the conditional phrase 'If replying to a comment' for parent_comment_urn, which is parameter-level, not tool-selection-level.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_create_pollA
Create a poll post with 2–4 options.
Poll content cannot be edited after creation. Do not ask for political opinions, health status, or other sensitive data (LinkedIn policy).
Args: author_urn: The author URN. question: The poll question (used as the post commentary). options: 2 to 4 answer options. duration: ONE_DAY, THREE_DAYS, SEVEN_DAYS, or FOURTEEN_DAYS.
| Name | Required | Description | Default |
|---|---|---|---|
| options | Yes | ||
| duration | No | SEVEN_DAYS | |
| question | Yes | ||
| author_urn | Yes | ||
| visibility | No | PUBLIC |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, and it delivers real behavioral traits: poll content is immutable after creation, and content must comply with LinkedIn policy. It omits auth/permission requirements and any rate or return-value behavior, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, then immediately the two most important warnings, then a compact args list. The args list duplicates schema keys, but with 0% schema coverage that duplication is informative rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no annotations and no output schema, the description covers immutability and policy limits but leaves 'visibility' undocumented and says nothing about permissions or what a successful call returns. Adequate, but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it documents four of five parameters with meaning ('question' is used as post commentary, 'options' must be 2–4, allowed 'duration' values). It omits the 'visibility' parameter entirely, which is the remaining gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Create a poll post') plus a distinguishing constraint ('2–4 options'), which separates it from the generic linkedin_create_post sibling. It does not explicitly name an alternative, so it is clear but not fully sibling-differentiating.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives content-policy constraints ('Do not ask for political opinions, health status, or other sensitive data'), which is a 'when-not' rule of sorts. However, it never says when to choose this tool over linkedin_create_post, nor any prerequisites, so usage guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_create_postA
Create a LinkedIn post. Supports text, image, multi-image, video, document, and article/link posts — pick ONE media type per call.
Text only: pass just
commentary.Image: upload with
linkedin_upload_imagefirst, pass its URN inimage_urns(1 = single image, 2–20 = multi-image carousel).Video: pass
video_urnfromlinkedin_upload_video.Document: pass
document_urnfromlinkedin_upload_document.Article/link: pass
article_url(+ optional title/description); no upload needed.
Args:
author_urn: urn:li:person:... (self) or urn:li:organization:... (page).
commentary: The post text (an empty string is coerced to a single space).
visibility: PUBLIC, CONNECTIONS, or LOGGED_IN.
image_urns: Image URNs for an image/multi-image post.
image_alt_texts: Optional alt text per image (same order as image_urns).
video_urn: A video URN for a video post.
document_urn: A document URN for a document post.
article_url: A URL for an article/link post.
| Name | Required | Description | Default |
|---|---|---|---|
| video_urn | No | ||
| author_urn | Yes | ||
| commentary | Yes | ||
| image_urns | No | ||
| visibility | No | PUBLIC | |
| article_url | No | ||
| video_title | No | ||
| document_urn | No | ||
| article_title | No | ||
| document_title | No | ||
| image_alt_texts | No | ||
| article_description | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, and it does well: it discloses the media-type mutual exclusion, the upload-first prerequisite chain, and the non-obvious coercion that an empty commentary becomes a single space. What it does not disclose is the return value (post URN?), any permission/auth requirements for posting to an organization page, or error behavior on conflicting URNs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the one-line purpose followed by a scannable per-media bullet list; each bullet carries distinct routing information. The trailing 'Args:' block partially restates the bullets and the schema, adding some redundancy, but it is short and still load-bearing for the URN formats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter, no-annotation, no-output-schema mutation tool, the description covers every media path, the required parameters, and cross-tool prerequisites. The remaining gap is the response contract and failure modes, which is modest given no output schema exists to defer to.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it documents author_urn (with person vs organization URN form), commentary, visibility values, all media URNs, alt-text ordering, and article title/description. It leaves video_title and document_title unexplained, but those are self-evident given their sibling fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Create a LinkedIn post') and immediately enumerates the six supported post shapes, so an agent knows exactly what this tool produces versus siblings like linkedin_reshare_post or linkedin_create_poll. The per-media routing rules make it distinguishable from the upload tools it depends on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states the mutual-exclusion rule ('pick ONE media type per call') and gives a when-to-use path per media type, including the required ordering with linkedin_upload_image, linkedin_upload_video, and linkedin_upload_document. It even notes which paths need no upload (article/link), which is exactly the kind of routing guidance most definitions omit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_delete_postC
Delete a post.
Args: post_urn: The post URN to delete.
| Name | Required | Description | Default |
|---|---|---|---|
| post_urn | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, and it says almost nothing. It does not disclose that the operation is destructive and irreversible, what permissions/ownership are required, or what happens on failure (e.g., post not found). 'Delete' implies mutation but no safety context is provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is short and front-loaded, but the Args block is pure boilerplate that repeats the schema without adding information. Brevity here reflects under-specification rather than earned conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive mutation with no annotations, no output schema, and 0% schema coverage, the definition is inadequate: no confirmation semantics, no error conditions, no ownership/permission prerequisites are described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and there is one required parameter. The description only restates the parameter name ('post_urn: The post URN to delete'), adding essentially nothing about the expected URN format (e.g., 'urn:li:share:...') or where to obtain it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource ('Delete a post'), which is clear. However, it does nothing to distinguish itself from the sibling linkedin_update_post, which could plausibly be confused with delete for an agent managing post lifecycle.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use delete versus update, nor any mention that deletion is typically irreversible or requires the post to belong to the authenticated user. The agent must infer all of this.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_get_profileA
Get the authenticated member's LinkedIn profile.
Returns name, email, profile picture, locale and — most importantly — the
member's person URN (e.g. urn:li:person:abc123), which is the
author_urn required by all post-creation tools. Call this first and
reuse the URN.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the return contents (name, email, picture, locale, person URN) and the key cross-tool behavioral fact that the URN is required as author_urn elsewhere. It does not mention token/permission prerequisites or rate limits, which is a minor remaining gap for a read-only profile call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action, then the return payload, then the imperative next step. The em-dash emphasis on the URN prioritizes correctly and no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must describe returns, and it does. Combined with the zero-parameter schema and the explicit reuse instruction, an agent has everything needed to call it and use the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate and the baseline is 4. No parameter information is missing.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (get the authenticated member's LinkedIn profile) and enumerates the returned fields. It is unambiguously the read/bootstrapping tool among a sibling set that is otherwise all write operations (create_post, upload_*, delete_post).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs ordering ('Call this first and reuse the URN') and explains the reason: the person URN is the author_urn required by all post-creation tools. That is a concrete when-to-use rule tied to the sibling set, not inferred guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_update_postA
Edit an existing post's commentary (text).
LinkedIn's partial-update only supports editing the commentary of an existing post; author, media, and poll content cannot be changed.
Args:
post_urn: The post URN (urn:li:share:... or urn:li:ugcPost:...).
commentary: New post text.
| Name | Required | Description | Default |
|---|---|---|---|
| post_urn | Yes | ||
| commentary | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It does disclose a genuinely useful behavioral trait — that the update is a partial update limited to commentary — but says nothing about permissions/auth requirements, error behavior, or reversibility for a mutation operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action, follows with the key constraint, then an Args block. Every sentence adds information; the only mild redundancy is restating 'commentary (text)' in the args.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-param mutation tool with no annotations and no output schema, the description covers the action, its scope limitation, and both parameters with format hints. Missing permission and failure-mode detail, but otherwise adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It documents both parameters and, notably, gives the accepted URN formats (urn:li:share / urn:li:ugcPost) for post_urn, which the schema does not, plus clarifies commentary is the 'new post text'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Edit an existing post's commentary') and immediately bounds the scope by naming what cannot be changed (author, media, poll). This clearly separates it from siblings like linkedin_create_post and linkedin_delete_post without needing their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for use: editing the text of an existing post. It also negates other edits ('author, media, and poll content cannot be changed'), but does not explicitly name alternative tools (e.g. delete vs create) or state when this tool should not be invoked at all.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_upload_documentA
Upload a local document (e.g. PDF) and return its document URN.
Reference the returned urn:li:document:... via document_urn on
linkedin_create_post to publish a document/carousel-style post.
Args: author_urn: The owner URN. file_path: Absolute path to a local document (PDF).
| Name | Required | Description | Default |
|---|---|---|---|
| file_path | Yes | ||
| author_urn | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it usefully discloses the return value (a urn:li:document URN) and the downstream consumption path. It says nothing about permissions/auth needed for the author URN, file size or type limits, idempotency, or failure modes of the upload, which are material for a network-bound mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and workflow value are front-loaded in the first two sentences, with parameters listed afterward in a compact Args block. Reasonably tight, though the Args block slightly restates the schema's property names.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter upload with no output schema, the description covers the essential loop: what to pass, what comes back, and where the result is used next. It omits file constraints and auth requirements, which is the main remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it only partially does: file_path is enriched with 'absolute path' and 'PDF', but author_urn is described tautologically as 'The owner URN' without stating the expected URN form (person vs. organization).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Upload a local document (e.g. PDF)') plus the output ('return its document URN'), which cleanly separates it from linkedin_upload_video and linkedin_upload_image. An agent can tell what this tool does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context: the returned URN is referenced via document_urn on linkedin_create_post to publish a document/carousel post, so the agent knows this is a preparatory step in a specific workflow. However, it names no exclusions or alternate paths (e.g. what to do for images/videos), so it falls short of explicit when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_upload_imageA
Upload a local image file and return its image URN.
Pass the returned urn:li:image:... to linkedin_create_post as one
of image_urns (one image = single-image post, 2–20 = multi-image).
Args:
author_urn: The owner URN (urn:li:person:... or urn:li:organization:...).
file_path: Absolute path to a local image (PNG/JPG/GIF).
| Name | Required | Description | Default |
|---|---|---|---|
| file_path | Yes | ||
| author_urn | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses the return value semantics, which is useful, but says nothing about auth/permission requirements, file size limits, or failure behavior for a network upload. Adequate but thin given zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded one-line purpose followed by the chaining instruction and an Args block. No filler sentences; every line carries actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly explains the returned URN and how to consume it, and it documents both required parameters despite 0% schema coverage. Missing only peripheral details like size limits and auth, which don't block correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate and it mostly does: author_urn is explained as the owner URN with both 'urn:li:person:...' and 'urn:li:organization:...' forms, and file_path is specified as an absolute local path restricted to PNG/JPG/GIF. Only the size/format constraints are left implicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Upload a local image file') and the output ('return its image URN'), which cleanly separates it from the upload_video and upload_document siblings. An agent can identify the tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear downstream contract: pass the returned 'urn:li:image:...' into linkedin_create_post as one of 'image_urns', and encodes the cardinality rule (1 = single-image post, 2-20 = multi-image). It does not explicitly say when to prefer this over upload_video/upload_document, but the sibling names make the selection obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_upload_videoB
Upload a local video file and return its video URN.
LinkedIn processes video asynchronously; a freshly uploaded video may take a short while before a post referencing it goes fully live.
Args: author_urn: The owner URN. file_path: Absolute path to a local video (MP4).
| Name | Required | Description | Default |
|---|---|---|---|
| file_path | Yes | ||
| author_urn | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose one important trait: processing is asynchronous and a post may not go live immediately. It omits auth/permission requirements, file size or duration limits, and any rate-limit or overwrite behavior, so the disclosure is partial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action and return value, followed by a useful async caveat and a clean Args block. No wasted sentences, though the Args section largely restates short schema titles.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-param mutation with no annotations and no output schema, the description helpfully names the returned URN and the async behavior, but it leaves auth requirements and success/failure conditions unstated. Adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate; it adds format detail ('absolute path to a local video (MP4)') for file_path, but author_urn is explained only as 'The owner URN', which is barely more than the schema. It adds meaning for one parameter and not the other.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Upload a local video file') plus the return artifact ('video URN'), which is enough for an agent to pick it over unrelated siblings. It does not, however, explicitly distinguish itself from linkedin_upload_image or linkedin_upload_document beyond the word 'video'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the async note suggests uploading here before referencing the video in a post, but the description never names a when-to-use condition or an alternative tool. An agent must infer the pipeline from sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
10 tool updates
v0.1.0- First observed
linkedin_comment - First observed
linkedin_create_poll - First observed
linkedin_create_post - First observed
linkedin_delete_post - First observed
linkedin_get_profile - First observed
linkedin_reshare_post - First observed
linkedin_update_post - First observed
linkedin_upload_document - First observed
linkedin_upload_image - First observed
linkedin_upload_video
TDQS
Scored across 10 tools
Each tool targets a distinct resource+action: three upload tools split cleanly by media type (image/video/document), and the post operations (create, create_poll, reshare, update, delete) plus comment and get_profile are mutually exclusive in purpose. Descriptions reinforce the boundaries, e.g. noting that create_post takes exactly one media type.
Every tool follows a uniform linkedin_verb_noun snake_case pattern (upload_video, create_post, create_poll, reshare_post, update_post, delete_post, get_profile). No mixed conventions or vague verbs appear.
Ten tools is well-scoped for the domain: uploads, post lifecycle, engagement, and identity lookup each earn their place with no redundancy or filler.
Post creation lifecycle (create/update/delete), media uploads, polls, reshares, comments, and profile lookup are all covered, forming a coherent surface. Minor gaps remain: no read/list tools for existing posts or comments, and no reaction/like operations, but core publishing workflows are fully achievable.
Maintenance
Related MCP Connectors
Create, schedule, and publish social posts, manage accounts, and read analytics as MCP tools.
Publish and schedule social posts, upload media, and review analytics through OAuth.
Create, schedule, and publish social posts through the hosted SocialSpool MCP connector.
Draft, validate, publish, schedule, and manage social posts across connected accounts.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables interaction with the Postiz social media management platform through MCP tools. Supports creating and managing posts, retrieving integrations, and accessing account information through multiple transport protocols.2-

Postoria MCP Serverofficial
AlicenseAqualityCmaintenanceEnables MCP-compatible clients to create, schedule, queue, inspect, and delete Postoria posts through the Postoria Public API.1411 npm1MIT
OwlStack MCPofficial
AlicenseAqualityCmaintenanceManages social media posts, accounts, and AI usage from MCP-aware clients. Supports scheduling, editing, canceling, AI caption generation, and repurposing URLs into platform-optimized content.14MIT
@fopost/mcpofficial
AlicenseAqualityBmaintenanceEnables managing social media posts, accounts, and AI-powered content features from any MCP client, including scheduling, publishing, analysis, and AI caption generation.1412 npmMIT