Skip to main content
Glama
mcp-facebook-ads

mcp-facebook-ads

by estapel-ai

Custom Facebook Ads MCP Server

Eigen MCP server (Python) voor Meta/Facebook Business Manager, met:

  • data inladen via Marketing API (insights/reporting),

  • campagnes opbouwen (campaigns, ad sets, ads, creatives),

  • optimalisatie en budgetadvies op basis van best practices.

Architectuur en endpoints

  • MCP-transport: stdio. Cursor (of een andere MCP-client) start het proces; er is geen apart HTTP-endpoint voor de MCP zelf.

  • Meta API: alle calls gaan via de Graph API / Marketing API zoals de SDK (facebook-business) die gebruikt. Basis-URL:

    https://graph.facebook.com/{META_API_VERSION}/...

    De standaard API-versie in deze codebase is v25.0 (zet META_API_VERSION in .env gelijk aan wat je app ondersteunt).

Related MCP server: Meta Marketing API MCP Server

1) Vereisten

  • Python 3.11+

  • uv

  • Een Meta Developer-app met Marketing API en een geldig access token met rechten op het gewenste ad account

Benodigde permissies (scopes) op het token:

  • ads_management

  • ads_read

  • business_management

  • pages_read_engagement

Zonder deze scopes kunnen tools deels of volledig falen.

2) Meta Developer-app aanmaken

  1. Ga naar Meta for Developers.

  2. Maak een app (kies het type dat past bij Marketing API / zakelijke ads).

  3. Voeg het product Marketing API toe en voltooi de stappen die Meta vraagt.

  4. Noteer onder App settings → Basic:

    • App ID → META_APP_ID

    • App Secret → META_APP_SECRET

3) Ad account en token (aanbevolen: System User)

Aanbevolen voor een stabiele, team- of server-achtige setup: een System user in Meta Business Settings (Gebruikers → System users), met toegewezen assets (het juiste ad account en indien nodig Pages). Genereer daar een token met de scopes hierboven.

  • Ad account-ID in .env als act_<numeriek_id>. De server voegt act_ automatisch toe als je alleen het nummer invult.

Alternatieven (minder ideaal voor productie):

  • Korte tokens uit de Graph API Explorer (vooral geschikt om even te testen).

  • OAuth-flow (zie hieronder) om user tokens of long-lived tokens te verkrijgen.

4) OAuth- en token-endpoints (Meta)

Vervang {VERSION} door dezelfde waarde als META_API_VERSION (bijv. v25.0). Vervang placeholders door je echte app- en redirect-gegevens.

Stap

URL

Gebruiker inloggen en scopes goedkeuren

https://www.facebook.com/{VERSION}/dialog/oauth?client_id={APP_ID}&redirect_uri={REDIRECT_URI}&scope=ads_management,ads_read,business_management,pages_read_engagement&response_type=code

Authorization code omzetten naar short-lived access token

GET https://graph.facebook.com/{VERSION}/oauth/access_token?client_id={APP_ID}&client_secret={APP_SECRET}&redirect_uri={REDIRECT_URI}&code={CODE}

Short-lived token omzetten naar long-lived token (ca. 60 dagen)

GET https://graph.facebook.com/{VERSION}/oauth/access_token?grant_type=fb_exchange_token&client_id={APP_ID}&client_secret={APP_SECRET}&fb_exchange_token={SHORT_LIVED_TOKEN}

Redirect URI: in de Meta-app (bijv. onder Facebook Login / OAuth-instellingen) moet de OAuth redirect URI exact overeenkomen met {REDIRECT_URI} in bovenstaande requests.

5) Installatie en .env

git clone <jouw-repo-url> mcp-facebook-ads
cd mcp-facebook-ads
uv sync
cp .env.example .env   # of maak .env handmatig

Vul .env (zie .env.example voor veldnamen):

META_APP_ID=...
META_APP_SECRET=...
META_ACCESS_TOKEN=...
META_AD_ACCOUNT_ID=act_...
META_API_VERSION=v25.0

De server laadt .env via python-dotenv vanaf de working directory van het proces. Zorg dat de MCP in Cursor cwd op de projectroot heeft staan als je geen inline env in de MCP-config gebruikt.

Commit .env nooit; die staat in .gitignore.

6) Cursor-configuratie

Je kunt de MCP op twee manieren configureren:

  1. Project (aanbevolen voor dit repo): .cursor/mcp.json in de projectroot (staat mogelijk niet in git; maak hem lokaal aan).

  2. Globaal: Cursor Settings → MCP, afhankelijk van je Cursor-versie.

Voorbeeld .cursor/mcp.json (geldige JSON — geen //-comments). Vervang het pad door je eigen projectmap; secrets horen in .env in die map, niet in git.

Optie A — cwd op de projectroot (aanbevolen; .env wordt dan automatisch geladen):

{
  "mcpServers": {
    "facebook-ads": {
      "command": "uv",
      "args": ["run", "python", "-m", "mcp_facebook_ads.server"],
      "cwd": "/ABSOLUUT/PAD/NAAR/mcp-facebook-ads"
    }
  }
}

Optie B — zonder cwd, met expliciet pad in uv run:

{
  "mcpServers": {
    "facebook-ads": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/ABSOLUUT/PAD/NAAR/mcp-facebook-ads",
        "python",
        "-m",
        "mcp_facebook_ads.server"
      ]
    }
  }
}

