Skip to main content
Glama
josephtandle

Query Analytics

by josephtandle
README.md
# Stop wrestling with analytics API syntax.

![MCPize](https://img.shields.io/badge/MCPize-live-brightgreen) ![License: MIT](https://img.shields.io/badge/License-MIT-blue)

**Query Analytics** is an MCP server that turns plain parameters into valid GA4 API requests, resolves human-readable date ranges, formats raw metric values, parses filter expressions, and aggregates response rows. No more digging through the GA4 reference docs mid-session.

## Quick Start

Add this to your Claude Desktop or MCP client config:

```json
{
  "mcpServers": {
    "query-analytics": {
      "url": "https://query-analytics-YOUR_HASH-uc.a.run.app/mcp"
    }
  }
}
```

Replace `YOUR_HASH` with the Cloud Run service URL from your deployment.

## Before / After

**Before:** Hand-building a GA4 request body at 2am.

```json
// What you used to write by hand:
{
  "dimensions": [{"name": "date"}, {"name": "country"}],
  "metrics": [{"name": "sessions"}, {"name": "bounceRate"}],
  "dateRanges": [{"startDate": "2026-03-06", "endDate": "2026-04-02"}],
  "limit": 1000,
  "orderBys": [{"metric": {"metricName": "sessions"}, "desc": true}]
}
```

**After:** One tool call.

```
build_ga4_query(
  metrics: ["sessions", "bounceRate"],
  dimensions: ["date", "country"],
  date_range: "last_28_days",
  order_by_metric: "sessions"
)
```

Output:
```json
{
  "query": {
    "dimensions": [{"name": "date"}, {"name": "country"}],
    "metrics": [{"name": "sessions"}, {"name": "bounceRate"}],
    "dateRanges": [{"startDate": "2026-03-06", "endDate": "2026-04-02"}],
    "limit": 1000,
    "orderBys": [{"metric": {"metricName": "sessions"}, "desc": true}]
  },
  "resolvedDateRange": {
    "startDate": "2026-03-06",
    "endDate": "2026-04-02",
    "daysCount": 28
  }
}
```

## Tools

| Tool | What it does |
|------|--------------|
| `build_ga4_query` | Build a valid GA4 Data API runReport request body from plain parameters |
| `get_date_range` | Convert named periods (last_28_days, this_month, etc.) to start/end date strings |
| `format_analytics_metric` | Format raw numbers into human-readable strings (62.34%, 2m 14s, $1,234.00) |
| `parse_filter_expression` | Convert plain-text filter strings into GA4 filterExpression JSON |
| `aggregate_rows` | Roll up GA4 response rows by a dimension with metric summation and top-N |

## Who is this for?

- **Analytics engineers** who are tired of re-reading the GA4 API docs to remember the exact filterExpression schema.
- **Product developers** building dashboards who need clean, formatted metric values without writing formatting helpers from scratch.
- **AI agents and automations** that need to construct valid GA4 queries programmatically without hallucinating API structure.

## Health Check

Both endpoints return the same JSON:

```
GET /
GET /health
```

```json
{
  "status": "ok",
  "server": "query-analytics",
  "version": "1.0.0",
  "tools": 5
}
```

Use `/health` for Cloud Run liveness probes.

## MCP Endpoint

```
POST /mcp
```

Handles all MCP protocol requests (tools/list, tools/call) via StreamableHTTP transport.

---

Built by [Mastermind HQ](https://mastermindshq.business)

MIT License