Tag Pilot GTM

io.github.tagpilotPublished by GitHub account tagpilotv0.1.0Updated Nov 14, 2026

Free, read-only Google Tag Manager: containers, tags, diffs vs live, audits. No GCP setup.

The publisher's own server: QuickBooks Connector by Meridian

VerifiedSTDIODesktop onlyDeveloper ToolsData & Analytics

Overview

AI-generated overview

Read-only Google Tag Manager access for an assistant: browse containers, tags, triggers and variables, diff workspaces against live, and audit a container.

What you can do
  • List accounts, containers, workspaces and versions, and read the live published version
  • Inspect a container's tags, triggers, variables, templates, folders and built-in variables, or one entity in full
  • Trace what uses a variable, trigger, tag or template
  • Diff a workspace against the live version to see what publishing would change
  • Run a Tag Pilot health audit flagging tags that can never fire, duplicate Google tags, missing consent settings and unused entities
  • Connect this computer and check connection status
When to use it
Useful when you want to ask questions about an existing GTM setup in plain language — which tags fire on which triggers, how a variable is configured, what is unpublished in a workspace, or what a container audit flags — without clicking through the GTM interface.
Requirements
Runs locally via npx, so Node.js 18 or newer is needed (the Claude Desktop extension does not). No GCP project, OAuth client or API key is required: the first request starts a browser sign-in to a free Tag Pilot account plus read-only Google Tag Manager consent. Optional TAGPILOT_API_KEY (a gtm:mcp key) for headless or CI use, and optional variables such as GTM_MCP_NO_BROWSER and GTM_MCP_AUTH_WAIT_SECONDS.
Before you install
Read-only: the only Google scope requested is tagmanager.readonly and the server sends GET requests only. Sign-in goes through Tag Pilot, which brokers the Google token exchange; the README says Tag Manager data goes directly from your machine to Google and that Tag Pilot stores no Google tokens. Credentials are kept locally in a config directory. A TAGPILOT_API_KEY is a secret and should not be committed or shared. Rate limits and a daily quota apply.

Installation

In SourceWeft

  1. Open Tag Pilot GTM in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

Tag Pilot GTM MCP

A free, read-only Model Context Protocol server for Google Tag Manager. Ask Claude, Cursor or any MCP client about your GTM containers: which tags fire on which triggers, how a variable is set up and what uses it, what publishing a workspace would change, the version history, and a Tag Pilot audit of the container.

No Google Cloud setup, no API key to copy. You don't need a GCP project, OAuth client, service account or gcloud. Add the server, ask a question, and approve once in your browser.

bash
claude mcp add gtm -- npx -y @tagpilot/gtm-mcp

Get started

  1. Install in your AI client (below). No configuration needed.
  2. Ask something, e.g. "Audit my GTM container GTM-ABC1234" or "What changes in the Default Workspace aren't published yet?" The first time, a browser window opens (or your AI shows a link and a code like ABCD-1234):
    • sign in to your free Tag Pilot account, or create one;
    • check that the code matches and approve this computer;
    • sign in with the Google account that can see your Tag Manager containers and allow read-only Tag Manager access.
  3. Ask again. You're connected; the computer shows up under Connected devices on the GTM MCP page.

Already use the Tag Pilot GA4 MCP or Search Console MCP? This is a separate server with its own connection (and its own Google consent), so you can install any of them.

Install

[Add to Cursor] [Install in VS Code]

ClientHow
Claude DesktopDownload the extension and open it (no Node.js needed)
Claude Codeclaude mcp add gtm -- npx -y @tagpilot/gtm-mcp
CursorAdd to Cursor, or the mcp.json below
VS CodeInstall in VS Code
Windsurf, Zed, …command npx, args ["-y", "@tagpilot/gtm-mcp"] (stdio)
Gemini CLIclone the repo, then gemini extensions install ./ga4-mcp/packages/gtm-mcp

