linkedin-pilot, an MCP server for LinkedIn
A TypeScript MCP server and CLI that lets an AI assistant update a profile, engage with people and apply to jobs using the user's real session, with explicit confirmation before every action other people can see.
Project facts
- Role
- Author and maintainer
- Period
- Sep 2026 to present
- Public links
- Code on GitHub(opens in a new tab)
35+
documented MCP tools for profile, engagement and job applicationsSource: Repository README, October 2026
The problem
The official LinkedIn API cannot write to a profile or apply to jobs, because real access requires a partner program and not even partners can edit work experience. I wanted an AI assistant to do that work with my own session, without storing my password and without surprise actions.
My role
- Designed the split between reading and writing and the form engine.
- Implemented the MCP server, the CLI and the reusable answer bank.
- Published it with installation and diagnostics docs, plus an emergency exit to finish any flow by hand.
Constraints
- There is no official write API, so the only way in is the real interface.
- The interface changes its structure and CSS classes without notice, and is served in the account's language.
- No action visible to other people can happen without explicit confirmation.
- Sign-in is not automated, because that triggers blocks and would require storing the password.
Decisions
- 01
Read through the internal API, write through the interface
The internal API the page itself uses returns the profile and job postings as structured data in a single call, with the same browser session. There is no endpoint for writing, so the interface is used, and if one path fails the other takes over.
Ruled out
- Scrape the HTML for both reading and writing
- 02
Fields identified by their visible label
The form engine reads each control's accessible name and matches it against a bilingual glossary, so it survives HTML changes and works whether the account is in Spanish or English.
Ruled out
- CSS class selectors
- 03
One engine for the profile and for applications
Editing a profile section and filling in an application are the same problem, a form with fields. A single piece solves both, and a new section is supported without code changes.
Ruled out
- A hand-written flow for every form
- 04
Dry run by default and explicit confirmation
Actions other people can see require confirmation, and applications first run as a dry run to review pending questions before submitting.
Ruled out
- Execute whatever the assistant asks for directly
Architecture
Clients
- AI assistantAny MCP client
- CLIThe same commands from the terminal
Server
- MCP serverMore than 35 tools with confirmation
- Form engineVisible labels and a bilingual glossary
- Answer bankReusable answers
Browser
- Persistent browserPlaywright with the user session
LinkedIn
- Internal APIReads profiles and job postings
- Web interfaceWrites to the profile and applications
How data moves
- AI assistanttoMCP serverTool calls
- CLItoMCP serverSame core
- MCP servertoPersistent browserReads and actions
- MCP servertoForm engineWrites
- Answer banktoForm engineSaved answers
- Persistent browsertoInternal APIReads with the browser session
- Form enginetoWeb interfaceFills in and submits forms
Results
- An assistant can update the whole profile, engage with other people and complete applications with the user's real session.
- Direct browser tools make it possible to finish any failing flow by hand, without editing the project.
- The code is public, with installation and diagnostics documentation.
What I would do differently
- I would set conservative daily limits and pauses between actions from day one, because platforms detect automation patterns even when the session is real.
- I would add tests against saved real pages to catch interface changes before they break in use.
Technologies
- TypeScript
- Node.js
- Model Context Protocol
- Playwright
- REST APIs