MCP server for Google Search Console integration with OAuth 2.1 authorization
This GSC MCP server demonstrates solid overall quality with 22 well-structured tools covering a comprehensive domain (search analytics, sitemaps, URL inspection, site health). Strengths: consistent verb_noun naming (list_*, get_*, submit_*, delete_*), explicit parameter schemas with types and descriptions, clear risk classifications (READ_ONLY, WRITE, DESTRUCTIVE, REVERSIBLE). Weaknesses: output schemas are not documented in the source, we can infer structure but cannot verify return field names, types, or pagination handling; error handling is implicit rather than explicit (no recovery guidance in descriptions); no tool annotations (readOnlyHint/destructiveHint) despite clear risk signals; some composite tools (analyze_site_health, identify_quick_wins) combine multiple concerns that could be split for better agent composition; descriptions are adequate (80-200 chars typically) but lack dependency hints ('call list_properties() first') that would guide agent planning.
Add a new property to GSC. Requires site owner verification.
One-call site health report: top pages with traffic, indexing status, mobile usability, and last crawl time.
Inspect multiple URLs for indexing status, mobile usability, and rich results.
Compare search performance between two date periods.
Aggregate crawl and indexing errors across a property's sampled pages.
Three tools (get_keyword_cannibalization, batch_search_analytics, export_full_dataset) have no visible description or schema in the source. Cannot assess their actual structure, parameter requirements, or return format. These appear to be stub definitions without implementation detail.
Output schemas are not documented anywhere in the codebase. While parameter inputs are well-structured with type and description, there is no visible documentation of what fields (site_url, permission_level, health_status, etc.) each tool returns, their types, or whether pagination is supported. LLMs cannot plan multi-step chains without knowing return structure.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 64 | <=2025-11-25 | v2 |
Remove a property from GSC. Irreversible — use with caution.
Remove a sitemap from GSC. Does not delete the actual sitemap file.
Find pages with high impressions but low CTR — quick-win optimization candidates.
Get a summary of clicks, impressions, CTR, and average position for a property.
Get pages filtered by position band.
Query GSC search analytics data.
Get details for a specific GSC property including permission level.
Get details for a specific sitemap.
Find pages worth quick optimization: high impressions, low CTR, ranked 4-10, no indexing issues.
Inspect a single URL for indexing status, mobile usability, rich results, and AMP.
List all GSC properties the authenticated user has access to, with permission levels.
List all sitemaps for a property with indexing stats and health classification.
Generate a migration checklist when moving a site.
Submit a sitemap to Google Search Console.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) in the schema, despite explicit risk classifications in the documentation (READ_ONLY, WRITE, DESTRUCTIVE, REVERSIBLE). Modern MCP supports these annotations; using them would signal intent to clients and guide LLM behavior without parsing descriptions.
No recovery guidance in error descriptions. Tools like delete_site carry DESTRUCTIVE risk but descriptions do not explain error conditions or suggest recovery steps (e.g., 'Site not found, call list_properties() to verify before deletion').
Composite tools like analyze_site_health and identify_quick_wins combine multiple read operations (search analytics + URL inspection + crawl errors) into single tools. While convenient, this reduces agent flexibility, if the agent only needs quick wins without crawl data, it still pays the cost of inspection. Consider decomposing into smaller, focused tools.
Parameters like 'band' in get_position_band_report and 'search_type' across multiple tools use enum constraints (indicated by 'Options: ...'), but these are stated in description text rather than as formal JSON Schema enum fields. LLMs cannot reliably parse natural-language enums, they should be declared as JSON Schema enums for machine-readability.