A read-only Python stdio MCP server wrapping GTM API v2
gtm-mcp-server
A read-only Model Context Protocol (MCP) server for the Google Tag Manager API v2.
Connect it to an LLM (Claude Desktop, Claude Code, or any MCP client) to explore and audit your GTM accounts in natural language — list and read accounts, containers, workspaces, tags, triggers, variables, templates, versions and more.
Read-only by design. This server exposes only
list/getoperations and requests only thetagmanager.readonlyOAuth scope. It cannot create, update, delete, or publish anything in your GTM account.
Tools
All tools take the short numeric IDs shown in the GTM UI (and returned by the
list_* tools); the server assembles the API resource paths for you.
| Area | Tools |
| --- | --- |
| Accounts | list_accounts, get_account, list_user_permissions |
| Containers | list_containers, get_container |
| Environments | list_environments, get_environment |
| Versions | list_version_headers, get_live_version, get_container_version |
| Destinations | list_destinations |
| Workspaces | list_workspaces, get_workspace |
| Tags | list_tags, get_tag |
| Triggers | list_triggers, get_trigger |
| Variables | list_variables, get_variable, list_built_in_variables |
| Folders | list_folders, get_folder |
| Templates | list_templates, get_template |
| Server-side | list_clients, list_transformations, list_zones, list_gtag_config |
Plus two read-only prompts: audit_container and generate_tracking_plan.
Install
pipx install "git+https://github.com/brynj-digital/gtm-mcp-server.git"
# or, for development:
pip install -e .
This installs the gtm-mcp-server console script (a stdio MCP server).
Authentication
You need a Google Cloud project with the Tag Manager API enabled, and a credential that can read your GTM resources. The server resolves credentials in this order:
Option A — Desktop OAuth (local / interactive)
Best for running locally with Claude Desktop or Claude Code.
-
In Google Cloud Console, create an OAuth client ID of type Desktop app and download the
client_secret_*.json. -
Point the server at it:
export GTM_MCP_OAUTH_CLIENT_SECRETS=/path/to/client_secret.json -
On first run the server opens a browser for one-time consent, then caches the token at
~/.config/gtm-mcp-server/token.json(override withGTM_MCP_TOKEN) and refreshes it automatically thereafter.
Option B — Application Default Credentials (headless / server)
Best for running behind a gateway or on a server, with no browser. Use either a service account or pre-authorised user credentials:
# a service account with GTM access:
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
# …or pre-authorised user credentials:
gcloud auth application-default login --scopes=https://www.googleapis.com/auth/tagmanager.readonly
The service account or user must be granted access to the GTM account(s) you want to read.
Claude Desktop / Claude Code config
{
"mcpServers": {
"gtm": {
"command": "gtm-mcp-server",
"env": {
"GTM_MCP_OAUTH_CLIENT_SECRETS": "/absolute/path/to/client_secret.json"
}
}
}
}
Environment variables
| Variable | Purpose | Default |
| --- | --- | --- |
| GTM_MCP_OAUTH_CLIENT_SECRETS | Path to a Desktop-app OAuth client_secret.json. If set, enables Option A. | (unset → use ADC) |
| GTM_MCP_TOKEN | Where the cached OAuth token is stored. | ~/.config/gtm-mcp-server/token.json |
| GTM_MCP_CONFIG_DIR | Base dir for the token when GTM_MCP_TOKEN is unset. | ~/.config/gtm-mcp-server |
| GOOGLE_APPLICATION_CREDENTIALS | Service-account key for ADC (Option B). | (standard ADC resolution) |
| GTM_MCP_SCOPES | Override OAuth scopes (space/comma separated). | tagmanager.readonly |
Development
pip install -e .
python -m gtm_mcp # run the stdio server
python tests/test_smoke.py # offline checks (no network/credentials)
License
MIT — see LICENSE.