Skip to content
juancespedes.dev
All projects
Case study

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
  • 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

  1. 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
  2. 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
  3. 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
  4. 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

An AI assistant calls tools on the MCP server. The server drives a browser with the user's persistent session, reads through the page's internal API and writes through the interface with a generic form engine.
  1. Clients

    • AI assistantAny MCP client
    • CLIThe same commands from the terminal
  2. Server

    • MCP serverMore than 35 tools with confirmation
    • Form engineVisible labels and a bilingual glossary
    • Answer bankReusable answers
  3. Browser

    • Persistent browserPlaywright with the user session
  4. LinkedIn

    • Internal APIReads profiles and job postings
    • Web interfaceWrites to the profile and applications

How data moves

  1. AI assistanttoMCP serverTool calls
  2. CLItoMCP serverSame core
  3. MCP servertoPersistent browserReads and actions
  4. MCP servertoForm engineWrites
  5. Answer banktoForm engineSaved answers
  6. Persistent browsertoInternal APIReads with the browser session
  7. 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