Meta MCP Server

repository·main·Indexed 41 days ago

https://github.com/brijr/meta-mcp

A multi-tenant, Cloudflare Workers-based Model Context Protocol (MCP) server for managing Meta Ads accounts, campaigns, ad sets, and reporting. It features a built-in admin UI, JWT-based authentication for secure MCP requests, and a MetaGraphClient for interacting with the Meta Graph API (defaulting to v25.0).

Tokens
14.1K
Snippets
59
Records
72
Agent score
52%

What's inside Meta MCP

  1. Understand the Auth Model and JWT requirements

    main

    The server is multi-tenant and requires every MCP request to include a Bearer JWT issued by your own application. The server uses the workspaceId in the JWT to bind Meta tokens to the correct context.

    Required JWT Claims

    • sub or userId: The identifier for the user.
    • workspaceId: The identifier for the workspace.
    • roles (optional): User permissions.

    Example JWT Payload

    {
      "sub": "user_123",
      "workspaceId": "workspace_abc",
      "roles": ["admin"]
    }
  2. Use the Built-in Admin UI

    main

    The server includes a lightweight browser interface at /app for administrators to manage connections without manually minting JWTs.

    Setup Steps

    1. Set the APP_UI_PASSWORD secret on your Cloudflare Worker.
    2. Ensure META_REDIRECT_URI matches your public host (e.g., https://meta-mcp.example.com/oauth/meta/callback).
    3. Access the UI at https://<your-worker-host>/app.

    Features

    • Prompts for the admin password.
    • Initiates the Meta OAuth flow.
    • Displays connection status for the admin workspace.
    • Lists accessible ad accounts.
  3. Initialize the D1 Database schema

    main

    The server uses a D1 database to store Meta user connections and ad account caches. Apply the provided schema using Wrangler:

    pnpm wrangler d1 execute META_DB --remote --file schema.sql -y

    This creates the following tables:

    • meta_connections
    • meta_ad_accounts_cache
  4. Set up a Meta Developer App

    main

    To use the server, you must configure a Meta developer app with the following settings:

    1. Add Products: Add the Marketing API product.
    2. Add Platform: Add a Website platform.
    3. Configure Website:
      • Set the Website platform URL to your Worker origin.
      • Set App Domains to your Worker domain.
    4. Configure Callback: Set the callback URL to: https://<your-worker-host>/oauth/meta/callback
    5. Facebook Login: If using Facebook Login or Facebook Login for Business, ensure the same callback URL is added to the product-specific redirect URI settings.
  5. Install and run Meta Ads MCP Server locally

    main

    To develop locally, ensure you have pnpm installed. Use the following commands to install dependencies and start the development environment.

    pnpm install
    pnpm dev

    Other useful scripts include:

    • pnpm build: Build the project.
    • pnpm test: Run unit and contract tests.
    • pnpm deploy: Deploy the Worker.
  6. Manage Ad Sets via Ad Set Services

    main

    The ad-set-service.ts module provides high-level service functions for managing Meta Ad Sets. These services can be used to retrieve, create, list, update, delete, or duplicate ad sets within a campaign. Most services return a result object containing a text summary and a data payload formatted for Meta MCP consumers.

    Key capabilities include:

    • Retrieval: Fetch a single ad set by ID or list ad sets within a specific campaign.
    • Lifecycle: Create new ad sets with targeting and budget, update existing ones, or delete them.
    • Duplication: Create a copy of an existing ad set with optional overrides.
  7. Understand MetaListResult and MetaPaging for paginated responses

    main

    When using the list<T>() method on MetaGraphClient, the response is wrapped in a MetaListResult<T> object to simplify handling Meta's pagination structure.

    MetaListResult<T>

    An object containing:

    • items: T[]: An array of the requested data type.
    • page: MetaPaging: An object containing pagination cursors.

    MetaPaging

    An object containing optional string cursors for navigating through result sets:

    • before?: string: Cursor for the previous page.
    • after?: string: Cursor for the next page.
    • next?: string: URL or identifier for the next page.
    • previous?: string: URL or identifier for the previous page.
    export interface MetaPaging {
      before?: string;
      after?: string;
      next?: string;
      previous?: string;
    }
    
    export interface MetaListResult<T> {
      items: T[];
      page: MetaPaging;
    }
  8. Configure Cloudflare Bindings and Secrets

    main

    The Meta Ads MCP Server requires specific Cloudflare bindings and environment variables to function.

    Required Bindings

    • META_DB: D1 database instance.
    • META_OAUTH_STATE: KV namespace for short-lived OAuth state.

    Required Secrets

    • JWT_SECRET or JWT_JWKS_URL: Used to validate incoming MCP requests.
    • META_APP_ID: Your Meta developer app ID.
    • META_APP_SECRET: Your Meta developer app secret.
    • META_TOKEN_ENCRYPTION_KEY: Key used to encrypt stored Meta access tokens.
    • APP_UI_PASSWORD: Password for the built-in admin UI at /app.

    Optional Configuration

    • META_GRAPH_VERSION: Defaults to v25.0.
    • META_OAUTH_SCOPES: Defaults to ads_management,business_management.
    • META_REDIRECT_URI: The public URL for the OAuth callback (e.g., https://<your-host>/oauth/meta/callback).
    • META_OAUTH_ALLOWED_RETURN_ORIGINS: Comma-separated list of origins allowed for post-OAuth redirects (e.g., https://your-ui.example.com).
  9. Configure the Meta MCP Admin UI

    main

    The Meta MCP Admin UI is a built-in web interface for managing Meta OAuth connections and generating MCP tokens. To use the Admin UI, you must first set the APP_UI_PASSWORD environment variable (Worker secret).

    If APP_UI_PASSWORD is not set, the login page will display an info banner instructing you to set the secret and reload.

  10. Authenticate MCP requests using JWT

    main

    The Meta Ads MCP server uses JSON Web Tokens (JWT) to secure requests. You can authenticate incoming Request objects by extracting the bearer token from the Authorization header and verifying it against configured secrets or a JWKS endpoint.

    To protect /mcp requests, you must configure either JWT_SECRET (for local symmetric signing) or JWT_JWKS_URL (for remote asymmetric verification) in your environment bindings.

    Required JWT Claims

    For a token to be valid, the payload must include:

    • sub or userId / user_id (User Identifier)
    • workspaceId or workspace_id (Workspace Identifier)

    Error Handling

    • UnauthorizedError: Thrown if the token is missing, malformed, or invalid/expired.
    • ValidationError: Thrown if the required userId or workspaceId claims are missing.
    • ConfigurationError: Thrown if neither JWT_SECRET nor JWT_JWKS_URL is configured.
    // Example of authenticating an incoming request
    try {
      const authInfo = await authenticateRequest(request);
      console.log("Authenticated user:", authInfo.extra?.userId);
    } catch (error) {
      // Handle UnauthorizedError or ValidationError
    }
  11. Generate an MCP Bearer Token for Agents

    main

    To connect an AI agent or MCP client to your Meta MCP instance, you need a short-lived bearer token. You can generate this via the Admin UI or by calling the /app/api/mcp-token endpoint.

    The generated token is intended for clients connecting to the /mcp endpoint and is separate from the browser session cookie.

    Example MCP Client Configuration:

    {
      "mcpServers": {
        "meta-mcp": {
          "transport": "http",
          "url": "https://your-worker-url.com/mcp",
          "headers": {
            "Authorization": "Bearer YOUR_GENERATED_TOKEN"
          }
        }
      }
    }
    {
      "mcpServers": {
        "meta-mcp": {
          "transport": "http",
          "url": "payload.url",
          "headers": {
            "Authorization": "Bearer " + payload.token
          }
        }
      }
    }
  12. Manual Test Flow for MCP Tools

    main

    If you need to test the server manually via CLI, follow these steps:

    1. Generate a Test JWT

    Use a script to sign a token with your JWT_SECRET containing a workspaceId.

    2. Start Meta OAuth

    Call the start endpoint with the workspace_id query parameter. Copy the Location header value into your browser to complete the login.

    curl -i \
      -H "Authorization: Bearer $TOKEN" \
      "https://<your-worker-host>/oauth/meta/start?workspace_id=workspace_test"

    3. Initialize MCP and List Tools

    Once connected, initialize the MCP session and list available tools using JSON-RPC over HTTP.

    # Initialize
    curl -s https://<your-worker-host>/mcp \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","id":"init-1","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"manual-test","version":"1.0.0"}}}'
    
    # List Tools
    curl -s https://<your-worker-host>/mcp \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","id":"tools-1","method":"tools/list","params":{}}'

    4. Call a Tool

    Example: Calling get_ad_accounts.

    curl -s https://<your-worker-host>/mcp \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","id":"call-1","method":"tools/call","params":{"name":"get_ad_accounts","arguments":{}}}'
    # Example: Call get_ad_accounts
    curl -s https://<your-worker-host>/mcp \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","id":"call-1","method":"tools/call","params":{"name":"get_ad_accounts","arguments":{}}}'