@theethosteam/ga4-mcp
v0.2.0
Published
Read + write MCP server (and CLI) for Google Analytics 4 — Admin API (config) + Data API (reports) over OAuth. Runs via npx, locally or in cloud.
Maintainers
Readme
@theethosteam/ga4-mcp
Read + write MCP server and CLI for Google Analytics 4 — GA4 Admin API (config) + Data API (reports), authenticated over OAuth (no service account). Runs via npx, identically locally or in a cloud session, because auth is a refresh token in env vars (no browser or per-machine credentials at runtime).
Built on the same pattern as the GTM MCP: one shared core/, exposed as both an MCP server (mcp.ts) and a commander CLI (cli.ts), run directly with tsx (no build step). Includes a generic raw tool so every Admin/Data API method is reachable.
Why OAuth, not a service account
GA4's "add user" UI rejects service-account emails ("This email doesn't match a Google Account"). OAuth sidesteps this entirely — the server acts as you, the consenting account owner, so nothing has to be granted inside GA4. (It can even grant other principals access via the API — see create_access_binding.)
One-time setup
- Enable APIs in your Google Cloud project: Google Analytics Admin API + Google Analytics Data API.
- OAuth client: Console → APIs & Services → OAuth consent screen → Audience Internal (Workspace org) → then Credentials → Create OAuth client → Desktop app → note the client id + secret.
- Mint a refresh token (no local server needed):
(Or clone this repo, put the three values inGA4_OAUTH_CLIENT_ID=… GA4_OAUTH_CLIENT_SECRET=… npx -y @theethosteam/ga4-mcp ga4 auth:url # open the URL, approve, copy the ?code=… from the localhost redirect that fails to load GA4_OAUTH_CLIENT_ID=… GA4_OAUTH_CLIENT_SECRET=… npx -y @theethosteam/ga4-mcp ga4 auth:exchange <code>.env, and runnpm run ga4 auth:url.)
Env vars
GA4_OAUTH_CLIENT_ID · GA4_OAUTH_CLIENT_SECRET · GA4_OAUTH_REFRESH_TOKEN · GA4_PROPERTY_ID (optional default; numeric, not the G-XXXX measurement id).
Connect to Claude
Local (Claude Code CLI), available in every project:
claude mcp add ga4 --scope user \
-e GA4_OAUTH_CLIENT_ID=… -e GA4_OAUTH_CLIENT_SECRET=… -e GA4_OAUTH_REFRESH_TOKEN=… \
-- npx -y @theethosteam/ga4-mcpCloud (Claude Code on the web): add the same server to the repo's .mcp.json, with env values via ${VAR} referencing the cloud environment's variables, then reload:
{
"mcpServers": {
"ga4": {
"command": "npx",
"args": ["-y", "@theethosteam/ga4-mcp"],
"env": {
"GA4_OAUTH_CLIENT_ID": "${GA4_OAUTH_CLIENT_ID}",
"GA4_OAUTH_CLIENT_SECRET": "${GA4_OAUTH_CLIENT_SECRET}",
"GA4_OAUTH_REFRESH_TOKEN": "${GA4_OAUTH_REFRESH_TOKEN}"
}
}
}
}Tools
whoami · list_properties · get_property · list_data_streams · list_key_events · list_custom_dimensions · list_custom_metrics · list_google_ads_links · list_access_bindings · get_data_retention_settings · get_attribution_settings · run_report · run_realtime_report · get_metadata · check_compatibility · create_key_event · delete_key_event · create_custom_dimension · create_custom_metric · update_data_retention_settings · create_google_ads_link · create_access_binding · health_check · verify_event_realtime · raw
Destructive tools (delete_key_event) require confirm: true.
CLI (handy for testing)
npx -y @theethosteam/ga4-mcp ga4 whoami
npx -y @theethosteam/ga4-mcp ga4 health 362919951
npx -y @theethosteam/ga4-mcp ga4 report -p 362919951 -m activeUsers,sessions -d date
npx -y @theethosteam/ga4-mcp ga4 raw admin properties.keyEvents.list '{"parent":"properties/362919951"}'License
MIT
