linkedin-mcp
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-mcpPublish a LinkedIn post about our latest 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
Post to LinkedIn from Claude, ChatGPT, Cursor or any AI assistant — on your personal profile, through the official LinkedIn API.
linkedin-mcp is an open-source Model Context Protocol server. You sign in once with your own LinkedIn developer app, and your assistant can publish text, link and image posts, comment and react. No scraping, no password sharing, no browser automation.
No company account needed. It works with a normal personal LinkedIn profile. LinkedIn only asks you to link your developer app to a Page, and you can create one yourself in a minute (see step 1).
Contents
Related MCP server: LinkedIn MCP Server
What can I do with it?
With a personal profile and the default setup (access is granted instantly):
✅ Publish posts | Plain text, with a link preview, or with an image (local file or URL) |
✅ Real hashtags |
|
✅ Visibility | Public, connections only, or signed-in members |
✅ Engage | Comment on posts and react (like, celebrate, support, love, insightful, funny) |
✅ Delete | Remove posts you created |
✅ Automate | Let your assistant write and publish on a schedule |
❌ Read your feed, posts or statistics | LinkedIn restricts |
❌ Messages, connections, search, other profiles | Not offered by LinkedIn's public API |
Company pages are supported as well, but need extra approval from LinkedIn (see Company pages).
Setup
You need Node.js 22+ (node -v) and a LinkedIn account.
1. Create a LinkedIn app (5 minutes)
Create a LinkedIn Page, if you don't have one. LinkedIn requires every developer app to be linked to a Page. This is only a formality: go to For Business → Create a Company Page, pick any name (e.g. "Jane Doe Tools"). It never has to post anything. Your posts still appear on your personal profile.
Open https://www.linkedin.com/developers/apps → Create app, pick that Page, upload any logo.
Settings tab → Verify the app with the Page. As the Page admin you approve it yourself.
Products tab → click Request access on exactly these two (both are granted instantly):
Share on LinkedIn: publish, comment, react (
w_member_social)Sign In with LinkedIn using OpenID Connect: identifies you as the author (
openid profile email)
Don't request the other products (Advertising, Lead Sync, Events, Community Management, …). You don't need them for personal posting.
Auth tab → Authorized redirect URLs for your app → pencil icon → Add redirect URL → paste exactly
http://localhost:8787/callbackand click Update. It must be
http(not https),localhost(not 127.0.0.1), with no trailing slash.Still in Auth: check that OAuth 2.0 scopes lists
openid,profile,email,w_member_social. Keep this tab open, you'll need the Client ID and Primary Client Secret.
2. Sign in
Run this in your terminal. It's the only command you need, and it asks for everything:
npx -y github:vlpmedialtd/linkedin-mcp authLinkedIn Client ID:→ paste the Client ID, press EnterLinkedIn Client Secret (hidden):→ click the copy icon next to Primary Client Secret, paste, press Enter. Nothing is shown while you paste; that's intentional. You'll see(received NN characters): the secret is much longer than the 14-character Client ID.Your browser opens → click Allow
Wait until the terminal shows
✔ Token saved to ~/.config/linkedin-mcp/token.json. Only then are you done.
The token is valid for 60 days. Run the same command again when it expires.
Paste values at the prompts, not behind the command. If your terminal shows
dquote>, pressCtrl+Cand start again.
3a. Use with Claude Code / Claude Desktop / Cursor
These clients start the server locally on your computer.
Claude Code
claude mcp add -s user linkedin -- npx -y github:vlpmedialtd/linkedin-mcpCheck with claude mcp list (should show linkedin … ✓ Connected), then start a new session.
Claude Desktop / Cursor / Windsurf / any stdio MCP client: add to claude_desktop_config.json, .cursor/mcp.json, …
{
"mcpServers": {
"linkedin": {
"command": "npx",
"args": ["-y", "github:vlpmedialtd/linkedin-mcp"]
}
}
}Restart the app. Test it by asking "Who am I on LinkedIn?". This only reads your profile; nothing is posted.
3b. Use with ChatGPT
ChatGPT can't start programs on your computer. It connects to MCP servers over public HTTPS instead. linkedin-mcp has an HTTP mode for this, and you make it reachable through a tunnel.
Requirements: a ChatGPT plan with Developer mode (Plus, Pro, Business, Enterprise or Education, on the web), and steps 1 and 2 above completed.
1. Start the HTTP server (terminal 1, keep it running)
npx -y github:vlpmedialtd/linkedin-mcp httpIt prints your secret endpoint, for example http://127.0.0.1:3000/mcp/Xy7…. The part after /mcp/ is a random secret stored in ~/.config/linkedin-mcp/http-token, so it stays the same across restarts.
2. Open an HTTPS tunnel (terminal 2, keep it running)
brew install cloudflaredcloudflared tunnel --url http://localhost:3000Copy the https://….trycloudflare.com address it prints. ngrok (ngrok http 3000) works the same way.
3. Add the app in ChatGPT
ChatGPT → Settings → Security and login → turn on Developer mode.
Go to Plugins (apps) → + to create a developer-mode app for a remote MCP server.
MCP server URL: your tunnel address +
/mcp/+ your secret, e.g.https://blue-sky-1234.trycloudflare.com/mcp/Xy7…Authentication: No authentication. The secret in the URL protects the server.
Confirm that you trust the app and create it.
4. Use it: in a chat, open the + menu → Developer mode → enable your LinkedIn app, then ask "Who am I on LinkedIn?". ChatGPT asks for confirmation before write actions such as publishing a post.
Good to know:
Both terminals must keep running and your computer must stay awake while ChatGPT uses the app.
Quick tunnels get a new address on every start. Update the app's URL in ChatGPT afterwards, or use a named Cloudflare tunnel or an ngrok static domain for a permanent address.
Images: ChatGPT can't hand files from the chat to the server. Use an image URL, or a file path on the computer running the server.
Always-on hosting: run
linkedin-mcp http --host 0.0.0.0on any Node host (VPS, Railway, Render, Fly.io …) withLINKEDIN_ACCESS_TOKENandMCP_AUTH_TOKENset as environment variables, behind HTTPS.Menu names in ChatGPT change from time to time. See OpenAI's Developer mode guide for the current steps.
Example prompts
"Who am I on LinkedIn?" (connection test, read-only)
"Write a LinkedIn post about our new open-source release, link https://github.com/…, show me the draft first."
"Post this image
/Users/me/Desktop/chart.pngwith the text '…' and alt text 'Revenue chart Q3'.""Publish it for my connections only."
"Delete the post you just published."
"Like urn:li:share:7234… and comment 'Congratulations!'"
Automated posting
The server provides the tools; something has to trigger them:
Claude: scheduled tasks, e.g. "Every Tuesday at 9:00, write a short post about this week's topic from my notes and publish it."
ChatGPT: scheduled tasks with the developer-mode app enabled
n8n, cron or an agent framework that can act as an MCP client
Keep in mind:
Token lifetime: standard LinkedIn apps get no refresh token. The access token expires after 60 days and the server then reports a clear error. Put a reminder in your calendar to run
authagain.Confirmation: the post tool asks the model to confirm the text with you first. For unattended runs, say explicitly in your prompt that publishing without confirmation is intended.
Fair use: posting through the official API is allowed, but LinkedIn's User Agreement prohibits spam and bulk posting. Keep the cadence human.
Troubleshooting
Problem | Cause & fix |
"Do I need a company account?" | No. You only need a Page to create the developer app (step 1.1). Posts go to your personal profile. |
Terminal shows | A value was pasted directly behind the command. Press |
Browser: "The redirect_uri does not match the registered value" | The redirect URL is missing or differs in the app's Auth tab. Add exactly |
| The Client Secret is wrong. If it says |
Browser: | One of the two products isn't added yet. Check Products → Added products for Share on LinkedIn and Sign In with LinkedIn using OpenID Connect. |
|
|
| 60 days are over. Run |
| npx cached an old version. Run |
| Something else uses the port. Run |
LinkedIn API | Expected for personal profiles: reading needs |
LinkedIn API | Set |
ChatGPT: "Error creating connector" / | Check the URL: tunnel address + |
ChatGPT worked yesterday, not today | The quick tunnel got a new address, or the computer slept. Restart both terminals and update the URL in ChatGPT. |
Claude: | Run |
Still stuck? Open an issue with the error message. Never post your Client Secret, access token or MCP URL.
Tools reference
Tool | What it does | LinkedIn permission |
| Name, email, picture and person URN of the signed-in member |
|
| Publish a text post, optionally with link preview ( |
|
| Delete a post you authored |
|
| Comment on a post |
|
| React to a post |
|
| Fetch a post by URN |
|
| List recent posts |
|
| Like and comment summary |
|
| Pages you administer |
|
* Restricted by LinkedIn to approved partners.
All write tools accept an optional organization_id to act as a company page. Tools carry MCP annotations (readOnlyHint, destructiveHint), so clients like ChatGPT and Claude can ask before write actions.
Configuration
Variable | Default | Description |
| – | Access token; takes precedence over the token file (useful for hosting) |
| prompted | Used by |
|
| Must match the app's Auth settings |
|
| Scopes requested by |
|
|
|
|
| Token storage |
| generated | Secret for the HTTP endpoint |
|
| HTTP mode listen address |
CLI:
linkedin-mcp stdio server (Claude Code, Claude Desktop, Cursor, …)
linkedin-mcp auth sign in and store the token
linkedin-mcp http Streamable HTTP server (ChatGPT, remote clients)
--port <port> --host <host> --new-tokenHTTP endpoints: GET /health; MCP at /mcp/<secret> or /mcp with Authorization: Bearer <secret>.
Company pages
To post, comment and read statistics as a company page:
Create a separate LinkedIn app. LinkedIn requires the Community Management API to be the only product in its app.
Request Community Management API (LinkedIn reviews the request).
Sign in with the extra scopes:
LINKEDIN_SCOPES="openid profile email w_member_social w_organization_social r_organization_social rw_organization_admin" npx -y github:vlpmedialtd/linkedin-mcp authAsk "Which LinkedIn pages do I manage?", then "Post … on page 12345".
Security
Tokens and the HTTP secret are stored locally with
600permissions and are never logged.The Client Secret is only used during
authand is not saved.Anyone with your HTTP MCP URL can post as you. Don't share it. Rotate it with
linkedin-mcp http --new-token, then update the URL in ChatGPT.The HTTP server listens on
127.0.0.1by default and is only reachable through your tunnel.Revoke access any time at https://www.linkedin.com/psettings/permitted-services.
Development
git clone https://github.com/vlpmedialtd/linkedin-mcp.git
cd linkedin-mcp
npm install
npm test # build + tests (LinkedIn API is mocked)
npx @modelcontextprotocol/inspector node dist/index.js # try tools interactivelysrc/
index.ts CLI (stdio, auth, http)
server.ts MCP tool definitions
http.ts Streamable HTTP transport with secret-token protection
linkedin.ts LinkedIn REST client (Posts, Assets, Organizations, Social Actions, Reactions)
auth.ts OAuth 2.0 authorization-code flow with local callback
config.ts Token storage
text.ts LinkedIn "little text" escaping + hashtags
test/ node:test suitesIssues and pull requests are welcome.
License
MIT © Andreas Henkel
Not affiliated with, endorsed or sponsored by LinkedIn Corporation or OpenAI. LinkedIn is a trademark of LinkedIn Corporation; ChatGPT is a trademark of OpenAI.
Available Tools
9 toolslinkedin_comment_on_postComment on a LinkedIn postA
Adds a comment to a post as yourself or an organization. Publishes immediately — confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| post_urn | Yes | ||
| organization_id | No | Post/act as this organization instead of yourself. Accepts a numeric id or urn:li:organization:<id>. Requires the Community Management API product. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses a critical side effect — 'Publishes immediately' — and adds a user-confirmation requirement, both of which are behavioral traits beyond the annotations (openWorldHint, idempotentHint false, destructiveHint false). This provides valuable context for a mutating action with no separate rate-limit or auth notes.
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 entire description is one tight sentence with the essential action and a critical warning front-loaded. There is no filler or repetition of schema data.
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 simple write action with no output schema, the description covers the main behavior and a safety guideline (confirm first. However, it omits return-value expectations and any error conditions, which would help an agent fully understand the call outcome.
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 only 33%; the description adds meaning for organization_id ('as yourself or an organization') but does not explain post_urn or text beyond what their names imply. The core parameters are simple enough that the gap is minor.
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 — 'Adds a comment to a post' — and clearly distinguishes identity modes ('as yourself or an organization'). It is immediately distinguishable from siblings like create_post, react_to_post, and delete_post without needing to inspect 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?
No explicit 'use this when' or alternative routing is provided; the intended scenario is implied by the tool name and action. The 'confirm with the user first' warning adds an operational guideline, but it does not explain when this tool should be preferred over react_to_post or create_post.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_create_postPublish a LinkedIn postA
Publishes a post on LinkedIn as the authenticated member (or an organization). Supports plain text, a link preview (article) or a single image. #hashtags in the text become real hashtags; all other special characters are escaped automatically. This publishes publicly and immediately — confirm the final text with the user before calling.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Post text (max 3000 characters). | |
| image | No | Attach an image: absolute local file path or http(s) URL (JPG, PNG, GIF). Cannot be combined with link_url. | |
| link_url | No | Attach a link preview to this URL. | |
| link_title | No | Title for the link preview. | |
| visibility | No | PUBLIC (anyone), CONNECTIONS (members only, not for organizations), LOGGED_IN (signed-in members). | PUBLIC |
| image_alt_text | No | Alt text for the image. | |
| organization_id | No | Post/act as this organization instead of yourself. Accepts a numeric id or urn:li:organization:<id>. Requires the Community Management API product. | |
| convert_hashtags | No | Convert #words into LinkedIn hashtags. | |
| link_description | No | Description for the link preview. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only openWorldHint, idempotentHint=false, and destructiveHint=false. The description adds crucial behavioral details: it publishes publicly and immediately, requires user confirmation, converts hashtags into real ones, and escapes special characters. It also clarifies the organization_id API requirement. These go beyond the annotations and give the agent a realistic sense of side effects and constraints. No contradiction with annotations.
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 description is three sentences, front-loaded with the core purpose, then the supported formats, then the critical public/immediate warning. No filler or repetition. Every sentence carries actionable information, and the most important user-confirmation warning is placed last for emphasis.
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?
Given 9 parameters, a rich schema, and no output schema, the description covers the essential operational context: what the tool does, supported content types, the public/immediate nature, the need for user confirmation, and the organization caveat. It does not explain return values (no output schema), but that is not required. It adequately prepares the agent to call this tool correctly without missing critical safety or scope details.
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 100%, so the baseline is 3. The description adds value beyond the schema by explaining that #hashtags become real and special characters are escaped (behavior of text), and that organization_id requires the Community Management API product. It also summarizes the three content modes (text, link, image) in plain language. These clarifications help the agent select parameters appropriately, though most details remain in the schema.
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 opens with a specific verb and resource: 'Publishes a post on LinkedIn as the authenticated member (or an organization).' It clearly distinguishes itself from siblings like linkedin_delete_post, linkedin_get_post, and linkedin_comment_on_post by focusing on creation. The mention of supporting text, link preview, or image adds specificity without ambiguity.
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: it is for publishing a post, and it explicitly warns 'This publishes publicly and immediately — confirm the final text with the user before calling.' This is a strong usage guideline. It also notes the organization option and its prerequisite (Community Management API product), which helps decide when to use it. It does not explicitly list exclusions (e.g., 'do not use for commenting'), but the sibling names make that implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_delete_postDelete a LinkedIn postADestructiveIdempotent
Deletes a post you (or your organization) authored. Irreversible — confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| post_urn | Yes | URN of the post, e.g. urn:li:share:123 or urn:li:ugcPost:123. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and openWorldHint=true, so the destructive nature is known. The description adds value by stating the operation is irreversible and explicitly instructs confirming with the user first—a practical behavioral safeguard not encoded in the annotations. It also clarifies the ownership scope (you or your organization), which is additional context. No contradictions with annotations.
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 description is two concise sentences. The first states the core action and scope; the second delivers the critical warning. Every word earns its place, and the most important caveat is front-loaded after the verb. No fluff or redundancy.
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 single-parameter destructive action, the description covers the essential operational context: what it does, who can do it, and the irreversibility warning. There is no output schema, which is typical for delete operations. It does not mention error handling or return values, but given the tool's simplicity and the annotations already flagging destructiveness, this is adequately complete. The only minor gap is the absence of explicit guidance on what happens after a successful deletion (e.g., confirmation message), but that is not required for 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?
The input schema already provides full coverage (100%) for the single parameter post_urn, including a regex pattern and an example. The description does not add further parameter-specific details, but it does clarify that the post must be authored by the caller, which is contextual rather than parameter-level. Given the schema is self-sufficient, a baseline score of 3 is appropriate.
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 clearly states the action ('Deletes'), the resource ('a post'), and the scope ('you (or your organization) authored'). It also implicitly distinguishes itself from siblings like linkedin_create_post, linkedin_get_post, and linkedin_list_posts by focusing solely on deletion. An agent can immediately understand what this tool does and when it applies.
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 provides clear context for use (deleting an authored post) and a critical safety guideline ('Irreversible — confirm with the user first'). It does not explicitly contrast with alternatives, but among the sibling tools, none other handles deletion, so the purpose alone sufficiently routes an agent. The confirmation warning is a strong usage directive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_get_postGet a LinkedIn postARead-only
Fetches a single post by URN. Reading member posts requires the r_member_social permission (restricted); organization posts require r_organization_social.
| Name | Required | Description | Default |
|---|---|---|---|
| post_urn | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, but the description adds critical context about required OAuth permissions (r_member_social vs r_organization_social) that is not in the annotations. This directly helps an agent anticipate authorization failures. No contradiction with annotations.
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?
Two sentences with zero fluff. The primary purpose is front-loaded in the first sentence, and the permission note is a concise, relevant addition. Every word earns its place.
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?
The tool is simple (one param, read-only) and annotations cover safety. The description covers permissions, which is a key operational detail. However, the lack of output-format description and the weak parameter explanation (see parameter_semantics) leave minor gaps. Still, for a basic fetch, it is largely 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 for the post_urn parameter. It only repeats the phrase 'by URN', which adds no meaning beyond the parameter name itself. It does not explain what a URN looks like, how to obtain one, or any format nuances beyond the schema pattern. This is a significant 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?
The description states a specific verb ('Fetches') and resource ('a single post') and specifies the key discriminator (by URN). This clearly differentiates from sibling tools like linkedin_list_posts and linkedin_get_post_stats, and the intent is unambiguous.
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: use this when you have a post URN and need that specific post. It also notes permission prerequisites, which are important usage constraints. However, it does not explicitly exclude alternatives (e.g., 'use list_posts to find URNs') or state when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_get_post_statsGet likes/comments summary of a postARead-only
Returns the like and comment summary of a post (socialActions).
| Name | Required | Description | Default |
|---|---|---|---|
| post_urn | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds the specific 'socialActions' detail, which is useful context about what is returned, but it does not disclose pagination, rate limits, or what happens if the post has no likes/comments.
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 description is a single sentence with no wasted words. It front-loads the action and resource, and the parenthetical 'socialActions' adds a useful API-level detail without bloating the text.
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 simple read-only tool with one parameter and no output schema, the description is mostly adequate. However, it does not mention what the response structure looks like or whether the summary includes counts, lists, or both, which an agent might need to know for downstream use.
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 does not explain the post_urn parameter beyond the schema's pattern, but the parameter is a single, self-explanatory identifier. The description adds no meaning beyond what the schema provides, so a baseline 3 is appropriate.
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 ('Returns') and resource ('like and comment summary of a post'), and the title reinforces the scope. It is clear enough to distinguish from siblings like linkedin_get_post, though it does not explicitly name the sibling it differs from.
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 implies usage for retrieving post engagement stats, and the sibling list shows alternatives like linkedin_get_post and linkedin_list_posts. However, it does not explicitly state when to use this tool versus those alternatives, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_get_profileGet my LinkedIn profileARead-only
Returns the authenticated member's basic profile (name, email, picture) and their person URN. Use this to verify the connection.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, covering safety. The description adds the specific return fields and the purpose (verification), which is useful context beyond the annotations. It doesn't contradict annotations, but it doesn't mention rate limits or auth requirements; acceptable for a simple read.
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?
Two sentences with zero waste. Front-loads what the tool returns, then gives the purpose. No unnecessary details or fluff.
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 zero-parameter read-only tool with no output schema, the description adequately covers the return value (basic profile fields and URN) and the intended use case. It could specify that these are the only fields returned, but 'basic profile' implies a defined set. Sufficient for an agent to call correctly.
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?
Tool has zero parameters, so schema coverage is trivially 100%. Per guidelines, baseline 4 applies when there are no parameters. The description doesn't need to add parameter info; it correctly focuses on the return value.
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?
Clearly states a specific verb ('Returns') and resource ('authenticated member's basic profile'), and enumerates the exact fields returned (name, email, picture, person URN). No overlap with sibling tools (all post/organization related), so distinction is unambiguous.
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?
Provides an explicit use case: 'Use this to verify the connection.' This tells the agent when to invoke it. Since there are no alternative profile tools among siblings, explicit exclusion isn't necessary, though it could mention when not to use (e.g., for detailed profile data) – minor gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_list_organizationsList my LinkedIn organizationsARead-only
Lists LinkedIn company pages the authenticated member administers (Community Management API, scope rw_organization_admin).
| Name | Required | Description | Default |
|---|---|---|---|
| role | No | ADMINISTRATOR |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds useful behavioral context: it names the Community Management API and the required scope rw_organization_admin. It also clarifies the membership/administrator constraint, which goes beyond the annotations. No contradiction with annotations is present.
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 description is a single, front-loaded sentence that conveys the resource, the authentication constraint, and the API/scope context. Every word adds value, and there is no redundant repetition of the tool name or title.
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 simple read-only listing tool with one optional parameter, the description includes the essential context: what is listed, who it is listed for, and the required scope. The role parameter is not mentioned in the description, but the schema documents it, so the overall tool definition is 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%, and the description does not mention the 'role' parameter at all. The schema's enum and default provide some self-documentation, but the description fails to explain how role filters the returned organizations. With low schema coverage, the description should compensate and does not.
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 uses a specific verb ('Lists') and a clearly defined resource ('LinkedIn company pages the authenticated member administers'). It also names the underlying API and scope, making the tool's purpose unambiguous. Sibling tools are all profile/post actions, so there is no risk of confusion.
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 clearly states that this lists organizations the authenticated member administers, which implies it should be used when the agent needs the member's manageable LinkedIn organizations. It doesn't explicitly name alternatives or conditions, but none of the sibling tools overlap with this listing function, so the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_list_postsList LinkedIn postsARead-only
Lists recent posts by an author (default: yourself). Requires r_member_social (restricted) for members or r_organization_social for organizations.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | ||
| start | No | ||
| organization_id | No | Post/act as this organization instead of yourself. Accepts a numeric id or urn:li:organization:<id>. Requires the Community Management API product. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true. The description adds the auth scopes, which is useful behavioral context, but it doesn't add detail on pagination, ordering, or open-world semantics beyond what annotations already provide. The description is consistent with the annotations.
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?
One sentence that states purpose and prerequisites without filler. The verb and resource are front-loaded, and the auth requirement is compactly appended.
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 list tool with 3 optional parameters and no output schema, the description covers the core purpose and auth, but omits pagination parameter semantics and any indication of the returned post fields. The openWorldHint and readOnlyHint annotations cover safety, but the missing count/start explanation leaves some ambiguity for agents needing pagination.
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 only 33% – count and start have no descriptions in either schema or description. Only organization_id is described in the schema, and the description only alludes to it via auth scopes. The description fails to clarify what count and start mean for pagination.
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 ('Lists') and resource ('recent posts by an author'), and clarifies the default author ('yourself'). This clearly distinguishes it from sibling tools like linkedin_get_post (single post) and linkedin_create_post (write operation).
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?
Provides auth prerequisites (r_member_social vs r_organization_social) and mentions the default self behavior, giving clear context on when it can run. It doesn't explicitly name alternatives or exclusions, but the scope requirements act as a usage condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
linkedin_react_to_postReact to a LinkedIn postAIdempotent
Adds a reaction (like, celebrate, support, …) to a post as yourself or an organization.
| Name | Required | Description | Default |
|---|---|---|---|
| post_urn | Yes | ||
| reaction | No | LIKE=Like, PRAISE=Celebrate, EMPATHY=Love, INTEREST=Insightful, APPRECIATION=Support, ENTERTAINMENT=Funny. | LIKE |
| organization_id | No | Post/act as this organization instead of yourself. Accepts a numeric id or urn:li:organization:<id>. Requires the Community Management API product. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds the actor-identity nuance but does not go deeper into behavior like idempotence consequences, permission requirements, or what happens if the reaction already exists. No contradiction with annotations.
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 description is a single, front-loaded sentence with no filler. It communicates the core action, the reaction types, and the actor scope efficiently.
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 simple operation with one required parameter and safety-relevant annotations already present, the description plus schema is sufficient for an agent to select and invoke the tool. It does not describe the return value or error conditions, but that is not essential for this kind of action without an output schema.
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 schema already documents the reaction enum and organization_id meaning, covering 67% of parameters. The description reinforces the reaction categories and organization mode, but it does not add much semantic detail for post_urn beyond the schema's pattern constraint.
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 uses a specific verb ('Adds a reaction') with a clear target ('to a post') and actor scope ('as yourself or an organization'). This cleanly distinguishes it from sibling tools like linkedin_create_post, linkedin_delete_post, and linkedin_comment_on_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?
The intended use is immediately clear: react to a LinkedIn post. The description also clarifies that the reaction can be performed as the user or an organization, which helps disambiguate the optional organization_id usage. It does not explicitly name alternative tools, but no sibling overlaps with reacting to a post.
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.
9 tool updates
v0.2.0- First observed
linkedin_comment_on_post - First observed
linkedin_create_post - First observed
linkedin_delete_post - First observed
linkedin_get_post - First observed
linkedin_get_post_stats - First observed
linkedin_get_profile - First observed
linkedin_list_organizations - First observed
linkedin_list_posts - First observed
linkedin_react_to_post
TDQS
Scored across 9 tools
Each tool targets a distinct resource-action pair: profile, post CRUD, organization listing, commenting, reacting, and stats. There is no overlap between getting a single post vs. listing posts, and comment/react/stats are clearly separate operations. The descriptions further clarify any potential boundary (e.g., get_post vs. list_posts).
All tools follow the same linkedin_<verb>_<noun> pattern with snake_case throughout. Each name starts with the domain prefix and then uses a clear action verb (get, create, delete, list, comment, react). Even the phrasal verbs like comment_on_post and react_to_post are internally consistent.
The 9 tools are well-scoped for a LinkedIn social API surface. The count covers profile verification, post management, engagement actions, and stats without being bloated. It sits comfortably in the ideal 3–15 range.
The tool set covers the core social workflow: create/read/delete posts, comment, react, and fetch stats. Missing operations like updating a post or listing individual comments/reactions are minor since LinkedIn edits are limited and stats provide summaries. No major dead ends exist for the stated purpose.
Maintenance
Related MCP Connectors
LinkedIn for AI agents: inbox, invitations, Sales Navigator search, posts. Quotas and webhooks.
Give AI agents the LinkedIn tools to find, qualify, engage, and follow up with prospects.
Full LinkedIn access for AI agents: leads, messaging, and campaigns with safe limits built in.
Write LinkedIn posts in your voice: ideas, drafts, scheduling, analytics from your personal AI.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables AI agents to manage LinkedIn profiles, posts, connections, skills, education, and certifications through the LinkedIn API.18176 npm64MIT
- AlicenseBqualityCmaintenanceEnables AI agents with read/write access to LinkedIn API, including profile, posts, media, organizations, comments, reactions, and analytics.2010 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with LinkedIn using the official API for profile access, company management, and job postings.Apache 2.0
- AlicenseAqualityBmaintenanceEnables AI agents to publish posts, images, videos, and articles to LinkedIn.10MIT