arielshemesh1999@gmail.com · Israel
← All articles

Meta Ads MCP servers

Four open-source Model Context Protocol servers that turn Claude, Cursor and Claude Desktop into a Meta Marketing API control surface — from a 5-tool campaign launcher to a 135-tool v25.0 monster covering catalogs, conversions and audiences.

What it is

The Meta Marketing API — the thing every agency, performance marketer and growth lead lives inside — is sprawling. Campaign, ad set, ad, creative, audience, pixel, catalog, business, page… each with its own create/read/update/delete surface and its own quirks. Four open-source MCP servers now wrap the entire Graph API and expose it to any client that speaks the Model Context Protocol. The pitch: stop clicking around Ads Manager, talk to Claude instead.

The MCP spec lets an AI assistant call a set of typed tools and read structured resources. Each of these servers translates “pause campaign 1234, lift the lookalike audience budget by 15%, fetch this week’s ROAS by ad set” into the exact Graph API requests Meta expects — with the right access token, ad account ID and rate-limit handling baked in.

Architecture

All four servers share the same shape. The MCP host (Claude Desktop, Cursor, Claude.ai connectors, Continue, etc.) launches the server as either a local stdio process or a remote HTTP endpoint. The server registers a tool list (e.g. create_campaign, get_ad_insights, upload_image) and waits. When the model calls a tool, the server signs the request with a Meta access token, hits graph.facebook.com/v25.0/…, parses the JSON, and returns a typed result the model can reason about.

Each server picks a different point on the simplicity–coverage curve:

  • pipeboard-co/meta-ads-mcp42 tools. Hosted remote MCP at meta-ads.mcp.pipeboard.co, OAuth via pipeboard.co, zero local config. Aimed at “just works” install. Python, BSL 1.1 (becomes Apache 2.0 on Jan 1 2029). Part of the five-platform Pipeboard family (Meta, Google, TikTok, Snap, Reddit, 230+ tools total).
  • mikusnuz/meta-ads-mcp135 tools. Full Graph API v25.0 coverage: campaigns, creatives, media, audiences, insights, leads, catalog & commerce, automation rules, experiments, conversions, budget planning, brand safety, ad library. Node, npx-installable. MIT.
  • hashcott/meta-ads-mcp-server54 tools (35 read + 19 write, write disabled by default). TypeScript, Node 18+, Meta Graph API v22.0. Both stdio and HTTP transports, deployable to Railway/Render/Fly. MIT.
  • attainmentlabs/meta-ads-manager-mcp5 tools: create_meta_campaign, get_campaign_status, pause_campaign, activate_campaign, delete_campaign. Python, uvx-installable. New campaigns default to PAUSED + dry_run=True. MIT.

Install

Each server is one command. Pick by how much surface area you actually want.

mikusnuz (135 tools, npx):

npx -y @mikusnuz/meta-ads-mcp

hashcott (54 tools, npx with token):

npx meta-ads-mcp-server --access-token YOUR_META_ACCESS_TOKEN

hashcott (from source):

git clone https://github.com/hashcott/meta-ads-mcp.git
cd meta-ads-mcp
npm install
npm run build
node dist/index.js --access-token YOUR_META_ACCESS_TOKEN

attainmentlabs (5 tools, uvx Python):

uvx meta-ads-manager-mcp

pipeboard-co (remote, no local install): just point your MCP client at https://meta-ads.mcp.pipeboard.co/ and OAuth-connect once at pipeboard.co. There is no npx or pip step.

Configuration

Meta auth is the gate. You need three things: an app (App ID + App Secret from developers.facebook.com), an access token with the right scopes, and the ad account ID in the form act_XXXXXXXXX.

Token scopes required for full Marketing API control:

  • ads_management — create/update/pause campaigns, ad sets, ads, plus all creative CRUD.
  • ads_read — insights, reporting, audience data.
  • business_management — act on assets owned by a Business Manager, system users, account assignments.
  • pages_show_list, pages_read_engagement — link page-based ad objects and lead forms.
  • leads_retrieval — pull Lead Ads form submissions.
  • catalog_management — catalog, product set, product and feed tools (mikusnuz only).

Three token flavours, in order of how much I trust them in production:

  1. Graph API Explorer token — ~1 hour, debugging only.
  2. 60-day user tokengrant_type=fb_exchange_token on /oauth/access_token, fine for personal tools.
  3. System User token — generated inside Business Manager (Settings → Users → System Users), no expiry, what every serious workflow uses.

Claude Desktop config at ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "meta-ads": {
      "command": "npx",
      "args": ["-y", "@mikusnuz/meta-ads-mcp"],
      "env": {
        "META_ADS_ACCESS_TOKEN": "EAABsbCS1iHg…",
        "META_AD_ACCOUNT_ID": "123456789012345",
        "META_APP_ID": "your-app-id",
        "META_APP_SECRET": "your-app-secret",
        "META_BUSINESS_ID": "your-business-id",
        "META_PIXEL_ID": "your-pixel-id"
      }
    }
  }
}

For hashcott, write tools are off by default; flip the env var to enable them:

