Skip to main content
Glama
PlatAid

Google Analytics MCP

by PlatAid
README.md
# Google Analytics MCP (shared, per-user OAuth)

A GCP-hosted MCP server for **Google Analytics (GA4)** where **each user logs in
with their own Google account** and queries are scoped to *that user's* GA
permissions — no shared service-account, no server-held keys, no ACL table.

It re-hosts the official [`analytics-mcp`](https://github.com/googleanalytics/google-analytics-mcp)
tools under [FastMCP](https://github.com/jlowin/fastmcp) so we get
streamable-HTTP + Google OAuth — the same pattern as the official Google Ads MCP
and the sibling Naver Search Ads MCP.

## How it works

```
Claude (each teammate) ──streamable-HTTP + Google OAuth (analytics.readonly)──▶
  FastMCP server (Cloud Run)
    ├ GoogleProvider  : brokers Google login, forwards the user's Google token
    ├ credential shim : each request → Credentials(token=<user's Google token>)
    └ analytics-mcp   : 9 GA tools, now running as the calling user
        └─▶ GA Admin/Data API  (returns only what that user may see)
```

The one swap that makes it per-user: `analytics_mcp.tools.client._get_credentials`
is replaced (in `server.py`) with a resolver that reads the current request's
Google token via `fastmcp.server.dependencies.get_access_token()`. When there is
no authenticated request (local stdio), it falls back to Application Default
Credentials.

## Tools (all read-only)

`get_account_summaries`, `get_property_details`, `list_google_ads_links`,
`list_property_annotations`, `get_custom_dimensions_and_metrics`, `run_report`,
`run_realtime_report`, `run_funnel_report`, `run_conversions_report`.

## Local dev (stdio, ADC)

```bash
uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python -e .
# Uses your gcloud ADC. GA_MCP_TRANSPORT defaults to stdio, no OAuth.
GA_MCP_TRANSPORT=stdio .venv/bin/google-analytics-mcp
```

## Hosted (Cloud Run, per-user OAuth)

See [DEPLOY.md](DEPLOY.md). In short: create an **Internal** OAuth Web client
(with the `analytics.readonly` scope on the consent screen), store the secret in
Secret Manager, then run `deploy/deploy.sh`.

### Environment

| Var | Purpose |
|-----|---------|
| `GA_MCP_TRANSPORT` | `stdio` (local) or `http` (hosted) |
| `GA_OAUTH_CLIENT_ID` / `GA_OAUTH_CLIENT_SECRET` | Google OAuth Web client. Presence activates OAuth. |
| `PUBLIC_BASE_URL` | Cloud Run HTTPS URL (OAuth redirect base; callback `/auth/callback`). |
| `GA_OAUTH_HD` | Workspace domain hint (e.g. `yourcompany.com`). |
| `GA_OAUTH_JWT_KEY` | Stable key so issued tokens survive redeploys. |
| `GCP_PROJECT_ID` | Enables Firestore OAuth-state persistence. |
| `GA_OAUTH_FIRESTORE_DATABASE` / `GA_OAUTH_FIRESTORE_COLLECTION` | Firestore location for OAuth state. |

### Connect (teammates)

```bash
claude mcp add --transport http google-analytics <PUBLIC_BASE_URL>/mcp
# first use opens the browser for Google login
```

## Credits

- The 9 GA tools come from Google's official
  [analytics-mcp](https://github.com/googleanalytics/google-analytics-mcp)
  (Apache-2.0). This project imports them and overrides only the credential
  resolver so each request runs as the calling user.
- OAuth + streamable-HTTP transport are provided by
  [FastMCP](https://github.com/jlowin/fastmcp) (Apache-2.0).

See [NOTICE](NOTICE) for attribution details.

## License

[Apache-2.0](LICENSE).