A side-by-side look at the Google Analytics MCP and Google Search Console MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.
Verdict: choose Google Analytics MCP for marketing work as a local process; choose Google Search Console for marketing as a local process. You can also run both side by side in one mcpServers block.
check_for_updates, list_properties, search_schema.performance_overview, hourly_performance, data_freshness.Rows where the two servers differ are marked.
| Spec | G Google Search Console | |
|---|---|---|
| Category | Marketing | Marketing |
| Quality signal | 63/100 · Good | 53/100 · Good |
| Install command | Confirmed | Confirmed |
| Transport | Local subprocess (stdio) | Local subprocess (stdio) |
| Auth | Not declared | Not declared |
| Pricing | Not declared | Not declared |
| Required env vars | None listed | None listed |
| Verified owner | Community listing | Community listing |
| GitHub stars | 243 | 2 |
| Directory activity | 3 views 0 installs 0 upvotes | 1 views 0 installs 0 upvotes |
| Tools | 12 | 17 |
| Full listing | View Google Analytics MCP | View Google Search Console |
check_for_updatesCheck PyPI for newer versions of this MCP server and get upgrade instructions.list_properties
List all GA4 properties associated with an account.
search_schema
Search for a keyword across all dimensions and metrics for this property.
Returns a ranked list of up to 10 matching fields scored by relevance.
Returns: {"top_results": {"DIMENSION: api_name": score, "METRIC: api_name": score, ...}}
Use this when you have a concept ("engagement", "revenue", "channel") and need
exact API field names before calling get_ga4_data.
Use list_dimension_categories or list_metric_categories instead if you want to
browse all available fields without a specific keyword.
Args:
keyword: One or more keywords to search for (e.g., "user", "campaign revenue").
get_property_schema
Returns the complete schema for the configured GA4 property, including all
available dimensions and metrics (standard and custom). Warning: This can be
a very large object (10k+ tokens). Use search_schema for most discovery tasks.
list_dimension_categories
List all dimension categories for this GA4 property, with a count of
dimensions in each category.
Returns: {"dimension_categories": {"Category Name": count, ...}}
Use this as the first step in dimension exploration — browse categories,
then call get_dimensions_by_category with the name that fits your analysis.
Use search_schema instead if you already have a keyword to search for.
list_metric_categories
List all metric categories for this GA4 property, with a count of
metrics in each category.
Returns: {"metric_categories": {"Category Name": count, ...}}
Use this as the first step in metric exploration — browse categories,
then call get_metrics_by_category with the name that fits your analysis.
Use search_schema instead if you already have a keyword to search for.
get_dimensions_by_category
Return all dimensions in a specific category with their API names and descriptions.
Returns: {"dimension_api_name": "description", ...}
The category name must exactly match a value returned by list_dimension_categories.
Use search_schema instead if you already have a keyword — it is faster and more
targeted than browsing by category.
Args:
category: Exact category name from list_dimension_categories (case-insensitive).
get_metrics_by_category
Return all metrics in a specific category with their API names and descriptions.
Returns: {"metric_api_name": "description", ...}
The category name must exactly match a value returned by list_metric_categories.
Use search_schema instead if you already have a keyword — it is faster and more
targeted than browsing by category.
Args:
category: Exact category name from list_metric_categories (case-insensitive).
get_ga4_data
Retrieve GA4 data with built-in intelligence for better and safer results.
Returns on success: {"data": [...], "metadata": {...}, "_skills_tip": "..."}.
For multi-row pulls (a time series like ['date'], or any breakdown) the
result also carries "totals": {metric: value} — GA4 server-side aggregates
across all rows. Read the period figure from "totals"; do NOT sum the rows
yourself. (Additive metrics sum; rate metrics are period-computed by GA4.)
Returns on volume warning: {"warning": "...", "estimated_rows": N, "suggestions": [...]}
Returns on error: {"error": "..."}
CRITICAL WORKFLOW — follow this sequence every time:
1. DISCOVER FIELDS: NEVER guess dimension or metric names. Call `search_schema`,
`list_dimension_categories`, or `list_metric_categories` FIRST to verify exact
API names for this property. Guessing costs you a failed round-trip.
2. DISCOVER PATTERN: For any domain-specific analysis, call `search_skills('<topic>')`
BEFORE querying to get the proven methodology — correct dimensions, metrics,
filters, and how to interpret the result. One extra call prevents multiple failures.
Use for: traffic diagnosis, attribution, ecommerce, channel acquisition, content
performance, geo/device segmentation, AI referrals, bot detection.
3. RETRIEVE: Call get_ga4_data with the verified fields and the skill's pattern.
4. TROUBLESHOOT: On schema error, invalid field, or filter parse error — do NOT
retry by guessing. Your training may predate current GA4 (UA was sunset
2023-07-01). Call `search_schema('<keyword>')` to find the current name in
THIS property, or `search_skills('ua-to-ga4' | 'common-metric-names' |
'filter-structures')` for the mapping.
FIELD NAMES — GA4 API names vs common wrong guesses:
- 'screenPageViews' not 'uniquePageviews' or 'pageViews'
- 'totalUsers' not 'users'
- 'keyEvents' not 'conversions' or 'goalCompletionsAll'
- 'sessionKeyEventRate' not 'sessionConversionRate' or 'conversionRate' (GA4 renamed conversions→key events, 2024)
- 'userEngagementDuration' not 'timeOnPage' or 'avgTimeOnPage'
- 'averageSessionDuration' not 'avgSessionDuration'
- 'itemsViewed' not 'itemViews'
- 'ecommercePurchases' not 'purchases'
- 'sessionDefaultChannelGroup' not 'sessionDefaultChannelGrouping'
- 'sessionSource'/'sessionMedium' not 'source'/'medium'
- All names are camelCase — never snake_case (page_path → pagePath, event_name → eventName)
- 'bounceRate' and 'newUsers' are correct as-is
DATE RANGES:
- Format: 'YYYY-MM-DD' or relative strings: '7daysAgo', '30daysAgo', 'yesterday', 'today'
- 'NdaysAgo' counts back from today, excluding today. 'yesterday' = last complete day.
- Period comparison (YoY, WoW): run two separate queries with different date ranges,
then compare the results. The API does not support multi-period in one call.
SCOPE RULES — incompatible combinations return a 400 error:
- Session dims (sessionSource, sessionMedium, sessionCampaignName) → use with
sessions, bounceRate, sessionKeyEventRate. NOT with eventCount.
- Event dims (eventName) → use with eventCount. NOT with sessions.
- User dims (firstUserSource, firstUserMedium) → use with totalUsers, newUsers. NOT sessions.
- Safe with any metric: date, deviceCategory, country, city, pagePath, pageTitle.
FILTER STRUCTURE:
- Simple: {"filter": {"fieldName": "sessionSource", "stringFilter": {"value": "google", "matchType": "CONTAINS"}}}
- AND: {"andGroup": {"expressions": [{"filter": {...}}, {"filter": {...}}]}}
- OR: {"orGroup": {"expressions": [{"filter": {...}}, {"filter": {...}}]}}
- NOT: {"notExpression": {"filter": {...}}}
- Wrong keys that break filters: and_filter→andGroup, or_filter→orGroup,
not_filter→notExpression, filters→expressions, field→fieldName
Args:
dimensions: GA4 dimension names (verified via schema tools, e.g. ["date", "city"]).
metrics: GA4 metric names (verified via schema tools, e.g. ["totalUsers", "sessions"]).
date_range_start: Start date — 'YYYY-MM-DD' or '7daysAgo', '30daysAgo', 'yesterday'.
date_range_end: End date — 'YYYY-MM-DD' or 'yesterday', 'today'.
dimension_filter: Optional FilterExpression dict. camelCase and snake_case both accepted.
limit: Max rows to return. Defaults to 1000.
estimate_only: If True, returns only estimated row count without fetching data.
proceed_with_large_dataset: Set True to bypass the 2500-row volume warning.
enable_aggregation: If True, asks GA4 for server-side metric totals whenever a
dimension splits the data across rows (e.g. a 7-day ['date'] pull), returned
in a "totals" block so the model needn't sum rows. Default True.
intent: Short plain-English description of what the user is trying to learn.
E.g. "which channels drive most signups", "bot traffic audit for last month".
get_troubleshooting_guide
Returns the troubleshooting/setup guide for a topic, served from inside the
server (no network needed). Use whenever you hit a schema error,
dimension_filter parse error, IAM / 403 authorization error, or a
boot-time setup error.
Args:
topic: One of "setup", "iam", or "schema".
search_skills
Fetch analytical recipes and how-to guides from the GA4 skills library.
Skills are domain-specific playbooks for common GA4 analysis patterns —
exact dimensions, metrics, filters, and interpretation logic for each use case.
Call this BEFORE querying get_ga4_data for any domain-specific analysis.
Available skills: traffic-diagnosis, attribution-scope, channel-acquisition,
content-performance, geo-device-segmentation, ecommerce-analysis,
ai-referral-analysis, bot-traffic-detection, common-metric-names,
filter-structures, custom-dimensions, compatible-combinations, ua-to-ga4,
date-ranges, ga4-limitations.
Usage:
- search_skills("") → returns full index of all skills
- search_skills("ecommerce") → returns the ecommerce-analysis skill
- search_skills("ua-to-ga4") → returns the UA→GA4 field name mapping
Args:
query: A skill name (exact slug) or empty string to browse the full index.
setup_ga4_access
Interactively fix a broken GA4 MCP setup (missing property ID, missing or
expired credentials, or missing GA4 access) by asking the user for the
needed input through the client, then re-initializing without a restart.
Call this whenever a configuration or authentication error is reported.
performance_overview*"How did example.com do in the last 6 months, month by month?"*hourly_performance*"Show the last 24 hours"* · *"Show last week as Tehran days"*data_freshness*"Is yesterday's data complete yet?"*build_query_regex*"Give me a regex for خرید خودرو that matches every spelling"*sync_history*"Sync the last 16 months of example.com"*history_status*"What history do I have saved?"*history_sql*"Run this SQL on my history: …"*inspect_url*"Is /new-article/ indexed? What canonical did Google pick?"*inspect_urls*"Inspect these 30 URLs"*indexing_summary*"Which of these pages have indexing issues?"*inspection_quota*"How many inspections do I have left today?"*list_sitemaps*"List my sitemaps and their errors"*Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.
{
"mcpServers": {
"google-analytics-mcp": {
"command": "uvx",
"args": [
"google-analytics-mcp"
]
}
}
}
{
"mcpServers": {
"google-search-console-8": {
"command": "uvx",
"args": [
"gsc-mcp-full"
]
}
}
}