Google Ads MCP server: connect Claude or Codex to your ad accounts
Google shipped an official Google Ads MCP server in April 2026. It is read-only by design — three tools, local stdio transport, your own OAuth credentials — and for asking questions about an account that is the correct, free answer. This guide covers what it does, what changes when an MCP server can also write, and the exact configuration for Claude Code, Claude Desktop and Codex.
What Google's official server gives you
Google's Ads API team shipped the official MCP server on 28 April 2026. It is written in Python, speaks stdio (so it runs on your own machine rather than as a hosted endpoint), and authenticates with your OAuth credentials or a service account.
It exposes three tools: `list_accessible_customers`, `search` for GAQL reporting, and `get_resource_metadata`. That is deliberate and it is enough for a large class of work — GAQL reaches essentially all of Ads reporting, so "which campaigns lost the most conversions last month" is fully answerable.
- Read-only. It cannot change a bid, pause a campaign or create an asset.
- Local. There is no Google-hosted remote endpoint for Ads; you run it or you self-host it.
- Your credentials. You supply a developer token and OAuth client, which is the part most people get stuck on.
What a full MCP server adds
The write count is the headline, but the gate around it is the point. A key gets `tools:write` or it does not, that decision belongs to the organization rather than to whoever is prompting, and a write still passes the autonomy guardrails in strict mode — change caps, protected campaigns, the monthly spend cap, and verification of the current value before it is replaced.
| Google's official server | Agent Planners MCP | |
|---|---|---|
| Transport | stdio, runs locally | Streamable HTTP, hosted |
| Google Ads tools | 3 (reporting + metadata) | 32 reads, 94 writes |
| Writes | None | Budgets, bids, negatives, status, assets, geo, RSAs |
| Credentials | Yours — developer token, OAuth client | Connected once over OAuth; the key never carries them |
| Approval before a write | n/a | Every write, with roles and an audit row |
| Audit trail | n/a | Writes logged with the acting key as actor |
| Other platforms in the same session | No | 16 more families on one endpoint |
How to configure it
- 1In the app, open API & MCP and create a key. Scopes decide the mode: `tasks:*` + `accounts:read` gives agent mode (hand over a goal, we plan and execute it); `tools:read` / `tools:write` gives tools mode (your agent calls our tools directly). Tools mode requires a paid plan and fails closed.
- 2Connect Google Ads under Integrations if you have not already — this is the OAuth step, and it is what means the MCP key never carries a developer token.
- 3Add the server to your client (snippets below).
- 4Ask your agent to call `describe_permissions` first. It answers what that key may actually do — mode, scopes, plan entitlement, connected accounts — so the agent stops guessing.
- 5Call `list_accounts` to get the account ids, then scope every tool call with one. Account resolution is exact or it refuses: one match inside your organization, or an error naming the candidates.
Client configuration
Claude Code — one command:
claude mcp add --transport http agentplanners https://www.agentplanners.com/api/mcp \
--header "Authorization: Bearer ap_live_…"Claude Desktop and Codex
Claude Desktop takes the endpoint and header as JSON:
{
"mcpServers": {
"agentplanners": {
"url": "https://www.agentplanners.com/api/mcp",
"headers": {
"Authorization": "Bearer ap_live_…"
}
}
}
}Use cases that need the write half
- Search-term cleanup end to end — pull the terms report, decide the negatives, and add them to the right ad groups, with the list waiting for your approval before it applies.
- Budget reallocation across campaigns, where the agent models the shift and the change cap stops it going further than you allow.
- Geo and location-option corrections — one of the places where reading the current value before replacing it genuinely matters, because "presence" versus "presence or interest" changes who sees the ad.
- Bulk status changes across an MCC, with an audit row per change naming who approved it.
One Google Ads specific thing worth knowing
GAQL is not SQL and the API version matters more than people expect. Google Ads v25 removed `campaign.start_date` and has no account-creation-date field at all; a query using either returns `UNRECOGNIZED_FIELD`, and the useful detail only appears if the caller prints the error's `details` array. Mutations have a related trap: 16 services reject `partialFailure` and 31 reject `responseContentType`, so a request built from a generic template fails at parse time with a message about an unknown field.
None of that is MCP's fault — it is the shape of the Google Ads API — but it is the kind of thing that decides whether an agent gets a useful answer or a confusing error.
Frequently asked questions
- Does Google have an official Google Ads MCP server?
- Yes — the Google Ads API team shipped one on 28 April 2026. It is read-only, exposes three tools (list_accessible_customers, search for GAQL, get_resource_metadata), runs locally over stdio, and uses your own OAuth credentials or a service account.
- Can Google's Google Ads MCP server change my campaigns?
- No. It is read-only by design and cannot modify bids, pause campaigns or create assets. Writing requires a server built for it, with its own approval and audit layer.
- How many Google Ads tools does Agent Planners expose over MCP?
- 32 reads and 94 writes for the Google Ads family, on the same endpoint as 16 other platforms. A key only sees the writes if it carries the tools:write scope.
- Do I need a Google Ads developer token to use it?
- Not for the hosted route — you connect Google Ads once over OAuth in the app, and the MCP key carries scopes rather than credentials. Google's own server does need a developer token and OAuth client of your own.
- Does an external agent bypass my approval settings?
- No. Writes run through the same dispatcher and the same autonomy guardrails as the in-app agent, in strict mode, regardless of which MCP client made the call.