K
Kodama Vault
knowledge hub
Vault
HomeBoardMap of ContentChatConversasAuditoria
Agentes
AgentsIssuesTerminalPreviews
Sistema
MCPSetup MCPSettings
Brain
Global agent instructions
Análise custos migração — evitar senha no payloadLevantamento fluxo registro + duplicados StripeRelatório segurança + pentes finos (Cláudio)Revisão security concerns e race conditionsMagic link / esqueceu senha via SupabaseCorrigir erros pós-upgrade TypeScriptTestar PRs do agente Vault para mergeAnálise de 3 issues para iniciarErro no terminal do VSCodePR #173 — aguardando aprovação do LeoTestar fluxo ponta a ponta — criação de clients no StripePR #172 — testar e subir correção de funções deprecatedPitch de vendas SaaS — agendar call de conversãoOrganizar issues e bugs rápidos para a semanaMerge PR cadastro-novo — funcionalidades e correçõesCorrigir bugs PR #173 e #172 — image domainsPR mesosóico — página de acesso mobile + segurança OTPRefatoração de códigos — PR #202Ajustes em PRs abertos de ontemEstudo de jornada de compra e técnicas de fechamentoDefinir preço e entregável do produtoProspecção de reuniões para esta semanaAgente anti AI slop — centralização de conhecimento ConnfitPR #179 — resolver conflitos e erros de teste CLIAlinhamento de preços e usos da ConffitFix adicional para PR #183 — perfil do usuárioCorrigir estilização da Connfit para identidade visualSubir modificações no copy da ConnfitCriação de 4 campanhas no Meta AdsRevisão de PRs do GilinesExploração do Roblox EditorRelatório João — devolutiva TikTok ShopReunião presencial Zassi Uniformes — diagnóstico automaçõesCriar repositório de diagnósticos e relatórios de entrevistasDiagnóstico da ZassiGeração de relatórios para reuniões de fechamentoProposta Zassi — apresentação amanhãProspecção — Clínica Odontológica Dr. But
VPS Hermes — acesso e estrutura
Always Commit Push DeployHermes Voice GeminiHermes VPSKodama Prospects TrackerMEMORYObsidian VaultRoblox Mining Sim
OpenSpec -- Spec-Driven Development no VaultPlano de Teste — OpenSpec Vault Persistence
CaumzitoNyxzZanini
Google Ads MCP Server — Spec
Claude Code — Setup MCP VaultClaude Desktop — Setup MCP Vault (remote)VS Code + Copilot — Setup MCP Vault
Skill — Carousel Designer (Paper Style)
Standup 2026-05-14Standup 2026-05-15Standup 2026-05-16Standup 2026-05-17Standup 2026-05-18Standup 2026-05-19Standup 2026-05-20Standup 2026-05-21Standup 2026-05-22Standup 2026-05-25Standup 2026-05-26Standup 2026-05-27Standup 2026-05-28Standup 2026-05-29Standup 2026-06-01Standup 2026-06-02Standup 2026-06-03Standup 2026-06-05Standup 2026-06-11Standup 2026-06-15Standup 2026-06-16Standup 2026-06-17Standups
MOCWelcome
v0.3
K
Kodama Vault
brain / projects / google-ads-mcp

Google Ads MCP Server — Spec

Google Ads MCP Server

Replica o toolkit demonstrado por Austin Lau (@helloitsaustin) — um MCP Server que expõe a Google Ads API (via GAQL) para o Claude, permitindo skills como mine-search-terms, budget-optimize, audit-ad-copy, weekly-review, etc.

Referência: https://x.com/helloitsaustin/status/2036553581625745511


1. O que é

Um servidor MCP (Model Context Protocol) em TypeScript/Node que:

  1. Conecta ao Google Ads API via OAuth 2.0
  2. Expõe tools que o Claude pode chamar (GAQL queries, mutations, relatórios)
  3. Permite criar skills no Claude.ai que encapsulam workflows de performance marketing
  4. Funciona no Claude Desktop, Claude Code e Cowork

2. Tools expostos

2.1 — get_search_terms

Puxa termos de busca de uma ou mais campanhas.

Parâmetros:

