Meta Ads Mcp Server

by hashcott

Not rated
GitHub

About

MCP (Model Context Protocol) server for the Meta (Facebook) Ads API.

Details

Author
hashcott
Categories
Productivity, Other, Marketing, API

Setup

Install Meta Ads Mcp Server in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/hashcott/meta-ads-mcp-server

Follow the installation instructions in the repository README, then restart your MCP client.

AModel Context Protocolserver for theMeta (Facebook) Ads API, written in TypeScript.
54 tools— 35 read tools (always on) plus 19 opt-in write/lifecycle tools — covering ad accounts, campaigns, ad sets, ads, creatives, media, insights, targeting catalog, Facebook Pages, budget schedules, and activity logs via theMeta Graph API v22.0.

Works withCursor,Claude Desktop(stdio) andClaude.aicustom connectors (HTTP).

Disclaimer:This is an unofficial third-party tool and is not associated with, endorsed by, or affiliated with Meta in any way. This project is maintained independently and uses Meta's public APIs in accordance with theirTerms of Service. Meta, Facebook, Instagram, and other Meta brand names are trademarks of their respective owners.

- Features
-
Requirements
-
Installation
-
Obtaining a Meta Access Token
-
Authentication
-
Enabling Write Tools
-
Transport Modes
-
Cursor / Claude Desktop Setup
-
Remote HTTP Server
-
Available Tools

- Accounts
-
Campaigns
-
Ad Sets
-
Ads
-
Creatives
-
Media
-
Insights
-
Targeting Catalog
-
Pages
-
Budget Schedules
-
Activities
-
Pagination

All mutation tools (create / update / delete / pause / resume / upload / budget schedule) areoff by defaultand only register when you opt in — seeEnabling Write Tools.

- Node.js>= 18
- AMeta User Access Tokenwith the right permissions for what you plan to do — see below.

# From npm npx meta-ads-mcp-server --access-token YOUR_META_ACCESS_TOKEN # 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

This server uses theMeta Marketing API. You need an access token attached to a Meta App that has the right permissions.

Quick option — Graph API Explorer (read-only experiments)

