Skip to main content
Glama
EgiStr

linkedin-mcp

by EgiStr

LinkedIn MCP Server

npm version License CI Node

MCP server for LinkedIn API integration — profiles, posts, feed, and connections.

Works with Claude Desktop, Cursor, Windsurf, Claude Code, OpenCode, and any MCP-compatible client.

Features

Tool

Description

Scope Required

linkedin_get_user_info

Get OpenID Connect user info

openid

linkedin_get_my_profile

Get full LinkedIn profile

openid + r_liteprofile

linkedin_create_post

Publish a LinkedIn post

w_member_social

linkedin_list_posts

List your/others' posts

r_member_social

linkedin_delete_post

Delete a LinkedIn post

w_member_social

linkedin_get_feed

Get your feed activity

r_member_social

linkedin_get_connections

Get your connections

Partner API

linkedin_send_message

Send a direct message

Partner API

linkedin_search_people

Search LinkedIn members

Partner API

linkedin_oauth_login

OAuth PKCE login flow

Related MCP server: linkedin-mcp-server

Quick Start

# Install from npm (recommended)
npx @eggisatriadev/linkedin-mcp

# Or install locally
npm install @eggisatriadev/linkedin-mcp

# Set your access token
export LINKEDIN_ACCESS_TOKEN=AQX_your_token_here

# Run the server
npx @eggisatriadev/linkedin-mcp

For Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "linkedin": {
      "command": "npx",
      "args": ["-y", "@eggisatriadev/linkedin-mcp"],
      "env": {
        "LINKEDIN_ACCESS_TOKEN": "AQX_your_token_here"
      }
    }
  }
}

For OpenCode

Add to your opencode.json:

{
  "mcpServers": {
    "linkedin": {
      "command": "npx",
      "args": ["-y", "@eggisatriadev/linkedin-mcp"],
      "env": {
        "LINKEDIN_ACCESS_TOKEN": "AQX_your_token_here"
      }
    }
  }
}

Setup

1. Create a LinkedIn Developer App

  1. Go to https://www.linkedin.com/developers/apps

  2. Create a new app

  3. Add products:

    • Sign In with LinkedIn using OpenID Connect (auto-approved)

    • Share on LinkedIn (for posting capabilities)

  4. Note your Client ID and Client Secret

  5. Add http://localhost:8080 as an OAuth redirect URL

2. Generate Access Token

The easiest way is to use the OAuth 2.0 token generator in the LinkedIn Developer Portal:

  1. Go to your app → Auth tab

  2. In OAuth 2.0 settings, find the access token section

  3. Select scopes: openid, profile, email, w_member_social

  4. Generate and copy the token

3. Run the Server

# Install dependencies
npm install

# Set your token
export LINKEDIN_ACCESS_TOKEN=AQX_your_token_here

# Build and run
npm run build
npm start

4. Connect to Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "linkedin": {
      "command": "node",
      "args": ["/absolute/path/to/linkedin-mcp-server/dist/index.js"],
      "env": {
        "LINKEDIN_ACCESS_TOKEN": "AQX_your_token_here"
      }
    }
  }
}

5. Connect to OpenCode

Add to your opencode.json (or use the MCP config):

{
  "mcpServers": {
    "linkedin": {
      "command": "node",
      "args": ["/absolute/path/to/linkedin-mcp-server/dist/index.js"],
      "env": {
        "LINKEDIN_ACCESS_TOKEN": "AQX_your_token_here"
      }
    }
  }
}

OAuth PKCE Login (No Token Required)

Skip step 2 — let the server handle authentication interactively:

# Required: set your LinkedIn app credentials
export LINKEDIN_CLIENT_ID=your_client_id
export LINKEDIN_CLIENT_SECRET=your_client_secret

# Run the server (it will detect no token and guide you)
npm run build
npm start

# Or from npm package:
npx @eggisatriadev/linkedin-mcp

Then call the linkedin_oauth_login tool from your MCP client:

  1. port (optional): Callback server port (default: 8080)

  2. open_browser (optional): Auto-open browser (default: true)

  3. timeout (optional): Max wait in ms (default: 120000)

The flow:

  1. Server starts a local HTTP server on port 8080

  2. Opens your browser to LinkedIn's authorization page

  3. You approve the request

  4. LinkedIn redirects to localhost — server captures the code

  5. Server exchanges the code for an access token via PKCE S256

  6. Token is saved to ~/.config/linkedin-mcp/config.json

  7. All tools immediately work without further setup

