Skip to main content
Glama
sviera91

linkedin-mcp-server

by sviera91

LinkedIn MCP Server

A local-first Model Context Protocol (MCP) server for LinkedIn's official OAuth and REST APIs. Each user runs their own instance and supplies credentials from their own LinkedIn Developer app.

Capabilities

The server exposes these MCP tools:

Tool

Capability

linkedin_authenticate

Starts the local LinkedIn OAuth flow.

linkedin_auth_status

Checks whether a local LinkedIn access token is available.

linkedin_get_my_profile

Reads the authenticated member's OpenID profile and email.

linkedin_create_post

Publishes a text post to the authenticated member's LinkedIn profile. Publishing requires confirm=true.

linkedin_create_post_with_image

Uploads a local image and publishes it with a text post. Publishing requires confirm=true.

linkedin_reshare_post

Reshares an existing post with optional commentary. Requires confirm=true.

linkedin_create_comment

Creates a comment on a post. Requires confirm=true.

linkedin_react_to_post

Adds a reaction such as Like, Praise, Empathy, Interest, Appreciation, or Entertainment. Requires confirm=true.

linkedin_remove_reaction

Removes your reaction from a post. Requires confirm=true.

linkedin_edit_comment

Edits one of your comments. Requires confirm=true.

linkedin_delete_comment

Deletes one of your comments. Requires confirm=true.

linkedin_delete_post

Deletes one of your posts. Requires confirm=true.

The server uses LinkedIn's official APIs only. It does not scrape LinkedIn, use browser cookies, search arbitrary people, read messages, or export connections.

Related MCP server: @mhdd_24/linkedin-mcp

LinkedIn Developer App Setup

LinkedIn API access is controlled by LinkedIn. A copy of this project does not provide API access or bypass LinkedIn permissions; every user must create and configure their own Developer app.

1. Create or select an app and Company Page

Create an app in the LinkedIn Developer Portal and associate it with a LinkedIn Company Page. A personal developer can create a small development Company Page and associate the app with it.

The default individual-developer page may be enough for basic sign-in, but it can restrict additional API products. If you need to publish posts, use a Company Page that permits the required product access.

2. Add products

Scopes are enabled through products rather than by adding scopes individually:

  1. Open the app's Products tab.

  2. Request Sign In with LinkedIn using OpenID Connect.

  3. Request Share on LinkedIn.

  4. Confirm both products appear under Added products.

These products enable the scopes used by this server:

  • Sign In with LinkedIn using OpenID Connect enables openid, profile, and email.

  • Share on LinkedIn enables w_member_social, required for posting.

Product approval and availability are controlled by LinkedIn. If Share on LinkedIn is not approved, authentication with this server's default scope set will fail and posting will not work.

3. Register the redirect URL

In the app's Auth tab, add this exact Authorized redirect URL:

http://127.0.0.1:3000/oauth/callback

The scheme, host, port, and path must match exactly. localhost and 127.0.0.1 are different redirect URLs. If you use another local callback, set LINKEDIN_REDIRECT_URI to that value and register the exact same value in LinkedIn. The server permits only local localhost or 127.0.0.1 callbacks.

4. Copy credentials

From the app's Auth tab, copy the Client ID and Client Secret. Keep the Client Secret private.

Run locally

npm install
cp .env.example .env
# Edit .env and add the Client ID and Client Secret.
npm run build
npm start

The server uses stdio, which is the simplest transport for Copilot CLI and other MCP clients. It should normally be launched by the MCP client rather than opened as an interactive terminal application.

Configuration

Required variables:

LINKEDIN_CLIENT_ID=your-linkedin-client-id
LINKEDIN_CLIENT_SECRET=your-linkedin-client-secret

Optional variables:

Variable

Default

Purpose

LINKEDIN_REDIRECT_URI

http://127.0.0.1:3000/oauth/callback

Local OAuth callback; register the exact value in LinkedIn.

LINKEDIN_VERSION

202607

