linkedin-mcp
Click on "Install 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-mcpSearch for remote Python jobs and match them to my profile."
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
An MCP (Model Context Protocol) server for LinkedIn and job hunting: authenticate via OAuth 2.0, read your profile, draft and analyze posts with an LLM, publish posts to your feed, search free job boards, and track applications — all through tools any MCP client (Claude, Cursor, custom agents) can call.
User / agent
│ (MCP: stdio or streamable HTTP)
▼
linkedin-mcp (FastMCP + FastAPI)
│ ├── LinkedIn OAuth 2.0 (authorization code + refresh)
│ ├── LinkedIn REST API (profile, email, create post)
│ ├── Job boards (Remotive · Arbeitnow · RemoteOK · Jobicy — keyless)
│ ├── Application tracker (local JSON store)
│ └── LLM provider layer (Grok · OpenAI · Ollama · unorouter — swappable via env)
▼
LinkedIn API / job board APIs / your LLM providerWhat's implemented (Phase 1 + a taste of Phase 3)
Tool | What it does |
| Check OAuth state; returns the login URL or a clear "what's missing" message |
| Member profile (name, picture, locale, email) via OpenID Connect |
| Member email (requires the |
| Publish a text or image post via the current Posts API ( |
| Generate a LinkedIn post with the configured LLM provider |
| Expert critique + suggested rewrites of a draft via the LLM |
| Search Remotive/Arbeitnow/RemoteOK/Jobicy — free, keyless, no LinkedIn permissions |
| LLM-scored fit for listings from |
| One call → fit assessment + cover letter + recruiter DM + interview prep |
| Save an application locally (company, role, URL, status, notes) |
| List tracked applications, filterable by status |
| Move an application along: saved → applied → interview → offer/rejected |
| Prioritized view of what needs action next |
| Compare a job description against your profile: fit score, gaps, talking points |
| Tailored cover letter or recruiter DM from a job description + your profile |
| Open-to-work / job-search announcement post |
| Queue a post to be published automatically at a future time |
| List queued posts, filterable by status |
| Remove a queued post before it publishes |
| Publish a queued post immediately (handy for testing) |
Resource | Profile exposed as an MCP resource |
Job search & application tracking
LinkedIn offers no public jobs API, so search goes through four free keyless boards (verified live): Remotive, Arbeitnow, RemoteOK, and Jobicy. The typical agent flow:
search_jobs("python fastapi") → match_jobs_to_profile(listings)
→ prepare_application(jd) → track_application(...)
→ draft_job_post(...) → create_post / schedule_postApplications are stored in .data/applications.json (gitignored). Board outages
never break a search: each board's error is reported per-board under board_errors.
Image posts
Pass a local JPG/PNG/GIF path to create_post (or schedule_post): the file is
uploaded through LinkedIn's Images API (/rest/images?action=initializeUpload →
signed PUT → referenced by urn:li:image: URN in the post) and published with
optional alt_text.
Post scheduling
schedule_post stores the post in .data/scheduled_posts.json; while the web
server is running it polls every SCHEDULER_POLL_SECONDS (default 30 s) and
publishes posts whose time has arrived. publish_at is ISO-8601 — naive values
are treated as UTC, or include an offset (e.g. 2026-09-05T15:30:00+05:30).
Failures (e.g. token expired) are recorded on the entry as status="failed" with
the error, so list_scheduled_posts shows exactly what happened.
Everything the LLM does goes through a provider-agnostic layer — you switch vendors by changing one env var, no code changes:
LLM_PROVIDER=grok # or: openai | ollama | unorouterRelated MCP server: LinkedIn MCP Zero
Prerequisites
Python 3.11+ (tested on 3.12)
A LinkedIn Developer account
An LLM provider key (or a local Ollama install — free)
Step 1 — Create the LinkedIn Developer App
Go to https://www.linkedin.com/developers → Create app.
Fill in the basics (name, LinkedIn Page, logo) and create it.
In Products, request:
Sign In with LinkedIn using OpenID Connect — grants
openid,profile,emailShare on LinkedIn — grants
w_member_social, required to post
In Auth, note your Client ID and Client Secret, and add the Authorized redirect URL:
(For production you'll use your deployed HTTPS URL instead — Phase 2.)
Step 2 — Configure
python -m venv .venv
source .venv/Scripts/activate # Git Bash on Windows; on macOS/Linux: .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env # then fill in the values.env essentials:
LINKEDIN_CLIENT_ID=your-client-id
LINKEDIN_CLIENT_SECRET=your-client-secret
LLM_PROVIDER=grok
GROK_API_KEY=your-xai-keyAbout xAI billing: xAI currently does not accept Indian payment cards for its API. If that's a blocker, just set
LLM_PROVIDER=openaiorLLM_PROVIDER=ollama— nothing else changes.
Step 3 — Run
Web mode (personal dashboard UI + OAuth + MCP over HTTP):
python -m linkedin_mcp web
# or: uvicorn linkedin_mcp.app:app --reloadOpen http://localhost:8000/ for the personal dashboard — no MCP client needed:
Compose & publish posts with an image picker, or schedule them for later
Upload documents (PDF/DOCX/TXT/MD, 10 MB max) — mark your resume as profile and every job-matching tool uses your real skills instead of bare profile metadata
Job search across the four boards + one-click LLM match against your profile
Application tracker with status buttons (saved → applied → interview → …)
Live scheduled-posts list with publish-now / cancel
The MCP endpoint is still available for clients at:
http://localhost:8000/mcp/Stdio mode (for Claude Desktop / local MCP clients):
python -m linkedin_mcpStep 4 — Connect an MCP client
Claude Desktop / Claude Code claude mcp add example (streamable HTTP):
claude mcp add linkedin --transport http http://localhost:8000/mcp/Or, from any JSON-RPC client, call auth_status first — it tells you exactly what's
missing (credentials, login, tokens) instead of failing blindly.
OAuth & token handling
Authorization-code flow with a per-login
state(validated on callback; 10 min TTL).Access + refresh tokens are persisted to
LINKEDIN_TOKEN_FILE(default.data/tokens.json).Expiry/refresh handling: every API call goes through
TokenManager, which transparently refreshes the access token when it's within 5 minutes of expiry. If no refresh token is available (LinkedIn grants those to approved apps only), tools raise a clear "re-authorize" error.The current LinkedIn API version header (
Linkedin-Version) is configurable viaLINKEDIN_API_VERSION— bump it when LinkedIn sunsets the version you use (check https://learn.microsoft.com/en-us/linkedin/marketing/).
LLM provider swap
| Requires | Notes |
|
| xAI, OpenAI-compatible ( |
|
|
|
| local Ollama running |
|
|
| any other OpenAI-compatible endpoint ( |
All three share one implementation (OpenAICompatProvider) because they all speak
OpenAI's chat-completions protocol; the factory in llm/factory.py validates the key
and produces a provider with a helpful error if you haven't configured one.
Project layout
src/linkedin_mcp/
├── config.py # pydantic-settings, all env vars, provider selection
├── errors.py # ConfigurationError, NeedsReauthError, LinkedInAPIError, LLMError
├── services.py # shared wiring (store, oauth, token manager, client, scheduler)
├── scheduling.py # scheduled-post store + background publisher loop
├── jobs.py # keyless job-board search (Remotive/Arbeitnow/RemoteOK/Jobicy)
├── applications.py # local application tracker store
├── documents.py # uploads (pdf/docx/txt/md) + resume/profile summary
├── api.py # REST endpoints backing the dashboard UI
├── server.py # FastMCP server: 23 tools + resources
├── app.py # FastAPI app: /auth/* routes + mounted /mcp endpoint
├── __main__.py # CLI: `python -m linkedin_mcp [web]`
├── llm/ # swappable LLM layer (base protocol, factory, provider)
└── linkedin/ # OAuth flow, token storage/refresh, REST client
tests/ # pytest (mocked HTTP), 66 testsSecurity notes
Never commit
.envor.data/— both are gitignored.Tokens are stored in plaintext on disk (local dev). For a deployed version, move them to an encrypted store / server-side secret manager.
The OAuth
stateregistry is in-memory — fine for a single-user local app; replace with a signed cookie or session store when deploying.The LLM layer only ever sends what you pass to
draft_post/analyze_postto the provider — the server never silently uploads your LinkedIn data.
Tests
pytest # 59 tests: tokens/refresh, LLM factory, LinkedIn client,
# job boards, application tracker, tools (all mocked HTTP)
ruff check src tests # lintRoadmap
Phase 2 — free hosting: containerize, deploy on a free tier (limits change often — verify current offers), HTTPS, point
LINKEDIN_REDIRECT_URIat the deployed URL.Phase 3 — more tools:
get_post_statistics(requires approved analytics permissions), video/document posts, an agent loop where the LLM picks tools itself, Adzuna board (free key, aggregates thousands of sites incl. India locations), resume storage + per-JD tailoring.Hardening: signed-cookie state, token encryption, rate-limit handling with retries.
License
MIT
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
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
Managed LinkedIn MCP server for AI agents: search, connect, message and enrich on accounts you own.
- LinkMCPOAuthio.linkmcp
Hosted MCP server for LinkedIn: 31 tools for profiles, search, messaging, posts, enrichment.
LinkedIn API as MCP tools to retrieve profile data and publish content. Powered by HAPI MCP.
7 recruiting tools over one MCP endpoint: ATS boards, LinkedIn jobs, profiles, companies, Naukri.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables AI assistants to access and interact with LinkedIn data—profiles, messaging, jobs, companies, and more—via MCP, with remote or local deployment.222529MIT
- AlicenseCqualityBmaintenance32 MCP tools for job search, resume analysis, matching, alerts, and exports using public LinkedIn endpoints, with optional read-only browser intelligence.323Apache 2.0
- AlicenseAqualityDmaintenanceEnables searching and scraping of LinkedIn profiles, companies, jobs, and posts using natural language through MCP-compatible AI clients.13MIT
- AlicenseAqualityCmaintenanceMCP server for safe LinkedIn automation: official-API posting, comments, and likes plus guest-endpoint job search and a local application tracker.16MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/iThinkAndCode/mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server