Meta Ads MCP
A read-only MCP server that pulls Meta Ads campaign, ad-set, and ad performance data to help users spot problems and adjust them in Ads Manager.
README
Meta Ads MCP
Meta Ads MCP is a minimal, read-only Python MCP server that pulls Meta (Facebook) Ads campaign, ad-set, and ad performance so a human can spot problems and adjust them in Ads Manager earlier. It never changes budgets, statuses, or creatives.
Tools
| Tool | Purpose |
|---|---|
list_ad_accounts |
List the Meta ad accounts available to the configured access token. |
get_campaigns |
Get campaigns for an explicit or configured default ad account. |
get_adsets |
Get ad sets beneath an account or campaign parent. |
get_ads |
Get ads beneath an account, campaign, or ad-set parent. |
get_insights |
Get raw Meta performance metrics for an object and reporting period. |
performance_summary |
Rank campaigns by spend and flag performance symptoms for review. |
The flags from performance_summary are HEURISTIC signals, not diagnoses.
Conversions and ROAS are platform-reported (Meta attribution), not incremental;
a holdout or lift test is required to claim incrementality.
Prerequisites
- Python 3.10 or newer
Meta credentials
- Create a Meta app at Meta for Developers.
- Add the Marketing API to the app.
- Generate a long-lived User access token with the
ads_readpermission and access to the required ad account. - Find the ad account ID in Ads Manager. It must use the
act_<digits>form, such asact_123456789.
Meta's screens and access-token options can change. Follow the official Marketing API Get Started documentation for the current screens. Treat the access token as a secret.
Quick setup
One command does the whole setup:
python -m meta_ads_mcp setup
For the full walkthrough - creating the Meta app, redirect URI rules, giving teammates access, and a troubleshooting table - see docs/SETUP.md.
It asks for the app id and app secret (the secret is never echoed), writes
.env with owner-only permissions, runs the browser login, lists the ad
accounts the token can read so you pick one from a numbered menu, and registers
the server in claude_desktop_config.json (backing up any existing file).
Restart Claude Desktop afterwards.
If META_ACCESS_TOKEN is already set in .env, setup offers to keep it and
skips the login entirely. Useful options:
| Option | Purpose |
|---|---|
--client-config PATH |
Patch a different MCP client config. |
--command-path PATH |
Command the client should launch. |
--env-file PATH |
Write to a different dotenv file. |
The manual route below is still supported if you would rather set each piece yourself.
Environment setup
Copy the template and fill in your credentials:
Copy-Item .env.example .env
There are two ways to supply the token. Pick one.
Route A - paste a token
META_ACCESS_TOKEN=your-long-lived-user-access-token
META_AD_ACCOUNT_ID=act_123456789
META_GRAPH_API_VERSION=v23.0
A system user token from Business Manager (Business Settings > Users > System Users) never expires and needs no login flow. A manually generated user token expires in about 60 days.
Route B - browser login
Put the app credentials in .env and leave META_ACCESS_TOKEN blank:
META_APP_ID=your-app-id
META_APP_SECRET=your-app-secret
META_AD_ACCOUNT_ID=act_123456789
Then authorize in a browser:
python -m meta_ads_mcp login
The command opens the Facebook Login dialog, receives the redirect on
http://localhost:8721/callback, exchanges the code for a long-lived token,
and caches it at ~/.local/share/meta-ads-mcp/token.json (%LOCALAPPDATA%
equivalent via XDG_DATA_HOME) with owner-only permissions. The server picks
that cached token up automatically, so no token ever needs to sit in a config
file.
http://localhost:8721/callback must be listed under Facebook Login >
Settings > Valid OAuth Redirect URIs on the app. Change the port or scheme
with META_OAUTH_REDIRECT_URI if needed.
If Meta rejects a localhost redirect URI, use the paste flow instead - it uses Meta's own desktop redirect page and needs no registered URI:
python -m meta_ads_mcp login --paste
Log in, then copy the full URL from the browser address bar and paste it back at the prompt.
Related commands:
| Command | Purpose |
|---|---|
python -m meta_ads_mcp status |
Show the cached token's expiry. |
python -m meta_ads_mcp logout |
Delete the cached token. |
Meta issues no refresh tokens, so a long-lived user token lasts about 60 days;
rerun login when status shows it near expiry. Only a system user token
(route A) avoids re-authorizing entirely.
META_ACCESS_TOKEN always wins over the cached token when both are present.
META_GRAPH_API_VERSION is optional and defaults to v23.0. The .env file
is git-ignored; never commit it.
Install
Create a virtual environment and install the package with its development dependencies:
python -m venv .venv
.venv\Scripts\python.exe -m pip install -e ".[dev]"
If you already use uv, the install step can instead be:
uv pip install -e ".[dev]"
uv is optional and is not required.
Run
From an activated virtual environment, start the stdio server with:
python -m meta_ads_mcp
The installed console entry point is also meta-ads-mcp. A stdio MCP server
waits on standard input, so it is normally launched by an MCP client rather
than run interactively.
MCP client configuration
For Claude Desktop, add a server entry under mcpServers in
claude_desktop_config.json. Replace the example path and credentials:
{
"mcpServers": {
"meta-ads": {
"command": "C:\\Users\\your-name\\path\\to\\meta-ads-mcp\\.venv\\Scripts\\python.exe",
"args": ["-m", "meta_ads_mcp"],
"env": {
"META_ACCESS_TOKEN": "your-long-lived-user-access-token",
"META_AD_ACCOUNT_ID": "act_123456789"
}
}
}
}
For Claude Code, put the equivalent configuration in the project-level
.mcp.json; it mirrors the Desktop configuration:
{
"mcpServers": {
"meta-ads": {
"command": "C:\\Users\\your-name\\path\\to\\meta-ads-mcp\\.venv\\Scripts\\python.exe",
"args": ["-m", "meta_ads_mcp"],
"env": {
"META_ACCESS_TOKEN": "your-long-lived-user-access-token",
"META_AD_ACCOUNT_ID": "act_123456789"
}
}
}
}
The token and account ID can live in the client's env block instead of
.env. Keep client configuration containing a real token private.
If you used browser login (route B), omit META_ACCESS_TOKEN from the env
block entirely - the server reads the cached token from
~/.local/share/meta-ads-mcp/token.json. Leaving a placeholder string there
would override the cached token and every call would fail with an auth error.
Graph API version
The server pins Graph API v23.0 by default. If Meta deprecates that version,
set META_GRAPH_API_VERSION to a current supported version.
Smoke test
After filling .env, run the manual real-network check:
python scripts/smoke_test.py
It lists up to five accessible ad accounts and up to five campaigns from the configured default account.
Security
Never commit .env or paste the access token into logs, issues, or chat. The
server and all six tools are read-only.
The app secret is used only for the server-side code exchange and is never put
in a URL sent to the browser. The cached token file is written with 0600
permissions inside a 0700 directory, and the login flow validates the OAuth
state value with a constant-time comparison before exchanging any code.
Development
Run the test suite with:
pytest
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.