Meta Ads Mcp Server
Servidor MCP (Model Context Protocol) para a API de Anúncios do Meta (Facebook).
Documentação
Meta Ads MCP Server
Um servidor Model Context Protocol para a API de Anúncios do Meta (Facebook), escrito em TypeScript.
54 ferramentas — 35 ferramentas de leitura (sempre ativas) mais 19 ferramentas opcionais de escrita/ciclo de vida — cobrindo contas de anúncios, campanhas, conjuntos de anúncios, anúncios, criativos, mídia, insights, catálogo de segmentação, Páginas do Facebook, agendamentos de orçamento e logs de atividades via Meta Graph API v22.0.
Funciona com Cursor, Claude Desktop (stdio) e conectores personalizados do Claude.ai (HTTP).
Aviso: Esta é uma ferramenta de terceiros não oficial e não está associada, endossada ou afiliada à Meta de forma alguma. Este projeto é mantido de forma independente e usa as APIs públicas da Meta de acordo com seus Termos de Serviço. Meta, Facebook, Instagram e outros nomes de marcas da Meta são marcas registradas de seus respectivos proprietários.
Sumário
- Recursos
- Requisitos
- Instalação
- Obtendo um Token de Acesso da Meta
- Autenticação
- Habilitando Ferramentas de Escrita
- Modos de Transporte
- Configuração no Cursor / Claude Desktop
- Servidor HTTP Remoto
- Ferramentas Disponíveis
- Ponta a Ponta: Crie um Anúncio do Zero
- Paginação
- Desenvolvimento
- Estrutura do Projeto
- Licença
Recursos
| Categoria | O que faz |
|---|---|
| Contas | Listar contas de anúncios, obter detalhes da conta |
| Campanhas | Obter / listar / criar / atualizar / pausar / retomar / excluir |
| Conjuntos de Anúncios | Obter / listar / buscar em lote / criar / atualizar / pausar / retomar / excluir |
| Anúncios | Obter / listar / criar / atualizar / pausar / retomar / excluir |
| Criativos | Obter / listar, criar + atualizar, calcular cortes de imagem |
| Mídia | Listar imagens de anúncios, enviar imagens, buscar por hash, obter prévias de anúncios e vídeos |
| Insights | Análises de desempenho no nível de conta, campanha, conjunto de anúncios e anúncio |
| Segmentação | Pesquisar interesses / comportamentos / dados demográficos / geo, estimativa de tamanho de público |
| Páginas | Listar Páginas do Facebook acessíveis pelo token, pesquisar por nome |
| Agendamentos de Orçamento | Agendar aumentos temporários de orçamento em um intervalo de tempo |
| Atividades | Histórico de alterações para contas de anúncios e conjuntos de anúncios |
| Paginação | Ferramenta utilitária para buscar páginas subsequentes de resultados |
Todas as ferramentas de mutação (criar / atualizar / excluir / pausar / retomar / enviar / agendar orçamento) estão desativadas por padrão e só são registradas quando você opta por ativá-las — veja Habilitando Ferramentas de Escrita.
Requisitos
- Node.js >= 18
- Um Token de Acesso de Usuário da Meta com as permissões corretas para o que você pretende fazer — veja abaixo.
Instalação
# From npm
npx meta-ads-mcp-server --access-token YOUR_META_ACCESS_TOKEN
# From source
git clone https://github.com/hashcott/meta-ads-mcp.git
cd meta-ads-mcp
npm install
npm run build
node dist/index.js --access-token YOUR_META_ACCESS_TOKEN
Obtendo um Token de Acesso da Meta
Este servidor usa a API de Marketing da Meta. Você precisa de um token de acesso vinculado a um Aplicativo da Meta que tenha as permissões corretas.
Opção rápida — Graph API Explorer (experimentos somente leitura)
- Abra o Graph API Explorer.
- Escolha seu Aplicativo da Meta no menu suspenso no canto superior direito (crie um em developers.facebook.com/apps se não tiver nenhum — escolha o tipo "Business").
- Clique em Generate Access Token e, em seguida, em Permissions, adicione no mínimo:
ads_read— para todas as ferramentas de leitura.ads_management— necessário para qualquer ferramenta de escrita (criar / atualizar / excluir / pausar / retomar / enviar / agendar orçamento).business_management— recomendado se você opera pelo Business Manager.pages_show_list,pages_read_engagement— necessários para as ferramentas de Páginas.
- Copie o token gerado. Este é um token de curta duração (~1 hora) — suficiente para testes.
Opção de produção — Token de Usuário de longa duração
Tokens de curta duração do Explorer expiram em cerca de uma hora. Troque o seu por um token de 60 dias:
curl -G "https://graph.facebook.com/v22.0/oauth/access_token" \
--data-urlencode "grant_type=fb_exchange_token" \
--data-urlencode "client_id=YOUR_APP_ID" \
--data-urlencode "client_secret=YOUR_APP_SECRET" \
--data-urlencode "fb_exchange_token=YOUR_SHORT_LIVED_TOKEN"
A resposta contém "access_token": "..." — esse token é válido por ~60 dias. Renove-o da mesma forma antes de expirar, ou crie um fluxo OAuth completo se precisar de acesso permanente.
Opção de produção — Token de Usuário do Sistema (recomendado para servidores)
Para uso de produção sem supervisão (sem expiração), gere um token de Usuário do Sistema no Business Manager:
- Vá para Business Manager → Configurações de Negócios → Usuários → Usuários do Sistema.
- Crie um usuário do sistema (ou use um existente), atribua a conta de anúncios relevante e conceda
ads_read/ads_management. - Clique em Generate New Token → escolha seu Aplicativo da Meta → selecione as mesmas permissões → Never para expiração.
Tokens de Usuário do Sistema não expiram e são ideais para implantações em backend.
Verificando seu token
curl "https://graph.facebook.com/v22.0/me?access_token=YOUR_TOKEN"
Deve retornar seu objeto de usuário/usuário do sistema. Se retornar um erro, verifique novamente as permissões e se o token não expirou.
Autenticação
Passe seu token de acesso da Meta usando um dos métodos:
Argumento de CLI (recomendado para Cursor / Claude Desktop):
node dist/index.js --access-token YOUR_META_ACCESS_TOKEN
Variável de ambiente:
export META_ADS_ACCESS_TOKEN=YOUR_META_ACCESS_TOKEN
node dist/index.js
O token é mantido apenas na memória do processo em execução — ele nunca é gravado em disco por este servidor.
Habilitando Ferramentas de Escrita
Por padrão, o servidor registra apenas as 35 ferramentas de leitura — as ferramentas de criar / atualizar / excluir / pausar / retomar / enviar / agendar orçamento não são expostas. Isso é intencional: um meta_ads_delete_campaign emitido por engano pode remover permanentemente campanhas e seus anúncios.
Para ativar, defina:
META_ADS_ENABLE_WRITE_TOOLS=true
Valores verdadeiros aceitos: true, 1, yes, on (sem diferenciar maiúsculas de minúsculas). Qualquer outro valor (ou não definido) mantém as escritas desativadas.
Quando ativado, o servidor registra um aviso de uma linha no stderr na inicialização:
[meta-ads-mcp] WARNING: META_ADS_ENABLE_WRITE_TOOLS is on — create/update/delete/pause/resume tools are EXPOSED. These can permanently delete campaigns/ad sets/ads or change live delivery.
Seu token de acesso também precisa da permissão ads_management para que as escritas sejam bem-sucedidas.
Exemplo de configuração no Cursor / Claude Desktop com escritas ativadas:
{
"mcpServers": {
"meta-ads": {
"command": "npx",
"args": ["-y", "meta-ads-mcp-server"],
"env": {
"META_ADS_ACCESS_TOKEN": "YOUR_META_ACCESS_TOKEN",
"META_ADS_ENABLE_WRITE_TOOLS": "true"
}
}
}
}
Modos de Transporte
| Modo | Caso de uso | Como ativar |
|---|---|---|
stdio (padrão) | Cursor, Claude Desktop, ferramentas locais | Nenhuma configuração necessária |
http | Conectores remotos do Claude.ai, configurações com vários clientes | Defina TRANSPORT=http |
Configuração no Cursor / Claude Desktop
Adicione uma das seguintes opções ao seu arquivo de configuração do cliente MCP:
Via npx (recomendado — sem necessidade de instalação local):
{
"mcpServers": {
"meta-ads": {
"command": "npx",
"args": ["-y", "meta-ads-mcp-server", "--access-token", "YOUR_META_ACCESS_TOKEN"]
}
}
}
Via build local:
{
"mcpServers": {
"meta-ads": {
"command": "node",
"args": ["/path/to/meta-ads-mcp/dist/index.js", "--access-token", "YOUR_META_ACCESS_TOKEN"]
}
}
}
Via variável de ambiente (e ativação de escritas):
{
"mcpServers": {
"meta-ads": {
"command": "npx",
"args": ["-y", "meta-ads-mcp-server"],
"env": {
"META_ADS_ACCESS_TOKEN": "YOUR_META_ACCESS_TOKEN",
"META_ADS_ENABLE_WRITE_TOOLS": "true"
}
}
}
}
Servidor HTTP Remoto
Execute como um servidor HTTP persistente para uso com conectores personalizados do Claude.ai ou qualquer cliente MCP remoto.
# Start on default port 3000
TRANSPORT=http META_ADS_ACCESS_TOKEN=YOUR_TOKEN node dist/index.js
# Start on a custom port, writes enabled
TRANSPORT=http \
META_ADS_ACCESS_TOKEN=YOUR_TOKEN \
META_ADS_ENABLE_WRITE_TOOLS=true \
PORT=8080 \
node dist/index.js
Endpoints:
POST /mcp— endpoint do protocolo MCPGET /health— verificação de saúde ({"status":"ok"})
Adicionando ao Claude.ai
- Vá para Settings → Connectors → Add custom connector
- Insira a URL do seu servidor:
https://your-domain.com/mcp - Clique em Add
Teste local com ngrok
# Terminal 1 — start the server
TRANSPORT=http META_ADS_ACCESS_TOKEN=YOUR_TOKEN PORT=8080 node dist/index.js
# Terminal 2 — expose publicly
ngrok http 8080
Use a URL HTTPS gerada (ex.: https://xxxx.ngrok-free.app/mcp) como a URL do seu conector.
Implantação em plataformas de nuvem
Defina as seguintes variáveis de ambiente no seu provedor de hospedagem (Railway, Render, Fly.io, etc.):
| Variável | Valor |
|---|---|
TRANSPORT | http |
META_ADS_ACCESS_TOKEN | Seu token de acesso da Meta |
META_ADS_ENABLE_WRITE_TOOLS | true para também expor ferramentas de mutação (desativado por padrão) |
PORT | Atribuída automaticamente pela plataforma |
Ferramentas Disponíveis
Legenda: 🔍 leitura • ✏️ escrita (controlada por META_ADS_ENABLE_WRITE_TOOLS) • 🛠️ utilitário puro (sem chamada de API).
Contas
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_list_ad_accounts | 🔍 | Listar todas as contas de anúncios acessíveis com seu token |
meta_ads_get_ad_account_details | 🔍 | Obter informações detalhadas de uma conta de anúncios específica |
Campanhas
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_get_campaign_by_id | 🔍 | Buscar uma campanha específica pelo ID |
meta_ads_get_campaigns_by_adaccount | 🔍 | Listar campanhas dentro de uma conta de anúncios, com filtros e paginação |
meta_ads_create_campaign | ✏️ | Criar uma nova campanha ODAX (CBO ou ABO) |
meta_ads_update_campaign | ✏️ | Atualizar nome/status/orçamento/lance; suporta migração CBO → ABO via adset_budgets |
meta_ads_delete_campaign | ✏️ | Excluir permanentemente uma campanha e seus conjuntos de anúncios/anúncios |
meta_ads_pause_campaign | ✏️ | Conveniência: definir status como PAUSED |
meta_ads_resume_campaign | ✏️ | Conveniência: definir status como ACTIVE |
Entradas de meta_ads_create_campaign:
act_id(string) — ID da conta de anúncios, formatoact_XXXXXXXXX.name(string) — Nome da campanha.objective(enum) — Objetivo baseado em resultado ODAX:OUTCOME_AWARENESS,OUTCOME_TRAFFIC,OUTCOME_ENGAGEMENT,OUTCOME_LEADS,OUTCOME_SALES,OUTCOME_APP_PROMOTION.- Objetivos legados (
BRAND_AWARENESS,LINK_CLICKS,CONVERSIONS,APP_INSTALLS, …) não são aceitos pela Meta v22+ e retornarão HTTP 400.
status(padrãoPAUSED),special_ad_categories(padrão[])daily_budget/lifetime_budget(centavos) — omita ambos quandouse_adset_level_budgets=true.bid_strategy—LOWEST_COST_WITHOUT_CAP(padrão),LOWEST_COST_WITH_BID_CAP,COST_CAP,LOWEST_COST_WITH_MIN_ROAS. Estratégias de limite de lance exigembid_amountem cada conjunto de anúncios filho.bid_cap,spend_cap,campaign_budget_optimization,use_adset_level_budgets,ab_test_control_setups,buying_type.
{
"act_id": "act_123456789012345",
"name": "2026 - Spring Sale - Awareness",
"objective": "OUTCOME_AWARENESS",
"special_ad_categories": [],
"status": "PAUSED",
"bid_strategy": "LOWEST_COST_WITHOUT_CAP",
"daily_budget": 10000
}
Conjuntos de Anúncios
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_get_adset_by_id | 🔍 | Buscar um único conjunto de anúncios pelo ID |
meta_ads_get_adsets_by_ids | 🔍 | Buscar em lote vários conjuntos de anúncios |
meta_ads_get_adsets_by_adaccount | 🔍 | Listar conjuntos de anúncios em uma conta de anúncios |
meta_ads_get_adsets_by_campaign | 🔍 | Listar conjuntos de anúncios dentro de uma campanha |
meta_ads_create_adset | ✏️ | Criar um novo conjunto de anúncios sob uma campanha |
meta_ads_update_adset | ✏️ | Atualizar os campos de um conjunto de anúncios (nota: frequency_control_specs é imutável após a criação) |
meta_ads_delete_adset | ✏️ | Excluir permanentemente um conjunto de anúncios |
meta_ads_pause_adset | ✏️ | Definir status como PAUSED |
meta_ads_resume_adset | ✏️ | Definir status como ACTIVE |
Destaques de meta_ads_create_adset:
- Obrigatórios:
act_id,campaign_id,name,optimization_goal,billing_event. targeting(objeto) — especificação completa de segmentação; lembre-se de quetargeting_automation.advantage_audienceassume o padrão0na Meta v24+ — defina-o explicitamente se quiser o Público Advantage+.bid_amount— necessário paraLOWEST_COST_WITH_BID_CAP/COST_CAP.bid_constraints— necessário paraLOWEST_COST_WITH_MIN_ROAS, ex.:{"roas_average_floor": 20000}para um piso de ROAS de 2,0×.dsa_beneficiary/dsa_payor— necessários para conjuntos de anúncios direcionados à UE.promoted_object— necessário paraAPP_INSTALLS.frequency_control_specs— DEVE ser definido na criação; a Meta o torna imutável depois.regional_regulated_categories/regional_regulation_identities— verticais regulamentadas de Taiwan / Austrália / Singapura / Índia.
Anúncios
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_get_ad_by_id | 🔍 | Buscar um único anúncio por ID |
meta_ads_get_ads_by_adaccount | 🔍 | Listar anúncios em uma conta de anúncios |
meta_ads_get_ads_by_campaign | 🔍 | Listar anúncios dentro de uma campanha |
meta_ads_get_ads_by_adset | 🔍 | Listar anúncios dentro de um conjunto de anúncios |
meta_ads_create_ad | ✏️ | Criar um novo anúncio referenciando uma criação existente |
meta_ads_update_ad | ✏️ | Atualizar nome / status / lance / especificações de rastreamento / referência de criação |
meta_ads_delete_ad | ✏️ | Excluir permanentemente um anúncio |
meta_ads_pause_ad | ✏️ | Definir status para PAUSED |
meta_ads_resume_ad | ✏️ | Definir status para ACTIVE |
ℹ️ Trocar
creative_idem um anúncio FLEX pode falhar comerror_subcode 3858355se as imagensasset_feed_specda nova criação não corresponderem ao seuobject_story_spec. Nesse caso, crie um novo anúncio com a nova criação e pause o antigo (você perde prova social, mas o anúncio é veiculado).
Criativos
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_get_ad_creative_by_id | 🔍 | Buscar um criativo |
meta_ads_get_ad_creatives_by_ad_id | 🔍 | Listar criativos anexados a um anúncio |
meta_ads_get_adcreatives_by_adaccount | 🔍 | Listar criativos em uma conta de anúncios |
meta_ads_compute_image_crops | 🛠️ | Calcular caixas de corte centralizadas para as 6 proporções aceitas pelo Meta (sem chamada de API) |
meta_ads_create_ad_creative | ✏️ | Criar um criativo — 3 modos simples além de uma saída completa via object_story_spec |
meta_ads_update_ad_creative | ✏️ | Atualizar name / asset_feed_spec (o Meta restringe a maioria das outras atualizações de conteúdo) |
meta_ads_create_ad_creative — três modos comuns:
- Promover uma publicação existente: passe apenas
object_story_idno formato{page_id}_{post_id}. - Anúncio de link com imagem única:
page_id+image_hash+link_url+message+ opcionalheadline,description,call_to_action_type. - Anúncio de vídeo único:
page_id+video_id+link_url+message+ opcionalheadline,call_to_action_type,thumbnail_url.
Para layouts avançados (FLEX/DOF, Personalização de Ativos de Posicionamento, Criativo Dinâmico, múltiplos títulos, formulários de geração de leads, conteúdo de marca, recortes de imagem), passe um object_story_spec e/ou asset_feed_spec totalmente compostos — eles têm precedência sobre a construção automática do modo simples.
Mídia
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_get_ad_images | 🔍 | Listar ativos de imagem em uma conta de anúncios |
meta_ads_get_image_by_hash | 🔍 | Consulta de imagem única por hash (URL + dimensões) |
meta_ads_get_ad_previews | 🔍 | Gerar prévias renderizadas de um anúncio em diferentes posicionamentos |
meta_ads_get_ad_video | 🔍 | Detalhes do vídeo (URL de origem, miniaturas, duração) por ad_id ou video_id |
meta_ads_upload_ad_image | ✏️ | Enviar uma imagem para a biblioteca de imagens de anúncios da conta e obter de volta seu image_hash |
meta_ads_upload_ad_image aceita exatamente um dos seguintes:
file— uma URL de dados (data:image/png;base64,iVBORw0KG...) ou uma string base64 bruta.image_url— uma URL pública; o servidor baixa os bytes e os envia.
Retorna o image_hash que você então passa para meta_ads_create_ad_creative.
Insights
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_get_adaccount_insights | 🔍 | Métricas de desempenho no nível da conta |
meta_ads_get_campaign_insights | 🔍 | Métricas de desempenho para uma campanha específica |
meta_ads_get_adset_insights | 🔍 | Métricas de desempenho para um conjunto de anúncios específico |
meta_ads_get_ad_insights | 🔍 | Métricas de desempenho para um anúncio específico |
Todos os quatro aceitam a mesma superfície de opções: fields, date_preset, time_range, time_ranges, time_increment, level, action_attribution_windows, action_breakdowns, breakdowns, filtering, sort, paginação e localidade.
Precedência de intervalo de tempo: time_ranges > time_range > since/until > date_preset.
Catálogo de Segmentação
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_search_interests | 🔍 | Pesquisar o catálogo de interesses do Meta por palavra-chave |
meta_ads_get_interest_suggestions | 🔍 | Obter interesses relacionados a partir de uma lista inicial |
meta_ads_search_behaviors | 🔍 | Listar opções de segmentação por comportamento disponíveis |
meta_ads_search_demographics | 🔍 | Listar opções demográficas (demographics / life_events / industries / income / family_statuses / user_device / user_os) |
meta_ads_search_geo_locations | 🔍 | Pesquisar países / regiões / cidades / CEPs / geo_markets / distritos eleitorais |
meta_ads_estimate_audience_size | 🔍 | Estimar alcance para uma especificação de segmentação via /act_X/delivery_estimate |
Páginas
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_get_account_pages | 🔍 | Listar Páginas do Facebook acessíveis a partir do token de acesso (/me/accounts) |
meta_ads_search_pages_by_name | 🔍 | Filtro de substring sobre as páginas do token (lado do cliente — o Meta não expõe um filtro de nome no servidor) |
Os valores page_id retornados são os que você passa para meta_ads_create_ad_creative.
Agendamentos de Orçamento
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_create_budget_schedule | ✏️ | Agendar um aumento temporário de orçamento para uma campanha em uma janela de timestamp Unix |
Entradas:
campaign_id(string)budget_value(int, positivo)budget_value_type—ABSOLUTE(centavos na moeda da conta) ouMULTIPLIER(por exemplo,2dobra o orçamento)time_start,time_end(timestamps Unix em segundos) —time_end > time_start
Atividades
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_get_activities_by_adaccount | 🔍 | Recuperar o log de histórico de alterações de uma conta de anúncios |
meta_ads_get_activities_by_adset | 🔍 | Recuperar o log de histórico de alterações de um conjunto de anúncios |
Ferramenta de Paginação
| Ferramenta | Tipo | Descrição |
|---|---|---|
meta_ads_fetch_pagination_url | 🛠️ | Seguir URLs paging.next / paging.previous da resposta de qualquer outra ferramenta |
Ponta a Ponta: Criar um Anúncio do Zero
Um fluxo de trabalho típico de "criar um novo anúncio" usa ferramentas de várias categorias. Com META_ADS_ENABLE_WRITE_TOOLS=true:
1. meta_ads_list_ad_accounts → pick an act_id
2. meta_ads_get_account_pages → pick a page_id
3. meta_ads_search_geo_locations(q="Vietnam") → grab the country/region keys
4. meta_ads_search_interests(q="cooking") → grab interest IDs
5. meta_ads_estimate_audience_size(act_id, targeting) → sanity-check reach
6. meta_ads_upload_ad_image(act_id, image_url) → returns image_hash
7. meta_ads_create_campaign(act_id, ...) → returns campaign_id
8. meta_ads_create_adset(act_id, campaign_id, targeting, ...) → returns adset_id
9. meta_ads_create_ad_creative(act_id, page_id, image_hash, link_url, message, ...) → returns creative_id
10. meta_ads_create_ad(act_id, name, adset_id, creative_id, status="PAUSED") → returns ad_id
11. (Optional) meta_ads_get_ad_previews(ad_id, ...) → render placements before going live
12. meta_ads_resume_ad(ad_id) → flip to ACTIVE when ready
Todos os passos que alteram o estado usam como padrão status: "PAUSED" para que nada seja publicado até que você chame explicitamente uma ferramenta de retomada.
Paginação
Muitas ferramentas de listagem retornam resultados paginados. Quando uma resposta contém uma URL paging.next, use meta_ads_fetch_pagination_url para recuperar as páginas seguintes:
1. Call meta_ads_get_campaigns_by_adaccount → receive first page
2. Check if response.paging.next exists
3. Call meta_ads_fetch_pagination_url(url=response.paging.next) → receive next page
4. Repeat until paging.next is absent
Desenvolvimento
npm run dev # Watch mode — auto-recompile on change
npm run build # Compile TypeScript to dist/
npm run clean # Remove dist/
npm run clean && npm run build # Full rebuild from scratch
Teste rápido de fumaça:
# Default (read-only)
META_ADS_ACCESS_TOKEN=dummy node dist/index.js
# → "Meta Ads MCP server running via stdio"
# With writes enabled
META_ADS_ACCESS_TOKEN=dummy META_ADS_ENABLE_WRITE_TOOLS=true node dist/index.js
# → WARNING line + "Meta Ads MCP server running via stdio"
Estrutura do Projeto
meta-ads-mcp/
├── src/
│ ├── index.ts # Entry point, server setup, transport selection, write-tools warning
│ ├── constants.ts # API version, base URLs, isWriteToolsEnabled() flag
│ ├── types.ts # Shared TypeScript interfaces
│ ├── services/
│ │ └── graph-api.ts # HTTP client (GET/POST/DELETE), auth, error handling, param builders
│ ├── schemas/
│ │ ├── common.ts # Shared Zod schemas (pagination, date ranges, filters)
│ │ └── insights.ts # Insights-specific Zod schemas
│ └── tools/
│ ├── accounts.ts # Account tools
│ ├── insights.ts # Insights tools (account/campaign/adset/ad level)
│ ├── campaigns.ts # Campaign read + write/lifecycle tools
│ ├── adsets.ts # Ad set read + write/lifecycle tools
│ ├── ads.ts # Ad read + write/lifecycle tools
│ ├── creatives.ts # Creative read tools, image crops utility, create/update creative
│ ├── media.ts # Image list / upload / hash lookup / video / preview
│ ├── activities.ts # Activity log tools
│ ├── pagination.ts # Pagination utility tool
│ ├── targeting.ts # Interest/behavior/demographic/geo search + audience-size estimate
│ ├── pages.ts # Facebook Pages list and name search
│ └── budget-schedules.ts # Campaign budget schedule create
├── dist/ # Compiled JavaScript output (generated)
├── package.json
└── tsconfig.json