MCP server for LinkedIn: read profiles, companies, jobs and messages through your own logged-in browser session
Strong naming conventions (all verb_noun pattern), comprehensive descriptions (avg 180 chars, well within 10-1024 range), and complete input schemas with types and descriptions across all 14 tools. Tool annotations present for read/write distinction. Key gaps: output schemas not documented in code (inferred from descriptions only), no pagination guidance despite search tools, and error handling relies on internal modules not visible in server.py. Mutually exclusive parameters (recipient vs conversation_id in send_message) documented but could be clearer. No examples of parameter constraints (enums) despite opportunities (e.g., sections in get_profile).
Sends a real LinkedIn connection invitation to another member, from your account, right now. This is a WRITE action visible to another person: the recipient sees an invitation from you, carrying your note if one is given (LinkedIn caps notes at 300 characters on free accounts).
Fetch a LinkedIn company's profile: name, tagline, follower count, industry, size, headquarters, founded date, website, and free-text about section. `company` accepts a full company URL or just the slug (the part after /company/). `sections` selects which parts to include, from {'overview', 'about'}: defaults to both. Read-only.
Fetch the full message history of one LinkedIn conversation, by the conversation_id returned from get_inbox or search_conversations. Read-only.
List your most recent LinkedIn message threads as previews (participant, snippet, timestamp, conversation id), not full history. Use get_conversation with a returned conversation id for the full thread. Read-only.
Fetch a LinkedIn job posting: title, company, location, seniority level, job type, description, and salary range if posted. `job` accepts a full job URL or just the job ID (the numeric part after /jobs/). Read-only.
Output schemas not documented in code. Tool descriptions infer structure but no formal schema definitions visible for return types. LLMs cannot reliably plan downstream calls without knowing what fields to expect.
Search tools (search_people, search_companies, search_jobs, search_conversations) lack pagination guidance. No mention of limit enforcement, total count, or next_cursor in descriptions. Large result sets could exhaust context.
Enum constraints not declared in schemas. get_profile 'sections' parameter accepts array of strings but valid values {'experience', 'education', 'skills', 'certifications', 'projects', 'languages', 'honors', 'posts'} are only in description text, not schema enum. LLMs may hallucinate invalid section names.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 65 | 2026-07-28+ | v2 |
Fetch the profile of the account this server is logged in as. Read-only.
Fetch recent posts from a LinkedIn member's profile. `profile` accepts a full profile URL or just the public identifier (the part after /in/). Read-only.
Fetch a LinkedIn member's profile as visible to your account: headline, about, current position. `profile` accepts a full profile URL or just the public identifier (the part after /in/). `sections` selects which extra sections to include, from {'experience', 'education', 'skills', 'certifications', 'projects', 'languages', 'honors', 'posts'}: defaults to experience and education. 'posts' costs one extra page load; every other section is free since it's already on the profile page. Read-only.
Check the status of the LinkedIn session and the action queue. Returns whether the session is authenticated, the current action queue usage, and rate limit information. Read-only.
Search LinkedIn companies by keywords (name, industry, location). Returns lightweight results. Call get_company for full detail on any hit. Read-only.
Search your LinkedIn message threads by participant name or keyword. Read-only.
Search LinkedIn jobs by keywords (title, company, location). Returns lightweight results. Call get_job for full detail on any hit. Read-only.
Search LinkedIn members by keywords (name, title, company, school). Returns lightweight results. Call get_profile for full detail on any hit. Read-only.
Sends a real LinkedIn message to another member, from your account, right now. This is a WRITE action visible to another person: the recipient sees it arrive as a message from you, and LinkedIn gives no way to unsend it from here. Pass exactly one of `recipient` (a profile URL/public identifier, to start or reply to whichever thread you already have with them) or `conversation_id` (to reply in a specific existing thread returned by get_inbox).
Error handling delegated to internal modules (people.do_*, messaging.do_*, etc.) not visible in server.py. _safe() wrapper catches RateLimited and LinkedInError but actual validation and error messages originate in unreviewable code. Cannot verify error guidance quality.
Mutually exclusive parameters (send_message: recipient vs conversation_id) documented in description but not enforced in schema. No oneOf constraint. LLMs may pass both, causing ambiguous behavior.