Meta Marketing API MCP Server

Interactúa con los datos publicitarios de Facebook e Instagram utilizando la API de Marketing de Meta.

Documentación

Meta Ads MCP Server

Un servidor MCP de Cloudflare Workers para la configuración de cuentas de Meta Ads, gestión de campañas, conjuntos de anuncios, creativos, audiencias, informes y flujos de trabajo por lotes.

Este repositorio está construido sobre xmcp y expone un endpoint MCP HTTP Streamable además de rutas de OAuth de Meta orientadas al navegador.

Código abierto / Autoalojado

Este repositorio está pensado para desplegarse en tu propia cuenta de Cloudflare con tus propias credenciales de aplicación de Meta.

No incluye:

  • un plano de control alojado
  • una aplicación de Meta compartida
  • un panel de usuario final integrado
  • un emisor de JWT para tus usuarios y espacios de trabajo

Tú aportas:

  • tu despliegue de Cloudflare Worker
  • tu aplicación de desarrollador de Meta
  • tu emisor de JWT o proveedor de autenticación
  • tu propia interfaz o backend que inicia el flujo de OAuth

Qué hace

  • Se ejecuta como un Cloudflare Worker
  • Usa llamadas directas a la API de Meta Graph fetch en lugar del SDK de Meta
  • Almacena las conexiones de usuarios de Meta por espacio de trabajo en D1
  • Almacena el estado de OAuth de corta duración en KV
  • Cifra los tokens de acceso de Meta almacenados
  • Protege las solicitudes MCP con los JWT emitidos por tu aplicación

Endpoints

  • GET /health
  • GET /app
  • POST /mcp
  • GET /oauth/meta/start
  • GET /oauth/meta/callback

Modelo de autenticación

Este servidor es multiinquilino. Cada solicitud MCP debe incluir un JWT de portador emitido por tu aplicación.

Si estás abriendo el código de este proyecto, la implicación importante es que los consumidores deben integrarlo en su propio sistema de autenticación. El servidor no sabe cómo identificar a un usuario o espacio de trabajo sin ese JWT.

Reclamaciones JWT requeridas:

  • sub o userId
  • workspaceId
  • opcional roles

Ejemplo de carga útil:

{
  "sub": "user_123",
  "workspaceId": "workspace_abc",
  "roles": ["admin"]
}

Por qué /oauth/meta/start no es un enlace público genérico:

  • el servidor debe saber a qué espacio de trabajo debe adjuntarse la cuenta de Meta
  • ese contexto de espacio de trabajo proviene del JWT
  • sin él, el servidor no puede vincular de forma segura el token de Meta resultante

Superficie de herramientas

Familias de herramientas implementadas:

  • Cuenta y configuración
  • Gestión de campañas
  • Gestión de conjuntos de anuncios
  • Creativos y anuncios
  • Audiencia y segmentación
  • Informes y perspectivas
  • Utilidades por lotes

El servidor registra actualmente 39 herramientas.

Estructura del proyecto

  • src/tools definiciones de herramientas agrupadas por dominio
  • src/lib autenticación, almacenamiento, OAuth, tiempo de ejecución y utilidades del cliente de Meta
  • src/services lógica de servicio de Meta específica del dominio
  • src/middleware.ts enrutamiento de OAuth y autenticación JWT de MCP
  • cloudflare-entry.mjs entrada envoltorio del Worker para la interceptación de rutas específicas de Cloudflare
  • schema.sql esquema de D1
  • test pruebas unitarias y de estilo de contrato

Desarrollo local

Instalar dependencias:

pnpm install

Ejecutar desarrollo local:

pnpm dev

Scripts útiles:

pnpm build
pnpm test
pnpm deploy

Enlaces de Cloudflare

Enlaces requeridos:

  • Base de datos D1 vinculada como META_DB
  • Espacio de nombres KV vinculado como META_OAUTH_STATE

Secretos requeridos:

  • JWT_SECRET o JWT_JWKS_URL
  • META_APP_ID
  • META_APP_SECRET
  • META_TOKEN_ENCRYPTION_KEY
  • APP_UI_PASSWORD para la página de administración integrada en /app

Configuración opcional:

  • JWT_ISSUER
  • JWT_AUDIENCE
  • APP_SESSION_SECRET
  • APP_UI_WORKSPACE_ID
  • APP_UI_USER_ID
  • META_REDIRECT_URI
  • META_GRAPH_VERSION
  • META_OAUTH_SCOPES
  • META_OAUTH_ALLOWED_RETURN_ORIGINS

