Meta Ads MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MCP_READ_ONLY | No | Set to 'true' to block all write operations. | false |
| META_ADS_TOKEN | No | Meta access token. Alternative to storing in OS credential store. Required if not using credential store. | |
| MCP_PUBLIC_HOSTS | No | Host allowlist for public HTTP deployments. Required for public HTTP deploys. | |
| META_API_VERSION | No | Graph API version. | v21.0 |
| MCP_BEARER_SECRET | No | Bearer token for HTTP transport authentication. | |
| MCP_RATE_LIMIT_RPM | No | Per-minute cap on the HTTP transport. | 60 |
| META_RATE_LIMIT_RPS | No | Local rate limiter (requests per second). | 5 |
| META_REQUEST_TIMEOUT | No | Read timeout in seconds. | 60 |
| META_DEFAULT_BUSINESS_ID | No | Fallback Business Manager ID. |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| ads_list_ad_accountsB | List all ad accounts the System User can access. Returns name, account_id, status, currency, owning business. |
| ads_get_ad_accountA | Get detailed info for a single ad account, including spending and limits. |
| ads_list_campaignsA | List campaigns of an ad account. Args:
account_id: Ad account ID (with or without |
| ads_get_campaignB | Get full details of a single campaign. |
| ads_list_adsetsA | List ad sets under an ad account or under a specific campaign. Args: parent_id: Either an ad account ID (act_...) or a campaign ID. status_filter: Optional effective_status filter. |
| ads_get_adsetA | Get full details of a single ad set, including targeting and dayparting ( |
| ads_list_adsA | List ads under an ad account, campaign, or ad set. Args: parent_id: act_... for an ad account, or a campaign/adset ID. status_filter: Optional effective_status filter. |
| ads_get_adB | Get full details of a single ad including creative. |
| ads_get_ad_previewB | Get a renderable HTML preview of an ad. Common ad_format values: MOBILE_FEED_STANDARD, DESKTOP_FEED_STANDARD, INSTAGRAM_STANDARD, INSTAGRAM_STORY, FACEBOOK_STORY_MOBILE, AUDIENCE_NETWORK_OUTSTREAM_VIDEO. |
| ads_create_campaignA | Create a new campaign. Defaults to PAUSED for safety. Args: account_id: Ad account ID. name: Campaign name. objective: One of OUTCOME_AWARENESS, OUTCOME_TRAFFIC, OUTCOME_ENGAGEMENT, OUTCOME_LEADS, OUTCOME_APP_PROMOTION, OUTCOME_SALES. status: ACTIVE or PAUSED (default PAUSED — safer). special_ad_categories: ["HOUSING"], ["EMPLOYMENT"], ["CREDIT"], ["ISSUES_ELECTIONS_POLITICS"], or [] for none. daily_budget_cents: Daily budget in account currency cents (e.g., 1000 = R$10). lifetime_budget_cents: Alternative to daily. bid_strategy: LOWEST_COST_WITHOUT_CAP, LOWEST_COST_WITH_BID_CAP, COST_CAP. buying_type: AUCTION (default) or RESERVED. confirm: Required True to actually create. |
| ads_update_campaignB | Update fields on an existing campaign. Changing objective restarts learning AND may force-unpublish ad sets that aren't compatible with the new objective. |
| ads_pause_campaignA | Pause a campaign (stops delivery, preserves learning). |
| ads_activate_campaignB | Activate (resume) a paused campaign. |
| ads_delete_campaignA | Delete a campaign permanently. Cascades to all ad sets and ads under it. |
| ads_create_adsetA | Create an ad set under a campaign. Args: account_id: Parent ad account. campaign_id: Parent campaign. daily_budget_cents: Daily budget in cents (use this OR lifetime_budget_cents). lifetime_budget_cents: Total budget for the entire run (requires end_time). optimization_goal: REACH, IMPRESSIONS, LINK_CLICKS, OFFSITE_CONVERSIONS, LANDING_PAGE_VIEWS, MESSAGES, LEAD_GENERATION, CONVERSATIONS, etc. billing_event: IMPRESSIONS (most common), LINK_CLICKS, etc. targeting: Full targeting JSON (geo, age, interests, custom audiences). promoted_object: For conversion campaigns: {"pixel_id": ..., "custom_event_type": ...}. destination_type: WEBSITE, APP, MESSENGER, INSTAGRAM_DIRECT, ON_AD, etc. start_time / end_time: ISO 8601 timestamps. adset_schedule: Day-parting blocks. Each block: {"days": [0..6], "start_minute": 0..1440, "end_minute": 0..1440, "timezone_type": "USER"|"ADVERTISER"}. Requires pacing_type=["day_parting"] AND lifetime_budget_cents (not daily). Tip: use ads_set_adset_schedule for an ergonomic builder. pacing_type: ["standard"] (default) or ["day_parting"] when adset_schedule is set. attribution_spec: e.g. [{"event_type":"CLICK_THROUGH","window_days":7}]. frequency_control_specs: e.g. [{"event":"IMPRESSIONS","interval_days":7,"max_frequency":3}]. |
| ads_update_adsetA | Update fields on an existing ad set. NOTE: Changing budget, bid, targeting, or optimization restarts learning. Day-parting ( |
| ads_pause_adsetC | Pause an ad set. |
| ads_activate_adsetB | Activate (resume) a paused ad set. |
| ads_delete_adsetA | Delete an ad set. Cascades to all ads under it. |
| ads_create_adA | Create an ad inside an ad set, referencing an existing ad creative. Use creatives_create_* tools first to build the creative, then pass its ID here. |
| ads_update_adA | Update an ad's name, status, or swap its creative. |
| ads_pause_adC | Pause a single ad. |
| ads_activate_adB | Activate (resume) a single ad. |
| ads_delete_adC | Delete a single ad permanently. |
| ads_duplicate_campaignA | Duplicate a campaign with optional deep copy of all ad sets and ads. Args: deep_copy: If True, copies all ad sets and ads under the campaign. status_option: PAUSED (recommended) or ACTIVE for the copy. rename_options: Optional dict {"rename_strategy": "DEEP_RENAME", "rename_suffix": " - copy"}. |
| ads_duplicate_adsetB | Duplicate an ad set, optionally including all ads inside it. |
| ads_duplicate_adC | Duplicate a single ad. |
| ads_get_adset_scheduleA | Read an ad set's day-parting schedule, decoded into human-readable form. Returns both the raw |
| ads_set_adset_scheduleA | Set day-parting on an ad set with an ergonomic format. Each block in
Day aliases accepted (case-insensitive): Portuguese: dom seg ter qua qui sex sab (also "domingo", "terça"...) English: sun mon tue wed thu fri sat (also "monday"...) Numeric: 0–6 (0=Sunday) Requirements (Meta API):
Pass an empty list to remove dayparting (return to 24/7). Example: ads_set_adset_schedule( "12345", schedule=[{"days":["seg","qua","sex"],"start_time":"18:00","end_time":"23:00"}], confirm=True, ) |
| audiences_list_savedB | List saved audiences for an ad account. |
| audiences_get_savedA | Get full detail of a single saved audience (including targeting JSON). |
| audiences_list_customB | List custom audiences for an ad account. |
| audiences_get_customB | Get full detail of a single custom audience. |
| audiences_apply_to_adsetA | Copy targeting from a saved audience to a live adset. This is the verified workaround for the saved_audiences write capability gate: the adset endpoint accepts the same targeting object under standard ads_management scope, so we just pull the targeting from the saved audience and POST it on the adset. Args: saved_audience_id: e.g. 120241644369970701 adset_id: target adset to update merge: how to combine the saved audience's targeting with the adset's existing targeting: - "replace" (default): overwrite the adset's targeting entirely - "merge": shallow-merge — saved-audience keys override adset keys, anything else on the adset is preserved overrides: extra targeting keys to apply on top of the resulting object (e.g. {"age_min": 25}). Useful for per-adset tweaks without editing the saved audience. confirm: must be True (the adset targeting WILL be rewritten). |
| audiences_create_savedA | Create a saved audience. KNOWN LIMITATION: Meta returns code=3 ("Application does not have the capability to make this API call") unless the underlying App has Advanced Access for saved_audiences writes. Most MCP deployments do NOT have this. If you hit that error, use audiences_apply_to_adset() to apply targeting directly to an adset instead. |
| audiences_update_savedA | Update a saved audience's name/description/targeting. KNOWN LIMITATION: see audiences_create_saved — usually fails with code=3 unless the App has Advanced Access. Workaround: audiences_apply_to_adset(). |
| audiences_delete_savedA | Permanently delete a saved audience. KNOWN LIMITATION: also gated by the saved_audiences write capability. |
| billing_get_account_spendA | Get total amount spent by an ad account. If no date params: returns lifetime amount_spent on the account. If date params provided: aggregates spend from insights for that period. |
| billing_get_spend_limitsC | Get configured spending limits for an ad account. |
| billing_list_invoicesB | List invoices/billing documents for a Business Manager. NOTE: This endpoint may require additional permissions or may be empty depending on the BM's payment configuration. |
| billing_get_invoiceA | Get details of a single invoice. |
| billing_get_funding_sourceA | Get info about the configured funding source on an ad account. Returns metadata only — no sensitive details (card numbers, etc.). |
| billing_summary_all_accountsA | Get a spend summary across ALL accessible ad accounts for a date range. Useful for dashboards / quick agency-wide visibility. |
| catalog_listB | List all product catalogs owned by a Business Manager. |
| catalog_getB | Get details of a single catalog. |
| catalog_createC | Create a new product catalog under a Business Manager. Args: vertical: commerce, hotels, flights, destinations, home_listings, vehicles, etc. |
| catalog_list_productsC | List products in a catalog. |
| catalog_get_productC | Get details of a single product. |
| catalog_create_productB | Create a single product in a catalog. Args: retailer_id: Your internal SKU/identifier. price: Price in cents (e.g., 9990 = R$99.90). currency: ISO 4217 (BRL, USD, EUR, etc.). availability: in stock, out of stock, preorder, available for order, discontinued. condition: new, refurbished, used. |
| catalog_update_productC | Update arbitrary fields on a product. |
| catalog_delete_productC | Delete a product from the catalog. |
| catalog_list_product_setsB | List product sets within a catalog (used for Advantage+ Catalog campaigns). |
| catalog_create_product_setA | Create a product set defined by a filter expression. Example filter_spec: {"availability": {"i_contains": "in stock"}} |
| catalog_list_feedsA | List product feeds (CSV/XML uploads) attached to a catalog. |
| catalog_get_diagnosticsB | Get diagnostic issues affecting catalog quality and ad eligibility. |
| creatives_listB | List all ad creatives in an account. |
| creatives_getB | Get full details of a single ad creative. |
| creatives_list_imagesB | List images uploaded to an account's image library. |
| creatives_list_videosB | List videos uploaded to an account's video library. |
| creatives_upload_imageB | Upload an image to an ad account's image library. Returns the image hash. Args: image_path: Absolute path to a local image file (PNG, JPG, GIF). |
| creatives_upload_videoA | Upload a video to an ad account's video library. Returns the video ID. NOTE: Large videos (>1GB) require chunked upload — not supported here. |
| creatives_create_link_adA | Create a single-image or single-video link ad creative. Either image_hash OR video_id must be provided. Use creatives_upload_image / creatives_upload_video to get those values first. |
| creatives_create_carousel_adB | Create a multi-card carousel creative. Args: cards: List of {"link": ..., "image_hash": ..., "name": ..., "description": ...}. |
| creatives_deleteA | Delete an ad creative. Will fail if any active ads still reference it. |
| creatives_previewB | Preview a creative in any ad format (returns rendered HTML). |
| graph_callA | Call any Graph API endpoint directly. Args: method: GET, POST, or DELETE. endpoint: Path AFTER the version prefix, e.g. "act_123/campaigns" or "me/adaccounts". Do NOT include "https://graph.facebook.com/v21.0/" — that's added automatically. params: Query string parameters as a dict. data: Body parameters for POST as a dict. confirm: Required True for POST and DELETE. Examples: - Read your user info: graph_call("GET", "me", {"fields": "id,name"}) - Get adaccount: graph_call("GET", "act_123", {"fields": "name,balance"}) - Pause ad: graph_call("POST", "12345", data={"status":"PAUSED"}, confirm=True) |
| graph_paginateA | Auto-paginate a GET endpoint and return a flat list of all Stops at max_pages to prevent runaway calls. |
| graph_debug_tokenA | Inspect the currently loaded access token (scopes, expiry, app, type). Useful for debugging permission issues without exposing the raw token. |
| ig_list_accountsA | List Instagram Business accounts via Pages the user has access to. |
| ig_get_accountC | Get profile info for an IG Business account. |
| ig_list_mediaB | List recent posts (media) from an IG account. |
| ig_get_mediaB | Get details for a single IG media post. |
| ig_get_insightsA | Get insights for an IG media post. Common metrics: impressions, reach, engagement, saved, video_views, profile_visits, follows, likes, comments, shares, total_interactions. Different media types support different metrics. |
| ig_get_account_insightsC | Get account-level insights for an IG Business account. Common metrics: impressions, reach, profile_views, follower_count, website_clicks, email_contacts, phone_call_clicks, text_message_clicks, get_directions_clicks. |
| ig_publish_imageA | Publish a single image to IG. Two-step: create container, then publish. image_url must be publicly reachable (Meta will fetch it). |
| ig_publish_videoC | Publish a video/reel to IG. Two-step process. Args: media_type: REELS (recommended) or VIDEO. |
| ig_list_commentsC | List comments on an IG media post. |
| ig_reply_to_commentC | Reply to an IG comment. |
| ig_hide_commentC | Hide or unhide an IG comment. |
| ig_delete_commentB | Permanently delete an IG comment. |
| insights_getA | Get insights for any entity (account, campaign, ad set, or ad). Args: entity_id: act_... for an ad account, OR a campaign/adset/ad ID. level: account, campaign, adset, or ad. Determines aggregation. date_preset: today, yesterday, this_week_mon_today, last_7d, last_14d, last_28d, last_30d, last_90d, this_month, last_month, this_quarter, maximum, etc. Mutually exclusive with time_range. time_range: {"since": "YYYY-MM-DD", "until": "YYYY-MM-DD"}. fields: Comma-separated list. Defaults to a comprehensive standard set. breakdowns: e.g. ["age", "gender"], ["publisher_platform", "platform_position"], ["country"], ["device_platform"], ["impression_device"]. action_breakdowns: e.g. ["action_type", "action_destination"]. filtering: e.g. [{"field":"spend","operator":"GREATER_THAN","value":"10"}]. time_increment: 1, 7, monthly, all_days. Aggregates by time buckets. sort: e.g. ["spend_descending"], ["impressions_descending"]. |
| insights_get_account_summaryB | Quick top-line spend/impressions/clicks for an entire account. |
| insights_compare_periodsB | Compare insights between two date ranges side-by-side. Args: period_a / period_b: {"since": "YYYY-MM-DD", "until": "YYYY-MM-DD"} |
| insights_get_async_reportA | Submit an async insights job for large reports. Returns the report run ID. Use insights_check_async_report(report_run_id) to check status, then insights_fetch_async_report(report_run_id) to get the data. |
| insights_check_async_reportC | Check the status of an async insights report job. |
| insights_fetch_async_reportC | Fetch results of a completed async insights report. |
| leads_list_formsB | List lead generation forms attached to a Page. |
| leads_get_formB | Get details of a single lead form including its question schema. |
| leads_list_from_formA | Retrieve actual leads submitted to a form. Args: after_cursor: Pagination cursor from a previous response (paging.cursors.after). |
| leads_get_leadB | Get full data for a single lead. |
| leads_list_from_adB | Retrieve all leads generated by a specific ad. |
| pages_listB | List all Facebook Pages the System User can access. |
| pages_getC | Get detailed info about a Page. |
| pages_list_postsC | List published posts of a Page. |
| pages_get_postA | Get details of a single post. |
| pages_get_insightsC | Get Page insights metrics. Args: metrics: e.g. ["page_impressions", "page_engaged_users", "page_post_engagements", "page_fans", "page_views_total"]. period: day, week, days_28, lifetime. |
| pages_publish_postB | Publish a text/link post to a Page. Args: scheduled_publish_time: Unix timestamp; if set, post is scheduled. Set published=False. |
| pages_publish_photoB | Publish a photo to a Page from an external URL. |
| pages_delete_postB | Delete a post permanently. |
| pages_list_commentsC | List comments on a post. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
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/AbnerZx/meta-ads-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server