LinkedIn MCP Server
This server is an MCP toolkit for interacting with the LinkedIn API, with OAuth session management, capability awareness, and explicit dry-run write workflows.
OAuth & session management:
auth_start,auth_poll,auth_finish,auth_refresh,auth_set_access_token,auth_set_role_hints,auth_status,auth_clearfor handling LinkedIn authentication and token state.Capability inspection:
list_tool_catalog,list_endpoint_manifest,list_capabilities,can_execute_toolto see what tools are available and whether they can run against current permissions.Raw API helpers:
linkedin_getandlinkedin_postfor arbitrary authenticated GET/POST requests to LinkedIn REST endpoints.Identity & organization access:
whoami,get_member_profile,list_accessible_organizationsto resolve the current principal and org ACLs.Posts:
create_post(preview by default),get_post,delete_post, pluslist_comments,create_commentfor social action interactions.Reactions:
list_reactions,create_reaction,delete_reactionfor managing social reactions.Media uploads:
initialize_media_uploadandfinalize_media_uploadfor image/video asset workflows, with preview by default.Advertising:
list_ad_accounts,list_campaign_groups,create_campaign_group,list_campaigns,create_campaign,update_campaign,get_ad_analyticsfor ad account/campaign management and analytics.Safety-oriented writes: Most mutating tools default to
execute=falseso you can preview requests before actually calling LinkedIn APIs.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@LinkedIn MCP Server Draft a LinkedIn post about our new product launch and show me the preview."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
LinkedIn MCP Server
Project
A Model Context Protocol (MCP) server that provides a practical, capability-aware LinkedIn API toolset to AI agents such as opencode, Claude, Cursor, and other MCP clients.
Related MCP server: LinkedIn MCP Server
Table of Contents
Why another LinkedIn MCP server?
Feature domain | stickerdaniel/linkedin-mcp-server | southleft/linkedin-mcp | linkedin-mcp |
OAuth code flow | ✅ Browser-based auth code exchange | ✅ OAuth 2.0 code flow | ✅ Full |
Write preview mode | ❌ (no dry-run default) | ❌ (no dry-run default) | ✅ All write tools default to |
Ads/campaign management | ❌ Not supported | ❌ Not supported | ✅ |
Media upload workflow | ❌ Not supported | ❌ Not supported | ✅ |
Comment/reaction tools | ✅ Basic comment and reaction support | ✅ Basic comment and reaction support | ✅ |
Direct messaging | ✅ (with session browser) / ⚠️ ToS violation via browser scraping | ✅ (with session browser) / ⚠️ ToS violation via browser scraping | ❌ Not included (requires Sales Navigator/partner approval / |
What it provides
Current scaffold includes:
OAuth code flow for interactive browser login (
auth_start->auth_finish)token bootstrap and refresh helpers
per-tool capability matrix in
src/linkedin_mcp/tool_catalog.jsonraw authenticated helpers for fast endpoint expansion
wrapped tools for profile, org ACLs, posts, comments, reactions, media upload, and ads
Getting started
You need an MCP-capable client (opencode, Claude Desktop, Cursor, etc).
LinkedIn app registration
Open the LinkedIn Developer portal and create a new app.
In app auth settings, add an OAuth redirect URL, for example
http://127.0.0.1:8765/callback.Copy
Client IDandClient Secretinto your environment.Under products/scopes, request only what you need now (start with sign-in scopes).
Ensure the redirect URL in app settings exactly matches
LINKEDIN_REDIRECT_URI.
1. Install
Option A - local editable install (recommended for development)
Requirements: Python 3.10+.
pip install -e .
linkedin-mcp-fullOption B - uvx from source folder
Requirements: uv (uvx) and a local clone of this repository.
uvx --from . linkedin-mcp-full2. Configure environment
Copy .env.example and set values (or export directly in shell).
Required variables (and usually the only ones you need):
LINKEDIN_CLIENT_IDLINKEDIN_CLIENT_SECRETLINKEDIN_REDIRECT_URI(example:http://127.0.0.1:8765/callback)
3. Register with your MCP client
Example for opencode (~/.config/opencode/opencode.json):
{
"mcp": {
"linkedin": {
"type": "local",
"enabled": true,
"command": ["uvx", "--from", "git+https://github.com/oliverhruby/linkedin-mcp.git", "linkedin-mcp-full"],
"env": {
"LINKEDIN_CLIENT_ID": "{env:LINKEDIN_CLIENT_ID}",
"LINKEDIN_CLIENT_SECRET": "{env:LINKEDIN_CLIENT_SECRET}",
"LINKEDIN_REDIRECT_URI": "{env:LINKEDIN_REDIRECT_URI}"
}
}
}
}
Restart your MCP client after config changes.Prompt examples
User prompt | Likely tool call(s) | Expected response |
"Start LinkedIn login" |
| Authorization URL + state + listener details |
"Search for company updates" |
| Organization ACL visibility |
"Create a post preview" |
| Dry-run request payload |
"Create the post now" |
| API write result |
"List my campaigns" |
| Ad campaigns list |
"Get ad analytics" |
| Ad analytics data |
"List my reactions" |
| Reactions for a social action |
"Check account capabilities" |
| Per-tool availability with missing scopes/roles |
Tool reference
Tool | Description | Writes? |
| Build OAuth URL and optional local callback listener | ✅ session |
| Poll pending OAuth callback state | |
| Exchange auth code for access token | ✅ session |
| Refresh access token | ✅ session |
| Manual token bootstrap | ✅ session |
| Set local role hints used for gating | ✅ session |
| Show active session metadata | |
| Clear in-memory session and pending OAuth states | ✅ session |
| Show tool capability metadata | |
| Show endpoint coverage scaffold | |
| Show effective per-tool availability | |
| Check one tool against current capabilities | |
| Raw authenticated GET helper | |
| Raw authenticated POST helper | ✅ |
| Resolve current principal profile endpoint | |
| Fetch member profile | |
| Fetch organization ACL visibility | |
| Create post ( | ✅ |
| Fetch post by URN | |
| Delete post ( | ✅ |
| Fetch comments for social action path | |
| Create comment ( | ✅ |
| Fetch reactions for social action path | |
| Create reaction ( | ✅ |
| Delete reaction ( | ✅ |
| Initialize media upload workflow ( | ✅ |
| Finalize media upload workflow ( | ✅ |
| List ad accounts (approval gated) | |
| List ad campaign groups | |
| Create ad campaign group ( | ✅ |
| List ad campaigns | |
| Create ad campaign ( | ✅ |
| Update ad campaign ( | ✅ |
| Fetch ad analytics (approval gated) |
Data & safety notes
Write tools are explicit and default to dry-run where feasible.
Capability checks prevent many avoidable permission failures.
API behavior still depends on LinkedIn app approvals and user/org roles.
Limitations
This is a scaffold-first implementation, not complete LinkedIn API coverage.
LinkedIn API availability depends on app-level approvals and account roles.
Token persistence is currently in-memory; restart requires re-auth or env token.
License
MIT © Oliver Hrubý
Available Tools
34 toolsauth_clearA
Clear active session from memory.
Inputs: no named parameters. Returns: object
auth_finishC
Exchange authorization code for token and activate session.
Inputs: state (required), code, client_secret. Returns: object
auth_pollB
Poll pending OAuth state for callback status and auth code availability.
Inputs: state (required). Returns: object
auth_refreshC
Refresh access token using refresh token from session or argument.
Inputs: client_id, client_secret, refresh_token. Returns: object
auth_set_access_tokenC
Set active LinkedIn access token and optional capability hints.
Inputs: access_token (required), source, expires_at, member_urn, +2 more. Returns: object
auth_set_role_hintsC
Update role hints used by capability gating.
Inputs: role_hints_csv (required). Returns: object
auth_startC
Start OAuth authorization by generating URL and optional localhost callback listener.
Inputs: client_id, scopes_csv, open_browser, redirect_uri, +1 more. Returns: object
auth_statusB
Return current session status.
Inputs: no named parameters. Returns: object
can_execute_toolB
Check whether a tool is available under current scope and role hints.
Inputs: tool_name (required). Returns: object
create_campaignB
Create ad campaign. Preview by default.
Inputs: path, execute, body_json. Returns: object
create_campaign_groupC
Create campaign group. Preview by default.
Inputs: path, execute, body_json. Returns: object
create_commentB
Create comment at provided endpoint path. Preview by default.
Inputs: path (required), body_json (required), execute. Returns: object
create_postA
Create a simple text post. Preview by default; set execute=true to send.
Inputs: author_urn (required), commentary (required), execute, visibility, +1 more. Returns: object
create_reactionB
Create reaction at provided endpoint path. Preview by default.
Inputs: path (required), body_json (required), execute. Returns: object
delete_postA
Delete a post by URN. Preview by default.
Inputs: post_urn (required), execute. Returns: object
delete_reactionB
Delete reaction using full endpoint path. Preview by default.
Inputs: path (required), execute. Returns: object
finalize_media_uploadC
Finalize media upload workflow for image/video assets. Preview by default.
Inputs: path (required), body_json (required), execute. Returns: object
get_ad_analyticsC
Fetch ad analytics with custom query payload.
Inputs: path, query_json. Returns: object
get_member_profileC
Get member profile using /v2/userinfo or member-specific endpoint if provided.
Inputs: member_urn. Returns: object
get_postB
Get a post by URN.
Inputs: post_urn (required). Returns: object
initialize_media_uploadC
Initialize media upload workflow for image/video assets. Preview by default.
Inputs: path (required), body_json (required), execute. Returns: object
linkedin_getC
Raw authenticated GET helper.
Inputs: path (required), query_json, api_version. Returns: object
linkedin_postC
Raw authenticated POST helper.
Inputs: path (required), body_json, api_version. Returns: object
list_accessible_organizationsC
List organizations where current user has admin-like roles.
Inputs: path. Returns: object
list_ad_accountsC
List ad accounts (approval-gated capability).
Inputs: path. Returns: object
list_campaign_groupsC
List ad campaign groups.
Inputs: path, query_json. Returns: object
list_campaignsC
List ad campaigns.
Inputs: path, query_json. Returns: object
list_capabilitiesA
Return effective capabilities for current session hints.
Inputs: no named parameters. Returns: object
list_commentsC
List comments for a resource path, e.g. /rest/socialActions/{urn}/comments.
Inputs: path (required), query_json. Returns: object
list_endpoint_manifestA
List endpoint coverage scaffold for drift tracking.
Inputs: no named parameters. Returns: object
list_reactionsB
List reactions for a resource path, e.g. /rest/socialActions/{urn}/reactions.
Inputs: path (required), query_json. Returns: object
list_tool_catalogB
List tool capability metadata used by approval-aware clients.
Inputs: no named parameters. Returns: object
update_campaignC
Update ad campaign fields. Preview by default.
Inputs: path (required), body_json (required), execute. Returns: object
whoamiB
Resolve current principal using a configurable profile endpoint.
Inputs: path. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 34 tools
Most tools are clearly separated by resource and action, such as list_campaigns and create_comment. However, whoami overlaps with get_member_profile, and the capability/metadata tools (list_tool_catalog, list_capabilities, list_endpoint_manifest, can_execute_tool) have fuzzy boundaries that could cause an agent to pick the wrong one.
The dominant snake_case style is readable and mostly follows a verb_noun pattern like list_campaigns and create_post. But the set mixes conventions with one-word whoami, noun_verb linkedin_get/linkedin_post, and auth_* tools that resemble domain-prefixed verbs or nouns, making the pattern inconsistent.
34 tools is too many for an agent to navigate efficiently, especially with 8 auth tools, 4 capability/metadata tools, and raw HTTP helpers padding the surface. The broad LinkedIn scope justifies some size, but several utility tools could be consolidated or removed.
Core workflows for posts, comments, reactions, media upload, and ad campaigns are represented, and raw linkedin_post can fill some gaps. However, there is no update_post, no delete_comment, and no semantic tool to attach uploaded media to a post, leaving notable lifecycle dead ends.
Maintenance
Related MCP Connectors
LinkedIn actions for AI agents: search, messaging, posts and invites, as hosted MCP tools.
LinkedIn for AI agents: search people, read profiles, posts and connections via a connected account
LinkedIn for AI agents: inbox, invitations, Sales Navigator search, posts, jobs, quotas, webhooks.
LinkedIn jobs, companies and people for AI agents, plus messages and invites via your own account.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI agents to manage professional networking on LinkedIn by providing tools for posting updates, searching for jobs, and analyzing profiles. It facilitates secure interaction with the LinkedIn platform through OAuth 2.0 authentication and the Model Context Protocol.1734 PyPI12MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to interact with LinkedIn for posting, commenting, liking, and managing connections via OAuth2 authentication.26 npmMIT
- AlicenseBqualityCmaintenanceEnables AI agents to manage LinkedIn profiles, posts, connections, skills, education, and certifications through the LinkedIn API.18176 npm64MIT
- AlicenseBqualityCmaintenanceEnables AI agents with read/write access to LinkedIn API, including profile, posts, media, organizations, comments, reactions, and analytics.207 npmMIT