google-analytics-gtm-mcp
Provides tools for interacting with Google Analytics 4: running standard and realtime reports, managing custom dimensions and metrics, key events, audiences, and Measurement Protocol API secrets, and sending events.
Provides tools for managing Google Tag Manager resources: listing accounts, containers, workspaces, tags, triggers, and variables, creating/updating/deleting tags, triggers, and variables, and creating and publishing container versions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@google-analytics-gtm-mcp pull last 28 days of users and conversions by channel"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
google-analytics-gtm-mcp
One Model Context Protocol (MCP) server for Google Analytics 4 and Google Tag Manager, with both read and write access. Connect it to Claude (or any MCP client) and, in natural language, pull GA4 reports, manage measurement configuration, build remarketing audiences, and edit and publish GTM tags, triggers, and variables — all with your own Google credentials. No third-party service, no subscription.
A single Google Cloud service account powers both surfaces: grant it access in Google Analytics and in Tag Manager, point one environment variable at its key, and you get 40 tools across the two products from one server entry.
Features
Google Analytics 4 — read
List accounts and properties, property details, and data streams
Run GA4 reports (
run_report) and realtime reports (run_realtime_report)List custom dimensions, custom metrics, key events (conversions), and audiences
Google Analytics 4 — write
Create and archive custom dimensions; create custom metrics
Create key events (conversions)
Create and archive audiences (remarketing lists you can share to Google Ads)
Create / list / delete Measurement Protocol API secrets
Send events via the Measurement Protocol (with a
validate=Truemode that checks a payload without ingesting it)
Google Tag Manager — read
List accounts, containers, workspaces, tags, triggers, and variables
Get a single tag; list container versions; get the live (published) version
Google Tag Manager — write
Create, update, and delete tags, triggers, and variables
Create a container version from a workspace
Publish a version to live (guarded by
confirm=true)
Related MCP server: gsc-mcp
Requirements
Python 3.10+ (the MCP SDK requires it)
A Google Cloud project and a service account with a JSON key
The service account granted access on your GA4 account/property and your GTM account/container
Google setup (one time)
In the Google Cloud Console, create (or pick) a project.
Enable three APIs for that project: Google Analytics Data API, Google Analytics Admin API, and Tag Manager API.
Create a service account and download a JSON key for it. Note its email (
...@your-project.iam.gserviceaccount.com).In Google Analytics → Admin → Account (or Property) access management, add that email as a user — Editor if you want write access, Viewer/Analyst for read-only.
In Tag Manager → Admin → User Management (at the account and/or container level), add the same email — grant Publish (container permission) if you want to create and publish versions, or Read for read-only.
That's it — no OAuth consent screen, no token refresh. The service account authenticates directly.
Install
Using uv (recommended — it manages an isolated Python for you):
git clone https://github.com/burhan29ee/google-analytics-gtm-mcp.git
cd google-analytics-gtm-mcp
uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python -e .Or with pip:
python3 -m venv .venv && source .venv/bin/activate
pip install -e .Configure your MCP client
Point the server at your service-account key with the GOOGLE_APPLICATION_CREDENTIALS environment variable, then add it to your client. For Claude Desktop, edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json; Windows: %APPDATA%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"google-analytics-gtm": {
"command": "/absolute/path/to/google-analytics-gtm-mcp/.venv/bin/python",
"args": ["-m", "google_analytics_gtm_mcp.server"],
"env": {
"GOOGLE_APPLICATION_CREDENTIALS": "/absolute/path/to/service-account-key.json"
}
}
}
}Restart the client. You should be able to ask things like "list my GA4 properties," "pull last 28 days of users and conversions by channel," "create a remarketing audience of everyone who fired generate_lead in the last 60 days," or "list the tags in my GTM container and show me the live version."
Tool reference
Google Analytics 4
Tool | Type | What it does |
| read | List accounts and their properties |
| read | Property name, time zone, currency, industry |
| read | Web/app streams and their measurement IDs |
| read | GA4 report by metrics/dimensions/date range |
| read | Realtime report (last ~30 min) |
| read | Custom dimensions on a property |
| write | Create a custom dimension |
| write | Archive a custom dimension |
| read | Custom metrics on a property |
| write | Create a custom metric |
| read | Key events (conversions) |
| write | Mark an event as a conversion |
| read | Audiences on a property |
| write | Create an audience of users who fired an event |
| write | Archive an audience |
| read | MP API secrets for a stream |
| write | Create an MP API secret |
| write | Delete an MP API secret |
| write | Send an event via the Measurement Protocol |
Google Tag Manager
Tool | Type | What it does |
| read | Show the service-account identity, scopes, and visible accounts |
| read | List GTM accounts |
| read | List containers in an account |
| read | List workspaces in a container |
| read | List tags in a workspace |
| read | List triggers in a workspace |
| read | List variables in a workspace |
| read | Get a single tag by id |
| read | List container version headers |
| read | Get the live (published) version |
| write | Create a tag from a JSON resource |
| write | Update an existing tag |
| write | Delete a tag ( |
| write | Create a trigger |
| write | Update a trigger |
| write | Delete a trigger ( |
| write | Create a variable |
| write | Update a variable |
| write | Delete a variable ( |
| write | Freeze a workspace into a new version |
| write | Publish a version to live ( |
Development
pip install -e ".[dev]"
ruff check .
pytest -qSee CONTRIBUTING.md for the full workflow.
Security
The service-account key is a credential — treat it like a password. Never commit it (the .gitignore blocks key files), grant the service account the least access it needs in each product, and rotate the key if it's ever exposed. GTM write tools that affect a live container (gtm_delete_*, gtm_publish_version) require confirm=true. See SECURITY.md for details and how to report a vulnerability.
Notes
The
mcpdependency is pinned to>=1.2,<2. The 2.0 SDK reorganized its API and removedmcp.server.fastmcp, which this server uses.GA4 audiences use the GA4 Admin v1alpha API; the rest of GA4 uses the stable v1beta and Data APIs. GTM uses the Tag Manager v2 API.
This is an independent open-source project and is not affiliated with or endorsed by Google.
License
Available Tools
40 toolsarchive_audienceA
Archive a GA4 audience. audience_id may be the numeric id or the full 'properties/NNN/audiences/MMM' name.
Inputs: audience_id (required), property_id (required).
archive_custom_dimensionB
Archive (delete) a custom dimension. custom_dimension_id may be the numeric id or the full 'properties/NNN/customDimensions/MMM' name.
Inputs: property_id (required), custom_dimension_id (required).
create_custom_dimensionB
Create a custom dimension. parameter_name is the event parameter / user property key; scope is 'EVENT', 'USER' or 'ITEM'. display_name may contain only letters, numbers, underscores and spaces.
Inputs: property_id (required), display_name (required), parameter_name (required), scope, +1 more.
create_custom_metricC
Create a custom metric. measurement_unit is one of STANDARD, CURRENCY, FEET, METERS, KILOMETERS, MILES, MILLISECONDS, SECONDS, MINUTES, HOURS.
Inputs: property_id (required), display_name (required), parameter_name (required), scope, +2 more.
create_event_audienceA
Create a GA4 audience of users who triggered a given event (e.g. 'purchase', 'generate_lead') — useful for remarketing lists that can be shared to Google Ads. membership_duration_days is how long a user stays in the audience (max 540).
Inputs: event_name (required), property_id (required), display_name (required), description, +1 more.
create_key_eventA
Mark an event as a key event (conversion). counting_method is 'ONCE_PER_EVENT' or 'ONCE_PER_SESSION'.
Inputs: event_name (required), property_id (required), counting_method.
create_measurement_protocol_secretA
Create a Measurement Protocol API secret on a data stream. Returns the secret_value (api_secret) needed by send_ga4_event. Treat it as sensitive.
Inputs: stream_id (required), property_id (required), display_name (required).
delete_measurement_protocol_secretB
Delete a Measurement Protocol API secret. secret_id may be the numeric id or the full resource name.
Inputs: secret_id (required), stream_id (required), property_id (required).
get_property_detailsA
Get configuration details for one GA4 property (name, time zone, currency, industry, create time).
Inputs: property_id (required).
gtm_create_tagB
Create a tag. tag_json is the full GTM Tag resource as a JSON string, e.g. {"name":"GA4 Config","type":"gaawc","parameter":[...], "firingTriggerId":["2147479553"]}.
Inputs: tag_json (required), account_id (required), container_id (required), workspace_id (required).
gtm_create_triggerB
Create a trigger from a full GTM Trigger resource (JSON string).
Inputs: account_id (required), container_id (required), trigger_json (required), workspace_id (required).
gtm_create_variableB
Create a variable from a full GTM Variable resource (JSON string).
Inputs: account_id (required), container_id (required), workspace_id (required), variable_json (required).
gtm_create_versionA
Freeze the current workspace into a new container version. Returns the new containerVersion (with containerVersionId) plus any compiler errors. This does NOT publish; use gtm_publish_version next.
Inputs: name (required), account_id (required), container_id (required), workspace_id (required), +1 more.
gtm_delete_tagA
Delete a tag. Requires confirm=true.
Inputs: tag_id (required), account_id (required), container_id (required), workspace_id (required), +1 more.
gtm_delete_triggerB
Delete a trigger. Requires confirm=true.
Inputs: account_id (required), trigger_id (required), container_id (required), workspace_id (required), +1 more.
gtm_delete_variableB
Delete a variable. Requires confirm=true.
Inputs: account_id (required), variable_id (required), container_id (required), workspace_id (required), +1 more.
gtm_get_live_versionC
Get the currently live (published) container version.
Inputs: account_id (required), container_id (required).
gtm_get_tagC
Get a single tag by id.
Inputs: tag_id (required), account_id (required), container_id (required), workspace_id (required).
gtm_list_accountsA
List all GTM accounts the service account can access.
Inputs: no named parameters.
gtm_list_containersB
List containers in a GTM account.
Inputs: account_id (required).
gtm_list_tagsB
List tags in a workspace.
Inputs: account_id (required), container_id (required), workspace_id (required).
gtm_list_triggersC
List triggers in a workspace.
Inputs: account_id (required), container_id (required), workspace_id (required).
gtm_list_variablesB
List variables in a workspace.
Inputs: account_id (required), container_id (required), workspace_id (required).
gtm_list_versionsA
List container version headers (published + saved versions).
Inputs: account_id (required), container_id (required).
gtm_list_workspacesC
List workspaces in a container.
Inputs: account_id (required), container_id (required).
gtm_publish_versionA
Publish a container version to live. Requires confirm=true because this affects the live site.
Inputs: account_id (required), version_id (required), container_id (required), confirm.
gtm_update_tagA
Update an existing tag with a full GTM Tag resource (JSON string).
Inputs: tag_id (required), tag_json (required), account_id (required), container_id (required), +1 more.
gtm_update_triggerB
Update an existing trigger with a full GTM Trigger resource (JSON string).
Inputs: account_id (required), trigger_id (required), container_id (required), trigger_json (required), +1 more.
gtm_update_variableA
Update an existing variable with a full GTM Variable resource (JSON string).
Inputs: account_id (required), variable_id (required), container_id (required), workspace_id (required), +1 more.
gtm_whoamiA
Show which service-account identity and scopes this server uses for GTM, and how many GTM accounts it can currently see. Use this to verify access after granting the service account permission in Tag Manager.
Inputs: no named parameters.
list_account_summariesA
List every GA4 account and its properties the service account can see. Returns account name/id plus each property's display name and numeric id. Call this first to discover property ids for the other GA4 tools.
Inputs: no named parameters. Returns: result
list_audiencesB
List audiences defined on a GA4 property.
Inputs: property_id (required). Returns: result
list_custom_dimensionsA
List custom dimensions defined on a GA4 property.
Inputs: property_id (required). Returns: result
list_custom_metricsB
List custom metrics defined on a GA4 property.
Inputs: property_id (required). Returns: result
list_data_streamsA
List the data streams (web/app) on a GA4 property. The stream id (last path segment of 'name') is needed by the Measurement Protocol secret tools.
Inputs: property_id (required). Returns: result
list_key_eventsB
List key events (conversions) on a GA4 property.
Inputs: property_id (required). Returns: result
list_measurement_protocol_secretsA
List Measurement Protocol API secrets for a data stream. stream_id is the numeric id from list_data_streams.
Inputs: stream_id (required), property_id (required). Returns: result
run_realtime_reportA
Run a GA4 realtime report (last ~30 minutes). Example: metrics ['activeUsers'], dimensions ['country','unifiedScreenName'].
Inputs: metrics (required), property_id (required), limit, dimensions.
run_reportC
Run a GA4 report. metrics/dimensions are GA4 API names (e.g. metrics ['activeUsers','conversions'], dimensions ['date','sessionDefaultChannelGroup']). Dates accept YYYY-MM-DD or relative forms like '28daysAgo' / 'today'.
Inputs: metrics (required), property_id (required), limit, end_date, +2 more.
send_ga4_eventA
Send an event into a GA4 property via the Measurement Protocol. measurement_id is the stream's 'G-XXXXXXX'; api_secret comes from a Measurement Protocol secret; client_id identifies the user/device. Set validate=True to hit GA4's debug/validation endpoint (checks the payload WITHOUT ingesting it) — recommended before real sends.
Inputs: client_id (required), api_secret (required), event_name (required), measurement_id (required), +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 40 tools
Every tool targets a distinct resource and action. The gtm_ prefix cleanly separates GTM tools from GA4 tools, and each list/get/create/update/delete/send tool maps to a unique resource (reports, dimensions, metrics, key events, audiences, secrets, tags, triggers, variables, versions). There is no overlap or ambiguity.
Most tools follow a verb_noun pattern, but the GA4 tools use bare verbs (list_, create_, archive_) while GTM tools are prefixed with gtm_ (gtm_list_, gtm_create_), which is a visible deviation. Also, 'get_property_details' doesn't align with 'list_account_summaries', 'send_ga4_event' and 'gtm_whoami' break the pattern, and archive vs delete is used inconsistently. Still, within each domain the pattern is fairly regular.
40 tools is well above the 25+ threshold that typically feels too heavy for an MCP server. Even though the server covers two distinct APIs (GA4 and GTM), the number of tools will clutter the agent's context and many are narrowly scoped (e.g., separate create/update/delete for three GTM resources). The count is excessive for practical use.
The server covers a broad range of GA4 and GTM operations, but there are notable gaps: no update for custom dimensions/metrics (only archive for dimensions), no update/delete for key events, no update for audiences, no update for measurement protocol secrets, and no GTM container/workspace creation or deletion. These gaps are workable but represent missing lifecycle operations in the domain.
Maintenance
Related MCP Connectors
Read and edit GA4, Search Console and Google Tag Manager from any MCP client. 29 tools.
Hosted MCP server for GA4, Google Ads and Search Console. Google OAuth, nothing to install.
Read-only Google Analytics 4 MCP server for AI assistants.
Hosted Google Analytics 4 MCP server, with each action switched on or off per account.
Related MCP Servers
- AlicenseAqualityBmaintenanceMCP server for Google Tag Manager and GA4, enabling tag management, consent auditing, workspace versioning, and analytics reporting through natural language.1158 npm3MIT
- AlicenseCqualityBmaintenanceMCP server providing 32 tools for Google Search Console and Google Analytics 4, enabling search analytics, URL inspection, indexing, and cross-platform analysis via natural language.8159 PyPI24MIT
- AlicenseNot gradedqualityDmaintenanceAutomates Google Analytics 4 and Google Tag Manager setup, management, and health monitoring with blueprints, multi-environment support, and MCP tools for AI agents.MIT
- FlicenseNot gradedqualityDmaintenanceMCP server providing access to Google Analytics Data API, enabling LLMs to retrieve reports, real-time data, and metadata from GA4 properties.-