meta-ads-mcp
Allows reading and managing Facebook ads via the Meta Marketing API, including ad account setup, campaign budgeting, targeting, and creative management.
Provides integration with Instagram advertising, enabling ad previews, placement checks, and creation of Instagram-specific ad formats (Story, Feed, Reels etc.) through the Meta Marketing API.
Supports Messenger ads by verifying placements and generating previews, ensuring ads comply with Messenger's format requirements.
Integrates with Meta's advertising platform (Marketing API) to provide tools for managing ad accounts, campaigns, ad sets, ads, and creatives, as well as fetching performance insights and creating paused ads after visual QA.
Enables Threads ad management, including placement validation and ad creation, while rejecting automatic placements that may deliver outside Threads.
Click on "Install 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., "@meta-ads-mcpShow me insights for my ad account"
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.
Meta Ads MCP
This repository contains two deliberately separate local MCP servers:
meta-ads-mcpis the default read-only reporting server. It usesads_readand cannot change Meta.meta-ads-writer-mcpis an optional, guarded creation server. It can upload reviewed images and create only newPAUSEDads from a validated manifest.
Both run over stdio. The writer reuses the same private credential store, but
it must be registered as a separate MCP server so enabling it never expands the
read-only server's tool set.
It also includes the meta-ads-upload-qa Codex skill under
skills/meta-ads-upload-qa. The skill coordinates
the two servers, requires explicit write authorization, renders every requested
placement preview, and keeps ads paused when visual QA does not pass.
What it can do
Tool | Purpose |
| Validate authorization and inspect granted permissions |
| List accessible ad accounts |
| Read account configuration and status |
| Read campaign budgets, objectives, schedules, and delivery |
| Read targeting, optimization, attribution, and budgets |
| Read ads and attached creative details |
| Read creative copy, images, calls to action, and asset feeds |
| Generate Meta-rendered placement previews for visual QA |
| Query paginated performance data and breakdowns |
| Compare matched entities across equal-length periods |
| Write paginated CSV or JSON reports locally |
compare_performance calculates spend, delivery, CTR, CPC, CPM, conversions,
cost per conversion, conversion value, and ROAS deltas. export_insights
flattens Meta action arrays by action_type, safely quotes CSV values, and
protects spreadsheet programs from formula injection.
Related MCP server: Meta Ads MCP Server
Safety model
Meta access is read-only. The server never creates, updates, pauses, resumes, or deletes campaigns, ad sets, ads, or creatives.
OAuth requests only
ads_read.The app secret and access token live outside the repository under
~/.config/meta-ads-mcp, with owner-only file permissions.Graph API requests send the token in the
Authorizationheader.Meta pagination URLs are never returned because they can contain credentials.
get_ad_previewsreturns Meta's ephemeral preview URLs and, by default, renders each successful placement to a labeled PNG image directly in the MCP response. This lets an agent inspect placement overlays without controlling the user's browser. Setrender_imagestofalsewhen only URLs are needed, orinclude_iframe_htmltotruewhen raw embed HTML is useful for debugging. Rendering uses an isolated temporary Chrome/Chromium profile and deletes its local files after the response. It does not edit the ad.The renderer discovers Chrome/Chromium automatically. Set
META_ADS_PREVIEW_BROWSER_PATHto an executable path to override discovery.export_insightscreates a new local file and never overwrites an existing export. It cannot modify Meta.The server never logs tokens or app secrets.
Guarded writer
The optional writer exposes five tools:
Tool | Purpose |
| Validate local 4:5/9:16 files, hash them, and save a plan |
| Read and verify the account, campaign, ad set, Page, and IG ID |
| Upload only the files fingerprinted in the validated plan |
| Upload fingerprinted images and MP4 videos in a validated plan |
| Create placement or carousel ads hard-coded |
It has no edit, publish, pause, resume, archive, or delete tools. Both write
phases require a specific confirmation string after the plan is reviewed.
Progress is saved after every successful Meta response, so the same plan can be
retried without intentionally duplicating completed items. A partial failure is
never rolled back or cleaned up automatically. Before each real creative or ad
creation, the writer sends the exact payload through Meta's validate_only
execution option.
The manifest is JSON and uses absolute media paths. Existing placement-image entries remain backward compatible:
{
"version": 1,
"account_id": "123",
"campaign_id": "456",
"campaign_name": "Main campaign",
"adset_id": "789",
"adset_name": "Testing",
"page_id": "101",
"instagram_user_id": "202",
"link": "https://example.com/landing",
"display_link": "https://apps.apple.com/",
"call_to_action_type": "DOWNLOAD",
"ads": [
{
"name": "Concept 01",
"title": "Headline ✨",
"body": "Primary text 🧡",
"description": "Description 📲",
"feed_image_path": "/absolute/path/concept_F45.png",
"vertical_image_path": "/absolute/path/concept_V916.png"
}
]
}Placement image and video ads can use two to five primary-text options in one
creative by replacing the singular "body" field with a "bodies" array:
{
"name": "Concept 01",
"title": "Headline ✨",
"bodies": [
"Primary text option A 🧡",
"Primary text option B 🧡"
],
"description": "Description 📲",
"feed_image_path": "/absolute/path/concept_F45.png",
"vertical_image_path": "/absolute/path/concept_V916.png"
}Placement videos use "format": "video" with feed_video_path (1:1 or 4:5)
and vertical_video_path (9:16). Carousels use "format": "carousel" and
two to ten square PNG/JPEG card objects under cards, each with an
image_path and optional card title, description, or HTTPS link.
Story-only image ads use "format": "story_image" with one
vertical_image_path (9:16):
{
"name": "Story concept",
"format": "story_image",
"title": "One Dinner. Two Plates. 🧡",
"body": "Family recipes with a baby-friendly version 🍽️",
"description": "7-day free trial • Then $29/year 🧡",
"vertical_image_path": "/absolute/path/concept_V916.png"
}The writer validates the target ad set before upload and rejects
story_image plans unless every explicitly configured placement is a
Facebook, Instagram, or Messenger Story. Automatic placements, feeds, Reels,
Search, Audience Network, and Threads are rejected. This prevents a
single-asset Story creative from silently delivering outside Stories.
The campaign and ad-set names are checked as well as their IDs. Images must be PNG or JPEG and no larger than 30 MB. MP4 videos are limited to 1 GB by the writer. A plan is invalidated if any fingerprinted file changes. Campaigns and ad sets must already exist in the Marketing API; unpublished Ads Manager drafts cannot be targeted.
Requirements
Node.js 20 or newer
A Meta developer app with access to the Marketing API
A Meta user who can access the required ad accounts
Install
git clone https://github.com/lil-j/meta-ads-mcp.git
cd meta-ads-mcp
npm install
npm run buildAuthorize Meta
In the Meta app dashboard, enable a Facebook Login web flow and add this exact Valid OAuth Redirect URI:
http://localhost:53682/callbackStart the local setup flow:
META_APP_ID=your_app_id npm run auth -- setupThe helper opens a local browser page. Enter the app secret there, then authorize
Meta. The form posts only to 127.0.0.1; credentials are not sent to the MCP
client or this repository.
Meta user tokens are time-limited. Reauthorize when health_check reports an
expired token:
npm run auth -- loginConnect an MCP client
For Codex CLI, register the built server using its absolute path:
codex mcp add meta-ads -- node /absolute/path/to/meta-ads-mcp/dist/index.jsFor clients that use a JSON MCP configuration:
{
"mcpServers": {
"meta-ads": {
"command": "node",
"args": ["/absolute/path/to/meta-ads-mcp/dist/index.js"]
}
}
}Restart or refresh the MCP client after changing its configuration.
Register the writer separately only when paused-ad creation is needed:
codex mcp add meta-ads-writer -- node /absolute/path/to/meta-ads-mcp/dist/writer-index.jsThe configured token must grant ads_management for the writer. The included
authorization helper intentionally requests only ads_read; it does not widen
the default server's access.
Install the Codex skill
Copy the included skill into your personal Codex skills directory:
mkdir -p ~/.codex/skills
cp -R skills/meta-ads-upload-qa ~/.codex/skills/Restart or refresh Codex after installing or updating the skill.
Development
npm run typecheck
npm run build
npm testThe test suite uses fake credentials and local mock transports. It does not call Meta or require access to an ad account.
Exports
Exports are written to ~/Downloads/Meta Ads by default. Set
META_ADS_EXPORT_DIR to use a different directory. Files are created with
owner-only permissions and receive a numeric suffix if a name already exists.
Environment overrides
META_ADS_CONFIG_DIRMETA_OAUTH_CLIENT_FILEMETA_ACCESS_TOKEN_FILEMETA_ACCESS_TOKENMETA_APP_SECRETMETA_GRAPH_API_VERSION(defaults tov25.0)META_GRAPH_BASE_URLMETA_ADS_EXPORT_DIRMETA_ADS_WRITER_PLAN_DIRMETA_OAUTH_PORT
Security
Never commit Meta credentials or exported ad data. See SECURITY.md for reporting instructions and additional guidance. CI runs Gitleaks on every push and pull request as an additional guard against committed credentials.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/lil-j/meta-ads-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server