Everything except the Claude Desktop extension runs the npm package with npx, so it needs Node.js 18 or newer. In the MCP Registry it's io.github.tagpilot/gtm-mcp.

Claude Desktop config file (claude_desktop_config.json), Cursor (~/.cursor/mcp.json) and similar clients:

json
{  "mcpServers": {    "gtm": {      "command": "npx",      "args": ["-y", "@tagpilot/gtm-mcp"]    }  }}

Headless and CI: where nobody can approve in a browser, create a gtm:mcp key on the GTM MCP page and set TAGPILOT_API_KEY=tpk_… in the server's environment. The device connect is then skipped and only the Google sign-in link is shown.

How connecting works, and what Tag Pilot sees

The same flow as the GA4 MCP (RFC 8628-style device connect, like gh auth login): it works from any browser on any device, also over SSH, in containers or WSL, because nothing listens on your machine.

  • Your Tag Manager data goes from your machine straight to Google (tagmanager.googleapis.com). It never passes through Tag Pilot.
  • Tag Pilot only brokers the token exchange. It adds Tag Pilot's Google OAuth client credentials to Google's token endpoint and returns Google's answer. It stores no Google tokens and never logs them; it holds the one-time sign-in code for at most 10 minutes, and that code is useless without the PKCE verifier that stays on your machine.
  • Read-only. The only Google scope requested is tagmanager.readonly. None of the tools can create, change, publish or delete anything, and the server only sends GET requests.
  • Your credentials stay on your machine, in ~/.config/tagpilot/gtm-mcp/device.json (readable only by you).
  • Disconnecting: revoke the device on the GTM MCP page, run npx -y @tagpilot/gtm-mcp logout, and remove the app's access at myaccount.google.com/permissions.

Tools

All tools are read-only. container_id is the numeric container ID from list_containers; the public ID (GTM-XXXXXXX) works too. Tools that read container contents read the live (published) version by default; pass workspace_id (from list_workspaces) for a workspace with its unpublished changes, or version_id (from list_versions) for an older version.

ToolWhat it does
list_accountsTag Manager accounts you can read. Start here.
list_containersContainers in an account: ID, public ID, name, usage context (web, server, …), domains.
list_workspacesWorkspaces of a container.
get_containerTags (with firing/blocking triggers by name, paused state), triggers, variables, custom templates, folders and built-in variables; clients and transformations of server containers. Compact by default; detail: "full" returns every entity body.
get_tag / get_trigger / get_variableOne entity in full, by id or name: parameters, conditions, consent settings, sequencing, the variables it uses and what uses it. Built-in variables (Page URL) by name.
find_referencesWhat uses a variable ({{Name}} anywhere), trigger (firing, blocking, trigger groups), tag (sequencing), custom template or folder.
list_versionsVersions, newest first, with entity counts and which one is live.
get_live_versionThe published version: name, description and contents.
diffWorkspace vs the live version (or another version): entities added, changed (with the changed fields and renames; include_values for before/after) and deleted.
audit_containerTag Pilot check (below).
connectConnects this computer: returns a link and a code for you to approve in the browser (your AI shows them; clients that support MCP URL elicitation offer to open the link). Say "connect my GTM" to start it explicitly.
connection_statusConnected (with the device name), waiting for approval (link and code again), not connected, or what went wrong. Waits up to 25 s for an open sign-in to finish.

audit_container

Offline checks over one read of the container. They are rules of thumb, not GTM errors:

CheckSeverityWhat it flags
missing_triggershighTags, trigger groups or variables pointing at triggers that don't exist.
duplicate_google_tagshighA Google tag (googtag) or GA4 configuration ID loaded by more than one active tag: double page views if they fire on the same page.
tags_without_triggersmediumActive tags with no firing trigger that aren't fired by tag sequencing.
tags_without_consent_settingsmediumWeb containers: active non-Google tags with consent settings "Not set". Google tags are skipped (built-in consent checks).
unpublished_changesinfoWorkspace audits: changes not live yet (or a container that was never published).
unused_triggers / unused_variableslowNot used by any tag, trigger or variable. Code reading variables through google_tag_manager[…] isn't detected.
expired_scheduleslowTags whose schedule ended.
paused_tagsinfoPaused tags.

