linkedin-ads-mcp
LinkedIn Ads MCP
A Model Context Protocol (MCP) server for LinkedIn Ads. Connect Claude (or any MCP-compatible AI client) directly to your LinkedIn ad accounts to query performance, manage campaigns, analyse audiences, and search the public Ad Library — all in natural language.
The server speaks the MCP authorization spec (2025-06-18), so it works as a remote connector anywhere Claude supports custom MCP servers — claude.ai (personal), Claude Desktop, and Claude Teams. Add one URL, click "Connect", sign in with LinkedIn, done. For a Teams plan, the org owner adds the URL once and each member individually authenticates on first use.
What you can do
Account & Campaign Management
List and inspect ad accounts
Create, update, and delete campaign groups and campaigns
Manage creatives and update their status
Upload images and create inline ads
Performance & Analytics
Get campaign and creative performance metrics
Compare performance across date ranges
View daily trends
Analyse audience demographics and reach
Conversions & Lead Gen
Track conversion performance
View lead gen form submissions and performance
Ad Library (Public)
Search any advertiser's public LinkedIn ads
Filter by country, date range, targeting categories, impression volume
Useful for competitive research and creative inspiration
Related MCP server: ads-mcp
How auth works
There are two modes. Pick one.
Mode A — Local STDIO (one user, no server)
Use this if you only want it on your own machine. npm run auth runs the LinkedIn OAuth flow once and stores your token in ~/.linkedin-ads-mcp/tokens.json. Claude Desktop launches the server as a subprocess. No Firestore, no Cloud Run, no public URL.
Mode B — Remote HTTP server (Claude Teams, claude.ai, multi-user)
The MCP server is also an OAuth 2.1 authorization server. When Claude connects:
Claude discovers our metadata at
/.well-known/oauth-protected-resourceand/.well-known/oauth-authorization-server.Claude registers itself via Dynamic Client Registration (
POST /oauth/register).Claude redirects the user to
/oauth/authorize. We delegate identification to LinkedIn OAuth.After LinkedIn login, we issue our own opaque bearer token to Claude — LinkedIn credentials never leave the server.
On each
/mcprequest Claude sends our bearer; we map it server-side to the right user's stored LinkedIn credentials and call the LinkedIn Marketing APIs.
A note on access control. LinkedIn returns whatever email the account was registered with — usually personal (gmail, hotmail, etc.) rather than work email. Domain-based restriction therefore isn't reliable. By default this MCP allows any LinkedIn user to connect; the security comes from LinkedIn's own permission model (each user only sees ad accounts their LinkedIn profile has access to). For tighter control, set
ALLOWED_EMAILSto a comma-separated allow-list of LinkedIn-account emails.
Prerequisites
Node.js 18+
A LinkedIn Marketing Developer Platform-approved app
A Google Cloud project (Mode B only)
Step 1 — Create a LinkedIn Developer App
Go to LinkedIn Developer Portal and create an app (or use an existing one).
Under Products, request:
Sign In with LinkedIn using OpenID Connect (gives
openid emailfor user identification)Marketing Developer Platform (gives
r_ads,r_ads_reporting,rw_ads,r_organization_social,w_organization_social— required for the ads tools; access requires LinkedIn approval)
Under Auth → OAuth 2.0 settings → Authorized redirect URLs, add:
http://localhost:8080/oauth/callback(local dev)https://YOUR-CLOUD-RUN-URL/oauth/callback(Mode B — add after deploy)
Copy the Client ID and Client Secret — you'll need them in the env config below.
Step 2 — Install
git clone https://github.com/dhawalshah/linkedin-ads-mcp
cd linkedin-ads-mcp
npm install
cp .env.example .env # fill in valuesStep 3 — Mode A: Local STDIO
npm run auth # one-shot browser sign-in; saves token to ~/.linkedin-ads-mcp/tokens.json
npm run buildThen add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"linkedin-ads": {
"command": "node",
"args": ["/absolute/path/to/linkedin-ads-mcp/dist/index.js"],
"env": {
"LINKEDIN_CLIENT_ID": "your_client_id",
"LINKEDIN_CLIENT_SECRET": "your_client_secret"
}
}
}
}Restart Claude Desktop. You're done — skip the rest.
Step 3 — Mode B: Remote HTTP server (Claude Teams / claude.ai)
Enable Firestore
The server stores OAuth bearer tokens and per-user LinkedIn credentials in Firestore.
In Cloud Console, Firestore → Create database → Native mode, pick a region.
Grant the Cloud Run service account Cloud Datastore User role under IAM & Admin → IAM.
Deploy to Cloud Run
gcloud run deploy linkedin-ads-mcp \
--source . \
--region YOUR_REGION \
--project YOUR_PROJECT_ID \
--platform managed \
--port 8080 \
--allow-unauthenticated \
--set-env-vars "GCP_PROJECT_ID=your-project-id,BASE_URL=https://YOUR-SERVICE-URL.run.app,LINKEDIN_CLIENT_ID=...,LINKEDIN_CLIENT_SECRET=..."Recommended: store
LINKEDIN_CLIENT_SECRETin Secret Manager and inject via--set-secretsrather than as a plain env var.
After it's up, go back to the LinkedIn Developer Portal and add the live callback URL:
https://YOUR-SERVICE-URL.run.app/oauth/callbackConnect from Claude
Claude Teams (org owner adds it once for everyone):
Settings → Connectors → Add custom connector
URL:
https://YOUR-SERVICE-URL.run.app/mcpEach member clicks Connect, signs in with LinkedIn, done.
claude.ai personal:
Settings → Connectors → Add custom connector
URL:
https://YOUR-SERVICE-URL.run.app/mcp
Claude Desktop with a remote server:
{
"mcpServers": {
"linkedin-ads": {
"url": "https://YOUR-SERVICE-URL.run.app/mcp"
}
}
}Claude Desktop will run the OAuth dance the first time you use it.
Environment Variables
Variable | Required | Description |
| Yes | OAuth client ID from your LinkedIn app. |
| Yes | OAuth client secret from your LinkedIn app. |
| No | Override the LinkedIn callback URL. Defaults to |
| Mode B | Public URL of this service. Used for OAuth metadata and as the canonical resource URI tokens are bound to. |
| Mode B | GCP project hosting Firestore. |
| No | Comma-separated allow-list of LinkedIn-account emails. Empty = no restriction. |
| Mode A | Override the local token file path. Defaults to |
| Mode A | Inline JSON to seed local tokens (overrides the file). |
| No | HTTP port (default |
Available Tools
Account & Campaign Management
Tool | Description |
| List all accessible LinkedIn ad accounts |
| Account name, currency, status, and serving status |
| List campaigns for an account |
| List campaign groups |
| Manage campaign groups |
| Manage campaigns |
| Manage creatives |
| One-shot creative + campaign creation |
| Upload an image asset for use in creatives |
Performance & Analytics
Tool | Description |
| Impressions, clicks, cost, CTR, CPC, conversions per campaign |
| Performance metrics broken down by creative, including engagement and video metrics |
| Side-by-side comparison of two date ranges |
| Daily performance trend data |
Audience & Demographics
Tool | Description |
| Performance breakdown by demographic pivot (industry, seniority, function, etc.) |
| Reach and impression counts across an audience |
| List saved targeting audiences |
Conversions & Lead Gen
Tool | Description |
| All configured conversion actions |
| Conversion counts and value across campaigns |
| All Lead Gen forms on an account |
| One-click leads, form opens, qualified leads |
Ad Library (Public)
Tool | Description |
| Search any advertiser's public LinkedIn ads with filters |
Example Prompts
List my LinkedIn ad accounts
Show campaign performance for the last 30 days
Compare last week vs the week before for account 12345
Which industries are clicking most on campaign X?
What did my top creative drive in conversions last month?
Search the LinkedIn Ad Library for ads from Stripe in the US in 2026OAuth endpoint reference (Mode B)
For developers who want to verify the implementation or write their own MCP client.
Endpoint | Spec | Purpose |
| RFC 9728 | Advertises the canonical resource URI and authorization server. |
| RFC 8414 | Authorization server metadata. |
| RFC 7591 | Dynamic Client Registration. |
| OAuth 2.1 | Starts the auth code flow with PKCE; redirects to LinkedIn. |
| — | LinkedIn redirects here; we mint our authorization code and bounce back to the MCP client. |
| OAuth 2.1 | Authorization code + refresh token grants. |
A GET /mcp without a valid bearer returns 401 with a WWW-Authenticate: Bearer resource_metadata="…" header pointing at the protected-resource metadata document, which is how a standards-compliant MCP client discovers the rest.
PKCE caveat: LinkedIn's OAuth implementation does not support PKCE on the upstream side, so PKCE is only enforced on the Claude → us channel. The us → LinkedIn channel uses a
stateparameter for CSRF protection.
Tech Stack
TypeScript + Node 18+
@modelcontextprotocol/sdk — MCP server framework
Express — HTTP server
@google-cloud/firestore — per-user token storage and OAuth-server state (Mode B)
Google Cloud Run — Serverless hosting
About Dhawal Shah
I run a 40-plus person digital marketing agency out of Singapore, and I build the automation my own teams use. This server is one of those tools rather than a weekend project: it runs against live LinkedIn Ads accounts every week, which is why the read-only surface is wide and the write surface is deliberately narrow.
Fourteen years building companies across Asia behind it. 5,000+ campaigns, 400+ brands, 30+ startups advised, and 300+ training sessions for teams including Sony, Toyota, DHL and Interpol. I am also an Accredited Director with the Singapore Institute of Directors, which in practice means I get asked what breaks, who is accountable and what it costs before anyone asks what it can do.
I write up the routines and agents I actually run at dhawalshah.net.
Worth reading alongside this repo: Google Ads, Meta, LinkedIn & TikTok MCPs for Claude: Agency Setup Guide.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted MCP server for Google Ads and LinkedIn Ads analysis.
Managed LinkedIn MCP server for AI agents: search, connect, message and enrich on accounts you own.
Google Ads MCP server — manage campaigns, keywords, and metrics.
- LinkMCPOAuthio.linkmcp
Hosted MCP server for LinkedIn: 31 tools for profiles, search, messaging, posts, enrichment.
Related MCP Servers
- AlicenseBqualityDmaintenanceAn MCP server that connects Claude to the LinkedIn Ads API for natural-language control over campaign management, audience targeting, creative uploads, analytics, and account auditing.377 npmMIT
- AlicenseNot gradedqualityCmaintenanceUnified MCP server for managing Meta Ads, LinkedIn Ads, Google Ads, GA4, and Search Console with 89 read/write tools, multi-account support, OAuth setup, and safe dry-run mutations.MIT
- AlicenseBqualityAmaintenanceA read-only MCP server for LinkedIn Ads that enables users to query ad accounts, campaigns, creatives, insights, and company intelligence via natural language.11MIT
- FlicenseNot gradedqualityDmaintenanceMCP server for posting and managing LinkedIn content, supporting personal and company accounts. Deployed on Cloudflare Workers with token management via KV.-