Budget-guarded Google Ads reporting and optimization MCP server.
Strong foundation with 15 well-named tools following verb_noun convention. All tools have descriptions (avg 95 chars, within baseline 34-392). Input schemas are complete with typed parameters and descriptions. However, output schemas are not documented, LLMs cannot predict response structure. Error handling is minimal; no recovery guidance or actionable error messages. Missing tool annotations (readOnlyHint/destructiveHint). Composition is sound: tools chain via customer_id/campaign_id/ad_group_id. Mutation tools support confirm pattern (dry-run before execute), which is excellent for safety.
Account totals: spend, clicks, impressions, conversions for a date range. Set daily=true for a per-day series.
Ad-group spend, CPC, and conversion performance, ordered by spend. Filter by campaign_id/ad_group_id; daily=true for per-day rows.
Ad-level spend and conversion performance with RSA headlines, descriptions, and final URLs. Filter by campaign_id/ad_group_id.
Add a negative keyword to an ad group.
Campaign spend and conversion performance, ordered by spend. Filter by campaign_id; daily=true for per-day rows.
Execute a read-only Google Ads Query Language SELECT statement. Sensitive fields (user emails, click details, local services, hotel reconciliation) are blocked.
Output schemas not documented. LLMs cannot predict response structure for any of the 15 tools. Responses are compact JSON (good for tokens), but without documented field names and types, agents cannot reliably extract data for downstream tool calls.
Error handling lacks recovery guidance. No tool provides actionable error messages (e.g., 'Invalid campaign_id: must be numeric. Call list_accessible_customers() to find valid IDs.'). Errors are generic internal_error with no classification (retryable vs. user-fixable vs. fatal).
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 60 | <=2025-11-25 | v2 |
Show credential and mutation-gate readiness without revealing secrets.
Keyword-level spend, CPC, and conversion performance. Filter by campaign_id/ad_group_id; daily=true for per-day rows.
List Google Ads customers directly accessible to the configured service account.
Atomically rebalance a set of campaign budgets.
Search term performance: the actual queries that triggered ads. Filter by campaign_id/ad_group_id; daily=true for per-day rows.
Performance breakdown by device, day of week, hour, or network.
Enable or pause a campaign. False/omitted returns a preview. True applies the change when mutations are enabled.
Update keyword status and/or max CPC bid. Account daily budget remains unchanged.
Replace headlines and descriptions in a responsive search ad.
Tool annotations missing. No readOnlyHint, destructiveHint, or idempotentHint declared. Mutation tools (set_campaign_status, update_keyword, etc.) should be marked destructiveHint=true to signal to agents that these are irreversible. Read-only tools should be marked readOnlyHint=true.
segment_performance 'breakdown' parameter lacks enum constraint. Description says 'device, day_of_week, hour, or network' but no formal enum. LLMs may hallucinate invalid values like 'device_type' or 'day-of-week'. Should be enum: ['device', 'day_of_week', 'hour', 'network'].
Pagination not fully specified. Report tools (campaign_performance, ad_group_performance, etc.) accept 'limit' and return 'limitReached=true' to signal more rows exist, but no 'offset' or 'page_token' parameter for fetching subsequent pages. Agents cannot iterate through large result sets.