Google Ads MCP: build the whole tree from your agent, atomically

Hermoso's MCP server creates a Google Ads campaign, ad group, responsive search or display ad and its keywords in a single atomic mutate — so a rejected ad means the budget was never created either. Plus bidding strategies, geo and language targeting, GAQL reporting, and a confirm gate on anything that starts spend.

Google Ads is a tree, and trees are where scripted campaign creation usually goes wrong. You create a budget, then a campaign, then an ad group, then an ad — and if the ad is rejected at step four you are left holding three orphaned objects and a budget you did not want. Cleaning that up by hand is the reason most people give up on automating Google Ads.

Hermoso’s MCP server builds the whole tree in one atomic operation, using temporary resource ids so the children can reference parents that do not exist yet. Either the campaign, ad group, ad and keywords all come into existence, or none of them do. A rejected ad means the budget was never created either.

Install it once: in Claude Code, Cursor or Codex run claude mcp add --transport http hermoso https://app.hermoso.ai/mcp. In Claude.ai or Claude Desktop, paste https://app.hermoso.ai/mcp under Settings → Connectors and approve it with your Hermoso account. For a terminal agent, npm install -g hermoso then hermoso auth login. Full setup on the MCP & CLI page.

The Google Ads tools

Build. create_google_ads_campaign, create_google_ads_ad_group, create_google_ads_ad, add_google_ads_keywords, upload_google_ads_asset.

Configure. set_google_ads_budget, set_google_ads_bidding (six strategies), set_google_ads_targeting (geo and language), find_google_ads_locations.

Read and change. list_google_ads_campaigns, google_ads_report for arbitrary GAQL, and set_google_ads_status — the one confirm-gated switch that starts real spend.

create_google_ads_campaign also accepts a dry-run mode, so an agent can validate a whole tree against the live API without creating anything — a good default when it is proposing a plan for you to approve.

The live-spend gate is wider than one tool

Pausing a campaign is not the only way to avoid spending, and treating it that way is a real trap: creating an enabled ad group, ad or keyword under an already enabled parent serves on the very next auction. So the same confirmation that guards set_google_ads_status also guards create_google_ads_ad_group, create_google_ads_ad and add_google_ads_keywords whenever the parent is live — read off the row each of those already fetches, at no extra round trip. Negative keywords only ever restrict spend, so they are never gated.

GAQL reporting, with one caveat worth knowing

google_ads_report takes arbitrary GAQL, so your agent can ask for whatever slice it needs rather than being boxed into a fixed report shape. One thing to keep in mind if you are writing queries by hand or letting a model write them: GAQL is not SQL. It has no subqueries, and IN takes a literal list. A WHERE id IN (SELECT …) is invalid and will fail rather than quietly return the wrong rows. Pipe the result straight into a spreadsheet with create_sheet and append_to_sheet, or into a document with create_doc.

Read back, then report

After the mutate, the tree is read back from Google and the summary you get is built from that read-back — not from what was requested. It is a small discipline that catches the specific failure where an agent confidently narrates a campaign the platform actually coerced or rejected.

What it will not do without asking

An agent with a budget is only useful if the blast radius is bounded, so spend authority is fenced in the server rather than in a prompt. Meta campaigns, ad sets and ads are created PAUSED with no caller override. The seven tools that can arm real ad spend — set_meta_campaign_status, set_google_ads_status, set_microsoft_ads_status, set_reddit_ads_status, set_linkedin_ads_status, set_pinterest_ads_status and set_openai_ads_status — each refuse to run without an explicit confirmation flag, and that same gate covers creating an enabled Google Ads ad group, ad or keyword under an already-enabled parent, because that serves on the very next auction. Deletes are confirm-gated too. On the generation side, hermoso_capabilities publishes each model’s exact credit cost before anything runs, and every render reserves an estimate then settles the true cost, so a failed dispatch refunds instead of quietly billing you.

Connecting your Google Ads account

You connect Google Ads to Hermoso through Google’s own OAuth flow in Connectors settings; no password passes through the model. Google Ads connections are shared at the brand level, so a whole team on a brand works from one connection rather than each person re-authorizing.

The creative half

Campaign management is only useful if there is something to run. The same server researches what is already winning in your market across the Meta, Google and LinkedIn ad libraries, renders finished image and video creative grounded in your real product across 50+ models, and uploads the assets — so “what should we run” and “build it” are one conversation instead of two tools. See the marketing MCP overview, the full tool list, or the Meta Ads MCP if you run both.

Frequently asked

Is there an MCP server for Google Ads?

Yes. Hermoso’s MCP server builds and manages Google Ads from any MCP client: create_google_ads_campaign, create_google_ads_ad_group, create_google_ads_ad and add_google_ads_keywords to build; set_google_ads_budget, set_google_ads_bidding and set_google_ads_targeting to configure; list_google_ads_campaigns and google_ads_report for reporting; and a confirm-gated set_google_ads_status to activate.

Can an AI agent create a Google Ads campaign?

Yes, and the whole tree is created in a single atomic operation using temporary resource ids — campaign, ad group, responsive search or display ad and keywords together. If the ad is rejected, the budget was never created either, so you are not left cleaning up orphaned objects. A dry-run mode validates the tree against the live API without creating anything.

Can it start spending my Google Ads budget?

Only with an explicit confirmation. set_google_ads_status is the switch that arms real money, and because creating an enabled child under an already-enabled parent serves on the very next auction, the same confirmation also guards create_google_ads_ad_group, create_google_ads_ad and add_google_ads_keywords when the parent is live. Negative keywords only restrict spend and are never gated.

Can it run reports?

Yes. google_ads_report takes arbitrary GAQL, so the agent can request whatever slice it needs. Note that GAQL is not SQL: it has no subqueries and IN takes a literal list, so a WHERE id IN (SELECT …) is invalid. Results can be written straight into a Google Sheet or Doc.

What bidding and targeting can it set?

Six bidding strategies, campaign schedule, and geographic and language targeting, with find_google_ads_locations to resolve location targets by name. Budgets are set through set_google_ads_budget, and keywords support negatives and per-keyword CPC.

Does the agent get my Google account password?

No. You connect Google Ads through Google’s own OAuth flow in Hermoso’s Connectors settings, and Hermoso holds the resulting token. The agent only calls Hermoso’s tools. Google Ads connections are shared at the brand level so a whole team works from one connection.

Can it make the ad creative as well?

Yes. The same server researches competitor ads, plans the concept, renders finished image and video creative across 50+ models with your real product composited in, and uploads assets with upload_google_ads_asset — so research, creative and campaign build happen in one conversation.

Connect Google Ads once, and your agent can research the market, write the ad, build the tree and report on it — with a hard gate before anything spends.

Start free   Read the MCP docs →