LinkedIn REST API version for /rest/* requests.

LINKEDIN_TOKEN_FILE

.data/linkedin-token.json

Local access-token file location.

MCP client configuration

Use an absolute path to the cloned repository:

{
  "mcpServers": {
    "linkedin": {
      "command": "node",
      "args": ["/absolute/path/to/linkedin-mcp-server/dist/server.js"],
      "env": {
        "LINKEDIN_CLIENT_ID": "your-client-id",
        "LINKEDIN_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}

Prefer the MCP client's secret or environment-variable facility instead of committing credentials to a configuration file.

Authenticate and use

  1. Start the MCP server through your MCP client.

  2. Call linkedin_authenticate.

  3. Open the returned LinkedIn authorization URL.

  4. Approve access.

  5. Call linkedin_auth_status.

  6. Call any of the tools above. Mutating tools require confirm=true.

Mutating tools require explicit confirmation to reduce accidental publishing or deletion. Example arguments:

{
  "commentary": "Hello from my LinkedIn MCP server.",
  "confirm": true
}

For social actions, provide the LinkedIn post URN returned by LinkedIn or a previous API response:

{
  "postUrn": "urn:li:share:123456789",
  "commentary": "Thanks for sharing this.",
  "confirm": true
}

The comment, reaction, reshare, edit, and delete tools operate on the specific post or comment identified by their URN/ID. They do not search LinkedIn or read your feed. The current default OAuth scopes support identity and member social actions, but do not provide general post-history, comment-history, messaging, people-search, or connections-read access.

LinkedIn controls access to individual API products and may change endpoint requirements. If a social-action call returns an authorization or scope error, check the app's enabled products and the permissions currently granted to the token; some newer feed APIs may require a feed-specific permission that is not included in the default w_member_social scope.

Troubleshooting

redirect_uri does not match the registered value

Register the exact callback URL shown above, or make sure LINKEDIN_REDIRECT_URI exactly matches the URL registered in LinkedIn. Check the hostname (127.0.0.1 versus localhost) and port.

invalid_scope_error

Verify that both required products are listed under Added products. If Share on LinkedIn is missing or not approved, w_member_social is unavailable and posting cannot succeed.

Re-authentication

Delete the local token file only when you intentionally want to authenticate again:

rm .data/linkedin-token.json

Then call linkedin_authenticate.

Security

  • Never commit .env or .data/.

  • The local token file is created with owner-only permissions.

  • Publishing requires explicit confirm=true.

  • Keep LinkedIn client secrets and tokens server-side.

  • Never paste credentials or token files into issues, pull requests, or public repositories.

Azure deployment plan

Azure is not required for the local version. Deploy only if the server must be available to multiple clients or run continuously.

A production deployment should use Azure Container Apps or App Service for the MCP HTTP service, Azure Key Vault for secrets and encryption keys, encrypted durable storage for tokens, a registered HTTPS redirect URL, and authentication and audit logging before exposing the service outside the local machine.

The local stdio transport should remain the default for personal Copilot use; an Azure deployment is a separate production transport and security boundary.

License

MIT. See LICENSE.

Available Tools

4 tools
linkedin_authenticateA

Start LinkedIn OAuth sign-in. Open the returned URL in a browser, approve access, then call linkedin_auth_status.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of disclosure. It explains that the tool returns a URL requiring browser interaction and that authentication is not complete until linkedin_auth_status is called. This is valuable behavioral context beyond what any structured field provides.

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 sentences, front-loaded with the purpose and followed by concise step-by-step guidance. Every word earns its place, with no redundancy 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 tool initiating a simple two-step OAuth flow, the description covers the essential workflow: initiating the sign-in, handling the returned URL, and proceeding to the status check. It could specify the response shape or error cases, but it is complete enough for an agent to act successfully.

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?

The tool has zero parameters, so there is no schema to explain. A baseline of 4 is appropriate given that the description does not need to compensate for missing parameter documentation.

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 'Start LinkedIn OAuth sign-in' with a specific verb and resource, unambiguously identifying the tool's function. It distinguishes itself from siblings like linkedin_auth_status (which checks status) and linkedin_get_my_profile (which fetches profile data).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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

The description provides explicit sequential instructions: open the returned URL, approve access, then call linkedin_auth_status. It names the next tool, effectively giving an alternative/next step and clarifying when to use this tool versus the status tool.

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

linkedin_auth_statusA

Check whether LinkedIn OAuth has completed and the local token is available.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior2/5

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

No annotations are present, so the description must disclose behavioral traits. It only states the function and lacks details on whether the check is read-only, whether it makes network calls, or what the return value looks like. This is insufficient for a tool with no 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 concise sentence, front-loaded with the verb 'Check' and clear about the resource. No wasted words.

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, but the description doesn't specify the return format or how to interpret the status (e.g., boolean vs. object), which would help an agent decide next steps. Adequate but has a clear gap.

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?

The tool has zero parameters, and the schema provides full coverage. The description adds no parameter details, but none are needed. Baseline 4 is appropriate for zero-parameter tools.

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 tool's function: checking LinkedIn OAuth completion and local token availability. This distinguishes it from siblings like linkedin_authenticate (initiating auth) and profile/post tools.

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 use is implied as a precondition check before other LinkedIn operations, but no explicit guidance or alternatives are provided. It does not suggest using linkedin_authenticate if auth is missing, though the context makes this inferable.

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

linkedin_create_postA

Publish a text post to the authenticated member's LinkedIn profile.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmYesMust be true to publish the post.
commentaryYesThe post text to publish.

TDQS

A3.7/5.0
Behavior2/5

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

No annotations are provided, so the description must convey behavioral implications. It states 'Publish' which indicates a mutating action, but does not disclose that the post becomes public, that the action is irreversible, or that there may be rate limits or permissions required. The confirm parameter hints at deliberate action, but the description itself adds no such context.

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 clear sentence that is front-loaded with the action and resource. Every word earns its place, and there is no redundancy or filler.

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?

Given the simplicity of the tool (two parameters, no output schema), the description covers the basic purpose. However, it lacks critical behavioral context such as irreversibility and public visibility, and it does not mention what the tool returns on success or failure. The schema covers parameters but not these operational aspects.

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 well-documented in the schema. The description adds no additional semantic meaning beyond what 'commentary' and 'confirm' already convey. Baseline 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 uses the specific verb 'Publish' and clearly identifies the resource as 'a text post to the authenticated member's LinkedIn profile.' It distinguishes itself from sibling tools which are about authentication and profile retrieval.

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 implies the tool is for posting text content to LinkedIn. It does not explicitly state when not to use it or mention alternatives, but among siblings it is the only posting tool, making the usage context clear enough.

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

linkedin_get_my_profileA

Read the authenticated LinkedIn member's OpenID profile and email.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden. It explicitly states 'Read', indicating a safe, non-destructive operation, and notes the data scope (OpenID profile and email). It adds context about authentication but does not detail response structure or error behavior, which would have raised it higher.

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, concise sentence of 10 words. It front-loads the action and resource without any wasted words or redundant detail, making it an exemplary concise description.

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?

Given the tool's simplicity (0 parameters, no output schema, no annotations), the description provides sufficient context: it names the resource, indicates authentication, and hints at return content. It lacks details on response format, but for a standard OpenID profile read, this is adequate.

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?

The input schema is empty with zero parameters, so there is nothing to explain. The baseline for 0 parameters is 4; the description adds no parameter-related information because none exists, which 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 ('Read') and the specific resource (the authenticated LinkedIn member's OpenID profile and email). This distinguishes it from siblings like 'linkedin_auth_status' (checking auth status) and 'linkedin_create_post' (creating content), making the purpose unambiguous.

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 the tool is used to retrieve profile/email data for the authenticated user, but it does not explicitly mention when not to use it or point to alternatives like 'linkedin_auth_status' for status checks. The usage is inferable but not explicitly framed.

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

TDQS

A4.2/5.0
Disambiguation5/5

Each tool addresses a distinct concern: authentication status, authentication initiation, profile retrieval, and post creation. There is no overlap in purpose.

Naming Consistency5/5

All tools use a consistent 'linkedin_' prefix followed by a clear verb_noun pattern (auth_status, authenticate, get_my_profile, create_post). Naming is uniform and predictable.

Tool Count5/5

Four tools is well-scoped for a LinkedIn integration server covering authentication, profile access, and posting. Each tool earns its place without redundancy.

Completeness4/5

The core workflow of authenticating, reading profile, and creating posts is covered. Minor gaps exist (e.g., no post deletion or feed reading), but these are not critical for the server's apparent primary purpose.

Maintenance

ActivityMaintained
ResponsivenessSyncing

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
    B
    maintenance
    Local-first MCP server for research on AI-assisted browsing of a user-owned professional-network account (e.g., LinkedIn), providing read-focused tools such as profile, company, search, and feed reads.
    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
    Not graded
    quality
    B
    maintenance
    MCP server that lets you publish text and image posts to LinkedIn, fetch your profile, and check auth status using natural language.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Remote MCP server for LinkedIn hosted on Azure Functions, enabling profile retrieval and post publishing through OAuth.
    214
    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/sviera91/linkedin-mcp-server'

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