{
  customer_id: string;
  date_range: "LAST_7_DAYS" | "LAST_14_DAYS" | "LAST_30_DAYS" | "LAST_90_DAYS";
  min_clicks?: number;           // default: 1
  limit?: number;                // default: 2000
  order_by?: "cost" | "clicks" | "impressions" | "conversions"; // default: "cost"
  campaign_ids?: string[];       // filtra por campanhas específicas (opcional)
  status_filter?: "NONE" | "ALL"; // default: "NONE" (só não-acionados)
}

GAQL gerado:

SELECT
  search_term_view.search_term,
  search_term_view.status,
  campaign.id,
  campaign.name,
  ad_group.name,
  metrics.clicks,
  metrics.impressions,
  metrics.cost_micros,
  metrics.conversions,
  metrics.ctr,
  metrics.average_cpc
FROM search_term_view
WHERE
  segments.date DURING {date_range}
  AND metrics.clicks >= {min_clicks}
  AND search_term_view.status = {status_filter}
ORDER BY metrics.cost_micros DESC
LIMIT {limit}

Retorno: Array de SearchTerm com campos normalizados (cost em $ não micros).


2.2 — get_campaigns

Lista campanhas com métricas de período.

Parâmetros:

{
  customer_id: string;
  date_range: DateRange;
  status?: "ENABLED" | "PAUSED" | "REMOVED"; // default: "ENABLED"
}

2.3 — get_ad_groups

Lista ad groups de uma campanha específica.

Parâmetros:

{
  customer_id: string;
  campaign_id?: string;
  date_range: DateRange;
}

2.4 — get_keywords

Keywords ativas com performance.

Parâmetros:

{
  customer_id: string;
  campaign_id?: string;
  date_range: DateRange;
  min_impressions?: number;
}

2.5 — get_ads

Anúncios com copy e performance.

Parâmetros:

{
  customer_id: string;
  campaign_id?: string;
  date_range: DateRange;
  include_paused?: boolean;
}

2.6 — add_negative_keywords

Adiciona negative keywords em bulk (exact match por padrão).

Parâmetros:

{
  customer_id: string;
  negatives: Array<{
    keyword: string;
    match_type: "EXACT" | "PHRASE" | "BROAD";
    level: "campaign" | "ad_group";
    campaign_id: string;
    ad_group_id?: string;  // obrigatório se level = "ad_group"
  }>;
}

Comportamento:

  • Batch mutate (único request para N keywords)
  • Retorna { added: N, failed: M, errors: [...] }
  • Idempotente: se keyword já existe como negative, ignora sem erro

2.7 — get_account_budget

Budget e spend atual da conta/campanhas.

Parâmetros:

{
  customer_id: string;
  date_range: DateRange;
}

2.8 — update_campaign_budget

Atualiza budget diário de uma campanha.

Parâmetros:

{
  customer_id: string;
  campaign_id: string;
  new_daily_budget_usd: number;
}

2.9 — get_account_conventions

Tool especial — lê arquivo account-conventions.md do working directory e retorna como contexto. Usado pelas skills para carregar convenções de nomenclatura da conta antes de avaliar campanhas. Não chama a Google Ads API.


2.10 — run_gaql

Escape hatch — executa GAQL arbitrário. Read-only: rejeita queries com INSERT, UPDATE, DELETE, MUTATE.

Parâmetros:

{
  customer_id: string;
  query: string;
  max_rows?: number;  // default: 5000, max: 10000
}

3. Arquitetura

google-ads-mcp/
├── src/
│   ├── index.ts              # Entry point — registra tools MCP
│   ├── server.ts             # MCP Server setup (stdio ou HTTP)
│   ├── auth/
│   │   ├── oauth.ts          # Google OAuth 2.0 flow
│   │   └── token-store.ts    # Refresh token persistence
│   ├── api/
│   │   ├── client.ts         # Google Ads API client (REST v18)
│   │   ├── gaql.ts           # GAQL query builder + executor
│   │   └── mutations.ts      # Bulk mutate helpers
│   ├── tools/
│   │   ├── get-search-terms.ts
│   │   ├── get-campaigns.ts
│   │   ├── get-ad-groups.ts
│   │   ├── get-keywords.ts
│   │   ├── get-ads.ts
│   │   ├── add-negative-keywords.ts
│   │   ├── get-account-budget.ts
│   │   ├── update-campaign-budget.ts
│   │   ├── get-account-conventions.ts
│   │   └── run-gaql.ts
│   └── utils/
│       ├── micros.ts         # micros ↔ $ conversion
│       ├── date-ranges.ts    # DateRange enum → GAQL string
│       └── csv.ts            # CSV bulk-upload-ready (Google Ads Editor format)
├── skills/
│   ├── mine-search-terms.md
│   ├── search-term-methodology.md
│   ├── budget-optimize.md
│   ├── audit-ad-copy.md
│   ├── investigate-campaign.md
│   ├── weekly-review.md
│   ├── performance-analysis.md
│   └── account-conventions.md  # Template — usuário customiza
├── package.json
├── tsconfig.json
└── README.md

