Complete Google Ads API v21 MCP Server - All 29 tools fully implemented and working
Server provides 24 tools with generally visible schemas and descriptions, but significant gaps in parameter documentation, enum constraints, error handling guidance, and output schema documentation prevent a higher score. Tool naming follows verb_noun convention consistently (get, list, create, update, pause, resume). Descriptions are present but often generic (e.g., 'Create a new campaign with budget and settings' lacks context on WHEN to use vs. similar tools, WHAT prerequisites exist, and WHY budget_amount is required). Critical issue: parameter descriptions are completely absent from the visible schema registry in src/tools.py, only type and required flag are present, violating the 'every parameter needs a description' rule. While the pyproject.toml indicates structlog logging and error_handler module exist, the actual error recovery guidance, categorization (retryable vs. fatal), and input validation messages are not visible in the tool definitions. Output schemas are undocumented, the response structure for each tool is not declared, forcing LLMs to guess at return fields and breaking tool chaining patterns. The server accepts some parameters without bounds (budget_amount, cpc_bid_micros, adjustments object) that could invite hallucinated or absurd values from LLMs.
Add audience targeting to an ad group
Create a new ad group in a campaign
Create a new campaign with budget and settings
Create a custom audience for targeting
Create an expanded text ad
Create a responsive search ad
Get the account hierarchy tree
Parameter descriptions completely absent from tool schema registry. The visible schema in src/tools.py shows only 'type' and 'required' flags; no 'description' field is populated for ANY parameter across all 24 tools. LLMs cannot infer parameter meaning from names alone (e.g., 'status' could mean HTTP status, campaign status, or boolean flag). This violates the CRITICAL requirement: 'Every parameter needs a description explaining what it controls.' [Source: pattern:tool-description]
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 49 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 12 | - | v1 |
Get detailed information about a specific account
Get detailed information about a specific ad group
Get performance data for current bid adjustments
Get detailed campaign information
List all accessible Google Ads accounts
List ad groups with filters
List ads with filters
List all assets with optional type filter
List all available audiences/user lists
List all campaigns with optional filters
Pause a running campaign
Resume a paused campaign
Set bid adjustments for campaign (device, location, demographic)
Update ad group settings
Update campaign settings
Upload an image asset
Create a text asset
Output schemas are completely undocumented. No tool declares what fields it returns, what types those fields have, or how the response is structured. This breaks tool chaining: if create_campaign returns a campaign_id, downstream tools need to know the field name to extract it. Currently, LLMs must guess. [Source: pattern:tool, baseline: 100% of A+ tools have documented return types]
Enum constraints missing. Parameters like 'status', 'campaign_type', 'bidding_strategy', 'audience_type', 'targeting_mode', and 'asset_type' accept free-form strings with no constraint declaration. Without enums, LLMs hallucinate invalid values (e.g., passing 'MAXIMIZE_PROFIT' instead of the valid 'MAXIMIZE_CLICKS'). [Source: pattern:constrained-input, review:param-validation-rules]
Numeric parameters lack bounds. 'budget_amount' in create_campaign, 'cpc_bid_micros' in create_ad_group, and 'bid_modifier' in add_audience_targeting have no minimum or maximum specified. LLMs may pass absurd values (e.g., budget_amount: 999999999 or negative bids) that break API calls or cause unexpected charges. [Source: review:param-validation-rules]
Error handling guidance absent. No tool definition includes recovery instructions. When an API call fails, the LLM receives no actionable guidance on whether to retry, ask the user, or give up. The error_handler module exists but its exception messages and categorization are not visible in tool definitions. [Source: pattern:recovery-guide, pattern:error-classification]
Complex object parameters lack structure documentation. 'rules' in create_custom_audience (type: object) and 'adjustments' in set_bid_adjustments (type: object) have no schema, no nested field descriptions, and no validation guidance. LLMs cannot construct valid nested objects without explicit schema. [Source: pattern:tool-description, review:param-validation-rules]
Array parameters lack element type specification. 'headlines' and 'descriptions' in create_responsive_search_ad, 'final_urls' in create_expanded_text_ad, 'target_locations' and 'target_languages' in create_campaign, and 'rules' in create_custom_audience are declared as arrays but element types are not specified. LLMs may pass wrong data types or structures. [Source: pattern:constrained-input]
Tool descriptions are generic and lack selection context. Many descriptions lack WHEN to use the tool vs. similar tools and what prerequisites are needed. E.g., 'Create a new campaign' does not explain whether to call create_campaign or update_campaign, whether a budget is always required, or whether certain fields are mutually exclusive. [Source: pattern:tool-description, review:incomplete-docstrings]
No pagination parameters visible for list tools. list_accounts, list_campaigns, list_ad_groups, list_ads, list_assets, and list_audiences have no limit, offset, or cursor parameters declared, yet Google Ads accounts can have thousands of campaigns. Large result sets will exhaust token limits and degrade LLM reasoning. [Source: pattern:paginated-result, mxe:enforce-result-limits]
Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are completely absent. WRITE operations like create_campaign, update_campaign, create_ad_group should declare themselves as destructive or non-idempotent so the LLM knows not to retry blindly. READ_ONLY tools should declare their safety. Spec Alignment: tool annotations are a CURRENT pattern in MCP 2026-07-28. [Source: MCP spec 2026-07-28]
No confirmation/dry-run for irreversible operations. Creating campaigns, uploading assets, and setting bid adjustments are production changes that could have financial impact. No tool declares a dry-run mode or asks for confirmation before executing. Agents can inadvertently make costly mistakes. [Source: pattern:confirmation-request]