Rate limits and caching

The Tag Manager API allows only a few requests per second per user and has a daily quota, so the server is frugal:

  • a container version (live or numbered) is one request; a workspace is one list request per entity kind (tags, triggers, variables, built-ins, templates, folders, plus clients and transformations for server containers), never one request per tag;
  • get_tag, get_trigger, get_variable, find_references and audit_container reuse the same read, which is cached for a minute (numbered versions for 30 minutes);
  • rate-limit errors (429, or 403 with a quota reason) and server errors are retried with backoff.

Workspace reads skip zones (Tag Manager 360); version reads include them.

Troubleshooting

"Not connected yet" (a link and a code like ABCD-1234): your AI shows them. Open the link in any browser (it doesn't have to be on this machine), sign in to Tag Pilot, check that the code matches, approve, and allow Tag Manager access, then tell your AI you're done: it retries your question (or calls connection_status). The server keeps checking in the background, so nothing needs restarting. The code is valid for 10 minutes; after that, ask again (or say "connect GTM") for a new one. To connect from a terminal instead (e.g. over SSH), run npx -y @tagpilot/gtm-mcp login: it shows the link, the code in a box and a countdown, and waits until you approve.

"The signed-in Google account has no access to …": use list_accounts and list_containers to see what it can read. To use another Google account, run npx -y @tagpilot/gtm-mcp logout and connect again.

"… has no live (published) version": the container was never published; pass workspace_id.

"This computer was disconnected from Tag Pilot": the device was revoked; ask again to reconnect. "Your Google sign-in expired or was revoked": ask again and approve again.

Rate limit or quota errors: wait a minute and ask again.

Check the setup: npx -y @tagpilot/gtm-mcp status. Logs go to stderr.

Configuration

Nothing is required. All variables are optional:

Variable
TAGPILOT_API_KEYA gtm:mcp key for headless/CI setups. Skips the device connect.
TAGPILOT_API_URLTag Pilot API base URL. Default https://api.tagpilot.io.
GTM_MCP_NO_BROWSER1 to only print/return the link instead of opening a browser.
GTM_MCP_BROWSERBrowser to open (macOS app name, or a command on Linux/Windows).
GTM_MCP_AUTH_WAIT_SECONDSHow long a tool call waits for the connect before returning the link. Default 45.
GTM_MCP_CONFIG_DIRCredential directory. Default ~/.config/tagpilot/gtm-mcp.

Commands: npx -y @tagpilot/gtm-mcp [serve|login|logout|status|--help|--version].

Development

See the repo README. GTM_MCP_TAGMANAGER_API_URL points the Google calls at a mock (used by npm run e2e).

License

Apache License 2.0. Copyright 2026 Tag Concierge sp. z o.o. The license does not cover the Tag Pilot name or logo (see NOTICE).

Source: packages/gtm-mcp/README.md at commit 34078fa

Tools

14

list_accounts

List Tag Manager accounts

Lists the Google Tag Manager accounts the signed-in Google account can read, with their numeric IDs. Start here.

Takes no parameters.

list_containers

List containers

Containers in a Tag Manager account: numeric container ID, public ID (GTM-XXXXXXX), name, usage context (web, server, amp, ios, android) and domains.

Parametersaccount_idrequired

list_workspaces

List workspaces

Workspaces of a container (where unpublished changes are made), with IDs and descriptions. Pass workspace_id to the other tools to read a workspace instead of the live version.

Parametersaccount_idrequiredcontainer_idrequired

get_container

Get container contents

Everything in a container: tags (with their firing and blocking triggers by name, paused state), triggers, variables, custom templates, folders and enabled built-in variables; clients and transformations for server containers. Reads the live (published) version by default, or a workspace (workspace_id) or an older version (version_id). Compact by default; use get_tag / get_trigger / get_variable for one entity in full.

Parametersdetailaccount_idrequiredversion_idcontainer_idrequiredworkspace_id

list_versions

List container versions

Container versions, newest first: version ID, name, entity counts, and which one is live (published). Pass a version_id to get_container, diff or the get_* tools to read an older version.

Parameterslimitaccount_idrequiredcontainer_idrequiredinclude_deleted

get_live_version

Get the live (published) version

The container version that is live on the site: version ID, name, description, and its contents (compact by default, like get_container).

Parametersdetailaccount_idrequiredcontainer_idrequired

get_tag

Get one tag

One tag in full (by id or name): type, parameters, firing and blocking triggers (with names), consent settings, tag sequencing, firing option, schedule, notes, and the variables it uses. Reads the live version unless workspace_id or version_id is given.

Parametersidnameaccount_idrequiredversion_idcontainer_idrequiredworkspace_id

get_trigger

Get one trigger

One trigger in full (by id or name): type, conditions (filter, customEventFilter, autoEventFilter), parameters, the variables it uses, and the tags, trigger groups and variables that use it. Reads the live version unless workspace_id or version_id is given.

Parametersidnameaccount_idrequiredversion_idcontainer_idrequiredworkspace_id

get_variable

Get one variable

One variable in full (by id or name; built-in variables such as "Page URL" by name): type, parameters, format settings, the variables it uses, and the tags, triggers and variables that use it. Reads the live version unless workspace_id or version_id is given.

Parametersidnameaccount_idrequiredversion_idcontainer_idrequiredworkspace_id

find_references

Find references

What uses an entity: for a variable (or built-in variable), every tag, trigger, variable or client containing {{Name}}; for a trigger, the tags that fire on or are blocked by it, trigger groups and variables; for a tag, tags that sequence it; for a custom template, the tags, variables and clients built from it; for a folder, its contents. Check this before suggesting to change, rename or delete something.

Parametersidkindrequirednameaccount_idrequiredversion_idcontainer_idrequiredworkspace_id

diff

Diff a workspace against the live version

What publishing a workspace would change: entities added, changed (with the changed fields, and renames) and deleted compared with the live version (or another version_id). Compares the actual contents, so it also shows changes that reached the live version after the workspace was created (the workspace then needs updating in GTM). Set include_values for the before/after values of changed fields.

Parametersaccount_idrequiredversion_idcontainer_idrequiredworkspace_idrequiredinclude_values

audit_container

Tag Pilot check: container audit

Tag Pilot tracking-health check for a GTM container. Flags tags that can never fire (no triggers, missing triggers, expired schedules), paused tags, unused triggers and variables, non-Google tags without consent settings (web containers), Google tag / GA4 configuration IDs loaded by more than one tag (double counting), and, for a workspace, changes that are not published yet. Reads the live version by default; pass workspace_id to audit a workspace (one extra call for the live version). Findings are sorted high → info.

Parametersaccount_idrequiredversion_idcontainer_idrequiredworkspace_id

connect

Connect GTM MCP

Connects this computer to Tag Pilot GTM MCP (free Tag Pilot account + read-only Google Tag Manager access). Call it when the user asks to connect, or when another tool says the computer is not connected. It returns a link and a code: show both to the user as given (a clickable link), ask them to open it, approve and allow Google access, and tell you when done; then call connection_status. Never ask the user to run terminal commands. If already connected, it says so.

Takes no parameters.

connection_status

GTM MCP connection status

Whether this computer is connected to Tag Pilot GTM MCP: "connected" (with the device name), "waiting" (a sign-in link is open; shows the link and code again), "not_connected" (call connect) or "error" (with the next step). While a sign-in is open it waits up to 25 seconds for the approval before answering, so call it after the user says they approved, not in a fast loop.

Parameterswait

Version history

1
  1. v0.1.0LatestNov 14, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

Other Pilot integrations