`google-analytics-mcp`: Teaching LLMs to Speak GA4 Without a Dashboard

A look at Google’s experimental MCP server for Analytics, where schema repair, Protobuf conversion, and LLM-facing hints turn a brittle API bridge into an agent-ready analytics layer.

8 min read • View on GitHub • More from googleanalytics

A wide editorial scene shows a dense GA4 machine on the left, a narrow coordinator booth in the middle, and a conversational interface on the right. The image explains that this project is a translation layer between Google Analytics, MCP clients, and an LLM, not a dashboard replacement.
The interesting thing here is not access to data. It is the machinery that makes the data usable by a model and acceptable to a strict client.
Key Takeaways

The Real Product Is the Translation Layer

The easiest way to misunderstand google-analytics-mcp is to treat it like a chat wrapper around Google Analytics. It is not doing that. It is sitting between three systems that were not designed for each other: GA4, MCP clients, and an LLM that needs structure, constraints, and rescue rails.

That matters because the hard problem is not exposing data. The hard problem is making the data legible to a model and still acceptable to a strict client like Claude Desktop. In this repo, the bridge is the product.

MCP is now the standard way for an AI tool (like Gemini) to connect to external systems through a set of structured “tools.” Instead of the model guessing from vibes, the AI can call real functions like “list my GA properties” or “run a report for the last 28 days,” get actual results back, and then reason on top of those results.

Why the Coordinator Is the Brain

The center of gravity is analytics_mcp/coordinator.py. It does more than register tools. It rewrites tool schema shape, maps ADK types into MCP types, and recursively sanitizes properties so the resulting JSON survives clients that are pickier than the API spec itself.

That defensive layer is the tell. The code is not assuming that the upstream tool definition, the MCP client, and the model will all agree on schema semantics. It actively normalizes them into something usable.

This flow is the whole trick. The model does not talk directly to GA4. The coordinator translates, repairs, and constrains the call before it leaves the building.

def sanitize_mcp_schema_properties(schema):
    properties = schema.get('properties', {})
    for key, value in properties.items():
        if isinstance(value, dict):
            value['additionalProperties'] = bool(value.get('additionalProperties', False))
            sanitize_mcp_schema_properties(value)
    return schema

# The important part is not the function itself.
# It is the fact that the server repairs schema for client compatibility.

The Tool Tree: Admin on One Side, Reporting on the Other

The repository splits its work into two obvious branches. The admin/ tools retrieve account and property metadata. The reporting/ tools fetch metrics, dimensions, and realtime data. That separation is clean, but the implementation detail matters more: admin endpoints lean on async pagination, while reporting endpoints carry more of the model-facing guidance.

AreaAdmin toolsReporting tools
Primary jobList accounts, properties, and linksRun core and realtime reports
Shape of outputMostly discovery metadataMetrics, dimensions, and report rows
Control flowAsync paging and collectionParameterized report execution
LLM supportMostly factual contextMore hints, constraints, and examples
Failure modeMissing contextBad query shape or invalid dimensions

That split is useful because the model needs different help in each branch. Discovery wants completeness. Reporting wants discipline.

Metadata as Prompt Engineering

The most original part of the repo lives in metadata.py. It does not just describe tools. It teaches them. Date range examples, constraint notes, and usage hints all function like a miniature manual written for a model that will not read a manual unless the text is embedded where it can see it.

This is the subtle shift that makes the project feel AI-native. The server is not merely exposing endpoints. It is shaping the prompt surface around those endpoints so the model is more likely to ask a valid question the first time.

A close-up shows a broken schema document being repaired by hand before passing through a narrow slot labeled Claude Desktop. The page has malformed boxes, corrected required fields, and margin notes that explain compatibility and hints. It explains how the server fixes tool definitions so a strict MCP client can accept them.
The repo’s quiet superpower is not access. It is repair. Tool definitions are cleaned up until the client will accept them and the model can use them.

From Protobuf to JSON Without Losing the Plot

The plumbing matters here because Google’s APIs do not return a model-friendly shape by default. The utility layer converts Protobuf responses into dictionaries, then hands back JSON-safe output that the MCP server can serialize cleanly. That sounds mundane until you remember the audience is not a person scanning a dashboard. It is a client passing structured data to a model.

# Conceptual flow, not the repo's exact internals
response = await data_client.run_report(request)
clean = proto_to_dict(response)
return clean

# The translation step matters because the LLM needs
# structured output it can reason over without schema drift.

The bigger point is that serialization is not an afterthought. It is part of the interface contract. If the output shape is unstable, the model's reasoning gets unstable with it.

How It Compares to the Other Way of Doing This

The official server lives in a different lane from a community alternative like surendranb/google-analytics-mcp. It is also answering a different question than the GA4 UI. The official repo feels conservative, Google-native, and compatibility-first. The community version looks more expansive and agent-optimized. The UI is still the most familiar, but it is also the least conversational.

ModePrimary userWhat it optimizes forWhat it leaves outFeels like
Official google-analytics-mcpTeams inside the Gemini and MCP ecosystemPredictable bridge behavior and schema compatibilityBroad exploratory tooling and flashy extrasInfrastructure
Community alternativeAnalysts and builders who want more agent-first featuresSchema discovery and large query handlingGoogle-native conservatismA power tool
GA4 UIHuman analystsVisual exploration and manual controlAutomation and conversational accessA dashboard

Google tiene todos sus MCP oficiales en un repositorio. Con ejemplos reales y guías para desplegarlos y usarlos. Google Maps, Analytics, Gmail, Docs y más De código abierto → https://t.co/l2gG2ewOWp https://t.co/hEZyXHwg2u

Miguel Ángel Durán, midudev, 320,407 followers · @midudev on X

The comparison is not really about feature count. It is about posture. One project optimizes for broad agent usefulness. This one optimizes for being a disciplined, official bridge that survives real client quirks.

What This Repo Suggests About the Next Wave of Agent Infrastructure

If there is a lesson here, it is that future agent tools will be judged on more than API coverage. They will need schema hygiene, examples, constraint hints, and compatibility shims. The best infrastructure will not just expose data. It will teach models how to ask for it safely.

That is why this repository is more interesting than a simple analytics connector. It is a small, practical preview of what AI-native plumbing looks like when it stops pretending the model can infer everything on its own.