- Open the
Graph API Explorer. - Pick your Meta App from the top-right dropdown (create one atdevelopers.facebook.com/appsif you don't have any — choose type "Business"). - ClickGenerate Access Token, then underPermissionsadd at minimum:

- ads_read— for all the read tools.
- ads_management— required for any write tool (create / update / delete / pause / resume / upload / budget schedule).
- business_management— recommended if you operate via Business Manager.
- pages_show_list,pages_read_engagement— required for the Pages tools.

Production option — long-lived User token

Short-lived tokens from the Explorer expire in about an hour. Exchange yours for a 60-day token:

curl -G "https://graph.facebook.com/v22.0/oauth/access_token" \ --data-urlencode "grant_type=fb_exchange_token" \ --data-urlencode "client_id=YOUR_APP_ID" \ --data-urlencode "client_secret=YOUR_APP_SECRET" \ --data-urlencode "fb_exchange_token=YOUR_SHORT_LIVED_TOKEN"

Response contains"access_token": "..."— that token is valid for ~60 days. Refresh it the same way before it expires, or build a full OAuth flow if you need permanent access.

Production option — System User token (recommended for servers)

For unattended production use (no expiry), generate aSystem Usertoken in Business Manager:
- Go to
Business Manager → Business Settings → Users → System Users.
- Create a system user (or use an existing one), assign the relevant ad account, and grantads_read/ads_management.
- ClickGenerate New Token→ pick your Meta App → select the same permissions →Neverfor expiration.

System User tokens don't expire and are ideal for backend deployments.

curl "https://graph.facebook.com/v22.0/me?access_token=YOUR_TOKEN"

Should return your user/system-user object. If it returns an error, double-check the permissions and that the token isn't expired.

Pass your Meta access token using either method:

CLI argument (recommended for Cursor / Claude Desktop):

node dist/index.js --access-token YOUR_META_ACCESS_TOKEN
export META_ADS_ACCESS_TOKEN=YOUR_META_ACCESS_TOKEN node dist/index.js

The token is held only in memory of the running process — it is never written to disk by this server.

By default the server registersonly the 35 read tools— create / update / delete / pause / resume / upload / budget-schedule tools arenot exposed. This is intentional: a mistakenly-issuedmeta_ads_delete_campaigncan permanently remove campaigns and their ads.

Accepted truthy values:true,1,yes,on(case-insensitive). Anything else (or unset) keeps writes off.

When enabled, the server logs a one-line warning to stderr at startup:

[meta-ads-mcp] WARNING: META_ADS_ENABLE_WRITE_TOOLS is on — create/update/delete/pause/resume tools are EXPOSED. These can permanently delete campaigns/ad sets/ads or change live delivery.

Your access token also needs theads_managementpermission for the writes to succeed.

Example Cursor / Claude Desktop configuration with writes enabled:

{ "mcpServers": { "meta-ads": { "command": "npx", "args": ["-y", "meta-ads-mcp-server"], "env": { "META_ADS_ACCESS_TOKEN": "YOUR_META_ACCESS_TOKEN", "META_ADS_ENABLE_WRITE_TOOLS": "true" } } } }

Add one of the following to your MCP client configuration file:

Via npx (recommended — no local install required):

{ "mcpServers": { "meta-ads": { "command": "npx", "args": ["-y", "meta-ads-mcp-server", "--access-token", "YOUR_META_ACCESS_TOKEN"] } } }
{ "mcpServers": { "meta-ads": { "command": "node", "args": ["/path/to/meta-ads-mcp/dist/index.js", "--access-token", "YOUR_META_ACCESS_TOKEN"] } } }

Via environment variable (and opt-in writes):

{ "mcpServers": { "meta-ads": { "command": "npx", "args": ["-y", "meta-ads-mcp-server"], "env": { "META_ADS_ACCESS_TOKEN": "YOUR_META_ACCESS_TOKEN", "META_ADS_ENABLE_WRITE_TOOLS": "true" } } } }

Run as a persistent HTTP server for use with Claude.ai custom connectors or any remote MCP client.

# Start on default port 3000 TRANSPORT=http META_ADS_ACCESS_TOKEN=YOUR_TOKEN node dist/index.js # Start on a custom port, writes enabled TRANSPORT=http \ META_ADS_ACCESS_TOKEN=YOUR_TOKEN \ META_ADS_ENABLE_WRITE_TOOLS=true \ PORT=8080 \ node dist/index.js

- POST /mcp— MCP protocol endpoint
- GET /health— Health check ({"status":"ok"})
- Go toSettings → Connectors → Add custom connector
- Enter your server URL:https://your-domain.com/mcp
- ClickAdd

# Terminal 1 — start the server TRANSPORT=http META_ADS_ACCESS_TOKEN=YOUR_TOKEN PORT=8080 node dist/index.js # Terminal 2 — expose publicly ngrok http 8080

Use the generated HTTPS URL (e.g.https://xxxx.ngrok-free.app/mcp) as your connector URL.

Set the following environment variables on your hosting provider (Railway, Render, Fly.io, etc.):

Legend: 🔍 read • ✏️ write (gated byMETA_ADS_ENABLE_WRITE_TOOLS) • 🛠️ pure utility (no API call).

- act_id(string)— Ad account ID, formatact_XXXXXXXXX.
- name(string)— Campaign name.
- objective(enum)— ODAX outcome-based objective:

- OUTCOME_AWARENESS,OUTCOME_TRAFFIC,OUTCOME_ENGAGEMENT,OUTCOME_LEADS,OUTCOME_SALES,OUTCOME_APP_PROMOTION.
- Legacy objectives (BRAND_AWARENESS,LINK_CLICKS,CONVERSIONS,APP_INSTALLS, …) arenotaccepted by Meta v22+ and will return HTTP 400.

{ "act_id": "act_123456789012345", "name": "2026 - Spring Sale - Awareness", "objective": "OUTCOME_AWARENESS", "special_ad_categories": [], "status": "PAUSED", "bid_strategy": "LOWEST_COST_WITHOUT_CAP", "daily_budget": 10000 }

- Required:act_id,campaign_id,name,optimization_goal,billing_event.
- targeting(object)— full targeting spec; remembertargeting_automation.advantage_audiencedefaults to0on Meta v24+ — set it explicitly if you want Advantage+ Audience.
- bid_amount— required forLOWEST_COST_WITH_BID_CAP/COST_CAP.
- bid_constraints— required forLOWEST_COST_WITH_MIN_ROAS, e.g.,{"roas_average_floor": 20000}for a 2.0× ROAS floor.
- dsa_beneficiary/dsa_payor— required for EU-targeted ad sets.
- promoted_object— required forAPP_INSTALLS.
- frequency_control_specs— MUST be set at creation; Meta makes it immutable afterward.
- regional_regulated_categories/regional_regulation_identities— Taiwan / Australia / Singapore / India regulated verticals.

ℹ️ Swappingcreative_idon a FLEX ad can fail witherror_subcode 3858355if the new creative'sasset_feed_specimages don't match itsobject_story_spec. In that case, create a new ad with the new creative and pause the old one (you lose social proof but the ad runs).

meta_ads_create_ad_creative— three common modes:
- Promote an existing post: pass onlyobject_story_idin the form{page_id}_{post_id}.
- Single-image link ad:page_id+image_hash+link_url+message+ optionalheadline,description,call_to_action_type.
- Single-video ad:page_id+video_id+link_url+message+ optionalheadline,call_to_action_type,thumbnail_url.

For advanced layouts (FLEX/DOF, Placement Asset Customization, Dynamic Creative, multi-headline, lead-gen forms, branded content, image crops), pass a fully composedobject_story_specand/orasset_feed_spec— those take precedence over the simple-mode auto-construction.

meta_ads_upload_ad_imageacceptsexactly oneof:

- file— a data URL (data:image/png;base64,iVBORw0KG...) or a raw base64 string.
- image_url— a public URL; the server downloads the bytes and uploads them.

Returns theimage_hashyou then pass tometa_ads_create_ad_creative.

All four accept the same option surface:fields,date_preset,time_range,time_ranges,time_increment,level,action_attribution_windows,action_breakdowns,breakdowns,filtering,sort, pagination, and locale.

Time-range precedence:time_ranges>time_range>since/until>date_preset.

The returnedpage_idvalues are the ones you pass tometa_ads_create_ad_creative.

- campaign_id(string)
- budget_value(int, positive)
- budget_value_typeABSOLUTE(cents in account currency) orMULTIPLIER(e.g.,2doubles the budget)
- time_start,time_end(Unix timestamps in seconds)time_end > time_start

A typical "build a new ad" workflow uses tools across several categories. WithMETA_ADS_ENABLE_WRITE_TOOLS=true:

1. meta_ads_list_ad_accounts → pick an act_id 2. meta_ads_get_account_pages → pick a page_id 3. meta_ads_search_geo_locations(q="Vietnam") → grab the country/region keys 4. meta_ads_search_interests(q="cooking") → grab interest IDs 5. meta_ads_estimate_audience_size(act_id, targeting) → sanity-check reach 6. meta_ads_upload_ad_image(act_id, image_url) → returns image_hash 7. meta_ads_create_campaign(act_id, ...) → returns campaign_id 8. meta_ads_create_adset(act_id, campaign_id, targeting, ...) → returns adset_id 9. meta_ads_create_ad_creative(act_id, page_id, image_hash, link_url, message, ...) → returns creative_id 10. meta_ads_create_ad(act_id, name, adset_id, creative_id, status="PAUSED") → returns ad_id 11. (Optional) meta_ads_get_ad_previews(ad_id, ...) → render placements before going live 12. meta_ads_resume_ad(ad_id) → flip to ACTIVE when ready

All steps that mutate state default tostatus: "PAUSED"so nothing goes live until you explicitly call a resume tool.

Many list tools return paginated results. When a response contains apaging.nextURL, usemeta_ads_fetch_pagination_urlto retrieve subsequent pages:

1. Call meta_ads_get_campaigns_by_adaccount → receive first page 2. Check if response.paging.next exists 3. Call meta_ads_fetch_pagination_url(url=response.paging.next) → receive next page 4. Repeat until paging.next is absent
npm run dev # Watch mode — auto-recompile on change npm run build # Compile TypeScript to dist/ npm run clean # Remove dist/ npm run clean && npm run build # Full rebuild from scratch
# Default (read-only) META_ADS_ACCESS_TOKEN=dummy node dist/index.js # → "Meta Ads MCP server running via stdio" # With writes enabled META_ADS_ACCESS_TOKEN=dummy META_ADS_ENABLE_WRITE_TOOLS=true node dist/index.js # → WARNING line + "Meta Ads MCP server running via stdio"
meta-ads-mcp/ ├── src/ │ ├── index.ts # Entry point, server setup, transport selection, write-tools warning │ ├── constants.ts # API version, base URLs, isWriteToolsEnabled() flag │ ├── types.ts # Shared TypeScript interfaces │ ├── services/ │ │ └── graph-api.ts # HTTP client (GET/POST/DELETE), auth, error handling, param builders │ ├── schemas/ │ │ ├── common.ts # Shared Zod schemas (pagination, date ranges, filters) │ │ └── insights.ts # Insights-specific Zod schemas │ └── tools/ │ ├── accounts.ts # Account tools │ ├── insights.ts # Insights tools (account/campaign/adset/ad level) │ ├── campaigns.ts # Campaign read + write/lifecycle tools │ ├── adsets.ts # Ad set read + write/lifecycle tools │ ├── ads.ts # Ad read + write/lifecycle tools │ ├── creatives.ts # Creative read tools, image crops utility, create/update creative │ ├── media.ts # Image list / upload / hash lookup / video / preview │ ├── activities.ts # Activity log tools │ ├── pagination.ts # Pagination utility tool │ ├── targeting.ts # Interest/behavior/demographic/geo search + audience-size estimate │ ├── pages.ts # Facebook Pages list and name search │ └── budget-schedules.ts # Campaign budget schedule create ├── dist/ # Compiled JavaScript output (generated) ├── package.json └── tsconfig.json

MCP server for Walmart Connect Ads (Sponsored Search + Display) — automatic RSA-SHA256 signing, multi-region config, and bundled API docs.

A Model Context Protocol (MCP) server for TikTok Ads API integration. This server enables AI assistants like Claude to interact with TikTok advertising campaigns, providing comprehensive campaign management, analytics, and optimization capabilities. Part of the AdsMCP project - MCP servers for advertising platforms.

An MCP server that serves ads to developers in clients like Cursor and Claude.

A remote Google Ads MCP server built by a marketer for marketers

Interact with the Meta Ads API to access, analyze, and manage advertising campaigns.

Interact with Facebook and Instagram advertising data using the Meta Marketing API.

Interact with the Taboola advertising platform using natural language via the Taboola Realize API.

Google Ads MCP server for Claude and ChatGPT — create, manage, and optimize Google Ads campaigns from chat with budget-aware keyword generation and ad copy drafting.

MCP server for VK Ads API — manage ad plans, ad groups, banners, and pull statistics.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.