Valores predeterminados:

  • META_GRAPH_VERSION=v25.0
  • META_OAUTH_SCOPES=ads_management,business_management
  • APP_UI_WORKSPACE_ID=workspace_admin
  • APP_UI_USER_ID=app_admin

Interfaz de administración integrada

El Worker ahora incluye una pequeña interfaz de navegador en /app.

Qué hace:

  • solicita una contraseña de administrador
  • inicia el flujo de OAuth de Meta existente sin requerir que generes manualmente un JWT de portador
  • muestra si una cuenta de Meta está conectada para el espacio de trabajo de administrador
  • carga las cuentas publicitarias accesibles usando la misma lógica de servicio que get_ad_accounts

Configuración requerida:

  1. Establece APP_UI_PASSWORD en el Worker.
  2. Asegúrate de que META_REDIRECT_URI coincida con tu host público, por ejemplo:
https://meta-mcp.gestalt.xyz/oauth/meta/callback
  1. Abre:
https://meta-mcp.gestalt.xyz/app

Configuración de la aplicación de Meta

En tu aplicación de Meta:

  1. Agrega el producto Marketing API.
  2. Agrega una plataforma de sitio web.
  3. Establece la URL de la plataforma del sitio web en el origen de tu Worker.
  4. Establece App Domains en el dominio de tu Worker.
  5. Establece la URL de devolución de llamada en:
https://<your-worker-host>/oauth/meta/callback

Si tu aplicación usa Facebook Login o Facebook Login for Business, agrega también esa URL de devolución de llamada exacta a la configuración de URI de redirección específica del producto.

Para un Worker desplegado en workers.dev, estos campos generalmente deben coincidir exactamente con el host del Worker.

Base de datos

Aplica el esquema de D1:

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

Tablas:

  • meta_connections
  • meta_ad_accounts_cache

Despliegue

Despliega el Worker:

pnpm deploy

Después del despliegue:

  1. anota la URL pública del Worker
  2. establece META_REDIRECT_URI en https://<your-worker-host>/oauth/meta/callback
  3. actualiza la misma devolución de llamada en la configuración de la aplicación de Meta

Si planeas usar un frontend o panel separado en otro origen, permite ese origen para las redirecciones del navegador posteriores a OAuth:

META_OAUTH_ALLOWED_RETURN_ORIGINS=https://your-ui.example.com,http://localhost:3000

Usa el origen real de tu frontend en producción.

Flujo de prueba manual

1. Genera un JWT de corta duración

Usa el mismo secreto JWT que tu aplicación usa para el Worker.

export JWT_SECRET="YOUR_JWT_SECRET"

TOKEN=$(node --input-type=module <<'NODE'
import { SignJWT } from 'jose';

const secret = new TextEncoder().encode(process.env.JWT_SECRET);
const token = await new SignJWT({ workspaceId: 'workspace_test', roles: ['admin'] })
  .setProtectedHeader({ alg: 'HS256' })
  .setSubject('user_test')
  .setIssuedAt()
  .setExpirationTime('10m')
  .sign(secret);

console.log(token);
NODE
)

2. Inicia OAuth de Meta

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

Copia el encabezado Location en tu navegador y completa el flujo de inicio de sesión de Meta.

Página de éxito esperada:

Meta account connected.

3. Inicializa MCP

curl -s https://<your-worker-host>/mcp \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: 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"}}}'

4. Lista de herramientas

curl -s https://<your-worker-host>/mcp \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"jsonrpc":"2.0","id":"tools-1","method":"tools/list","params":{}}'

5. Llama a una herramienta real

Después de que OAuth tenga éxito, esto debería devolver las cuentas publicitarias accesibles para ese espacio de trabajo:

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

Si obtienes un error de conexión/reconexión, el flujo de OAuth y la llamada MCP usaron valores diferentes de workspaceId.

Notas

  • Los dominios workers.dev de Cloudflare pueden requerir cuidado adicional en la configuración de la aplicación de Meta.
  • El punto de entrada del Worker intercepta explícitamente las rutas de OAuth antes de delegar en el Worker XMCP generado.
  • La ruta de compilación del Cloudflare Worker no es idéntica a la de xmcp dev local, por lo que siempre verifica las rutas desplegadas después de cambios relacionados con OAuth.

Referencias