4. Auth — Google Ads API

4.1 — Credenciais necessárias

Credencial Onde obter Env var
client_id Google Cloud Console → OAuth 2.0 GOOGLE_CLIENT_ID
client_secret Google Cloud Console GOOGLE_CLIENT_SECRET
refresh_token OAuth flow (1x, persiste) GOOGLE_REFRESH_TOKEN
developer_token Google Ads API Center GOOGLE_ADS_DEVELOPER_TOKEN
customer_id Google Ads (sem hífens) GOOGLE_ADS_CUSTOMER_ID
login_customer_id MCC account ID (se MCC) GOOGLE_ADS_LOGIN_CUSTOMER_ID

4.2 — Obter refresh token (1x)

npm run auth
# Abre browser → Google OAuth → grava refresh_token em ~/.google-ads-mcp/credentials.json

4.3 — Headers de request

Authorization: Bearer {access_token}
developer-token: {developer_token}
login-customer-id: {login_customer_id}   // só se MCC

5. Stack

Item Escolha
Runtime Node.js 20+
Linguagem TypeScript 5
MCP SDK @modelcontextprotocol/sdk
Google Ads REST API v18 (não gRPC)
Auth googleapis package (OAuth2 client)
Transport stdio (Claude Desktop) + HTTP/SSE opcional
CSV output csv-stringify

6. Skills (prompts estruturados)

6.1 — mine-search-terms

Load `search-term-methodology` and `account-conventions` skills before starting.

Mine the search term report for negative keyword candidates, using relevance-based
evaluation (not just conversion count). Final deliverable is a bulk-upload-ready
CSV importable into Google Ads Editor.

Steps:
1. Call get_search_terms with date_range=LAST_30_DAYS, min_clicks=1,
   limit=2000, order_by=cost. Pass campaign_ids if $ARGUMENTS provided.
2. Evaluate every term using three-way cross-reference:
   - Search term (what user typed)
   - Keyword (what triggered the ad)
   - Campaign + ad group theme (use account-conventions to interpret names)
   Decide: Negate or Keep. Relevance matters more than conversion count.
3. Build CSV with only negation candidates.
   Format: Google Ads Editor bulk upload. Filename: search-term-negatives-YYYY-MM-DD.csv
4. Present top 10 negatives by spend with reasoning + category breakdown.
   Offer to execute add_negative_keywords campaign-by-campaign with explicit
   user YES before each batch.

6.2 — search-term-methodology

Search Term Mining Methodology

Goal: relevance to campaign theme — NOT "zero conversions = bad".

Core Approach:
1. Filter to unactioned terms (status=NONE) — get_search_terms does this automatically.
2. Sort by spend descending — $5 CPC with 20 clicks matters more than $0.10 with 200.
3. Cross-reference: search term + matched keyword + campaign/ad group name.
   Question: does this search term fit the theme?

Decision Rules:
- Competitor brand → Negate (exact)
- Job/hiring intent → Negate (broad)
- Research/educational intent → Negate (phrase)
- Free/open-source alternative → Negate (exact)
- Unrelated industry → Negate (broad)
- Adjacent product, same industry → Flag for review
- On-theme, low conversion → Keep (more data needed)
- High-volume, on-theme, no keyword yet → Keyword opportunity

6.3 — budget-optimize

Analyze budget allocation and surface reallocation opportunities.

Steps:
1. Call get_account_budget for LAST_30_DAYS.
2. Call get_campaigns for same period.
3. For each campaign compute: utilization % (spend/cap), CPA vs average, ROAS vs average.
4. Flag:
   - Budget-constrained (utilization >90%) + CPA ≤ average → increase candidate
   - Under-delivering (utilization <50%) + poor CPA → pause or cut
   - High cost + zero conversions + 30 days → immediate cut
