Skip to main content
Glama
vlpmedialtd

linkedin-mcp

by vlpmedialtd

linkedin-mcp

CI License: MIT

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

#AI becomes a clickable hashtag; special characters are escaped automatically

✅ 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 r_member_social to approved partners

❌ 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)

  1. 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.

  2. Open https://www.linkedin.com/developers/appsCreate app, pick that Page, upload any logo.

  3. Settings tab → Verify the app with the Page. As the Page admin you approve it yourself.

  4. 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.

  5. Auth tab → Authorized redirect URLs for your app → pencil icon → Add redirect URL → paste exactly

    http://localhost:8787/callback

    and click Update. It must be http (not https), localhost (not 127.0.0.1), with no trailing slash.

  6. 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 auth
  1. LinkedIn Client ID: → paste the Client ID, press Enter

  2. LinkedIn 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.

  3. Your browser opens → click Allow

  4. 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>, press Ctrl+C and 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-mcp

Check 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 http

It 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 cloudflared
cloudflared tunnel --url http://localhost:3000

Copy the https://….trycloudflare.com address it prints. ngrok (ngrok http 3000) works the same way.

3. Add the app in ChatGPT

  1. ChatGPT → Settings → Security and login → turn on Developer mode.

  2. Go to Plugins (apps) → + to create a developer-mode app for a remote MCP server.

  3. MCP server URL: your tunnel address + /mcp/ + your secret, e.g. https://blue-sky-1234.trycloudflare.com/mcp/Xy7…

  4. Authentication: No authentication. The secret in the URL protects the server.

  5. 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.0 on any Node host (VPS, Railway, Render, Fly.io …) with LINKEDIN_ACCESS_TOKEN and MCP_AUTH_TOKEN set 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.png with 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 auth again.

  • 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 dquote> or zsh: no matches found

A value was pasted directly behind the command. Press Ctrl+C, run only npx -y github:vlpmedialtd/linkedin-mcp auth, then paste values at the prompts.

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 http://localhost:8787/callback and click Update. Watch for https, 127.0.0.1, a trailing / or spaces. Then press Ctrl+C and run auth again.

Token exchange failed (401): invalid_client

The Client Secret is wrong. If it says received 14 characters, you pasted the Client ID again. Copy Primary Client Secret with the copy icon (or generate a new one) and run auth again.

Browser: unauthorized_scope_error

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.

No LinkedIn access token found

auth didn't finish. Run it again and wait for ✔ Token saved to …. No restart of your MCP client is needed; the token is read on every call.

The stored LinkedIn access token expired

60 days are over. Run auth again.

auth still shows old behaviour

npx cached an old version. Run rm -rf ~/.npm/_npx and try again.

EADDRINUSE on port 8787

Something else uses the port. Run export LINKEDIN_REDIRECT_URI=http://localhost:8788/callback, register that URL in the app, then run auth.

LinkedIn API 403 on reading posts or stats

Expected for personal profiles: reading needs r_member_social, which LinkedIn doesn't grant to regular apps.

LinkedIn API 426 / version errors

Set LINKEDIN_API_VERSION to a current YYYYMM month (LinkedIn supports each version for about a year).

ChatGPT: "Error creating connector" / 401

Check the URL: tunnel address + /mcp/ + the secret the server printed. Is the http server still running?

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: linkedin not listed / not connected

Run claude mcp list. Re-add with the command from step 3a and start a new session.

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

linkedin_get_profile

Name, email, picture and person URN of the signed-in member

openid profile email

linkedin_create_post

Publish a text post, optionally with link preview (link_url) or image (image)

w_member_social

linkedin_delete_post

Delete a post you authored

w_member_social

linkedin_comment_on_post

Comment on a post

w_member_social

linkedin_react_to_post

React to a post

w_member_social

linkedin_get_post

Fetch a post by URN

r_member_social* / r_organization_social

linkedin_list_posts

List recent posts

r_member_social* / r_organization_social

linkedin_get_post_stats

Like and comment summary

r_member_social* / r_organization_social

linkedin_list_organizations

Pages you administer

rw_organization_admin

* 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

LINKEDIN_ACCESS_TOKEN

Access token; takes precedence over the token file (useful for hosting)

