safe-meta-ads-mcp
Enables advertising using Facebook Pages, such as creating creatives posted as a Facebook Page and listing the Pages available to the ad account.
Supports linking an Instagram account to ad creatives so ads can be delivered through Instagram.
Provides tools for managing Meta ad accounts, campaigns, ad sets, creatives, and ads through Meta's Marketing API, including budgets, targeting, status changes, and media uploads, with safeguards to keep new objects paused until activation is approved.
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., "@safe-meta-ads-mcpCreate a paused campaign for my new product launch"
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.
safe-meta-ads-mcp

An MCP server for Meta ads. It lets Claude, or any other MCP client, read your ad accounts and build campaigns, ad sets, creatives and ads through Meta's official Marketing API, with guards that keep an agent from turning on spend by accident.
Everything it creates starts paused, whatever the agent asks for. Pausing is always allowed. Turning anything on needs the exact phrase ACTIVATE AND ALLOW SPEND, which the agent is told to ask you for, and when your MCP client can show a form, the server also asks you there, with the daily budget at stake, before anything goes live. Set a daily budget ceiling and it refuses anything that would take a campaign above it. The access token stays inside the server: no tool returns it, and it is stripped from every result and every error.
We built it for the launches we run. One build for a real product launch created 21 ad sets, 456 creatives and 455 ads, and every ad set and ad was created paused, waiting for a person to say go. It uploaded 563 images and videos on the way. Two of the videos came back with HTTP 413, too large to send in a single request, so this server uploads video in chunks, the way Meta's own SDK does, and resumes an interrupted upload where it stopped. The write-up, with how the guards work and how to keep the token out of the chat: Meta ads MCP: Claude builds the campaign, and nothing spends until you say go.
See it in under a minute
https://github.com/user-attachments/assets/dc779ea4-b847-49ff-b29d-0416a158fe8c
Related MCP server: meta-ads-mcp
Quick start
You need Node.js 20 or later and a Meta access token with the ads_management permission. The FAQ explains how to get one.
Claude Code. On a Mac, keep the token in the Keychain. The first command asks for it and does not echo it.
security add-generic-password -s safe-meta-ads-mcp -a meta -w
claude mcp add meta-ads -- npx -y github:oussch702/safe-meta-ads-mcp --keychain safe-meta-ads-mcp --max-daily-budget 5000Elsewhere, pass the token from your shell's environment instead:
claude mcp add meta-ads -e META_ACCESS_TOKEN="$META_ACCESS_TOKEN" -- npx -y github:oussch702/safe-meta-ads-mcp --max-daily-budget 5000Claude Desktop. Open Settings, then Developer, then Edit Config, and add the server to claude_desktop_config.json:
{
"mcpServers": {
"meta-ads": {
"command": "npx",
"args": ["-y", "github:oussch702/safe-meta-ads-mcp", "--keychain", "safe-meta-ads-mcp", "--max-daily-budget", "5000"]
}
}
}Without the Keychain, drop the two --keychain arguments and add "env": { "META_ACCESS_TOKEN": "your token" } next to args. Restart Claude Desktop afterwards.
The first start downloads the server and its two dependencies. If your client gives up while that happens, run npx -y github:oussch702/safe-meta-ads-mcp --version once in a terminal, then start it again.
Then ask Claude to run meta_diagnose. It reports what the token can do, the state of your ad account, and the Facebook Pages you can advertise with.
What it does
Reads your accounts. Ad accounts, campaigns, ad sets and ads with their status, budget and spend, and insights for any period, split by day, level or breakdowns such as age, gender, country or placement.
Builds campaigns, paused. It creates campaigns, ad sets, creatives and ads, and duplicates ads. The create tools have no status input, and the server sets
PAUSEDon every campaign, ad set, ad and copy it creates, so nothing an agent passes can start delivery.Turns things on only with the phrase.
meta_set_statuspauses anything at once. Activating needsconfirmset to exactlyACTIVATE AND ALLOW SPEND, and when the client supports MCP elicitation, a yes from you in a form that shows the ID and the daily budget at stake, never text the agent wrote. With--max-daily-budget, the server first reads from Meta what the campaign would spend per day once the object is on, and refuses when that is above your ceiling.Uploads media. Images go up in one request. Videos go up in chunks, with the progress saved after each one, so an interrupted upload resumes from the last chunk Meta confirmed, even after a restart. The tool then waits until Meta has processed the video. It only sends files that are images or videos by their content, not just by their name.
Respects Meta's rate limits. It reads the usage headers on Meta's answers, slows down as usage climbs, waits out a limit for as long as Meta says it lasts (up to
--max-wait), and retries the errors Meta marks as temporary, except when something is being created.Explains errors. Meta's error codes come back as a plain sentence followed by Meta's own message, for example: Meta rejected the access token: it has expired. Create a new token, then restart the server.
Tools
Read tools, always available:
Tool | What it does |
| The ad accounts the token can use, with status, currency and time zone. |
| Campaigns with status, budget, and spend and impressions for a period. |
| Ad sets of an account or a campaign, with budget, optimization goal and spend. |
| Ads of an account, campaign or ad set, with review feedback and delivery issues. |
| Spend, reach, clicks, costs and actions for a date range, by level, by day or by breakdown. |
| What the token can do: permissions, account status, payment method, and the Pages it can advertise with. |
Write tools, left out with --read-only:
Tool | What it does |
| Creates a campaign, paused, with an optional campaign budget. |
| Creates an ad set with targeting, budget and optimization goal, paused. |
| Creates a website-link creative from one image or one video, posted as your Facebook Page, with an optional Instagram account. |
| Creates an ad from an ad set and a creative, paused. |
| Uploads an image to the ad account and returns its hash. |
| Uploads a video in chunks, resumes after an interruption, and waits for processing. |
| Copies an ad into the same ad set or another one, paused. |
| Pauses anything. Activates only with the phrase and under the budget ceiling, and asks you directly when the client can. |
Example session
An example, with made-up names and IDs, on a server started with --max-daily-budget 5000:
You Set up a traffic campaign for the spring sale: 20 USD a day, people in the
US aged 25 and over, with hero.jpg from the ads folder.
Claude meta_create_campaign "Spring sale", OUTCOME_TRAFFIC, daily_budget 2000
campaign 2001, PAUSED
meta_create_ad_set campaign 2001, "US 25+", LINK_CLICKS, US, age_min 25
ad set 2002, PAUSED
meta_upload_image ads/hero.jpg
image_hash 6f1c09e2
meta_create_creative Page 3001, https://example.com/spring, image 6f1c09e2
creative 2003
meta_create_ad ad set 2002, creative 2003
ad 2004, PAUSED
meta_set_status campaign 2001, ACTIVE
Not activated. No confirmation phrase was given. Turning this on can spend
money, so the person has to approve it: ask them to type ACTIVATE AND ALLOW
SPEND, then call again with confirm set to exactly that. Nothing was changed.
Everything is built and paused. To start spending 20 USD a day, type
ACTIVATE AND ALLOW SPEND.
You ACTIVATE AND ALLOW SPEND
Claude meta_set_status campaign 2001, ACTIVE, confirm "ACTIVATE AND ALLOW SPEND"
ACTIVE, daily budget 2000 checked against the ceiling of 5000
meta_set_status ad set 2002, ACTIVE, confirm "ACTIVATE AND ALLOW SPEND"
meta_set_status ad 2004, ACTIVE, confirm "ACTIVATE AND ALLOW SPEND"
The ad goes live once Meta has reviewed it.Options
The token comes from the META_ACCESS_TOKEN environment variable, unless --keychain names a Keychain item.
Option | What it does |
| Default ad account, with or without |
| Registers only the six read tools. Nothing can be created or changed. |
| Refuses to create anything with a daily budget above |
| Reads the token from this macOS Keychain item. |
| Graph API version. Default |
| How long one call may wait out a rate limit or video processing before it returns. Default 120. |
| Where interrupted video uploads keep their progress. Default |
What it cannot do
Delete anything. No tool deletes or archives a campaign, ad set, ad or file.
Edit what already exists, apart from pausing and activating. Budgets, targeting and creatives of existing objects are changed in Ads Manager.
Build every ad format. Creatives are website-link ads with one image or one video. Carousels, collections, catalog ads, lead forms and dynamic creative are not covered.
Stop an agent that ignores its instructions, on every client. The phrase is a deliberate step, not a password. When your client supports MCP elicitation, the server asks you directly and the agent cannot answer for you. Otherwise, Claude Desktop and Claude Code still ask you before each tool call unless you have allowed that tool permanently, so keep
meta_set_statuson ask, and use--read-onlywhen you only need reports.Run very large reports. Insights use Meta's synchronous endpoint. Meta's asynchronous report jobs are not supported.
Retry a create after a lost connection or a temporary error. Either way the object may exist or not. The server says so instead of retrying, and the agent should list before trying again. Rate limits are the exception: Meta refuses those calls outright, so they are retried.
Touch billing or business settings. Payment methods, spending limits and Business Manager permissions stay in Meta's own tools.
FAQ
Can an AI agent spend my ad budget?
Not by accident. Everything an agent creates here starts paused, and the create tools have no way to ask for anything else. The one tool that turns ads on refuses unless it receives the exact phrase ACTIVATE AND ALLOW SPEND, which the agent is instructed to ask you for, and clients that support MCP elicitation also show you a yes or no before anything goes live. With --max-daily-budget, activation is refused whenever it would take a campaign above your ceiling, phrase or not. If you only want reports, --read-only removes every write tool.
Does it work with Instagram ads?
Yes. Instagram ads use the same campaigns, ad sets and ads. Leave publisher_platforms out of the ad set's targeting and Meta uses all its default platforms, Instagram included, or set it to ["instagram"] to run on Instagram only. Pass instagram_user_id when you create the creative to show your Instagram account on those placements.
How do I get a Meta access token? Use a system user, the kind of account Meta provides for software that calls its API.
In Meta for Developers, create an app and connect it to your business portfolio.
In Meta Business Suite, open Business settings, then Users, then System users. Add a system user and assign it your ad account and the Facebook Page your ads run as, with permission to advertise.
Generate a token for the system user and your app, with the
ads_management,ads_readandpages_read_engagementpermissions.Store it in the macOS Keychain or in
META_ACCESS_TOKEN, then runmeta_diagnoseto see what it can do.
If Meta answers that your app is still in Development mode, switch it to Live in Meta for Developers before you create creatives.
Is this official? No. It is an independent open-source project by AI Strike Force, not made or endorsed by Meta or Anthropic. It calls Meta's official Marketing API with your own token, so Meta's terms and limits apply as they would to any app you build.
Contributing
Issues and pull requests are welcome. Run npm test before sending a change. The tests run against a fake Graph API and never call Meta.
License
MIT
Built by AI Strike Force, an AI automation agency. We publish the tools and findings that come out of the systems we run.
This server cannot be deployed
Maintenance
Related MCP Connectors
Read and manage Meta Ads campaigns, ad sets, ads, audiences, pages and Business Manager. You provide
Connect authorized ad accounts to AI assistants for audits, reporting, and approval-gated changes.
Run Google, Meta, Microsoft, TikTok and LinkedIn Ads from Claude or ChatGPT. Writes need approval.
Meta Ads MCP: bulk-create Facebook & Instagram ads across accounts from Drive folders, guardrailed.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceEnables programmatic access to Meta Ads data and management features, including campaign insights, ad account details, performance metrics, and change history through the Meta Ads API.-
- AlicenseNot gradedqualityCmaintenanceProvides read-only access to Meta Ads data and optionally creates paused ads, with safety features like OAuth and validation.1,161 npmMIT
- FlicenseNot gradedqualityBmaintenanceMCP server for the Meta Marketing API enabling ad performance reports and operational adjustments like pause/resume and budget changes on client ad accounts, with strict allowlist and read-only safeguards.-
- AlicenseNot gradedqualityAmaintenanceEnables running marketing platforms like Google Ads, Meta Ads, GA4, Search Console, Tag Manager, and WordPress from any MCP client to read performance, audit wasted spend, build reports, and launch campaigns (created paused until you say otherwise).1MIT