5. Propose reallocation table: From → To, amount, expected impact.
6. Ask confirmation before calling update_campaign_budget on any campaign.

6.4 — weekly-review

Generate weekly performance review.

Sections:
1. Executive summary — 3 bullets: what worked, what didn't, one action item.
2. Campaign performance table — this week vs last week (impressions, clicks,
   CTR, conversions, CPA, spend).
3. Top movers — biggest positive/negative WoW changes with hypothesis.
4. Search term highlights — call get_search_terms LAST_7_DAYS, top 5 spend
   with no conversions as immediate negative candidates.
5. Budget pacing — on track / over / under for the month.
6. Recommendations — max 5, prioritized, with effort estimate (Quick/Medium/Big).

Output: Markdown report, ready to paste into Notion or email.

6.5 — audit-ad-copy

Audit ad copy quality and flag improvement opportunities.

Steps:
1. Call get_ads for LAST_30_DAYS.
2. For each ad evaluate:
   - Headlines: presence of keyword, value prop, CTA
   - Descriptions: specificity, differentiator, urgency
   - CTR vs campaign average (below average = copy problem)
   - Pinning issues (headline 1/2 pinned unnecessarily?)
3. Flag: underperforming ads (CTR < 50% of campaign avg) + reason.
4. Suggest rewrites for top 3 underperformers.
5. Output table: Ad | CTR | Issue | Suggested Fix.

7. Setup — Claude Desktop (local)

7.1 — Instalar

git clone https://github.com/kodama-labs/google-ads-mcp
cd google-ads-mcp
npm install && npm run build
npm run auth   # OAuth browser flow

7.2 — claude_desktop_config.json

{
  "mcpServers": {
    "google-ads": {
      "command": "node",
      "args": ["/absolute/path/to/google-ads-mcp/dist/index.js"],
      "env": {
        "GOOGLE_CLIENT_ID": "...",
        "GOOGLE_CLIENT_SECRET": "...",
        "GOOGLE_REFRESH_TOKEN": "...",
        "GOOGLE_ADS_DEVELOPER_TOKEN": "...",
        "GOOGLE_ADS_CUSTOMER_ID": "1234567890"
      }
    }
  }
}

7.3 — Skills no Claude.ai

Claude.ai → Settings → Skills → New Skill → colar conteúdo de cada arquivo em /skills/.


8. Deploy remoto (HTTP/SSE)

Para multi-user ou Cowork:

import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
const transport = new StreamableHTTPServerTransport({ port: 3100 });
await server.connect(transport);

Auth multi-user: refresh_token por usuário em DB, passado via header X-Google-Customer-Id.


9. Gotchas

  • Developer token: requer aprovação Google (~1 semana com conta MCC com spend). Test accounts liberados imediatamente.
  • Micros: Google Ads retorna cost em micros (÷1.000.000 pra $). Sempre normalizar antes de exibir.
  • MCC: login-customer-id = MCC ID, customer-id = conta do cliente. Ambos nos headers.
  • Rate limits: 15.000 operações/dia tier básico. Bulk mutate: até 5.000 operations por request.
  • CSV format: colunas específicas do Google Ads Editor — ver https://support.google.com/google-ads/editor/answer/57747

10. Roadmap

  • Fase 1 — MCP Server local (stdio), tools de leitura (get_*)
  • Fase 2 — Mutations (add_negative_keywords, update_campaign_budget)
  • Fase 3 — Skills completas em /skills/
  • Fase 4 — Auth CLI (npm run auth) + token persistence
  • Fase 5 — Deploy HTTP/SSE multi-user
  • Fase 6 — Publicar no npm como @kodama/google-ads-mcp

11. Referências

  • Google Ads API REST v18: https://developers.google.com/google-ads/api/rest/overview
  • GAQL reference: https://developers.google.com/google-ads/api/fields/v18/overview
  • MCP SDK TypeScript: https://github.com/modelcontextprotocol/typescript-sdk
  • Google Ads Editor bulk upload: https://support.google.com/google-ads/editor/answer/57747
  • Post original Austin Lau: https://x.com/helloitsaustin/status/2036553581625745511
notas relacionadas
carregando…