Google Tag Manager MCP Server (Alpha)
🚀 Empower your AI agents to handle the whole Google Tag Manager workflow!
This repo contains the source code for running a local MCP server that interacts with APIs for Google Tag Manager.
Features
- No frequent authentication. Standard Google ADC with your own OAuth client is all you need. Everything runs on your machine, straight against the GTM API.
- No service account required. The server runs as you, with the GTM permissions your account already has.
- Built for LLM context windows. A single GTM tag can be hundreds of
lines of JSON;
list_*tools return slim skeletons andget_*fetches full detail only when asked.
Tools
The server uses the Google Tag Manager API to provide Tools for use with LLMs. The most frequently used tools are:
| Tool | Purpose |
|---|---|
list_containers |
Containers in an account — where every session starts |
list_tags |
Tags in the workspace as slim skeletons |
get_tag |
One tag's full configuration, on demand |
get_workspace_status |
Unpublished changes and merge conflicts |
create_tag |
Add a tag to the workspace draft |
update_tag |
Merge partial changes into a tag (fingerprint-checked) |
delete_tag |
Remove a tag (requires confirm=true) |
Triggers and variables have the same four tools as tags, and versioning and publishing have their own. See Appendix I for the full list.
The write safety model:
- Editing and going live are separate. Create/update/delete only touch
the workspace draft; only
publish_versionchanges the live site. - Updates are merge patches. The model sends just the fields it changes,
and the server submits the entity's
fingerprint, so a concurrent edit fails cleanly instead of being clobbered. - Deletes and publishing need
confirm=true, and every destructive tool is declared withdestructiveHint. - No blind retries on writes. Rate-limit rejections are retried, ambiguous 5xx errors are not, so a create is never silently duplicated.
Prerequisites
- Python 3.10+
- pipx or uv
- The gcloud CLI
- A Google account with access to your GTM containers
- A GCP project (used only for quota attribution)
Setup instructions
1. Install
pipx install tagmanager-mcp
or, with uv:
uv tool install tagmanager-mcp
Either one puts a tagmanager-mcp executable on your PATH.
2. Enable the Tag Manager API on your quota project
gcloud services enable tagmanager.googleapis.com --project=YOUR_PROJECT
3. Create a Desktop OAuth client
Check out Manage OAuth Clients for how to create an OAuth client. Two choices matter here: pick application type Desktop app, and publish the app to Production, because an app left in Testing issues refresh tokens that expire after 7 days. Download the client JSON at the end — step 4 needs it.
Why your own client? Google may block gcloud's built-in one for Tag Manager scopes ("This app is blocked"), and that block is not something you can work around from your side.
4. Log in
gcloud auth application-default login \
--client-id-file=path/to/your-client.json \
--scopes=\
https://www.googleapis.com/auth/tagmanager.readonly,\
https://www.googleapis.com/auth/tagmanager.edit.containers,\
https://www.googleapis.com/auth/tagmanager.edit.containerversions,\
https://www.googleapis.com/auth/tagmanager.publish,\
https://www.googleapis.com/auth/cloud-platform
gcloud auth application-default set-quota-project YOUR_PROJECT
The browser will warn "Google hasn't verified this app" — it is your own app; choose Advanced → Continue.
Those scopes unlock everything. Drop the lines you do not want:
| Scope | Unlocks |
|---|---|
tagmanager.readonly |
Every read tool |
tagmanager.edit.containers |
Create / update / delete in a workspace |
tagmanager.edit.containerversions |
create_version |
tagmanager.publish |
publish_version |
cloud-platform |
Nothing in GTM — needed by set-quota-project |
Tools outside your granted scopes fail with a clear re-login hint, and everything else keeps working.
Connect an MCP client
Configure Claude Code
claude mcp add --scope user tagmanager-mcp -- tagmanager-mcp
--scope user registers the server for every project instead of just the
current directory. Verify with claude mcp list, or run /mcp inside a
session.
Configure Claude Desktop
Claude Desktop needs the absolute path to the executable. Print it:
which tagmanager-mcp
Open Settings → Developer → Edit Config, which reveals
claude_desktop_config.json
(~/Library/Application Support/Claude/ on macOS,
%APPDATA%\Claude\ on Windows), and add the server with the path you just
printed:
{
"mcpServers": {
"tagmanager-mcp": {
"command": "/Users/you/.local/bin/tagmanager-mcp"
}
}
}
Save the file and restart Claude Desktop — it reads the config only at startup. The tools then appear under the tools icon in the chat box.
Example prompts
- "Which GTM accounts and containers do I have?"
- "How many tags are in container GTM-XXXXXXX, grouped by type?"
- "Show me the purchase tag's config and which triggers fire it."
- "Does the current workspace have unpublished changes?"
- "Pause every tag that fires on the checkout trigger."
- "Create a custom-event trigger for
sign_upand a GA4 event tag that fires on it."
Note on quota
The GTM API allows 10,000 requests/day and 25 requests per 100 seconds per GCP project; per-user overrides do not raise it. Ordinary audit conversations fit comfortably — just avoid sweeping every tag across many containers at once.
Appendix I: A Full List of Tools
Read
| Tool | Purpose |
|---|---|
list_accounts |
GTM accounts you can access (optionally Google Tag accounts) |
list_containers |
Containers in an account |
list_workspaces |
Workspaces in a container |
get_workspace_status |
Unpublished changes and merge conflicts |
list_tags / get_tag |
Tags — skeleton list / full configuration |
list_triggers / get_trigger |
Triggers — skeleton list / full configuration |
list_variables / get_variable |
Variables — skeleton list / full configuration |
list_versions |
Container version headers — skeleton list |
get_version / get_live_version |
One version / the currently live version, with slimmed contents |
Write
| Tool | Purpose |
|---|---|
create_tag / create_trigger / create_variable |
Create an entity in the workspace draft |
update_tag / update_trigger / update_variable |
Merge partial changes into an entity |
delete_tag / delete_trigger / delete_variable |
Delete an entity (requires confirm=true) |
create_version |
Snapshot the workspace into a version (consumes the workspace; returns newWorkspacePath) |
publish_version |
Publish a version live (requires confirm=true) |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tagmanager_mcp-0.3.2.tar.gz.
File metadata
- Download URL: tagmanager_mcp-0.3.2.tar.gz
- Upload date:
- Size: 19.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
603ebbcc50b1ca801673e8ba4ea119cba41186c46a6b30f329636a619f5c3465
|
|
| MD5 |
ce3be6611e0a5dbc1ad30a71c385b9c3
|
|
| BLAKE2b-256 |
fc506c35a142ff3b6835b2ecd9ef0b7d6d6f2662ddd847b69cfcbfa70b521c37
|
Provenance
The following attestation bundles were made for tagmanager_mcp-0.3.2.tar.gz:
Publisher:
release.yml on jinchliu/tagmanager-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tagmanager_mcp-0.3.2.tar.gz -
Subject digest:
603ebbcc50b1ca801673e8ba4ea119cba41186c46a6b30f329636a619f5c3465 - Sigstore transparency entry: 2403396558
- Sigstore integration time:
-
Permalink:
jinchliu/tagmanager-mcp@042ac98ca6c82d192528f3dccf99aabb31f05688 -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/jinchliu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@042ac98ca6c82d192528f3dccf99aabb31f05688 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tagmanager_mcp-0.3.2-py3-none-any.whl.
File metadata
- Download URL: tagmanager_mcp-0.3.2-py3-none-any.whl
- Upload date:
- Size: 25.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e961ee99c023e892175bd16629d6e99ff999876b98272a90aba3f9df237d4bb5
|
|
| MD5 |
e412c1d486c753fa6313f3effe48b35d
|
|
| BLAKE2b-256 |
563be5d1a8493aef5f40a7388aae1ba8f257cdf5820e10d5460b4c6958a32464
|
Provenance
The following attestation bundles were made for tagmanager_mcp-0.3.2-py3-none-any.whl:
Publisher:
release.yml on jinchliu/tagmanager-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tagmanager_mcp-0.3.2-py3-none-any.whl -
Subject digest:
e961ee99c023e892175bd16629d6e99ff999876b98272a90aba3f9df237d4bb5 - Sigstore transparency entry: 2403396897
- Sigstore integration time:
-
Permalink:
jinchliu/tagmanager-mcp@042ac98ca6c82d192528f3dccf99aabb31f05688 -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/jinchliu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@042ac98ca6c82d192528f3dccf99aabb31f05688 -
Trigger Event:
push
-
Statement type: