FastMCP server exposing the LinkedIn internal API as MCP tools. Pure requests-based API client with no browser automation. Reads and writes wired with live-captured request bodies.
Scoring was not performed
Post a top-level comment on a post (activity_urn = urn:li:activity:<id>, or a bare id). People-facing → requires confirm=True. Returns status + the new comment URN when resolvable. Pure API (SDUI createComment, verified browserless 200). No browser.
Delete a comment. comment_id = the numeric comment id; activity_urn = the post it's on (urn:li:activity:<id>). Destructive → requires confirm=True. SAFETY GUARD: by default only the OWNER's own comments can be deleted. Deleting someone else's comment (e.g. a reply on your post) is refused unless force=True — this prevents accidentally removing a real person's comment during testing. Pure API: browserless Voyager REST DELETE (verified 204). dry_run=True builds+returns the request without sending. No browser fallback.
Return the owner's connection + pending-invitation counts.
List the owner's messaging conversations (inbox).
Read ONE job posting as a flat projection (title, company, location, employment_status, remote_allowed, listed_at, applies, views, salary, reposted, description_text). Browserless. job_id accepts a numeric id, a urn:li:fsd_jobPosting:<id> URN or a full linkedin.com/jobs/view/… URL. Unusable input returns an error WITHOUT any call. The result is IDENTITY-CHECKED: if the response describes a different job than the requested one — or names two job ids that disagree — ok=False and NO url is returned. The url is always built from the id you asked for, never from an id found in the response. A response that identifies the job but yields no readable field is also ok=False ("could not read" is not "a job without details"). Unknown values are null, never false; `salary_present` tells "salary exists but is not readable" apart from "no salary".
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 23 | 2026-07-28+ | v2 |
Return LinkedIn's own job recommendations for the owner (the jobs feed) as flat cards. Browserless read. `count` = how many to fetch; pass the returned pagination_token for the next page. `state` distinguishes an ANSWER from a failure: "hits"/"empty" means the result list was really read (ok=True), "unknown"/"drift"/"ambiguous" mean it could NOT be read (ok=False, with the re-capture hint) — an empty list is never reported as "no jobs" unless it was read as empty. `read_entries` and `discarded` balance `count` against the raw list that was read: on a partial loss ok stays True but `note` names how many entries were dropped.
Fetch LinkedIn's rich link-preview metadata (title/image/desc) for a URL, as the composer shows it when you paste a link. Browserless read.
Return the owner's core LinkedIn profile (name, headline, plainId, profile URN).
Return the owner's most recent posts (full text) via voyagerFeedDashProfileUpdates — the endpoint the official/Composio API cannot access. `count` = how many to fetch.
Return the owner's recent notifications (reactions, comments, mentions, invites).
Read the comments on a post by its activity URN (urn:li:activity:<id>). Browserless.
Read a full profile by its vanityName (the public /in/<name> identifier). Defaults to the owner. Returns experience, education, skills, etc.