Secrets kun je óf in .env in die cwd laten staan, óf (minder ideaal) als env-object in mcp.json zetten — let op dat je die file dan niet deelt.

7) Delen met collega’s

Wel delen: repository, deze README, App ID, bekende ad account-identifiers waar ze toch al toegang toe moeten hebben, en het Cursor-commando + cwd.

Niet delen (alleen via een secrets manager of 1:1 veilig kanaal): META_APP_SECRET, META_ACCESS_TOKEN. Liever per persoon of per omgeving een eigen System user-token met minimale benodigde rechten dan één gedeelde token zonder rotatie.

8) Sneltest tegen de Graph API

Controleer of je token werkt (zelfde {VERSION} als in .env):

GET https://graph.facebook.com/{VERSION}/me?access_token={META_ACCESS_TOKEN}

Als dit faalt, los eerst app- en tokenconfiguratie op voordat je de MCP gebruikt.

9) Starten als MCP-server (handmatig)

uv run python -m mcp_facebook_ads.server

Draait op stdio; normaal start Cursor dit proces zelf.

10) Beschikbare toolgroepen

Account Management

  • get_ad_accounts

  • get_account_info

  • get_account_pages

Campaigns

  • get_campaigns

  • get_campaign_details

  • create_campaign

  • update_campaign

  • delete_campaign

Ad Sets

  • get_adsets

  • get_adset_details

  • create_adset

  • update_adset

  • delete_adset

Ads

  • get_ads

  • get_ad_details

  • create_ad

  • update_ad

  • delete_ad

Creatives & Media

  • get_ad_creatives

  • upload_ad_image

  • create_ad_creative

  • create_asset_feed_ad_creative

  • update_ad_creative

  • get_ad_previews

Insights & Reporting

  • get_insights

  • get_account_insights

  • compare_performance

Audience & Targeting

  • search_interests

  • search_behaviors

  • search_demographics

  • search_geo_locations

  • estimate_audience_size

Best Practices & Optimization

  • get_campaign_templates

  • create_campaign_from_template

  • analyze_campaign

  • suggest_budget_allocation

11) Best-practice defaults

  • Nieuwe entities worden standaard met status PAUSED aangemaakt.

  • Templates zijn beschikbaar voor awareness, traffic, leads, sales.

  • Adviezen sturen op CTR/CPC, en op funnel-gescheiden structuur.

12) Veiligheid en governance

  • Gebruik bij voorkeur een system user-token, niet je persoonlijke user-token.

  • Geef productie-activatie (ACTIVE) pas na review.

  • Log API-fouten en fbtrace_id-waarden voor snelle debugging bij Meta.

13) Testen

uv run pytest

Available Tools

39 tools
analyze_campaignC

Analyze campaign performance and return practical recommendations.

Inputs: campaign_id (required), date_preset. Returns: object

compare_performanceC

Compare two periods for spend/clicks/conversions.

Inputs: ad_account_id, date_preset_a, date_preset_b. Returns: object

create_adC

Create ad from an existing creative.

Inputs: name (required), adset_id (required), creative_id (required), status, +1 more. Returns: object

create_ad_creativeC

Create a link ad creative.

Inputs: name (required), page_id (required), headline (required), link_url (required), +5 more. Returns: object

create_adsetC

Create ad set with targeting and optimization settings.

Inputs: name (required), targeting (required), campaign_id (required), billing_event (required), +8 more. Returns: object

create_ad_video_creativeB

Create a link ad creative that uses a previously uploaded video (video_id).

Dit maakt een object_story_spec met zowel link_data (landing URL + CTA) als video_data (video asset).

Inputs: name (required), page_id (required), headline (required), link_url (required), +5 more. Returns: object

create_asset_feed_ad_creativeC

Create a dynamic creative using raw asset_feed_spec and object_story_spec.

Inputs: name (required), asset_feed_spec (required), object_story_spec (required), url_tags, +3 more. Returns: object

create_campaignC

Create a campaign (paused by default for safe review).

Inputs: name (required), objective (required), status, daily_budget, +3 more. Returns: object

create_campaign_from_templateC

Create a campaign from a best-practice template.

Inputs: template_key (required), campaign_name (required), daily_budget, ad_account_id. Returns: object

delete_adB

Archive ad.

Inputs: ad_id (required). Returns: object

delete_adsetC

Archive ad set.

Inputs: adset_id (required). Returns: object

delete_campaignB

Archive a campaign (safe delete).

Inputs: campaign_id (required). Returns: object

estimate_audience_sizeC

Estimate audience size for targeting specification.

Inputs: targeting_spec (required), optimize_for, ad_account_id. Returns: object

get_account_infoC