LINKEDIN_CLIENT_ID / LINKEDIN_CLIENT_SECRET

prompted

Used by auth

LINKEDIN_REDIRECT_URI

http://localhost:8787/callback

Must match the app's Auth settings

LINKEDIN_SCOPES

openid profile email w_member_social

Scopes requested by auth

LINKEDIN_API_VERSION

202608

LinkedIn-Version header (YYYYMM)

LINKEDIN_TOKEN_FILE

~/.config/linkedin-mcp/token.json

Token storage

MCP_AUTH_TOKEN

generated

Secret for the HTTP endpoint

PORT / HOST

3000 / 127.0.0.1

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-token

HTTP 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:

  1. Create a separate LinkedIn app. LinkedIn requires the Community Management API to be the only product in its app.

  2. Request Community Management API (LinkedIn reviews the request).

  3. 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 auth
  4. Ask "Which LinkedIn pages do I manage?", then "Post … on page 12345".


Security

  • Tokens and the HTTP secret are stored locally with 600 permissions and are never logged.

  • The Client Secret is only used during auth and 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.1 by 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 interactively
src/
  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 suites

Issues 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 tools
linkedin_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
post_urnYes
organization_idNoPost/act as this organization instead of yourself. Accepts a numeric id or urn:li:organization:<id>. Requires the Community Management API product.

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesPost text (max 3000 characters).
imageNoAttach an image: absolute local file path or http(s) URL (JPG, PNG, GIF). Cannot be combined with link_url.
link_urlNoAttach a link preview to this URL.
link_titleNoTitle for the link preview.
visibilityNoPUBLIC (anyone), CONNECTIONS (members only, not for organizations), LOGGED_IN (signed-in members).PUBLIC
image_alt_textNoAlt text for the image.
organization_idNoPost/act as this organization instead of yourself. Accepts a numeric id or urn:li:organization:<id>. Requires the Community Management API product.
convert_hashtagsNoConvert #words into LinkedIn hashtags.
link_descriptionNoDescription for the link preview.

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 postA
DestructiveIdempotent

Deletes a post you (or your organization) authored. Irreversible — confirm with the user first.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_urnYesURN of the post, e.g. urn:li:share:123 or urn:li:ugcPost:123.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 postA
Read-only

Fetches a single post by URN. Reading member posts requires the r_member_social permission (restricted); organization posts require r_organization_social.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_urnYes

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 postA
Read-only

Returns the like and comment summary of a post (socialActions).

ParametersJSON Schema
NameRequiredDescriptionDefault
post_urnYes

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 profileA
Read-only

Returns the authenticated member's basic profile (name, email, picture) and their person URN. Use this to verify the connection.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 organizationsA
Read-only

Lists LinkedIn company pages the authenticated member administers (Community Management API, scope rw_organization_admin).

ParametersJSON Schema
NameRequiredDescriptionDefault
roleNoADMINISTRATOR

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 postsA
Read-only

Lists recent posts by an author (default: yourself). Requires r_member_social (restricted) for members or r_organization_social for organizations.

ParametersJSON Schema
NameRequiredDescriptionDefault
countNo
startNo
organization_idNoPost/act as this organization instead of yourself. Accepts a numeric id or urn:li:organization:<id>. Requires the Community Management API product.

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 postA
Idempotent

Adds a reaction (like, celebrate, support, …) to a post as yourself or an organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
post_urnYes
reactionNoLIKE=Like, PRAISE=Celebrate, EMPATHY=Love, INTEREST=Insightful, APPRECIATION=Support, ENTERTAINMENT=Funny.LIKE
organization_idNoPost/act as this organization instead of yourself. Accepts a numeric id or urn:li:organization:<id>. Requires the Community Management API product.

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 9 tool updatesv0.2.0
    • First observedlinkedin_comment_on_post
    • First observedlinkedin_create_post
    • First observedlinkedin_delete_post
    • First observedlinkedin_get_post
    • First observedlinkedin_get_post_stats
    • First observedlinkedin_get_profile
    • First observedlinkedin_list_organizations
    • First observedlinkedin_list_posts
    • First observedlinkedin_react_to_post

TDQS

A4.1/5.0

Scored across 9 tools

Disambiguation5/5

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).

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers