MCP GTM B2 TECH

Model Context Protocol · Google Tag Manager API v2

Run Tag Manager
straight from Claude.

An MCP server that connects Claude to your GTM containers — read, audit, create, version and publish tags, triggers and variables without ever opening the Tag Manager UI. Embedded OAuth login. Status: LIVE.

27 tools · embedded OAuth · multi-tenant · free

Workspace → version → publish Hexagonal architecture preview=true dry-run confirm=true on destructive ops Fingerprint conflict guard Multi-tenant on Vercel OAuth 2.1 Authorization Server Workspace → version → publish Hexagonal architecture preview=true dry-run confirm=true on destructive ops Fingerprint conflict guard Multi-tenant on Vercel OAuth 2.1 Authorization Server
What it is

Your GTM, driven in natural language

MCP GTM B2 TECH is a Model Context Protocol server that gives Claude real access to your containers — not a chatbot that guesses, but typed calls against the Google Tag Manager API v2.

Real connection

Claude talks to your container

Install or audit a Meta Pixel, a Google Ads conversion tag or GA4; wire click, form and scroll triggers; publish a new version — all by chatting with Claude. The Google login is OAuth2, embedded in the flow.

Mental model

GTM works like git

Account → Container → Workspace (branch) → create_version (commit) → publish (deploy). Every edit happens in a workspace; optimistic concurrency via each entity's fingerprint.

Status

LIVE in production

Multi-tenant deploy at mcp-gtm.vercel.app — encrypted tokens in Supabase, cache in Upstash, and we are the OAuth 2.1 Authorization Server. Same stack as the Meta Ads, Google Ads, Instagram and Cloudflare MCPs.

What it already does

The complete tool catalog

27 tools grouped by function — from auth to publish, from the install snippet to editing tags, triggers and variables. Everything below is already implemented and live.

Auth

4 tools
  • gtm_loginConnect a Google account (browser consent); stores the refresh token.
  • gtm_submit_callbackFinish login by submitting the redirected callback URL.
  • gtm_token_statusReports whether the stored credential is valid, its scopes and expiry.
  • gtm_refresh_tokenMints a fresh access token from the stored refresh token.

Accounts & containers

7 tools
  • list_accountsLists the GTM accounts the credential can access.
  • get_accountDetails a GTM account.
  • list_containersLists an account's containers.
  • get_containerDetails a container (publicId, usage context).
  • create_containerCreates a web/server/amp/iOS/Android container and returns its publicId (GTM-XXXX).
  • get_container_snippetBuilds the head/noscript install snippet locally — deterministic, no API quota spent.
  • get_live_versionShows the published version — what's live right now.

Workspaces

3 tools
  • list_workspacesLists a container's workspaces (drafts).
  • get_workspace_statusShows pending changes against the base version.
  • create_workspaceOpens a new workspace — the "branch" where edits happen.

Elements — tags, triggers & variables

6 tools
  • list_elementsLists a workspace's tags, triggers or variables (kind ∈ tag/trigger/variable).
  • get_elementDetails an element, including its fingerprint.
  • create_elementCreates a tag, trigger or variable — accepts the raw parameter array + an extra escape hatch.
  • update_elementEdits an element (optimistic concurrency via fingerprint).
  • delete_elementRemoves an element (destructive, needs confirm).
  • list_builtin_variablesLists the built-in variables enabled in the workspace.

Built-in variables

2 tools
  • enable_builtin_variablesEnables built-ins (Click Classes, Page URL, Scroll Depth, etc.).
  • disable_builtin_variablesDisables built-ins (destructive, needs confirm).

Versions & publish

5 · confirm=true
  • list_version_headersLists the container's version history.
  • get_versionDetails an immutable container version.
  • list_environmentsLists the environments (Live, Latest, custom).
  • create_versionThe "commit": freezes the workspace into an immutable version.
  • publish_versionThe "deploy": puts the version live on your site (destructive, needs confirm).

From nothing to published in one conversation: create_containerget_container_snippet → tags and triggers → create_versionpublish_version.

Write safety model

Claude doesn't publish anything on its own

Publishing a container changes your production site. So every write goes through explicit guardrails — you're always in control of what goes live.

Edits stay in the workspace