Get detailed info for one ad account (incl. opportunity_score = Kansscore in Ads Manager).

Inputs: ad_account_id. Returns: object

get_account_insightsC

Get account summary insights.

Inputs: date_preset, ad_account_id. Returns: object

get_account_opportunity_recommendationsC

Kansscore-uitleg: openstaande aanbevelingen (zelfde bron als Ads Manager). summary_only groepeert per type; anders ruwe items (max limit).

Inputs: limit, summary_only, ad_account_id. Returns: object

get_account_pagesC

Get Facebook pages connected to ad account business.

Inputs: ad_account_id. Returns: object

get_ad_accountsB

Get ad accounts the token can access.

Inputs: no named parameters. Returns: object

get_ad_creativesC

Get creatives attached to an ad.

Inputs: ad_id (required). Returns: object

get_ad_detailsC

Get one ad with details.

Inputs: ad_id (required). Returns: object

get_ad_previewsC

Generate ad previews for a specific format.

Inputs: ad_id (required), ad_format. Returns: object

get_adsC

Get ads with optional filters.

Inputs: limit, adset_id, campaign_id, ad_account_id. Returns: object

get_adset_detailsC

Get one ad set in detail.

Inputs: adset_id (required). Returns: object

get_adsetsC

Get ad sets, optionally filtered by campaign.

Inputs: limit, campaign_id, ad_account_id. Returns: object

get_campaign_detailsC

Get one campaign with rich details.

Inputs: campaign_id (required). Returns: object

get_campaignsC

Get campaigns with optional status/objective filters.

Inputs: limit, status, objective, ad_account_id. Returns: object

get_campaign_templatesA

Get built-in campaign templates by objective.

Inputs: no named parameters. Returns: object

get_insightsC

Get insights on account or a specific campaign.

Inputs: level, limit, breakdowns, campaign_id, +2 more. Returns: object

search_behaviorsC

Search behavior targeting options.

Inputs: query (required), limit. Returns: object

search_demographicsC

Search demographic targeting options.

Inputs: query (required), limit. Returns: object

search_geo_locationsC

Search geolocation targeting options.

Inputs: query (required), limit, location_types. Returns: object

search_interestsC

Search interest targeting options.

Inputs: query (required), limit. Returns: object

suggest_budget_allocationC

Suggest budget shifts based on campaign CTR and CPC.

Inputs: date_preset, ad_account_id. Returns: object

update_adC

Update ad status, name, or creative.

Inputs: ad_id (required), name, status, creative_id. Returns: object

update_ad_creativeC

Update mutable creative fields.

Inputs: creative_id (required), body, name, title. Returns: object

update_adsetD

Update ad set fields.

Inputs: adset_id (required), status, end_time, targeting, +2 more. Returns: object

update_campaignC

Update campaign status/budget/name.

Inputs: campaign_id (required), name, status, daily_budget, +1 more. Returns: object

upload_ad_imageC

Upload an image by public URL to use in creatives.

Inputs: image_url (required), ad_account_id. Returns: object

upload_ad_videoB

Upload a local video file to the ad account.

Let op: video_file_path moet op deze machine bestaan, omdat de SDK hier direct uploadt.

Inputs: video_file_path (required), title, description, ad_account_id. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.5/5.0

    Scored across 39 tools

    Disambiguation4/5

    Most tools target clearly distinct resources and actions (campaign vs adset vs ad vs creative). Some overlap remains between get_insights, get_account_insights, and compare_performance, and between get_ad_accounts and get_account_info, but descriptions help differentiate.

    Naming Consistency4/5

    The set is predominantly snake_case with a verb_noun pattern. Minor deviations exist, such as get_account_info versus get_campaign_details/get_adset_details/get_ad_details, and multiple similar prefixes for creative tools.

    Tool Count2/5

    39 tools is heavy for this domain and exceeds the 25+ threshold for 'too many'. Several tools could be consolidated, including the multiple creative-creation tools, insight variants, and separate targeting search tools.

    Completeness4/5

    Core CRUD/lifecycle coverage exists for campaigns, adsets, ads, and creatives, plus targeting searches, uploads, previews, and insights. Minor gaps include no delete_ad_creative and no clear adset/ad-level insights tool.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to manage Facebook and Instagram advertising via the Meta Marketing API. It provides comprehensive tools for campaign lifecycle management, performance analytics, audience targeting, and creative optimization.
      40 npm
      202
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to manage Facebook and Instagram advertising data through the Meta Marketing API. It supports full campaign lifecycle management, performance analytics, audience targeting, and creative optimization.
      698 npm
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables comprehensive management of Facebook and Instagram advertising campaigns via the Meta Marketing API, supporting campaign creation, targeting optimization, and budget management. It provides tools for detailed performance reporting and creative analysis, including insights into spend, ROI, and audience breakdowns.
      MIT
    • -
      license
      Not graded
      quality
      Not graded
      maintenance
      Enables AI assistants to manage Facebook and Instagram advertising campaigns through the Meta Marketing API. Supports full campaign lifecycle management, performance analytics, audience targeting, and creative optimization.
      -