Google Analytics Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Google Analytics Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
An MCP server that connects an MCP client (Claude Desktop, etc.) to Google Analytics 4. You log into your Google account once; after that every tool reports on the GA4 properties that login can access.
Built with the official google-analytics-data and google-analytics-admin Python clients and FastMCP. Reporting, intelligence, charts, admin reads, and write/management tools (creating/updating key events, custom dimensions/metrics, and data streams).
Simpler than the Google Ads server: GA4 needs no developer token — just an OAuth client and your login.
Reporting
| Tool | Purpose |
|---|---|
ga4_run_report | Core report: metrics, dimensions, date range, filters, export to CSV/XLSX |
ga4_compare_periods | Compare a current vs previous period with % change |
ga4_run_pivot_report | Cross-tabulate dimensions (rows × columns) |
ga4_run_cohort_report | Retention by acquisition cohort (daily/weekly/monthly) |
ga4_run_funnel_report | Step-by-step funnel completion / drop-off |
ga4_run_realtime_report | Realtime activity (last ~30 min) |
ga4_check_compatibility | Which metrics + dimensions can be queried together |
ga4_get_metadata | Discover valid metric & dimension names |
ga4_batch_run_reports | Run up to 5 reports in one batched call |
ga4_property_overview | One-call snapshot: totals, top channels & pages, devices, new vs returning |
Preset shortcuts (zero-config reports)
| Tool | Purpose |
|---|---|
ga4_top_pages | Top pages by views |
ga4_traffic_by_channel | Sessions & users by default channel group |
ga4_conversions_summary | Conversions by event name |
ga4_trend | A single metric over time (daily/weekly/monthly) |
Accounts & configuration (admin reads)
| Tool | Purpose |
|---|---|
ga4_list_account_summaries | Accounts + their properties (find property IDs) |
ga4_list_properties | Properties under an account |
ga4_list_data_streams | Data streams (web measurement ID, app streams) |
ga4_list_custom_dimensions | Custom dimensions on a property |
ga4_list_custom_metrics | Custom metrics on a property |
ga4_list_key_events | Key events (conversions) |
ga4_list_audiences | Audiences |
ga4_list_google_ads_links | Linked Google Ads accounts |
ga4_get_data_retention_settings | Event-data retention settings |
ga4_search_change_history | Who changed what, and when |
ga4_list_channel_groups | Channel groups and their grouping rules |
Audience export (pull the actual users in an audience — async create → query)
| Tool | Purpose |
|---|---|
ga4_create_audience_export | Start an export for an audience (waits for it to finish) |
ga4_list_audience_exports | List exports and their state (CREATING/ACTIVE) |
ga4_query_audience_export | Read the exported user rows |
Intelligence
| Tool | Purpose |
|---|---|
ga4_what_changed | Top gainers/losers driving a metric's change between two periods |
ga4_detect_anomalies | Flag days a metric deviated from its baseline (z-score) |
ga4_forecast_metric | Project a metric forward with a linear trend |
Charts — ga4_chart_report: render a bar/line PNG of a metric by a dimension (saved to exports/).
More admin reads
| Tool | Purpose |
|---|---|
ga4_list_access_bindings | Who has access (and roles) to an account/property |
ga4_list_bigquery_links | BigQuery export links |
ga4_list_firebase_links | Firebase project links |
ga4_list_measurement_protocol_secrets | MP secrets for a data stream |
ga4_get_property_details | Full property settings (industry, tz, currency, tier) |
ga4_get_enhanced_measurement_settings | Enhanced-measurement toggles for a stream |
Write / management ⚠️ these modify your GA4 configuration
| Tool | Purpose |
|---|---|
ga4_create_key_event / ga4_update_key_event | Create / update a key event (conversion) |
ga4_create_custom_dimension / ga4_update_custom_dimension | Create / update a custom dimension |
ga4_create_custom_metric / ga4_update_custom_metric | Create / update a custom metric |
ga4_create_data_stream | Create a web data stream (returns its measurement ID) |
ga4_run_report)Pass dimension_filters / metric_filters — a list of conditions. Set filter_logic to AND (default) or OR; set negate: true on a condition for NOT. Each condition has field, operator, and value (or values for IN_LIST, or value + value_to for BETWEEN):
EXACT, CONTAINS, BEGINS_WITH, ENDS_WITH, REGEXP, IN_LISTEQUAL, LESS_THAN, LESS_EQUAL, GREATER_THAN, GREATER_EQUAL, BETWEENExample: country is India and sessions > 100 → dimension filter country EXACT India plus metric filter sessions GREATER_THAN 100.
ga4_run_report optionsorder_by_dimension (+ order_desc: false for ascending) — e.g. chronological by date.include_totals: true appends a totals row (and computes min/max).Set export_path on ga4_run_report (e.g. report.csv or report.xlsx). Bare filenames are written to an exports/ folder next to the server. CSV works out of the box; XLSX needs openpyxl (already in requirements.txt).
cd google-analytics-mcp
python -m pip install -r requirements.txtGoogle Analytics Admin API.
(If the OAuth consent screen is in "Testing", add your Google account as a Test user.)
python get_refresh_token.pyA browser opens — choose the Google account with access to your GA4 property and approve. The script writes the client ID/secret + refresh token into .env.
.envcp .env.example .env # Windows: copy .env.example .envRequired:
GOOGLE_ANALYTICS_CLIENT_ID=... # from step 2 (also written by step 3)
GOOGLE_ANALYTICS_CLIENT_SECRET=... # from step 2 (also written by step 3)
GOOGLE_ANALYTICS_REFRESH_TOKEN=... # from step 3
# Optional convenience:
GOOGLE_ANALYTICS_DEFAULT_PROPERTY_ID=... # numeric, e.g. 123456789Find your Property ID in GA4: Admin → Property Settings → Property ID (a number like 123456789).
python -c "import server; print('server imports OK')"Then verify credentials end-to-end (lists your accounts/properties):
python -c "import asyncio, server; from server import AccountSummariesInput; \
print(asyncio.run(server.ga4_list_account_summaries(AccountSummariesInput())))"Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\) — use the absolute path to server.py:
{
"mcpServers": {
"google-analytics": {
"command": "python",
"args": ["/ABSOLUTE/PATH/TO/google-analytics-mcp/server.py"]
}
}
}The server reads .env from its own folder, so no secrets go in this config. Restart Claude Desktop.
activeUsers, sessions, screenPageViews, conversions,totalRevenue, engagementRate, bounceRate, averageSessionDuration.
date, country, city, deviceCategory, pagePath,sessionDefaultChannelGroup, firstUserSource, eventName.
Use ga4_get_metadata to see everything (including custom fields) for a property.
| Symptom | Fix |
|---|---|
Missing Google Analytics credentials: ... | Fill the named vars in .env. |
invalid_grant / RefreshError | Refresh token expired/revoked — re-run get_refresh_token.py. |
Permission denied | The login lacks access to that property, or the Data/Admin APIs aren't enabled in your Cloud project. |
Not found | Check the numeric property_id (Admin → Property Settings). |
Invalid request | Check metric/dimension names (ga4_get_metadata) and date formats (YYYY-MM-DD or NdaysAgo). |
.env holds secrets and is git-ignored — never commit it.analytics.readonly (reporting + config reads), analytics.edit(config writes — the create/update tools), and analytics.manage.users.readonly (reading access bindings). The edit scope lets the server change GA4 configuration, so treat the refresh token accordingly. After changing scopes you must re-run get_refresh_token.py and re-consent.
google-analytics-mcp/
├── server.py # FastMCP server + 6 tools
├── ga_client.py # credentials, client factories, error handling
├── get_refresh_token.py # one-time OAuth login -> refresh token
├── requirements.txt
├── .env.example # copy to .env and fill in
├── .gitignore
└── README.md~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.