Every write happens in a draft. Your site only changes when you freeze a version and publish it — never before.

Destructive ops need confirm=true

delete_element, disable_builtin_variables and publish_version. Without confirm, the tool returns a preview and executes nothing.

preview=true = dry-run

Returns the exact payload that would be sent, without calling the API. Check before running for real.

fingerprint conflict guard

Optimistic concurrency: a stale fingerprint returns a 409-style conflict error telling you to re-read — nobody silently overwrites someone else's change.

Tenant is never an argument

Locally it's the single stored credential; in production the tenant is derived from the embedded Authorization Server's access token. No tool accepts "which client".

Tokens encrypted at rest

Refresh tokens with AES-256-GCM in Supabase, default-deny RLS and a server-side-only service key. gtm_token_status shows exactly which scopes are active.

How to connect

Up and running in minutes

Two paths: hosted (recommended, zero setup) and local stdio (for single-tenant devs). Both end in the same place — Claude operating your account.

Recommended

Hosted — mcp-gtm.vercel.app

Add the MCP server as a connector in Claude and log in. Nothing to install; we handle the OAuth and the tokens.

  1. Add the connector. In Claude.ai → Settings → Connectors → Add custom connector, paste https://mcp-gtm.vercel.app/api/mcp. In Claude Code, use the command below.
    # Claude Code
    claude mcp add --transport http \
      gtm https://mcp-gtm.vercel.app/api/mcp
  2. Log in to Google. The OAuth handshake (our Authorization Server → Google login) runs automatically when you connect; in Claude Code, complete it via /mcp.
  3. Confirm. Run gtm_token_status to validate the credential and list_accounts to see your GTM accounts. Ready to operate.
Advanced

Local stdio — single-tenant

Run the server on your machine. The refresh token lives in a local 0600 file; you use your own GCP OAuth client.

  1. Install. Create the environment and install dependencies.
    python -m venv venv
    venv/bin/pip install -e ".[dev]"
    cp .env.example .env.local
  2. Configure credentials. Fill .env.local: GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET and NGROK_URL (the redirect URI is ${NGROK_URL}/oauth/callback on the GCP OAuth client).
  3. Run and log in. Start the server and connect your account.
    PYTHONPATH=src venv/bin/python \
      -m mcp_gtm
    # in Claude: gtm_login → gtm_submit_callback

Frequently asked questions

Still have a question? Write to bruno@b2tech.io.

How much does it cost?
The MCP GTM server is free. You only need a Google account with access to Google Tag Manager.
Is it safe? Can Claude break my site?
Nothing goes live without you. All edits happen in a workspace (draft); your site only changes when publish_version runs with confirm=true. Destructive actions without confirm return only a preview, and preview=true returns the exact payload without calling the API.
How does the workspace/version model work?
GTM works like git: Account → Container → Workspace (branch) → create_version (commit) → publish (deploy). You edit in a workspace, freeze it into an immutable version, and only then publish.
What is the fingerprint?
It's the GTM API's optimistic-concurrency mechanism: every entity carries a fingerprint, and a stale fingerprint returns a 409-style conflict error telling you to re-read before writing — nobody silently overwrites someone else's change.
Multi-tenant — where do my tokens live?
On the hosted deploy, refresh tokens are AES-256-GCM-encrypted in Supabase (default-deny RLS) and the cache lives in Upstash; we are the OAuth 2.1 Authorization Server. In local mode, the refresh token sits in a 0600 file on your machine (single-tenant).
Are there usage limits?
The Tag Manager API allows ~0.25 QPS per GCP project (25 requests/100s) and 10,000 calls/day. A full container setup (~15 sequential calls) fits comfortably; heavier automation needs pacing or a quota increase in the GCP console.
Local or hosted — which should I pick?
Hosted (mcp-gtm.vercel.app) is the fast path: zero setup, just add it as a connector in Claude and log in. Local stdio is single-tenant, for devs who want everything on their own machine with the refresh token in a 0600 file.
Start now

Stop clicking through the GTM UI.
Ask Claude and it installs, versions and publishes.

Tags, triggers, variables, versions and environments — from nothing to a published container, with embedded OAuth and publish only with confirm=true. Free and live.

27 tools · embedded OAuth2 · multi-tenant on Vercel