LinkedIn Recruiter MCP Server: build candidate search, projects and InMail into your ATS with a coding agent
Give Codex, Cursor, Claude Code or Gemini CLI the LinkedIn Recruiter API routes through the hosted Unipile MCP server. Your coding agent reads the endpoints, writes Recruiter candidate search, hiring projects, pipelines, applicants, job postings and Recruiter InMail into your ATS, and tests them on a Development application, on the Recruiter contract of the account each recruiter connects.
Codex
Cursor
Claude Code
Gemini CLI
Windsurf
Any MCP client
Start with a Development application. 7-day free trial, no credit card.
Your coding agent
Unipile MCP connected
Add LinkedIn Recruiter candidate search to the sourcing page of my ATS. Recruiters connect their own LinkedIn account from Settings.
Read endpointPOST /v2/{account_id}/linkedin/recruiter/search/peopleschema loaded
Added searchCandidates(filters) on the backend. It checks the account's contracts first, resolves skills and locations to IDs, then runs the Recruiter search. Tested on the Development app: 40 candidates on the first page.
Now a "Save to pipeline" button on each result, for the requisition's hiring project.
Run requestPOST /v2/{account_id}/linkedin/recruiter/projects/{project_id}/pipeline/candidate/save200 OK
Describe the next feature…
The short answer
Is there an official LinkedIn Recruiter MCP server?
No. LinkedIn does not publish a Model Context Protocol server, for Recruiter or for anything else. The Unipile MCP server is a hosted third-party server generated from the Unipile API, and it exposes the LinkedIn Recruiter API routes: candidate search, hiring projects, pipelines, talent pool, applicants, job postings and Recruiter InMail. Your coding agent reads those endpoints and writes the integration into your product, where each recruiter connects their own LinkedIn account through Hosted Auth and your code acts on behalf of that authenticated user, on the Recruiter contract they hold.
The server URL
https://developer.unipile.com/mcp?branch=v2.0
AuthHeader
X-API-KEY with a scoped Account API key, over streamable HTTP. The same URL serves LinkedIn Classic, Sales Navigator, Recruiter and eight other channels.AccountsA test LinkedIn account with a Recruiter contract on your Development application while you build; in production, the account each recruiter connected through Hosted Auth.
Recruiter25 routes under
/v2/{account_id}/linkedin/recruiter, plus Recruiter InMail on POST /v2/{account_id}/chats/send.ClientsCodex, Cursor, Claude Code, Gemini CLI, Windsurf, or any MCP client over streamable HTTP.
How one prompt becomes code in your ATS
1
You describe the featureAdd Recruiter candidate search to the sourcing page, filtered by skills, location and years of experience.
2
The agent reads the Recruiter endpoints
Read endpointPOST /v2/{account_id}/linkedin/recruiter/search/peopleschema loaded
3
It writes the code and tests it on your Development applicationAdded searchCandidates() and a filter form fed by the Recruiter search parameters route, wired to the sourcing page. Ran it on the Development app: 25 candidates, profile opened with the Recruiter variant.
Prompts, not glue code
What your coding agent builds with the LinkedIn Recruiter MCP
Pick a recruiting feature. Each transcript shows the prompt you give the agent, the LinkedIn Recruiter API endpoints it reads and runs through the Unipile MCP server, and what lands in your ATS. Paths are complete, on the API base URL
https://api.unipile.com, with a scoped key in the X-API-KEY header.Add LinkedIn Recruiter candidate search to the sourcing page: skills, job title, seniority, a postal code with a radius, years of experience.
Run requestPOST /v2/{account_id}/linkedin/recruiter/search/parametersIDs resolved
Run requestPOST /v2/{account_id}/linkedin/recruiter/search/people40 candidates
Added
recruiter-search.ts: the filter form resolves skills, titles and locations to IDs with the search parameters route, then calls people search with skills, title, seniority, postal_code_radius and years_of_experience. Results page with what the API returns. Tested on the Development app: 40 candidates on the first page.Recruiter candidate search, with Recruiter's own filters
The people search route takes the Recruiter filter set: skills, titles, seniority, companies, schools, locations, languages, and Recruiter signals such as
recently_joined, is_past_applicant or hide_previously_viewed. Results are what the connected recruiter can see on their own contract.Endpoints the agent uses
POST/v2/{account_id}/linkedin/recruiter/search/parametersPOST/v2/{account_id}/linkedin/recruiter/search/peopleGET/v2/{account_id}/users/{user_id}
Common mistake: Sending a location or a skill as free text. Filters that point to a LinkedIn entity take IDs: resolve them first with
Recruiter search API guide
POST /v2/{account_id}/linkedin/recruiter/search/parameters. It is a POST, unlike the GET parameters route of Sales Navigator.Let recruiters paste a LinkedIn Recruiter search URL, or pick one of their saved searches, and import the candidates into the ATS.
Read endpointPOST /v2/{account_id}/linkedin/recruiter/searchschema loaded
Run requestPOST /v2/{account_id}/linkedin/recruiter/search/people25 candidates
Added an "Import from Recruiter" dialog. A pasted URL goes to the search-from-URL route; a saved search goes through people search with
load_saved_search. Candidates are upserted by their LinkedIn ID, so a second import does not duplicate them.Reuse the searches recruiters already built in Recruiter
Recruiters spend time tuning a search. The search-from-URL route runs a Recruiter search URL as it is, and people search can load a saved search or a saved custom filter (
load_saved_search, load_custom_filter) or save a new one (save_search, save_custom_filter).Endpoints the agent uses
POST/v2/{account_id}/linkedin/recruiter/searchPOST/v2/{account_id}/linkedin/recruiter/search/peoplePOST/v2/{account_id}/linkedin/recruiter/search/parameters
Common mistake: Sending a Classic or Sales Navigator URL to the Recruiter route. Each product has its own search-from-URL route; pick the route from where the URL comes from.
LinkedIn API for recruiting software
When a recruiter opens a candidate, show the profile as LinkedIn Recruiter shows it, with the recruiting activity section.
Read endpointGET /v2/{account_id}/users/{user_id}schema loaded
Run requestGET /v2/{account_id}/users/{user_id}?variant=linkedin_recruiter&with_sections=linkedin_recruiting_activity200 OK
Added
getRecruiterProfile(id) with variant=linkedin_recruiter and the linkedin_recruiting_activity section, and a "Recruiting activity" tab on the candidate page. The call runs only when the recruiter opens the profile.The candidate profile as Recruiter shows it
The profile route has three LinkedIn variants:
linkedin_classic, linkedin_sales_navigator and linkedin_recruiter. With the Recruiter variant, the agent can request the recruiting activity section, which exists on Recruiter only, next to sections such as experience, education, skills and languages.Endpoints the agent uses
GET/v2/{account_id}/users/{user_id}POST/v2/{account_id}/linkedin/recruiter/search/peopleGET/v2/{account_id}/linkedin/contracts
Common mistake: Leaving out
LinkedIn MCP server: Classic profiles and messaging
variant=linkedin_recruiter and expecting Recruiter data. The linkedin_recruiting_activity section is Recruiter only; ask for it with the Recruiter variant.Mirror each ATS requisition as a LinkedIn Recruiter hiring project: create it when the recruiter opens the job, update it when the job changes.
Run requestGET /v2/{account_id}/linkedin/recruiter/projects12 projects
Read endpointPOST /v2/{account_id}/linkedin/recruiter/projectsschema loaded
Added
recruiter-projects.ts: the first sync links existing projects to requisitions, "Create in Recruiter" creates a project from the requisition page, and edits go through PATCH on the project. The project ID is stored on the requisition.Hiring projects in sync with your requisitions
List, create, read and edit Recruiter hiring projects from your ATS. The project ID then scopes everything else: pipeline, talent pool search, applicants and job postings.
Endpoints the agent uses
GET/v2/{account_id}/linkedin/recruiter/projectsPOST/v2/{account_id}/linkedin/recruiter/projectsPATCH/v2/{account_id}/linkedin/recruiter/projects/{project_id}
Common mistake: Retrying a project creation after a timeout. List the projects first to check whether it was created, then decide; a blind retry can leave two projects.
Features for recruiting software
Show the pipeline of each Recruiter project on the requisition page, add a talent pool search, and let recruiters save a candidate to the pipeline.
Run requestPOST /v2/{account_id}/linkedin/recruiter/projects/{project_id}/pipeline34 candidates
Run requestPOST /v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/search18 matches
Added the pipeline view (candidates upserted on the requisition), a talent pool search box on the project, and a "Save to pipeline" button wired to the save-candidate route. A save runs on the recruiter's click, one candidate at a time.
Pipelines and talent pools, inside the requisition
The pipeline route lists the candidates of a project and the save route adds one. Talent pool search runs a people search from the project's talent pool, so the requisition page shows the same candidates the recruiter works with in Recruiter.
Endpoints the agent uses
POST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/pipelinePOST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/pipeline/candidate/savePOST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/search
Common mistake: Calling the list routes with GET. Listing pipeline candidates and searching the talent pool are both POST routes that take a request body.
Messaging and workflow features for ATS
Import the applicants of each project's LinkedIn job posting into the ATS candidate list, with their resumes.
Run requestPOST /v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/applicants52 applicants
Run requestGET /v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/applicants/{applicant_profile_id}/resumeresume
Added the applicant import per project (list, then detail with the get-applicant route) and resume retrieval, stored on the candidate file. Resumes are fetched when the recruiter opens an applicant, not for the whole list.
Job applicants and their resumes, in the ATS
For a project with a job posting, the applicants route lists who applied, the applicant route returns one application, and the resume route returns that applicant's resume. Your ATS gets LinkedIn applicants next to the ones from its own career site.
Endpoints the agent uses
POST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/applicantsGET/v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/applicants/{applicant_id}GET/v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/applicants/{applicant_profile_id}/resume
Common mistake: Assuming the resume route takes the same ID as the applicant route. Its path parameter is
LinkedIn job posting API
applicant_profile_id, not applicant_id; the agent reads both schemas before wiring them.Let recruiters send a Recruiter InMail from the candidate page, with a subject and their signature, visible to the project team.
Read endpointPOST /v2/{account_id}/chats/sendspecifics loaded
Run requestGET /v2/{account_id}/linkedin/inmail-creditscredits
Added
sendRecruiterInmail() on the start-chat route with specifics.linkedin.recruiter: subject, signature, visibility: PROJECT, intent: HIRE_FOR_OWN_COMPANY, send_as: INMAIL. The composer shows the InMail credits, and a failed send is reported to the recruiter, never retried.Recruiter InMail from the candidate page
Recruiter messages go through the start-chat route with
specifics.linkedin.recruiter: subject, signature, visibility (PUBLIC, PRIVATE or PROJECT), intent (HIRE_FOR_CLIENT or HIRE_FOR_OWN_COMPANY), send_as (INMAIL, or EMAIL using profile data), a channel_type from the project talent pool, and follow_up to schedule a follow-up message on Recruiter Pro contracts.Endpoints the agent uses
POST/v2/{account_id}/chats/sendGET/v2/{account_id}/linkedin/inmail-creditsGET/v2/{account_id}/chats/{chat_id}/messages
Common mistake: Keeping the defaults without checking them.
Send messages on behalf of recruiters
intent defaults to HIRE_FOR_CLIENT and visibility to PRIVATE: an in-house team usually wants HIRE_FOR_OWN_COMPANY, and a shared project may want PROJECT.Publish ATS jobs to LinkedIn from the requisition page: create the draft, check job slot credits, publish, and close the posting when the job is filled.
Run requestGET /v2/{account_id}/linkedin/recruiter/job-slots-creditscredits
Run requestPOST /v2/{account_id}/linkedin/recruiter/projects/{project_id}/jobs/{job_id}/publishpublished
Added the job posting flow: a draft in the requisition's project (or in a new project), edits with
PATCH, the budget of the posting, a job slot credits check before the Publish button is enabled, and Close when the requisition is filled. Each step is a recruiter click.Job postings from the requisition, credits checked first
Create a draft in an existing project or in a new one, edit it, publish it, close it. List the postings, read one, read the budget of a posting and the job slot credits of the contract before publishing.
Endpoints the agent uses
POST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/jobsGET/v2/{account_id}/linkedin/recruiter/job-slots-creditsPOST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/jobs/{job_id}/publish
Common mistake: Publishing without reading the credits. Call
LinkedIn job posting API
GET /v2/{account_id}/linkedin/recruiter/job-slots-credits first and show the result to the recruiter; publishing stays their decision.Real routes, complete paths
Every LinkedIn Recruiter API route the MCP server exposes
The server exposes the Unipile API itself, so what your coding agent can build on Recruiter is what the API does. Below are all 25 Recruiter routes, grouped by feature, and the shared LinkedIn routes a Recruiter integration also uses. Paths are complete, on the API base URL
https://api.unipile.com, with the scoped key in the X-API-KEY header.25Recruiter routes under /linkedin/recruiter, on the contract the user connected
3ways to search: filters, a Recruiter URL, a project's talent pool
1send route for Recruiter InMail, with specifics.linkedin.recruiter
0endpoints to guess: the agent reads the exact schema before it writes code
3 routes
Candidate search
Recruiter people search with the full filter set, a search from a Recruiter URL, and the parameters route that resolves filter values to IDs.
POST/v2/{account_id}/linkedin/recruiter/search/people
POST/v2/{account_id}/linkedin/recruiter/search
POST/v2/{account_id}/linkedin/recruiter/search/parameters
4 routes
Hiring projects
List, create, read and edit the hiring projects of the Recruiter contract. The project ID scopes pipeline, talent pool, applicants and jobs.
GET/v2/{account_id}/linkedin/recruiter/projects
POST/v2/{account_id}/linkedin/recruiter/projects
GET/v2/{account_id}/linkedin/recruiter/projects/{project_id}
PATCH/v2/{account_id}/linkedin/recruiter/projects/{project_id}
3 routes
Pipeline and talent pool
List the candidates of a project pipeline, save a candidate to it, search the project's talent pool.
POST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/pipeline
POST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/pipeline/candidate/save
POST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/search
3 routes
Applicants and resumes
List the applicants of a project's job posting, read one application, retrieve the applicant's resume.
POST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/applicants
GET/v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/applicants/{applicant_id}
GET/v2/{account_id}/linkedin/recruiter/projects/{project_id}/talent-pool/applicants/{applicant_profile_id}/resume
8 routes
Job postings
Create a draft in a new or an existing project, edit, publish and close it, list postings and read one.
POST/v2/{account_id}/linkedin/recruiter/jobs
POST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/jobs
GET/v2/{account_id}/linkedin/recruiter/projects/{project_id}/jobs
GET/v2/{account_id}/linkedin/recruiter/jobs
GET/v2/{account_id}/linkedin/recruiter/jobs/{job_id}
PATCH/v2/{account_id}/linkedin/recruiter/projects/{project_id}/jobs/{job_id}
POST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/jobs/{job_id}/publish
POST/v2/{account_id}/linkedin/recruiter/projects/{project_id}/jobs/{job_id}/close
2 routes
Budget and job slots
Read the budget of a job posting and the job slot credits of the contract before your UI offers to publish.
GET/v2/{account_id}/linkedin/recruiter/projects/{project_id}/jobs/{job_id}/budget
GET/v2/{account_id}/linkedin/recruiter/job-slots-credits
2 routes
Company member verification
Verify the identity of a company member: request the verification email, then submit the one-time code the user receives.
POST/v2/{account_id}/linkedin/recruiter/company/{company_id}/member/verify-email
POST/v2/{account_id}/linkedin/recruiter/company/{company_id}/member/submit-otp
8 shared
Shared LinkedIn routes
Recruiter InMail, the Recruiter profile variant, InMail credits, contracts, and the account connection through Hosted Auth.
POST/v2/{account_id}/chats/send
POST/v2/{account_id}/inboxes/{inbox_id}/chats/send
GET/v2/{account_id}/users/{user_id}
GET/v2/{account_id}/linkedin/inmail-credits
GET/v2/{account_id}/linkedin/contracts
POST/v2/{account_id}/linkedin/contracts/{contract_id}/select
POST/v2/auth/link
GET/v2/accounts/
One complete request, exactly as the agent runs it
The server follows every Unipile API release, so a new Recruiter route reaches your agent the day it ships. In production your product calls the same routes on the account each recruiter connected through Hosted Auth, as user actions in your UI. Same routes as the Unipile LinkedIn API, in the code the agent writes or through the official SDKs.·API reference
LinkedIn Recruiter MCP search filters: the whole Recruiter set
Recruiter people search is where most ATS and sourcing features start. The route
POST /v2/{account_id}/linkedin/recruiter/search/people documents 56 body fields; the agent reads them from the schema and builds the filter form your recruiters expect. The main ones, grouped the way a recruiter thinks.Skills and experience12 fields
The filters recruiters reach for first: what the candidate does, at what level, for how long.
Body fields of the people search
Skills, titles and functionskills, title, job_title, job_function
Seniority and tenureseniority, years_of_experience, years_in_current_company, years_in_current_position
Keywords and nameskeywords, first_name, last_name, occupation
Companies and education9 fields
Where the candidate works or worked, the kind of company, and where they studied.
Body fields of the people search
Companiescompany, current_company, past_company
Industry and company sizeindustry, company_size
Educationschool, degree, field_of_study, graduation_year
Location, work type and languages8 fields
Where the candidate is, how they want to work, which languages they speak.
Body fields of the people search
Location and radiuslocation, postal_code, postal_code_radius
Workplace and employmentworkplace_type, employment_type
Languagesspoken_language, proficiency, profile_language
Recruiter signals and your team's work16 fields
Filters that only make sense in Recruiter: activity signals, the team's projects, tags and notes, and saved searches.
Body fields of the people search
Signalsrecently_joined, hide_previously_viewed, new_results_only, is_past_applicant, recruiting_activity, spotlights, is_military_veteran, network_distance
Projects, tags and notesproject, project_id, tags, notes
Saved searches and custom filtersload_saved_search, save_search, load_custom_filter, save_custom_filter
Filters that point to a LinkedIn entity (a location, a skill, a company, a school) take IDs. The agent resolves them with
POST /v2/{account_id}/linkedin/recruiter/search/parameters before calling the search, then passes the IDs. The schema also documents exclude, group, id, include, max, min, name, preferences, priority, timespan and type; the agent reads their exact shape before it writes the form. Every filter runs on the Recruiter contract of the connected account.Quick start
Add the LinkedIn Recruiter MCP to your coding agent in one line
There is no separate Recruiter server to install: the hosted Unipile MCP server covers LinkedIn Recruiter under the same URL as LinkedIn Classic, Sales Navigator and every other channel. Point your coding agent at it with a scoped API key, and it reads the Recruiter endpoints and runs requests against your Development application. The snippets below are the ones from the official documentation.
Cursor~/.cursor/mcp.json
Claude Codeclaude mcp add --transport http …
Codex CLI and IDE extension~/.codex/config.toml
Gemini CLI~/.gemini/settings.json
Windsurf~/.codeium/windsurf/mcp_config.json
# Register the hosted Unipile MCP server in Claude Code
claude mcp add --transport http --scope user \
unipile "https://developer.unipile.com/mcp?branch=v2.0" \
--header "X-API-KEY: your-scoped-api-key"
# Verify the connection, or type /mcp inside a session
claude mcp list
{
"mcpServers": {
"unipile": {
"url": "https://developer.unipile.com/mcp?branch=v2.0",
"headers": {
"X-API-KEY": "your-scoped-api-key"
}
}
}
}
{
"mcpServers": {
"unipile": {
"url": "https://developer.unipile.com/mcp?branch=v2.0",
"headers": {
"X-API-KEY": "your-scoped-api-key"
}
}
}
}
# Codex CLI and the Codex IDE extension share this file
[mcp_servers.unipile]
url = "https://developer.unipile.com/mcp?branch=v2.0"
http_headers = { X-API-KEY = "your-scoped-api-key" }
# Verify: codex mcp list
{
"mcpServers": {
"unipile": {
"httpUrl": "https://developer.unipile.com/mcp?branch=v2.0",
"headers": {
"X-API-KEY": "your-scoped-api-key"
}
}
}
}
# Verify: /mcp inside Gemini CLI
Server connected. Try: "Add LinkedIn Recruiter candidate search to the sourcing page, then open the selected profile with the Recruiter variant."
1
Start with a Development applicationIn the Unipile dashboard, work in your Development application: connect a test LinkedIn account that holds a Recruiter contract through Hosted Auth, create a Scope with it and a scoped Account API key for that Scope. Production stays untouched, and an MCP client never gets a global or Service key.
2
Add the server to your coding agentPaste the config for your client, with the scoped key in the X-API-KEY header. Restart the client if it does not pick it up right away.
3
Describe the feature, review the codeDescribe the Recruiter feature you need. The agent reads the endpoints, writes the code in your project and runs requests on the Development app. Switch the key to Production when the flow passes.
On behalf of the recruiter
Whose Recruiter contract does your integration act on?
While you build, on the test account of your Development application. In production, on the LinkedIn account each recruiter connected through Hosted Auth, with the Recruiter contract that account holds, inside workflows that recruiter starts and controls.
1 · Your coding agent
Codex, Cursor, Claude Code
Reads the Recruiter schemas, writes the code
2 · Unipile MCP server
Hosted, scoped API key
Runs test requests on your Development app
3 · Unipile API
The Recruiter routes
Scopes the action to one account ID
4 · LinkedIn Recruiter
The selected contract
LinkedIn's rules, InMail and job slot credits
5 · The recruiter's account
Connected through Hosted Auth
Their projects, their pipeline, their credits
Sarah MitchellLinkedIn · Recruiter contract · linked by the user through Hosted Auth
Account ID
acc_7f3…c91, the only identifier your code storesContractListed with
GET …/linkedin/contracts, selected with POST …/contracts/{contract_id}/selectSessionHeld by Unipile, never exposed to your app
StatusConnected · status changes arrive by webhook
ReconnectDisconnect
Honest limits
What LinkedIn Recruiter limits still apply
The server does not lift LinkedIn's rules and does not add credits to a contract. The API gives your ATS the account's real signals so the feature you ship works inside them, the way the recruiter would.
What LinkedIn and the contract enforce
A Recruiter contract on the connected accountEvery route under
/linkedin/recruiter needs one. Without it, the account still works on the Classic LinkedIn routes, but your Recruiter features stay hidden.InMail creditsRecruiter InMail spends the credits of the contract. Read them with
GET /v2/{account_id}/linkedin/inmail-credits and show them before the recruiter sends.Job slot credits and posting budgetPublishing a job uses what the contract has. Read
GET /v2/{account_id}/linkedin/recruiter/job-slots-credits and the budget of the posting before offering Publish.Search paginationRecruiter searches return pages. Your code pages with what the API returns, within what the contract allows the recruiter to see.
Checkpoints and identity checksLinkedIn may ask the account owner for a code when the account is linked, and a company member identity check uses an email and a one-time code. The user enters the code; your code never sees a password.
What to build into your ATS
Writes are recruiter actionsSend an InMail, save a candidate, create a project, publish or close a job: each one is triggered by the recruiter in your UI, never by a background loop.
Check before you retry a writeAfter an ambiguous failure, list the projects, the pipeline or the jobs to see what happened. A blind retry can create a second project or send a second InMail.
One Scope and one scoped key per tenantA workspace only sees the accounts assigned to its Scope. The global key stays on your backend for administration, and the recruiter can disconnect at any time.
Adapt the UI to the contractHide what the account cannot do: no Recruiter contract, no Recruiter tab; no Recruiter Pro contract, no scheduled follow-up.
Use webhooks for new messagesIf your ATS must react to candidate replies, subscribe to webhooks and let the event bring the message, instead of polling the inbox.
Four ways to connect an ATS to LinkedIn
How the LinkedIn Recruiter MCP options compare
Every LinkedIn Recruiter MCP option is third-party, so the real question for a recruiting product is how each one reaches Recruiter, on whose contract, and what you can ship with it. The four families you will find, side by side.
Unipile MCP server
Community open-source servers
Public-data marketplaces
No-code MCP bridges
How it reaches Recruiter
Unipile MCP serverThe LinkedIn account each recruiter connects through Hosted Auth, then the Recruiter API routes on its contract
Community open-source serversYour own LinkedIn login on your machine, driven by a browser session
Public-data marketplacesPublic pages, no account, no Recruiter access
No-code MCP bridgesTheir LinkedIn app connection and a set of predefined actions
Recruiter surfaces
Unipile MCP serverSearch, projects, pipelines, talent pool, applicants, job postings, Recruiter InMail
Community open-source serversRarely beyond the Classic profile
Public-data marketplacesPublic profiles only, no projects or pipelines
No-code MCP bridgesFew or no Recruiter actions
Read, or read and act
Unipile MCP serverRead and act: save candidates, create projects, publish jobs, send InMail, as features of your ATS
Community open-source serversMostly read, a few writes depending on the project
Public-data marketplacesRead only
No-code MCP bridgesPredefined writes, little reading
Hosting and clients
Unipile MCP serverHosted, one URL, any coding agent over HTTP: Codex, Cursor, Claude Code, Gemini CLI, Windsurf
Community open-source serversSelf-hosted, local or Docker, usually one client at a time
Public-data marketplacesHosted, token per client
No-code MCP bridgesHosted, one generated URL per configuration
Other channels on the same server
Unipile MCP serverEight: WhatsApp, Instagram, Telegram, Gmail, Outlook, IMAP, Google and Outlook calendars
Community open-source serversNone
Public-data marketplacesOther public data sources
No-code MCP bridgesThousands of apps, each with a shallow action set
Pricing model
Unipile MCP serverPer connected account, whatever the request volume, 7-day free trial
Community open-source serversFree, you host and maintain it
Public-data marketplacesPer credit or per result
No-code MCP bridgesPer task or per action
Whose terms your product works under
Unipile MCP serverEach recruiter's own account and Recruiter contract, in workflows the recruiter initiates and controls from your product
Community open-source serversYour personal account, at your own risk
Public-data marketplacesThe marketplace's data collection terms
No-code MCP bridgesThe bridge's terms and its LinkedIn app permissions
Categories are described generically on purpose. What sets the Unipile server apart is the account model: your ATS reads and acts as the recruiter who connected the account, on their own Recruiter contract, behind a single server URL shared with eight other channels.
LinkedIn Recruiter MCP FAQ
The questions people actually type: official or not, the server URL, candidate search, projects and pipelines, Recruiter InMail, contracts, and price.
Not from LinkedIn: it does not publish a Model Context Protocol server for Recruiter. The Unipile MCP server is a hosted third-party server generated from the Unipile API, and it exposes the LinkedIn Recruiter API routes: candidate search, hiring projects, pipelines, talent pool, applicants, job postings and Recruiter InMail. Your coding agent reads those endpoints and writes the integration into your product, where each recruiter connects their own account and your code acts on behalf of that authenticated user. Unipile is an independent technical intermediary and is not affiliated with, endorsed by, or sponsored by LinkedIn.
The same URL as the whole Unipile API:
https://developer.unipile.com/mcp?branch=v2.0, over streamable HTTP, with a scoped Account API key in the X-API-KEY header. There is no separate Recruiter server. Paste it into Codex, Cursor, Claude Code, Gemini CLI or Windsurf, and the agent finds the Recruiter endpoints under /v2/{account_id}/linkedin/recruiter on its own.Yes, on an account with a Recruiter contract. The agent reads
POST /v2/{account_id}/linkedin/recruiter/search/people and builds the search with Recruiter filters such as skills, title, seniority, company, school, location with a postal code radius, spoken language, or signals like recently_joined and hide_previously_viewed. It resolves filter values to IDs with POST /v2/{account_id}/linkedin/recruiter/search/parameters, can run a search from a Recruiter URL with POST /v2/{account_id}/linkedin/recruiter/search, and tests the result on your Development application. Searches run as actions of the recruiter who connected the account.Yes. Your ATS can list, create, read and edit hiring projects (
GET and POST /v2/{account_id}/linkedin/recruiter/projects, PATCH /v2/{account_id}/linkedin/recruiter/projects/{project_id}), list the candidates of a project pipeline with POST /v2/{account_id}/linkedin/recruiter/projects/{project_id}/pipeline, save a candidate to it, search the project's talent pool, and import applicants with their resumes. Saving a candidate or creating a project stays a recruiter action in your UI.Yes, through
POST /v2/{account_id}/chats/send with specifics.linkedin.recruiter: a subject, a signature, a visibility (PUBLIC, PRIVATE or PROJECT), an intent (HIRE_FOR_CLIENT or HIRE_FOR_OWN_COMPANY), and send_as set to INMAIL or to EMAIL using profile data. A scheduled follow_up is available on Recruiter Pro contracts only. InMail spends the contract's credits, readable with GET /v2/{account_id}/linkedin/inmail-credits, and each message is sent by the recruiter from your UI.The Recruiter routes require a Recruiter contract on the connected account; without one, the account only works on the Classic LinkedIn routes (messaging, profiles, classic search). What a given account can do depends on the contract it holds, so your code lists its contracts with
GET /v2/{account_id}/linkedin/contracts, selects one with POST /v2/{account_id}/linkedin/contracts/{contract_id}/select, and shows only the features that answer. Test with the kind of contract your customers use.They are the same routes used at two moments. The LinkedIn Recruiter MCP is how your coding agent reads the Recruiter endpoints and tests them while it writes your integration. The LinkedIn Recruiter API is what your product calls in production, over the REST API or the official SDKs, with its own scoped keys, on the accounts your recruiters connected. You build with the MCP and run on the API.
The MCP server is included in every Unipile plan, with no per-message or per-request fee. Billing is per connected account, whatever the channel: from 49 EUR per month for up to 10 accounts, then 5 EUR per additional account, down to 3 EUR at volume. The 7-day free trial needs no credit card. The Recruiter contract itself remains the recruiter's own LinkedIn subscription. Full grid on the pricing page.
Instagram