Media Upload

LinkedIn supports image upload via a 3-step /rest/images flow:

  1. Initialize: POST /rest/images?action=initializeUpload → returns uploadUrl + image URN

  2. Upload binary: PUT {uploadUrl} with image data

  3. Attach to post: Use the image URN as media.id in createPost()

Supported formats: JPEG, PNG, GIF (static) Max file size: 10 MB Recommended dimensions: 2048×2048px

Image upload happens automatically when you pass a media_url parameter to linkedin_create_post. The MediaUploader handles retries on expired upload URLs and validates format/size before uploading.

Development

# Watch mode (auto-reload)
npm run dev

# Build
npm run build

# Test with MCP Inspector
npm run inspector

Architecture

The server follows a layered architecture with four bounded contexts:

linkedin-mcp-server/
├── src/
│   ├── index.ts                 # Entry point: server init, tool registration, health check
│   ├── types.ts                 # Shared types and enums
│   ├── services/
│   │   └── linkedin-client.ts   # LinkedIn API client (14+ methods, error classification)
│   ├── tools/
│   │   ├── profile.ts           # Profile tools: getMyProfile, getUserInfo
│   │   ├── posts.ts             # Posts tools: createPost, listPosts, deletePost
│   │   ├── network.ts           # Network tools: getFeed, getConnections, sendMessage, searchPeople
│   │   └── auth.ts              # Auth tool: oauthLogin
│   ├── auth/
│   │   ├── oauth.ts             # PKCE OAuth 2.0 flow (RFC 7636)
│   │   ├── config.ts            # Config file management
│   │   └── token-store.ts       # Token persistence (env var → config file fallback)
│   └── media/
│       └── uploader.ts          # 3-step image upload: init → binary → URN
├── tests/
│   ├── linkedin-client.test.ts
│   ├── tools/
│   ├── auth/
│   └── media/
├── docs/
│   └── pocket/arch/*/tech-design.md   # Full technical design document
├── package.json
├── tsconfig.json
└── README.md

Token Resolution Chain

  1. LINKEDIN_ACCESS_TOKEN env var (highest priority)

  2. ~/.config/linkedin-mcp/config.json (persistent local token)

  3. OAuth PKCE flow (if LINKEDIN_CLIENT_ID + LINKEDIN_CLIENT_SECRET are set)

See tech-design.md for the full architecture, API contracts, data flow diagrams, and ADRs.

Contributing

We welcome contributions! See CONTRIBUTING.md for:

  • Bug reports & feature requests (GitHub Issues)

  • Development setup guide

  • Coding standards & test requirements

  • Pull request guidelines

This project adheres to a Code of Conduct.

Limitations

  • Connections API: Requires LinkedIn Partner Program (not available on free tier)

  • People Search: Not available via public API (needs Sales Navigator)

  • Messaging API: Requires LinkedIn Messaging API (partner program)

  • Feed: Limited by API restrictions

  • Rate Limits: 100-500 requests/day per app on free tier

License

MIT — see LICENSE for details.

Available Tools

10 tools
linkedin_create_postCreate a LinkedIn PostA

Create and publish a new LinkedIn post.

Publishes a text post to your LinkedIn feed. Supports PUBLIC, CONNECTIONS-only, or LOGGED_IN visibility settings.

Args:

  • text (string, required): Post content (1-3000 chars)

  • visibility ("PUBLIC" | "CONNECTIONS" | "LOGGED_IN"): Who can see the post (default: "PUBLIC")

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns (JSON format): { "postId": string, // Post ID "urn": string, // LinkedIn URN "text": string, // Text preview (first 100 chars) "visibility": string, // Visibility setting used "status": string, // Always "PUBLISHED" "url": string // Direct link to the post }

Requires scope: w_member_social (Share on LinkedIn product)

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already show this is a write and non-idempotent operation. The description adds meaningful behavioral context: it requires the w_member_social scope, always returns status 'PUBLISHED', and creates a publicly visible or restricted feed post. It does not mention rate limits or reversibility, but it does not contradict 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well structured with a one-line summary, Args, Returns, and a scope requirement. There is mild redundancy between the first sentence and the title, but the content is relevant and front-loaded.

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 that the schema declares no parameters and there is no output schema, the description is remarkably complete: purpose, parameters, defaults, visibility enum, return fields, and auth scop e are all present. An agent can call this tool and interpret the response without additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema is empty, so the description carries the full burden of parameter documentation. It defines text as required with a 1-3000 character constraint, provides the visibility enum with a default, and documents response_format with a default. This is complete and actionable for an agent.

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: 'Create and publish a new LinkedIn post.' It further clarifies that it publishes a text post to the user's feed and supports distinct visibility modes, making it easy to distinguish from siblings like linkedin_send_message or linkedin_delete_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 description gives clear context for when to use the tool: publishing a text post to the LinkedIn feed with PUBLIC, CONNECTIONS, or LOGGED_IN visibility. It does not explicitly name alternative tools or state when not to use it, so it stops short of full routing guidance, but the intended use case is unambiguous.

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
Destructive

Permanently delete a LinkedIn post by its ID or URN.

⚠️ DESTRUCTIVE — This action cannot be undone.

Args:

  • post_id (string, required): Post ID or URN (e.g., 'post-123' or 'urn:li:share:post-123')

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns (JSON format): { "postId": string, // The ID that was deleted "status": "DELETED", // Always "DELETED" "note": string // Warning about permanence }

Requires scope: w_member_social

ParametersJSON Schema
NameRequiredDescriptionDefault
post_idYesThe ID or URN of the post to delete (e.g., 'post-123' or 'urn:li:share:post-123')
response_formatNoOutput format: 'markdown' for human-readable or 'json' for machine-readablemarkdown

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint annotation, the description adds critical context: the deletion is permanent and cannot be undone, and it requires the w_member_social OAuth scope. This gives the agent meaningful behavioral information beyond what annotations already declare.

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 well-structured and dense with useful information: a clear opening warning, parameter list, return format, and required scope. Every section earns its place, and the destructive warning is front-loaded for immediate visibility.

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?

For a simple two-parameter destructive operation, the description is complete. It covers inputs, output shape, required scope, and permanence, and since there is no output schema, the explicit return example fills that gap.

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 100%, so the schema already documents both parameters. The description mostly repeats the schema details, providing the same examples for post_id and the same default for response_format, adding little new semantic 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?

The description opens with a specific verb and resource: 'Permanently delete a LinkedIn post by its ID or URN.' This clearly distinguishes the tool from sibling tools like linkedin_create_post and linkedin_list_posts, so an agent can select it 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 Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states the operation and prerequisites, but it does not explicitly say when to prefer this tool over alternatives or mention when not to use it. The destructive warning implies careful usage, but there is no routing to sibling tools such as listing posts first to get a valid post_id.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_connectionsGet LinkedIn ConnectionsA
Read-onlyIdempotent

Get the authenticated user's LinkedIn connections.

Lists your 1st-degree connections with pagination support.

Args:

  • start (number): Start index for pagination (default: 0)

  • count (number): Number of connections to return, max 50 (default: 10)

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns (JSON format): { "total": number, "count": number, "start": number, "has_more": boolean, "connections": [{ "id": string, // Member ID "name": string, // Display name "profileUrl": string // LinkedIn profile URL }] }

⚠️ NOTE: Connections API requires LinkedIn Partner Program access. Standard OAuth apps will receive an error message explaining the limitation.

ParametersJSON Schema
NameRequiredDescriptionDefault
countNoNumber of connections to return (max 50)
startNoStart index for pagination
response_formatNoOutput format: 'markdown' for human-readable or 'json' for machine-readablemarkdown

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already state readOnly/idempotent/non-destructive, but the description adds meaningful behavioral context beyond those: pagination behavior via start/count/has_more and the critical Partner Program limiation that standard OAuth apps will receive an error. This is genuinely useful risk disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the core purpose. The Args section is somewhat redundant with the schema, but the return-shape example and the Partner Program caveat ear their place, keeping the overall definition compact and scannable.

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?

For a read-only, non-destructive tool with no output schema, the description provides the return JSON shape, pagination fields, defaults, and a critical access limiation. Nothing an agent needs to select or invoke this tool correctly is missing.

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 documents all three parameters with defaults, constraints, and descriptions, so the description's Args section mostly repeats schema information. Baseline 3 is appropriate because schema coverage is 100% and the description adds no new semantic meaning beyond what the schema provides.

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: 'Get the authenticated user's LinkedIn connections,' and immediately clarifies it lists '1st-degree connections.' This clearly distinguishes it from sibling tools like list_posts or search_people by naming the exact data set being returned.

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 frames when this tool is appropriate: when you need the authenticated user's 1st-degree connections, with pagination. It does not explicitly name alternatives or exclusions, so it misses the top tier, but the context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_feedGet LinkedIn FeedA
Read-onlyIdempotent

Get recent activity from the authenticated user's LinkedIn feed.

Returns recent posts and activities from your network.

Args:

  • start (number): Start index for pagination (default: 0)

  • count (number): Number of items to return, max 50 (default: 10)

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns (JSON format): { "total": number, "count": number, "start": number, "has_more": boolean, "items": [{ "id": string, // Activity URN "actor": string, // Actor URN "time": string, // Human-readable timestamp "timestamp": number,// Unix timestamp ms "content": string // Content preview }] }

Note: LinkedIn's public API has limited feed access.

ParametersJSON Schema
NameRequiredDescriptionDefault
countNoNumber of feed items to return (max 50)
startNoStart index for pagination
response_formatNoOutput format: 'markdown' for human-readable or 'json' for machine-readablemarkdown

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry readOnlyHint, idempotentHint, and destructiveHint=false, so the description mainly adds extra context. It reveals that the feed belongs to the authenticated user, that results are paginated with has_more, and that LinkedIn's public API has limited feed access — useful behavioral nuance beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and then organized into Args and Returns sections. The Args block duplicates schema information somewhat, but the Returns block is valuable because there is no output schema, and the note about limited API access is non-redundant.

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?

For a read-only tool with full parameter annotations, the description provides everything needed to invoke it correctly: parameter meanings, defaults, output format options, a detailed return structure, and a caveat about API limitations. The absence of an output schema is compensated by the embedded JSON return example.

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 100%, so the input schema already fully documents all three parameters. The description restates start, count, and response_format with defaults and enums, but does not add meaningfully new semantics beyond what the schema provides.

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 names a specific verb and resource: 'Get recent activity from the authenticated user's LinkedIn feed.' It is clear about what the tool returns, but it does not explicitly differentiate itself from the sibling linkedin_list_posts, which could overlap conceptually with feed items.

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 intended usage is implied by the name and description: reading the authenticated user's feed vs. creating or sending LinkedIn content. However, there is no explicit guidance about when to prefer this tool over linkedin_list_posts or other siblings, and no exclusions are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_my_profileGet My LinkedIn ProfileA
Read-onlyIdempotent

Get the authenticated user's LinkedIn profile information.

Returns your full profile details including name, headline, vanity URL, profile picture, email, and locale. Combines both the OpenID Connect userinfo endpoint and the LinkedIn profile API.

Args:

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns (JSON format): { "id": string, // LinkedIn member ID "firstName": string, // First name "lastName": string, // Last name "fullName": string, // Full display name "headline": string, // Professional headline "vanityName": string, // Custom URL identifier "profileUrl": string, // Full LinkedIn URL "email": string, // Email address (if available) "pictureUrl": string, // Profile picture URL "locale": string // Locale setting }

Requires scope: openid + r_liteprofile (or r_basicprofile)

ParametersJSON Schema
NameRequiredDescriptionDefault
response_formatNoOutput format: 'markdown' for human-readable or 'json' for machine-readablemarkdown

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only and idempotent behavior. The description goes further by revealing that the tool combines the OpenID Connect userinfo endpoint and the LinkedIn profile API, requiring specific scopes, which is meaningful behavioral context beyond 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the main purpose and uses structured Args and Returns sections. It is a bit longer than strictly necessary due to duplicating the schema's parameter info, but the return-structure block earns its place since there is no output schema.

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?

With no output schema, the description compensates by enumerating every return field, the response format options, and scope requirements. It is complete enough for an agent to invoke the tool with confidence. Minor gaps like error scenarios or when email may be missing prevent a perfect score.

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 coverage is 100% and the schema already documents response_format with an enum, default value, and description. The description mostly restates that parameter. The detailed return-shape block is useful but relates more to output semantics than to deeper parameter meaning.

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 clearly specifies the verb 'Get' and resource 'the authenticated user's LinkedIn profile information,' and the details about full profile data and endpoint composition make the purpose apparent. However, it never explicitly differentiates itself from the sibling linkedin_get_user_info, so it stops short of full sibling distinction.

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 when to use the tool: whenever the authenticated user's own profile data is needed. It also notes the required OAuth scopes, which is valuable operational guidance, but it does not explicitly say when not to use this tool or name alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_get_user_infoGet LinkedIn User Info (OpenID Connect)A
Read-onlyIdempotent

Get basic user identity information via OpenID Connect.

This works with the minimal "openid" scope and returns:

  • sub (unique member ID for your app)

  • name, given_name, family_name

  • email (if "email" scope is granted)

  • picture

  • locale

Unlike getMyProfile, this always works even with minimal scopes.

Args:

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns (JSON format): { "sub": string, // Unique member ID "name": string, // Full name "givenName": string, // First name "familyName": string, // Last name "email": string, // Email address "emailVerified": boolean // Whether email is verified "picture": string, // Profile picture URL "locale": string // Locale }

Requires scope: openid (always available with Sign In with LinkedIn)

ParametersJSON Schema
NameRequiredDescriptionDefault
response_formatNoOutput format: 'markdown' for human-readable or 'json' for machine-readablemarkdown

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already mark this as read-only, idempotent, and non-destructive. The description adds behavioral context by disclosing the required 'openid' scope, noting that email is only returned if the 'email' scope is granted, and fully documenting the response shape. 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 well-structured and front-loaded: purpose first, then return fields, then sibling differentiation, then parameters/return example/scope. Every section earns its place and the prose is tight with no fluff, even though the JSON return example is somewhat detailed.

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?

Despite having no output schema, the description provides a full JSON return contract, covers the parameter, states the required scope, and clarifies behavior with minimal scopes. An agent has everything needed to invoke the tool correctly and understand what it will receive.

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 single parameter is already fully documented with 100% schema coverage, including enum values, default, and a concise description. The description's Args section merely restates this information without adding deeper semantics, so the 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 first sentence states a specific action and resource: 'Get basic user identity information via OpenID Connect.' It enumerates exactly which fields are returned and explicitly differentiates from getMyProfile via the minimal-scope guarantee, so an agent can distinguish it from its sibling tools.

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 a clear usage context by stating it 'always works even with minimal scopes' and contrasting it with getMyProfile. This tells the agent when to prefer this tool over the likely alternative, though it doesn't explicitly describe when to choose getMyProfile instead.

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

List LinkedIn posts for a member.

Returns posts published by the specified member (or the authenticated user by default). Posts are returned newest-first with pagination support.

Args:

  • member_id (string, optional): LinkedIn member ID (sub) to fetch posts for

  • start (number): Start index for pagination (default: 0)

  • count (number): Number of posts to return, max 50 (default: 10)

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns (JSON format): { "total": number, // Total posts available "count": number, // Posts in this response "start": number, // Current offset "has_more": boolean, // Whether more pages exist "next_offset": number, // Offset for next page "posts": [{ "id": string, // Post ID "text": string, // Post commentary/text "author": string, // Author URN "created": string, // Human-readable date "created_timestamp": number, // Unix timestamp ms "visibility": string,// Visibility setting "url": string // Direct link }] }

Requires scope: r_member_social or r_organization_social

ParametersJSON Schema
NameRequiredDescriptionDefault
countNoNumber of posts to return (max 50)
startNoStart index for pagination
member_idNoLinkedIn member ID (sub) to fetch posts for. Defaults to authenticated user
response_formatNoOutput format: 'markdown' for human-readable or 'json' for machine-readablemarkdown

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only and idempotent. The description goes well beyond that by disclosing pagination semantics, ordering (newest-first), scopes required (r_member_social/r_organization_social), and the exact JSON response structure including fields like total, has_more, and next_offset. There is 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 front-loaded with the core purpose, then provides structured Args and Returns sections that are dense but not verbose. Every section earns its place, especially the response JSON sample, which is essential because there is no output schema.

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?

The description is self-sufficient for an agent: it explains default behavior, member targeting, pagination, maximum count, output format options, required scopes, and the full response shape. Since no output schema exists, the detailed JSON return specification fills exactly that gap.

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 100%, so each parameter is already documented in the schema. The description's Args section largely repeats defaults and meanings already present in the schema (count max 50, start defalt 0, response_format enum), adding little semantic value beyond what the input schema provides.

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 clearly states the verb ('List') and resource ('LinkedIn posts for a member'), and specifies that it returns posts published by the specified member or the authenticated user by default. It does not explicitly contrast itself with sibling tools like linkedin_get_feed, so it stops short of full explicit sibling differentiation.

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 invocation context: it lists posts for a specified member, defaults to the authenticated user, and explains pagination behavior with start/count/next_offset. It does not explicitly state when to prefer this over linkedin_get_feed or linkedin_create_post, but the 'posts published by a member' framing makes the intended use obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_oauth_loginLogin to LinkedIn via OAuthA

Authenticate with LinkedIn using OAuth PKCE flow.

Opens your browser to LinkedIn's authorization page, captures the callback, exchanges the authorization code for an access token, and saves it to the config file for future use.

This is the recommended way to authenticate. Once complete, all other tools can use the saved token automatically.

Prerequisites:

  • LINKEDIN_CLIENT_ID environment variable set

  • LINKEDIN_CLIENT_SECRET environment variable set

  • A LinkedIn Developer App with "Sign In with LinkedIn using OpenID Connect" and "Share on LinkedIn" products configured

Args:

  • port (number, 1024-65535): Localhost port for the OAuth callback (default: 8080)

  • open_browser (boolean): Auto-open browser (default: true). Set false for headless.

  • timeout (number, 30000-600000): Max wait for callback in ms (default: 120000)

Returns: Confirmation message with token expiry and granted scopes.

ParametersJSON Schema
NameRequiredDescriptionDefault
portNoTCP port for the localhost callback server (default: 8080)
timeoutNoMaximum time in ms to wait for the OAuth callback (default: 120000)
open_browserNoWhether to automatically open the browser to LinkedIn (default: true). Set to false in headless environments.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no meaningful annotation guidance, the description carries full weight. It discloses that the tool opens a browser, captures the callback, exchanges the authorization code, and saves the token to the config file. It also mentions the return value and prerequisites, giving the agent a clear model of side effects and persistence behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a summary, prerequisites, args, and return value, and it front-loads the core purpose. It is more verbose than strictly necessary because the Args section duplicates the schema, but the extra context about prerequisites and token persistence earns its place.

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?

For an OAuth login tool with three optional parameters and no output schema, this description is complete. It explains the flow, side effects, prerequisites, parameter behavior, and what the caller receives. An agent can invoke this tool and understand the downstream consequence for all other tools without further guessing.

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 100%, so the schema already documents all parameters. The Args section mostly repeats the schema's names, ranges, defaults, and meanings, adding little beyond the schema. The only marginal addition is 'Set false for headless,' which is already effectively captured in the schema description.

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: 'Authenticate with LinkedIn using OAuth PKCE flow.' It further describes the end-to-end process, making it unmistakably distinct from the sibling data-operation tools like linkedin_create_post or linkedin_get_my_profile.

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 frames this as the recommended authentication step and notes that 'all other tools can use the saved token automatically,' which establishes when to use it. It also lists the required prerequisites. It does not explicitly name alternatives or exclusion conditions, but the context strongly implies this is the entry point for all other tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_search_peopleSearch LinkedIn People (Not Available)A
Read-onlyIdempotent

Search for LinkedIn members by keywords.

⚠️ NOTE: This tool is NOT available with standard OAuth apps. People search requires LinkedIn Sales Navigator API or a third-party provider.

This tool returns a clear error message explaining the limitation.

Args:

  • keywords (string, required): Search keywords (name, title, company, etc.)

  • start (number): Start index for pagination (default: 0)

  • count (number): Number of results (max 50, default: 10)

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

ParametersJSON Schema
NameRequiredDescriptionDefault
countNoNumber of results to return (max 50)
startNoStart index for pagination
keywordsYesKeywords to search for (name, title, company, etc.)
response_formatNoOutput format: 'markdown' for human-readable or 'json' for machine-readablemarkdown

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly and idempotent annotations, the description discloses a critical behavioral trait: it returns a clear error message explaining the limitation under standard OAuth. This prevents an agent from expecting real results and is a valuable addition.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The warning is front-loaded and the error behavior is stated clearly in a few sentences. The Args list is redundant with the schema but does not make the description unnecessarily long or unclear.

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?

For a tool whose observable behavior is to fail with a clear error, the description is complete: it explains availability constraints, required prerequisites, and expected error behavior. No output schema is needed because the tool does not return real search results under normal circumstances.

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 100%, so the parameters are already fully documented in the schema. The description's Args block largely repeats that information without adding semantic detail beyond what the schema provides.

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 identifies the tool as searching LinkedIn members by keywords, and immediately flags that it is not available with standard OAuth. The title also reinforces this limitation. This is a specific verb and resource, unambiguously differentiated from reading profiles or posts.

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 explicitly warns that the tool is NOT available with standard OAuth and explains that Sales Navigator API or a third-party provider is required. It gives clear when-not-to-use guidance, though it does not point to a specific sibling tool as an alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

linkedin_send_messageSend a LinkedIn Message (Partner API)A

Send a direct message to a LinkedIn member.

⚠️ NOTE: This tool is NOT available with standard OAuth apps. Direct messaging requires LinkedIn's Messaging API (partner program).

This tool returns a clear error message explaining the limitation.

Args:

  • recipient_id (string, required): LinkedIn member ID of the recipient

  • text (string, required): Message text (1-2000 chars)

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesMessage text content
recipient_idYesLinkedIn member ID of the recipient
response_formatNoOutput format: 'markdown' for human-readable or 'json' for machine-readablemarkdown

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds meaningful behavioral context beyond the annotations by warning that the tool is not available with standard OAuth apps and that it will return a clear error message explaining the limitation. This is valuable because it sets expectations that the call may fail in the current auth context. No contradiction with the annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured: purpose first, then an important warning, then a note about error behavior, then parameters. The Args section is somewhat redundant with the schema, but the overall layout is scannable and free of unnecessary filler.

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 tool with three flat params and no output schema, the description covers the parameters, required auth access, limitation behavior, and output format. It does not describe the shape of a successful response, but given the explicit statement that an error message will be returned under the common standard-OAuth setup, the context is adequately complete.

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 100%, so the schema already documents all parameters. The Args block restates the same information with only minor formatting details, such as '1-2000 chars', which duplicates the schema constraints. It adds no new semantic guidance like recipient ID format examples or message encoding details.

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 begins with a specific verb and resource: 'Send a direct message to a LinkedIn member.' This clearly distinguishes it from sibling tools like linkedin_create_post or linkedin_get_feed, which operate on different resources or actions.

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 the critical prerequisite: standard OAuth apps cannot use this tool, and Messaging API partner access is required. This tells the agent when the tool cannot be used, though it does not explicitly name alternative tools or direct the agent to alternatives when unavailable.

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. Dates show when Glama detected each change.

  1. 10 tool updatesv1.0.0
    • First observedlinkedin_create_post
    • First observedlinkedin_delete_post
    • First observedlinkedin_get_connections
    • First observedlinkedin_get_feed
    • First observedlinkedin_get_my_profile
    • First observedlinkedin_get_user_info
    • First observedlinkedin_list_posts
    • First observedlinkedin_oauth_login
    • First observedlinkedin_search_people
    • First observedlinkedin_send_message

TDQS

A4/5.0
Disambiguation4/5

Most tools clearly target distinct actions and resources, but linkedin_get_my_profile and linkedin_get_user_info overlap in profile identity purposes, and linkedin_list_posts vs linkedin_get_feed could be confused as both return content. The unavailable tools are clearly labeled with limitation messages, which reduces ambiguity.

Naming Consistency5/5

All tools follow a consistent linkedin_verb_noun pattern with snake_case throughout, e.g., create_post, list_posts, delete_post, get_feed. The oauth_login tool fits the same pattern and does not introduce stylistic inconsistency.

Tool Count4/5

Ten tools is a reasonable size for a LinkedIn MCP server and the scope is understandable. However, three tools (send_message, get_connections, search_people) are non-functional placeholders for standard OAuth users, slightly reducing the effective surface.

Completeness3/5

The server covers authentication, profile retrieval, post creation, listing, and deletion, but lacks post updating, comments, reactions, and other common LinkedIn interactions. Several advertised tools are unavailable without partner access, leaving notable gaps in messaging, connections, and search.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with LinkedIn tools and services through the Universal MCP framework, allowing operations like posting and profile management via natural language.
    1
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    MCP server that posts to LinkedIn through the LinkedIn API. Enables creating text posts on your LinkedIn profile using natural language from any MCP-compatible client.
    3
    ISC
  • A
    license
    A
    quality
    D
    maintenance
    Enables searching and scraping of LinkedIn profiles, companies, jobs, and posts using natural language through MCP-compatible AI clients.
    13
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/EgiStr/linkedin-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server