linkedin-ads-readonly-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@linkedin-ads-readonly-mcpwhat did my campaigns spend and how many leads in August 2026?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
linkedin-ads-readonly-mcp
Your LinkedIn Ads data for AI agents and the terminal. Ask what a campaign spent, what a lead cost, which job titles the ads actually reached, or what a campaign is targeting, and get the answer from LinkedIn's Marketing API with your own token, on your own machine.
$ npx linkedin-ads-readonly-mcp performance --since 2026-08-01 --until 2026-08-31
Performance by campaign, 2026-08-01 to 2026-08-31 (spend in USD)
id name spend impr clicks lp clicks ctr cpc cpm leads cpl conv
500000001 Ops leaders - lead form 2,410.75 96,400 538 0 0.56% 4.48 25.01 41 58.80 0
500000002 Finance directors - guide 1,385.20 41,250 310 221 0.75% 4.47 33.58 0 9
500000003 Retargeting - site visitors 402.10 18,830 167 119 0.89% 2.41 21.35 6 67.02 0
500000004 Video - brand awareness 612.00 88,100 205 48 0.23% 2.99 6.95 0 0
total 4,810.05 244,580 1,220 388 0.50% 3.94 19.67 47 102.34 9
clicks counts every click on the ad (profile, expand, play). lp clicks are clicks to your landing page. leads are lead gen form submissions; conv are website conversions.
Only campaigns with delivery in the range are listed.Illustrative output with made-up campaigns and numbers (run node examples/sample-performance.mjs); real runs return your account's figures.
It runs as an MCP server (Claude Code, Cursor, Claude Desktop and others) and as a CLI. It is read-only: the client only knows how to send GET requests, so it cannot create, edit, pause or delete anything, and it never fetches lead details.
Why this one
LinkedIn does not publish an MCP server for its ads API. The hosted ones charge a subscription and run your token through their servers. This one is open source, runs locally, and is built for the questions analysts and marketers actually ask:
Performance by campaign, creative, campaign group or account, in total or by day, month or year, with CTR, CPC, CPM and cost per lead worked out for you. Ratios with a zero denominator are blank, not 0 or infinity.
Landing-page clicks next to clicks. LinkedIn's
clicksincludes profile visits and video expands. A traffic campaign with 500 clicks and 0 landing-page clicks sent nobody to your site, and the table shows it.Demographics that say what they don't know. LinkedIn withholds small counts for member privacy, and members match several titles or industries at once. The output says so, gives each value as a share of total impressions instead of a sum, and leaves a column blank when LinkedIn didn't report it rather than printing zeros.
Names instead of URNs. Campaign and group names on every row, and targeting URNs (
urn:li:title:...,urn:li:geo:..., companies, industries, seniorities, company sizes) resolved to what they mean.Creatives with their copy. Post text, headline, landing page, call to action and lead form, read from the creative and the post behind it.
Lead form counts without lead data. Opens, submissions, completion rate and cost per lead per form, from ad analytics. The lead responses endpoint is never called, so no names or emails pass through your agent.
A clear message when LinkedIn retires an API version. LinkedIn turns versions off about a year after release and answers with a bare 426; this tells you which setting to change.
If you need to check that a campaign can serve before you spend (bid, destination, approval, geo, spend cap), that is a different job; see ad-preflight.
Related MCP server: Meta Ads MCP Server
Setup
You need three things from LinkedIn:
A LinkedIn developer app (linkedin.com/developers) with access to the Advertising API (part of the Marketing Developer Platform). Request it from the app's Products tab; LinkedIn reviews each request, and approval can take a while.
An access token with the
r_adsandr_ads_reportingscopes, created through the app's OAuth flow or the developer portal's token generator. Tokens last 60 days.A role on the ad account for the LinkedIn member who authorized the token. The token can read the accounts that member has a role on in Campaign Manager.
Then set these in your environment. See .env.example.
Variable | |
| required |
| optional; the account used when a command doesn't name one (digits only) |
| optional; |
Credentials are read from the environment only. The token is sent in a request header, never in a URL, and error messages are scrubbed of it before printing.
MCP server
claude mcp add linkedin-ads -- npx -y linkedin-ads-readonly-mcp mcp # Claude CodeFor Cursor, Claude Desktop and others:
{ "mcpServers": { "linkedin-ads": { "command": "npx", "args": ["-y", "linkedin-ads-readonly-mcp", "mcp"], "env": { "LINKEDIN_ACCESS_TOKEN": "..." } } } }Tool | What it does |
| Accounts the token can read, with currency and status |
| Groups with status, objective, total budget, schedule |
| Campaigns with status, objective, bid, daily and total budget, schedule |
| Spend, impressions, clicks, landing-page clicks, leads, conversions, CTR, CPC, CPM, CPL by campaign, creative, group or account |
| Delivery by job title, job function, seniority, industry, company size, company, country or region |
| Post text, headline, landing page, CTA, lead form and review status |
| Forms with state, field types, opens, leads, completion rate and CPL |
| A campaign's targeting with every URN named |
| URNs to names |
| Find URNs by text in a facet (titles, locations, industries ...) |
All ten are annotated read-only. Account-scoped tools take an optional
account; date-ranged tools take since and until (YYYY-MM-DD,
inclusive, default the last 30 days).
Claude Code plugin
/plugin marketplace add GroMarketing/linkedin-ads-readonly-mcp
/plugin install linkedin-ads@linkedin-ads-readonly-mcpIt installs the MCP server and a linkedin-ads-analysis skill. The skill tells
Claude how to read the numbers: clicks versus landing-page clicks, form leads
versus website conversions, why demographic rows don't add up, and when a
cost per lead rests on too few leads to plan on.
CLI
npx linkedin-ads-readonly-mcp accounts
npx linkedin-ads-readonly-mcp campaigns --status ACTIVE,PAUSED
npx linkedin-ads-readonly-mcp performance --level creative --days 14
npx linkedin-ads-readonly-mcp performance --granularity monthly --since 2026-01-01 --csv > monthly.csv
npx linkedin-ads-readonly-mcp demographics seniority --campaign 500000001
npx linkedin-ads-readonly-mcp creatives --campaign 500000001
npx linkedin-ads-readonly-mcp forms --since 2026-08-01
npx linkedin-ads-readonly-mcp targeting 500000001
npx linkedin-ads-readonly-mcp lookup titles "revenue operations"
npx linkedin-ads-readonly-mcp resolve urn:li:seniority:6 urn:li:title:1Installed globally (npm i -g linkedin-ads-readonly-mcp), the command is
linkedin-ads. Every command takes --account <id>, --json and --csv.
Demographics
$ npx linkedin-ads-readonly-mcp demographics job_title --since 2026-08-01 --until 2026-08-31 --limit 5
Delivery by job title, 2026-08-01 to 2026-08-31: 244,580 impressions in total (spend in USD)
job title impr share clicks ctr spend lp clicks leads
Operations Manager 31,200 12.8% 214 0.69% 701.40 61 9
Chief Financial Officer 22,950 9.4% 96 0.42% 512.85 40 6
Controller 18,410 7.5% 120 0.65% 398.20 37 5
Director of Operations 15,300 6.3% 88 0.58% 341.10 22 4
Finance Manager 9,870 4.0% 41 0.42% 207.60 12 1
Top 5 of 214 values by impressions.
LinkedIn leaves out values with very small counts to protect member privacy. A value that is missing here is withheld or had no delivery; it is not zero.
Members can match several values (more than one title, industry or company), so rows can add up to more than the total. Read each row as a share of all impressions; do not sum them.Illustrative output with made-up titles and numbers (run node examples/sample-demographics.mjs).
Breakdowns: job_title, job_function, seniority, industry,
company_size, company, country, region. Some of them come back from
LinkedIn with impressions only; when a whole column is missing, it is shown
blank with a note, not as zeros.
Reading the numbers
Spend is in the ad account's currency (
costInLocalCurrency).clicksis every click on the ad.lp clicksare clicks to your landing page. CPC is spend over all clicks; the JSON output also hascostPerLandingPageClick.leadsare LinkedIn lead gen form submissions.convare website conversions tracked by the Insight Tag or Conversions API. CPL is spend over form leads.Form completion is leads over form opens.
Dates are inclusive on both ends. The default
untilis today's date in UTC.
Library
import { performance, demographics } from 'linkedin-ads-readonly-mcp';
const p = await performance({ account: '123456789', level: 'campaign', since: '2026-08-01', until: '2026-08-31' });
const d = await demographics({ account: '123456789', pivot: 'seniority', since: '2026-08-01' });Limits
Read-only by design. There is no way to change budgets, bids or status here.
Lead details are out of scope. Counts come from ad analytics; individual leads stay in Campaign Manager or your CRM sync.
Listing lead forms can need an extra lead-sync permission on some apps. Without it, forms that creatives point at still appear by id, with counts.
Message ads (Sponsored Messaging) are listed, but their message text is not fetched.
LinkedIn caps how many rows one analytics response can hold. A daily breakdown by creative over many months can hit it; narrow the range.
LinkedIn rate-limits the Marketing API per app and per member per day. This tool retries on 429 and 5xx with backoff, and does not cache.
Tokens expire after 60 days. Refreshing them is up to your app.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
- linkedinOAuthio.reachium
LinkedIn campaigns, content, leads and inbox from your AI client. Scoped, revocable keys.
Query Meta Ads performance data — accounts, campaigns, ad sets, ads, metrics & settings.
- mcpOAuthcom.curviate
LinkedIn actions for AI agents: search, messaging, posts and invites, as hosted MCP tools.
Full LinkedIn access for AI agents: leads, messaging, and campaigns with safe limits built in.
Related MCP Servers
- AlicenseAqualityBmaintenanceMCP server for the LinkedIn Marketing API — query campaigns, performance, and Lead Gen Forms from Claude in plain English. 19 read-only tools covering ad accounts, campaigns, creatives, performance analytics, demographics, video analytics, budget pacing, period comparisons, conversions, Lead Gen Forms, audiences, and targeting facets. Built for B2B paid social teams.194-
- AlicenseNot gradedqualityDmaintenanceEnables Claude to fetch and analyze Meta ad accounts, campaigns, ad sets, ads, and performance insights via the Meta Marketing API.1,978 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables management and analysis of LinkedIn ad campaigns, including listing accounts, campaigns, creatives, and retrieving analytics, through natural language queries.170 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to audit and analyze LinkedIn Campaign Manager accounts, campaigns, targeting, creatives, performance, and audience demographics without requiring a LinkedIn Developer App.MIT