"env": {
  "META_ADS_ACCESS_TOKEN": "EAA…",
  "META_ADS_ENABLE_WRITE_TOOLS": "true"
}

For pipeboard’s remote server, no token in the config — you authenticate once in the browser:

{
  "mcpServers": {
    "meta-ads-remote": { "url": "https://meta-ads.mcp.pipeboard.co/" }
  }
}

Code examples

The MCP layer is the wrapper; the real work is Graph API. Here is what each tool actually does under the hood.

Create a campaign via the v25.0 endpoint — this is what create_campaign resolves to:

POST https://graph.facebook.com/v25.0/act_123456789012345/campaigns
Content-Type: application/x-www-form-urlencoded

name=Spring%20Launch
&objective=OUTCOME_SALES
&status=PAUSED
&special_ad_categories=[]
&access_token=EAABsbCS1iHg…

Fetch insights — the get_ad_insights tool returns ROAS, CPC, CPM, CTR, conversions:

GET https://graph.facebook.com/v25.0/act_123456789012345/insights
  ?level=ad
  &fields=ad_id,ad_name,spend,impressions,clicks,ctr,cpc,
          actions,action_values,purchase_roas
  &date_preset=last_7d
  &access_token=EAA…

Upload a creative image (mikusnuz upload_image):

POST https://graph.facebook.com/v25.0/act_123456789012345/adimages
Content-Type: multipart/form-data

filename=creative_spring.jpg
&access_token=EAA…

Returns an image hash you reference when building an ad creative.

Typical Claude conversation once the server is wired up:

You: Pause every ad set in act_1234 with ROAS < 1.2 over the last 7 days.

Claude (tool call) -> get_ad_account_insights({
  account_id: "act_1234",
  level: "adset",
  date_preset: "last_7d",
  fields: ["adset_id", "purchase_roas"]
})

Claude (tool call) -> update_adset({
  adset_id: "238...91",
  status: "PAUSED"
}) x 6 underperformers

What’s new / version

Meta Marketing API v25.0 is the current graph version (Meta cuts a new one every 3–4 months; v25.0 has the longest active support window). Three shifts that matter:

  • Advantage+ shopping campaigns are now first-class — mikusnuz exposes the dedicated AAA endpoints in its 25-tool Campaign Management bucket.
  • Conversions API tools (4 in mikusnuz) handle server-side event sending for iOS 14.5+ attribution.
  • Catalog & Commerce got the biggest expansion — 17 tools for product feeds, sets, dynamic ads.

Version table:

  • mikusnuz/meta-ads-mcp — 135 tools, Graph API v25.0, MIT, Node.
  • pipeboard-co/meta-ads-mcp — 42 tools, hosted remote MCP, BSL 1.1 (Apache 2.0 Jan 1 2029), Python.
  • hashcott/meta-ads-mcp-server — 54 tools (35 read + 19 write), Graph API v22.0, MIT, Node 18+.
  • attainmentlabs/meta-ads-manager-mcp — 5 campaign-lifecycle tools, uvx-installable, MIT, Python 3.9+.

Why it matters / where I use it

I run paid campaigns for the landing pages I ship (Areta, Tzahi, AE Moments). Pre-MCP, every “quick check” meant Ads Manager — load the SPA, find the account, filter, eyeball numbers, click into ad sets, copy to a sheet. Post-MCP, I ask Claude “how did the Areta wine consulting ad set do this week vs last” and it pulls the insights, computes the delta and tells me what to pause. Same workflow, 30 seconds vs 10 minutes.

The split I use: mikusnuz when I need the full surface (catalog work, audience engineering), hashcott for read-heavy reporting (35 read tools, no write risk), pipeboard when I want zero-setup demo on someone else’s laptop, and attainmentlabs when I just want to launch one campaign and never touch the account again. Never give a model write tools on an account you can’t afford to recover — always test with a paused dev campaign first; attainmentlabs’ dry_run=True default is the cleanest safety belt I have seen.

The choice between v25.0 (mikusnuz) and v22.0 (hashcott) matters more than the Graph API version numbers make it look. v25.0 has the longest active support window right now and is the only version where Advantage+ shopping campaigns, the newer Conversions API endpoints, and the full ODAX outcome-based objective set are first-class. v22.0 still works fine for read-heavy reporting, but if you try to create_campaign with a legacy objective like LINK_CLICKS or CONVERSIONS, both versions will return HTTP 400 — only outcome-based values (OUTCOME_TRAFFIC, OUTCOME_SALES, …) are accepted.

One last operational note. mikusnuz exposes 3 MCP resources alongside the 135 tools — ads://account (account overview, balance, currency, timezone, total spend), ads://campaigns-overview (all active campaigns with budget), and ads://spending-today (spend, impressions, clicks, reach for the current day). Plus 3 MCP prompts: campaign_wizard, performance_report, audience_builder. Those resources are what makes “morning check” a single sentence: Claude reads ads://spending-today, compares it to yesterday’s budget, and tells me whether anything needs to pause. Worth wiring up before you start hand-crafting tool calls.

Source