ga4-mcp
GA4 Toolkit
A Python CLI and MCP server for read-only Google Analytics 4 reports. It provides daily summaries, top pages, acquisition, events, realtime activity, metadata, and custom reports through the Google Analytics Data and Admin APIs.
Why use it?
Use the same reporting client in shell scripts and MCP conversations. Common reports have ready-made commands, and results export as tables, JSON, or CSV.
This is an independent community project. Google maintains an official Analytics MCP server. This toolkit focuses on a small CLI and reusable report presets alongside MCP. It is an early release; see the limits below before using it for bulk exports.
Install
Requires Python 3.11 or newer and uv.
git clone https://github.com/onionst/ga4-toolkit.git
cd ga4-toolkit
uv tool install .
ga4 --versionInstallation provides the ga4 and ga4-mcp commands. To update an existing installation after pulling
changes, run uv tool install --force .. There is no PyPI release; install from
this repository. If upgrading from the earlier private package, uninstall that
package first with uv tool uninstall ga4-codex-toolkit, then install this one.
Try the output format without a Google account:
uv sync --locked
uv run --locked python examples/offline_report.pyThe example uses synthetic data and shows a report with two returned rows out of three, including its truncation warning.
Authentication
Enable the Google Analytics Data API and Google Analytics Admin API in the Google Cloud project used for authentication. The Google identity must have access to the target GA4 property; the Viewer role is sufficient for reports.
The client checks credentials in this order:
A service-account JSON key referenced by
GOOGLE_APPLICATION_CREDENTIALS.~/.config/ga4-cli/google-credentials.json, if present.Google Application Default Credentials (ADC).
The second path respects XDG_CONFIG_HOME when set. Keep credential files outside
this repository. For a service account, grant its email access to the GA4 property
and point to its key:
export GOOGLE_APPLICATION_CREDENTIALS="/absolute/path/outside/repo/service-account.json"
ga4 propertiesFor user authentication, install the Google Cloud CLI and supply a Desktop OAuth client JSON file from your Google Cloud project:
ga4 auth --client-id-file /absolute/path/outside/repo/client_secret.jsonThis invokes gcloud auth application-default login with the Analytics read-only
and Cloud Platform scopes. Follow the URL printed by gcloud; the browser does not
launch automatically unless you add --launch-browser. Reporting requests use
the analytics.readonly scope. No Analytics modification tools are exposed.
ga4 doctor checks access by listing properties. ga4 auth starts a new user
authentication flow or detects the dedicated service-account file; use doctor
to verify an existing ADC setup.
CLI
Use the numeric GA4 property ID, not the G-... measurement ID. Pass --property
on every report to make the target explicit:
ga4 properties --format json
ga4 overview --property 123456789 --start 28daysAgo --end yesterday
ga4 pages --property 123456789 --limit 25
ga4 acquisition --property 123456789 --format csv
ga4 events --property 123456789 --format json
ga4 realtime --property 123456789 --dimensions country --metrics activeUsers,eventCount
ga4 report --property 123456789 --dimensions date,country --metrics sessions,activeUsers
ga4 metadata --property 123456789 --search sessionData commands support --format table, json, and csv. Historical reports
default to 28daysAgo through yesterday. Custom reports also accept
--dimension-filter-json, --metric-filter-json, and --order-by.
An explicit property takes precedence over GA4_PROPERTY_ID, followed by an
optional default saved with ga4 use PROPERTY_ID. The default lives in
~/.config/ga4-cli/config.json and can be inspected with ga4 config. When
--property is omitted, the CLI prints the selected property on stderr before
querying it. An explicitly empty or invalid ID is rejected.
MCP
Configure an MCP client to launch ga4-mcp over stdio. Use the absolute executable
path if the client does not inherit your shell's PATH:
{
"mcpServers": {
"google-analytics": {
"command": "/absolute/path/to/ga4-mcp"
}
}
}The server exposes eight tools:
Tool | Purpose |
| Discover accessible properties |
| Daily traffic, engagement, key events, and revenue |
| Top page paths and titles |
| Session channels and source/medium |
| Event counts, users, and values |
| Custom historical reports and filters |
| Realtime activity |
| Available dimensions and metrics |
property_id is required for every report and metadata call. Omitted, null, and
empty values are rejected; MCP reports do not fall back to environment variables
or saved defaults. Use property discovery when the target is unknown.
Example arguments for ga4_top_pages:
{
"property_id": "123456789",
"start_date": "7daysAgo",
"end_date": "yesterday",
"limit": 25
}MCP and CLI share authentication. The saved default property is a CLI convenience.
Report completeness
JSON and MCP reports include the target property_id, total row_count,
returned_row_count, a truncated flag, and a warnings list. If the API reports
more rows than returned, the report is marked truncated. The CLI also writes the
warning to stderr in every output format, leaving stdout suitable for pipelines.
Increase --limit (or MCP limit) or narrow the report to retrieve more of the
matching rows. The daily overview uses a fixed 366-row cap; shorten its date range
or use a custom report when it is truncated. truncated: false only describes row
limits; Google may still apply thresholds or sampling, reflected in metadata.
Limits
Report requests return at most 10,000 rows and do not paginate. Daily overview requests cap results at 366 rows. Historical reports require 1–9 dimensions and 1–10 metrics; realtime reports require 1–4 of each. This version accepts simple dimension and metric names; namespaced custom fields are not supported.
Metric/dimension compatibility, retention, and quotas are enforced by Google. The client uses a 60-second request timeout and does not automatically retry API failures. The CLI reports API errors on stderr and exits with status 2.
Development
uv sync --locked
uv run --locked python -m unittest discover -s tests -v
uv buildTests use fake API responses and a local MCP handshake. They require no Google credentials and do not query Analytics.
See CONTRIBUTING.md for contribution guidelines and CHANGELOG.md for release notes. Licensed under MIT.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/onionst/ga4-toolkit'
If you have feedback or need assistance with the MCP directory API, please join our Discord server