Labsco
MCP SERVER

Meta Marketing API MCP Server

by brijr

Run Meta ad accounts, campaigns, ad sets, creatives, audiences and reporting from an assistant — deployed to your own Cloudflare account, against your own Meta app.

Marketing Automation & Advertising
Summary
Built for you to host, with the tenancy question answered up front.

The design decision that shapes everything here is that the server refuses to guess who is calling: no JWT, no workspace, no Meta token binding. That is more setup than a single-user server — you supply the auth issuer — but it is the reason one deployment can serve several workspaces without their ad accounts leaking into each other. The `/app` page exists so you do not have to hand-sign a token just to connect the first account.

What it is

A Cloudflare Worker that speaks MCP over Streamable HTTP and calls the Meta Graph API directly, with browser-facing Meta OAuth routes alongside it. It is multi-tenant by design: Meta connections are stored per workspace in D1, access tokens are encrypted at rest, and every MCP request must carry a JWT your own application issued. The server registers 39 tools.

What you get
  • 39 registered tools grouped by domain — account and setup, campaign management, ad set management, creatives and ads, audiences and targeting, reporting and insights, and batch helpers
  • The accessible ad accounts for a workspace, once its Meta OAuth flow has completed — `get_ad_accounts`
  • OAuth handled in the Worker: `GET /oauth/meta/start` and `GET /oauth/meta/callback` bind the resulting Meta token to the workspace named in the caller's JWT, so the start link is never a generic public URL
  • Per-workspace isolation backed by D1 (`meta_connections`, `meta_ad_accounts_cache`) with short-lived OAuth state in KV
  • A small admin page at `/app` that takes a password, runs the OAuth flow without you minting a bearer JWT by hand, and shows whether a Meta account is connected
  • Direct Graph API `fetch` calls rather than the Meta SDK, with `META_GRAPH_VERSION` defaulting to `v25.0`
Requirements

Your own Cloudflare Worker deployment, your own Meta developer app with the Marketing API product added, and your own JWT issuer — the repository ships no hosted control plane, no shared Meta app and no auth provider. Required bindings are a D1 database as `META_DB` and a KV namespace as `META_OAUTH_STATE`; required secrets are `JWT_SECRET` or `JWT_JWKS_URL`, `META_APP_ID`, `META_APP_SECRET`, `META_TOKEN_ENCRYPTION_KEY`, and `APP_UI_PASSWORD` for the admin page. Every MCP request needs a bearer JWT carrying `sub` (or `userId`) and `workspaceId`. Default OAuth scopes are `ads_management,business_management`. The Meta app's callback URL must match `https://<your-worker-host>/oauth/meta/callback` exactly.

Setup effort

One command plus a key — npx -y meta-mcp, then supply credentials