
stape-io/google-tag-manager-mcp-server
Developer toolsAn interface to the Google Tag Manager API over MCP, in two flavours: a hosted server with Google OAuth built in, and a local CLI that runs on your own credentials.
Overview
An interface to the Google Tag Manager API over MCP, in two flavours: a hosted server with Google OAuth built in, and a local CLI that runs on your own credentials.
README
MCP Server for Google Tag Manager
An interface to the Google Tag Manager API over MCP, in two flavours: a hosted server with Google OAuth built in, and a local CLI that runs on your own credentials.
Table of Contents
- MCP Server for Google Tag Manager
Repository layout
npm workspace with one app and two published packages:
| Path | Package | What it is |
|---|---|---|
apps/worker |
(private) | The hosted Cloudflare Worker at gtm-mcp.stape.io: Google OAuth, the approval flow, the public pages, session removal. |
packages/cli |
google-tag-manager-mcp-server |
The npm package: a local MCP server over stdio, authenticating with credentials you supply. |
packages/core |
google-tag-manager-mcp-core |
Every GTM tool and schema, independent of how credentials are obtained. |
Tools reach Google through a GtmAuthProvider (getAccessToken(): Promise) rather than through any particular session, which is what lets the same tool set back both servers — and a private one with your own auth. See the core package README.
Installation
This server comes in two flavours: Hosted server and Local CLI. Both give you the same 20 GTM tools; the difference is who handles Google auth.
| Hosted server | Local CLI | |
|---|---|---|
| Auth | Google OAuth in your browser, handled for you | You supply a service account key, refresh token, or access token |
| Data | Passes through gtm-mcp.stape.io |
Only ever leaves your machine |
| Setup | None | Set one environment variable |
If you’re a contributor testing an unreleased change rather than just using the tools, skip everything below and see Test your changes locally instead.
Pick your client below. The hosted server is a remote, HTTP-based MCP endpoint at https://gtm-mcp.stape.io/mcp. Clients that complete the Google OAuth flow themselves (Claude Desktop, Claude Code, VS Code, Copilot CLI, Cursor, ChatGPT) connect straight to that URL and sign you in with Google the first time they connect; the rest (Antigravity, stdio-only clients) reach it through mcp-remote, a small bridge to remote HTTP MCP servers. Restart the client after changing its config.
Claude Desktop
Claude Code
VS Code
GitHub Copilot
Copilot CLI
Cursor
Antigravity
ChatGPT
Other MCP clients
Troubleshooting
Authentication errors
If tools fail with 401/403 errors, ask your assistant to run gtm_auth_status. It reports whether the current Google token is accepted, when it expires and which Tag Manager scopes are missing, without revealing the token.
MCP Server Name Length Limit
Some MCP clients (like Cursor AI) have a 60-character limit for the combined MCP server name + tool name length. If you use a longer server name in your configuration (e.g., gtm-mcp-server-your-additional-long-name), some tools may be filtered out.
To avoid this issue:
- Use shorter server names in your MCP configuration (e.g.,
gtm-mcp-server)
Clearing MCP Cache
If you’re connecting through mcp-remote (Antigravity, Claude Desktop configured that way, or other clients using the mcp-remote block), it stores all the credential information inside ~/.mcp-auth (or wherever your MCP_REMOTE_CONFIG_DIR points to). If you’re having persistent issues, try running:
rm -rf ~/.mcp-auth
Then, restart your MCP client.
Test your changes locally
Which workflow you need depends on what you changed. Most changes are in the first category — reach for the second only if you’re touching the Worker itself.
Changes to packages/core or packages/cli
This is the tool logic itself (schemas, GTM API calls, error handling) — almost everything you’d fix or add lives here. You don’t need a Google Cloud OAuth client or any Worker setup: build from source and run the CLI directly with credentials you already have.
git clone https://github.com/stape-io/google-tag-manager-mcp-server
cd google-tag-manager-mcp-server
gh pr checkout # or: git checkout
npm install
npm run build
Point your MCP client at the local build instead of npx — same credential
options as the Claude Desktop Local CLI example above, an access
token from the OAuth Playground is
the fastest way to test a single change:
{
"mcpServers": {
"gtm-mcp-local": {
"command": "node",
"args": ["/absolute/path/to/google-tag-manager-mcp-server/packages/cli/dist/index.js"],
"env": {
"GOOGLE_ACCESS_TOKEN": "..."
}
}
}
}
See the CLI README for every credential option.
Changes to apps/worker
Only needed for the hosted server’s own code: the OAuth flow, routing, session
handling, the approval and status pages. This runs that code on your own machine
against your own Google Cloud OAuth credentials instead of gtm-mcp.stape.io.
1. Set up a Google Cloud OAuth client
- In the Google Cloud Console, create or select a project, then enable the Tag Manager API.
- Go to APIs & Services > OAuth consent screen and configure it (External is fine). While the app is in Testing publishing status, only accounts listed as test users can log in.
- Go to Audience, under Test users add your own Google account.
- Go to APIs & Services > Credentials > Create Credentials > OAuth client ID, type Web application.
- Under Authorized redirect URIs, add
http://localhost:8788/callback. (You can leave Authorized JavaScript origins empty — this flow is server-side only, no browser JS calls Google directly.) - Save, then copy the generated Client ID and Client secret.
2. Configure local environment variables
Copy the example file and fill in the values from the previous step:
cp apps/worker/.dev.vars.example apps/worker/.dev.vars
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""
COOKIE_ENCRYPTION_KEY=""
WORKER_HOST="http://localhost:8788"
HOSTED_DOMAIN=""
.dev.vars is git-ignored — it’s only used locally and never committed.
3. Start the server
npm install
npm run build
npm run dev
npm run build compiles the core package the Worker bundles against; npm run dev starts the Worker on http://localhost:8788.
4. Point your MCP client at the local server
Claude Desktop’s Custom Connectors need a publicly reachable URL, so mcp-remote is the only option for pointing at localhost:
{
"mcpServers": {
"gtm-mcp-server-local": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:8788/mcp"]
}
}
}
Restart Claude Desktop. A browser window will open for the Google OAuth flow; log in with the account you added as a test user in step 1.
Note: if you’ve previously connected to the hosted server (or switch back and forth between local and hosted), clear mcp-remote’s cache first (see Troubleshooting above) and fully restart your MCP client, otherwise it may reuse a stale/cached connection.
Releasing
Versions and changelogs are managed with Changesets. Along with a change that should ship, add:
npm run changeset
On merge to main the release workflow opens a “Version Packages” PR; merging that PR publishes to npm, core first and then the CLI that depends on it. The Worker is private and never published — it deploys from main on every push.
Development
npm install
npm run build # core, then the CLI, then the Worker's generated version
npm run typecheck
npm run lint
npm run smoke # starts the built CLI and runs an MCP handshake against it
Pull requests run all of the above plus a Worker bundle check, and flag changes to a published package that arrive without a changeset.
Both @modelcontextprotocol/sdk and agents are pinned to exact versions in apps/worker. The SDK identifies tool schemas with instanceof, so the whole workspace has to resolve a single copy, and agents releases pin the SDK version they were built against. Bump them together and deploy deliberately.
Useful resources
Open Source
The MCP Server for Google Tag Manager is developed and maintained by Stape Team under the Apache 2.0 license.
Install
npx -y mcp-remote https://gtm-mcp.stape.io/mcpConfiguration
{
"mcpServers": {
"gtm-mcp-server": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://gtm-mcp.stape.io/mcp"
]
}
}
}