An MCP server that exposes Google Ads Keyword Planner as tools for AI assistants
This server has 3 tools with acceptable naming (verb_noun pattern) and moderate descriptions, but critical gaps in parameter schemas and descriptions. The source shows C# code with tools registered via attributes, but the actual JSON Schema input definitions are NOT visible in the provided code excerpt. The tool descriptions exist but are generic (~150-200 chars) and lack actionable guidance. Parameter schemas are inferred from method signatures but not explicitly declared in the visible code. Error handling is present (try-catch with error serialization) but provides minimal recovery guidance. The server accepts comma-separated string inputs rather than arrays, which is a usability gap for LLM-generated tool calls.
Generate keyword ideas from seed keywords and/or a URL using Google Ads Keyword Planner. Returns related keywords with average monthly search volume, competition level, and CPC estimates.
Get historical search volume and competition metrics for a list of specific keywords using Google Ads Keyword Planner.
Get projected impressions, clicks, and cost for a set of keywords at a given max CPC bid using Google Ads Keyword Planner.
Input schemas are NOT visible in source code. Tools accept comma-separated strings instead of properly typed JSON arrays. Parameter types (string, integer, array) are inferred from C# method signatures but no explicit JSON Schema is shown. Hard scoring rule: if input schema not visible, schema score must be 0.
Parameters lack type annotations in descriptions. 'seedKeywords' parameter description says 'Comma-separated seed keywords' but does not clarify format, length limits, or constraints. LLMs cannot infer from descriptions alone whether to pass 'C# tutorial, dotnet' or ['C# tutorial', 'dotnet'].
Tool descriptions lack actionable guidance. E.g., 'Generate keyword ideas from seed keywords and/or a URL using Google Ads Keyword Planner' does not state WHEN to use it instead of get_historical_metrics, what the response structure is, or how to handle the case where both seedKeywords and url are provided. Descriptions should be 50-200 chars optimized for LLM selection.
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 53 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 13 | - | v1 |
Error handling provides no recovery guidance. E.g., 'Error generating keyword ideas: {ex.Message}' returns the raw exception message but does not tell the LLM what to do next, should it retry, ask the user for clarification, or attempt a different tool? Hard pattern violation.
Output schema is NOT documented. The code serializes responses to JSON (KeywordIdeasResponse, HistoricalMetricsResponse, ForecastResponse) but the structure of these types is not visible in the provided source. LLMs cannot plan downstream actions without knowing what fields to expect.
Mutual exclusivity not enforced in schema. generate_keyword_ideas requires 'at least one of seedKeywords or url' but this is validated in code, not in the parameter schema. The schema should use JSON Schema 'oneOf' or 'anyOf' to make this constraint machine-parseable. Currently an LLM could pass neither and receive a validation error.
Comma-separated string interface is hostile to LLMs. All three tools accept comma-separated strings ('C# tutorial, dotnet performance') rather than arrays. LLMs are trained on JSON arrays and frequently get this wrong, leading to malformed calls like passing a single string instead of splitting it. Should expose proper array parameters.