关于 samarth-gtm-mcp
samarth-gtm-mcp 是面向分析团队的开源 MCP 服务,连接 Google Tag Manager 与 GA4,涵盖容器管理、报告和实施审计。默认只读,写入操作须单独启用并确认,也支持模拟写入。
主要功能
- 01覆盖 GTM API v2
- 02提供 GA4 管理与数据报告
- 03自动分页并重试读取请求
- 04审计 GTM 与 GA4 实施
- 05写入需启用并确认
- 06支持写入模拟
适用场景
- 01检查 GTM 容器配置
- 02生成 GA4 数据报告
- 03审计标签与分析实现
- 04在模拟模式下预览更改
MCP 相关
该 MCP 服务向客户端提供 Google Tag Manager 和 GA4 工具,并支持本地 stdio 与 Streamable HTTP。还提供可托管的只读社区实例。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y samarth-gtm-mcpGOOGLE_OAUTH_CLIENT_ID密钥Your Google OAuth 2.0 client ID (Desktop app type)GOOGLE_OAUTH_CLIENT_SECRET密钥Your Google OAuth 2.0 client secretGTM_MCP_ENABLE_WRITESSet to 'true' to allow create/update operations (default: read-only)GTM_MCP_ENABLE_PUBLISHSet to 'true' to allow publish operations (default: disabled)GTM_MCP_ENABLE_DELETESSet to 'true' to allow delete operations (default: disabled)本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
107收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| includeGoogleTags | boolean | 否 | 也包含 Google Tags 账户的结果。 |
详细介绍
Samarth Analytics MCP
一款开源的 Model Context Protocol (MCP) 服务,可让 Claude Desktop、Claude Code 和 Cursor 等 AI 助手使用 Google Tag Manager 和 GA4。它涵盖完整的 GTM API v2 功能(100 多种工具,包括服务端容器)、GA4 Admin 和 Data API、内置的实施审计,以及另一个用于抓取网站并检查其标签和 Consent Mode v2 设置的服务。由 Samarth Analytics 为我们自己的客户项目开发,并以 MIT 许可证向分析社区发布。
默认只读。 创建、更新、发布和删除操作分别受独立的环境标志控制,每次写入还必须设置 confirm=true,而试运行模式可在不调用 API 的情况下模拟写入。请参阅安全防护。
使用风险自负,并从虚拟容器开始。 该服务使用你的 Google 凭据执行操作,因此它所做的每项更改都由你负责。请先在沙盒 GTM 容器和测试 GA4 媒体资源中试用,在观察其行为之前保持写入标志关闭,并在每次写入操作后检查容器的版本历史记录。我们在生产环境中使用它,但你的环境与我们不同。
三种使用方式
| 你将获得什么 | 从哪里开始 | |
|---|---|---|
| 托管,无需安装 | 我们的社区实例:https://mcp.samarthanalytics.com/mcp。使用你自己的 Google 账号登录;它只能访问你的容器和媒体资源,并且仅允许只读操作。共享服务,尽力提供支持,不承诺正常运行时间。 | 使用 mcp-remote 将其添加到你的 MCP 客户端:{"mcpServers":{"samarth-gtm":{"command":"npx","args":["mcp-remote@next","https://mcp.samarthanalytics.com/mcp"]}}} |
| 本地 | 在你的计算机上通过 stdio 运行服务,使用你自己的 Google OAuth 客户端,并由你控制写入标志。 | 快速入门和 Google Cloud OAuth 设置 |
| 自托管 | MCP 服务、网站审计服务和采集工作器作为一个 docker-compose 堆栈运行,并由你自己的令牌保护。 | docs/SELF_HOSTING_DOCKER.md 和云部署 |
仓库还附带 Samarth Desktop,这是一款内置聊天界面的本地 Electron 应用,其中集成了此服务(快速入门);此外还提供基于浏览器的客户门户 apps/portal/,用于运行实时只读 QC 审计。
欢迎贡献。 附有可复现容器配置的 Bug 报告最有帮助。请先阅读 CONTRIBUTING.md;每次拉取请求都会触发 CI。
目录
功能
- 完整的 GTM API v2 功能 — 账号、容器、工作区、标签、触发器、变量、文件夹、内置变量、版本、同步、发布、预览
- 服务端与高级 GTM 功能 — 环境、用户权限、目标位置、客户端、转换、区域、自定义模板、gtag 配置,以及容器代码片段/查找/合并/移动标签 ID 和工作区变更差异状态
- GA4 功能 — GA4 管理工具(
ga4_*)以及用于核对意图与实际情况的 GA4 Data API 报告(ga4_run_report、ga4_run_realtime_report)。读取和报告仅需analytics.readonly;GA4 管理写入工具默认关闭,由GA4_MCP_ENABLE_WRITES/GA4_MCP_ENABLE_DELETES控制,且还需要analytics.edit - 自动分页 — 所有分页列表工具都会透明地跟进
nextPageToken,返回所有结果,并可选用maxPages/pageToken设置范围 - 指数退避重试并加入抖动 — 读取请求遇到暂时性 Google API 故障(HTTP 408/429/5xx、网络错误)时会自动重试;变更操作绝不会自动重试(可通过
GTM_MCP_RETRY_*调整) - 两种传输模式:stdio(本地,用于 Claude Desktop/Cursor)和 Streamable HTTP(云端/团队)
- 默认启用防护措施:除非明确启用,否则为只读;发布和删除分别设有门控
- 试运行模式:模拟所有写入操作,不会调用 API
- 所有写入/删除/发布操作都必须设置
confirm=true - 审计工具:检查工作区中常见的 GA4/GTM 实现问题
- 导出工具:将完整工作区转储为结构化 JSON
- 对所有输入进行 Zod 架构验证
- 向 MCP 客户端显示详细的 Google API 错误消息
快速开始
运行 Samarth 的方式是使用桌面应用——一款本地 Electron 应用,带有聊天界面,并在进程内嵌入 MCP 服务。支持多个 Google 账号登录、每个账号单独设置大模型密钥(OpenAI / Anthropic / Gemini),并将密钥保存在操作系统的钥匙串中。无需手动配置:首次运行时,在应用中输入 Google OAuth 客户端和大模型密钥即可。
你需要: Node.js 18 或更高版本、Git,以及一个免费的 Google“桌面应用”OAuth 客户端——在 Google Cloud 项目中创建一次即可获得两个值(逐步操作说明)。
git clone https://github.com/samarthanalytics-sj/samarth-analytics-mcp.git
cd samarth-analytics-mcp/apps/desktop
npm install # downloads the Electron binary (~100 MB first time)
npm run dev
窗口打开后,按提示粘贴 OAuth 客户端 ID 和密钥以及大模型 API 密钥,登录 Google,即可开始与 GTM / GA4 配置聊天。
更愿意使用配置文件,而不是在应用中输入? 将 OAuth 客户端信息放入 .env 文件——应用启动时会读取该文件(在应用中输入的值和真实的 shell 变量始终优先):
GOOGLE_DESKTOP_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_DESKTOP_CLIENT_SECRET=your-client-secret
将其保存为 apps/desktop/.env 或放在仓库根目录(该文件已加入 gitignore,切勿提交)。使用服务端 GOOGLE_OAUTH_CLIENT_ID / GOOGLE_OAUTH_CLIENT_SECRET 名称的仓库根目录 .env 也同样适用,因此一个文件即可供应用和 MCP 服务共用。打包后的安装程序则会从其数据目录读取 .env(Windows 上为 %APPDATA%)。
之后,日常启动只需运行:
cd samarth-analytics-mcp/apps/desktop && npm run dev
完整指南涵盖 Windows/macOS 相关说明、首次运行设置、构建真正的 .exe / .dmg 安装程序,以及 Error: Electron uninstall 修复方法:
apps/desktop/INSTALL.md。
Google Cloud OAuth 设置
步骤 1:启用 GTM API
- 前往 Google Cloud Console
- 选择或创建一个项目
- 前往 APIs & Services → Library
- 搜索 “Tag Manager API”,然后点击 Enable
- 搜索 “Google Analytics Admin API”,然后点击 Enable(只读
ga4_*管理工具必需) - 搜索 “Google Analytics Data API”,然后点击 Enable(
ga4_run_report/ga4_run_realtime_report必需)
步骤 2:创建 OAuth 2.0 凭据
- 前往 API 和服务 → 凭据
- 点击 创建凭据 → OAuth 2.0 客户端 ID
- 选择应用类型:
- 桌面应用 — 最适合本地 stdio 使用(无需重定向 URI)
- Web 应用 — 用于 HTTP 服务(添加重定向 URI)
- 下载 JSON,或复制 客户端 ID 和 客户端密钥
- 添加到
.env:GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com GOOGLE_CLIENT_SECRET=your-client-secret GOOGLE_REDIRECT_URI=http://localhost:3001/oauth/callback
步骤 3:配置 OAuth 同意屏幕
- 前往 API 和服务 → OAuth 同意屏幕
- 选择 外部(如果你使用 Google Workspace,也可以选择“内部”)
- 填写应用名称和支持邮箱
- 添加范围:
https://www.googleapis.com/auth/tagmanager.readonlyhttps://www.googleapis.com/auth/tagmanager.edit.containershttps://www.googleapis.com/auth/tagmanager.edit.containerversionshttps://www.googleapis.com/auth/tagmanager.manage.accountshttps://www.googleapis.com/auth/tagmanager.manage.usershttps://www.googleapis.com/auth/tagmanager.publishhttps://www.googleapis.com/auth/analytics.readonly(GA4 Admin 和 Data API 工具的只读权限)https://www.googleapis.com/auth/analytics.edit(GA4 Admin 写入工具 — 由GA4_MCP_ENABLE_WRITES控制)https://www.googleapis.com/auth/analytics.manage.users(GA4 访问权限绑定写入工具)
- 将你的 Google 账号添加为测试用户(应用处于“测试”模式时)
注意:个人或代理机构使用时,将应用保持在“测试”模式即可。除非你发布应用或通过验证,否则每 7 天都需要重新授权。
步骤 4:运行 OAuth 设置
npm run auth:google
或者,如果你更喜欢旧版的粘贴代码辅助程序:
npm run oauth:setup
服务账号限制
简而言之:服务账号默认无法与 GTM 搭配使用。请使用 OAuth 2.0。
Google Tag Manager API 是一个用户数据 API — 它管理由个人 Google 账号拥有的资源。服务账号不是 Google 用户,也不会自动获得 GTM 容器的访问权限。
选项 A:将服务账号添加为 GTM 用户(最简单)
如果你仍想使用服务账号:
- 获取服务账号邮箱(例如,
[email protected]) - 在 GTM 中,前往账号或容器级别的 管理 → 用户管理
- 添加服务账号邮箱,并授予相应角色(读取、编辑、批准、发布)
- 在
.env中设置GOOGLE_SERVICE_ACCOUNT_KEY_FILE=/path/to/key.json
注意事项:仅当 GTM 容器关联的是 Google 账号,而非限制外部共享的 Google Workspace 时,此方法才有效。
选项 B:全网域委派(仅限 Google Workspace)
适用于 Google Workspace 组织:
- 创建带有 JSON 密钥的服务账号
- 在 Google Cloud Console 中为该服务账号启用全网域委派
- 在 Google Workspace 管理控制台 → 安全性 → API 控制 → 全网域委派中:
- 添加服务账号客户端 ID
- 添加范围:
https://www.googleapis.com/auth/tagmanager.edit.containers(以及所需的其他范围)
- 在
.env中设置:GOOGLE_SERVICE_ACCOUNT_KEY_FILE=/path/to/key.json - 如果在
buildGoogleAuth()中设置了 subject,服务将自动模拟该用户
注意事项:需要付费的 Google Workspace 账号。仅适用于你自己的网域。
环境变量参考
| 变量 | 默认值 | 描述 |
|---|---|---|
GOOGLE_OAUTH_CLIENT_ID | — | OAuth 客户端 ID(优先使用)。未设置时回退到 GOOGLE_CLIENT_ID。 |
GOOGLE_OAUTH_CLIENT_SECRET | — | OAuth 客户端密钥(优先使用)。未设置时回退到 GOOGLE_CLIENT_SECRET。 |
GOOGLE_OAUTH_REDIRECT_URI | http://localhost:3001/oauth/callback | OAuth 重定向 URI。未设置时回退到 GOOGLE_REDIRECT_URI。 |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET / GOOGLE_REDIRECT_URI | — | 旧版名称,仍受支持。 |
SAMARTH_GOOGLE_OAUTH_CLIENT_ID | — | 仅托管版使用。 Samarth 所有的公共 OAuth 客户端。设置后优先于可自托管版变量。 |
SAMARTH_GOOGLE_OAUTH_CLIENT_SECRET | — | 仅托管版使用。 从平台密钥管理器注入。切勿提交。 |
GOOGLE_ACCESS_TOKEN | — | 当前 OAuth 访问令牌。环境变量的优先级高于令牌文件。 |
GOOGLE_REFRESH_TOKEN | — | OAuth 刷新令牌(长期有效)。环境变量的优先级高于令牌文件。 |
GTM_MCP_TOKEN_FILE | ./.gtm-mcp-tokens.json | npm run auth:google 写入的本地 OAuth 令牌文件路径(已加入 gitignore)。 |
GOOGLE_SERVICE_ACCOUNT_KEY_FILE | — | 服务账号 JSON 密钥文件路径(参见上文限制) |
GTM_MCP_TRANSPORT | stdio | 传输方式:stdio 或 http |
GTM_MCP_HTTP_PORT | 3001 | HTTP 服务端口(仅限 http 传输;未设置时回退到 PORT) |
GTM_MCP_HTTP_AUTH_TOKEN | — | 用于限制对 /mcp 的访问的 Bearer 令牌(http 传输)。若此变量和 STYTCH_PROJECT_ID 均未设置,HTTP 传输将拒绝启动。 |
GTM_MCP_HTTP_ALLOW_UNAUTHENTICATED | false | 本地开发时选择在无身份验证的情况下启动。除非 GTM_MCP_HTTP_HOST 覆盖此设置,否则仅绑定到环回地址。 |
GTM_MCP_HTTP_HOST | — | 绑定主机。未启用身份验证时默认为环回地址,启用身份验证时绑定到所有网络接口。 |
STYTCH_PROJECT_ID | — | 设置此变量会将 HTTP 传输切换到多用户模式:每个 /mcp 请求都携带一个 Stytch JWT,并解析为该用户自己的 Google 身份。未设置 = 单一身份模式。仅接受 Connected App 访问令牌(必须包含 client_id,拒绝会话 JWT),且颁发者和受众始终固定:STYTCH_JWT_ISSUER / STYTCH_JWT_AUDIENCE 默认分别为 stytch.com/<project id> / <project id>(参见 .env.example)。 |
STYTCH_SECRET | — | Stytch 项目密钥(仅限服务端)。设置了 STYTCH_PROJECT_ID 时必须设置此变量,否则服务端将退出。 |
STYTCH_PUBLIC_TOKEN | — | 为 /oauth/authorize 页面提供支持的可公开令牌。不是密钥。 |
GTM_MCP_PUBLIC_URL | http://localhost:<port> | 此服务的公共源地址,会在 OAuth 受保护资源元数据文档中公布。 |
GTM_MCP_ENABLE_WRITES | false | 允许创建和更新操作 |
GTM_MCP_ENABLE_PUBLISH | false | 允许发布操作 |
GTM_MCP_ENABLE_DELETES | false | 允许删除操作 |
DRY_RUN | false | 模拟所有写入操作,不调用 API |
GTM_MCP_RETRY_MAX | 3 | 临时读取失败(408/429/5xx、网络错误)的重试次数。0 表示禁用重试。绝不自动重试变更操作。 |
GTM_MCP_RETRY_MAX_DELAY_MS | 30000 | 单次退避等待的上限(带抖动的指数退避) |
GTM_MCP_RETRY_TOTAL_TIMEOUT_MS | 60000 | 从首次请求到最后一次重试的总耗时上限 |
防护机制
除了 confirm=true 要求外,服务还会实施三项相互独立的防护机制:
| 防护机制 | 环境变量 | 控制范围 |
|---|---|---|
| 写入防护 | GTM_MCP_ENABLE_WRITES=true | 所有 create 和 update 操作 |
| 删除防护 | GTM_MCP_ENABLE_DELETES=true | 所有 delete 操作 |
| 发布防护 | GTM_MCP_ENABLE_PUBLISH=true | 所有版本发布操作 |
| 试运行 | DRY_RUN=true | 模拟操作,不调用 API(覆盖所有防护机制) |
无论环境设置如何,写入、删除和发布工具始终都要求 confirm=true。即使启用了防护机制,这也能防止意外修改。
推荐配置
只读探索(默认设置,适合安全地与团队共享):
GTM_MCP_ENABLE_WRITES=false
GTM_MCP_ENABLE_PUBLISH=false
GTM_MCP_ENABLE_DELETES=false
开发工作区编辑(不发布):
GTM_MCP_ENABLE_WRITES=true
GTM_MCP_ENABLE_PUBLISH=false
GTM_MCP_ENABLE_DELETES=false
完全访问(请谨慎使用):
GTM_MCP_ENABLE_WRITES=true
GTM_MCP_ENABLE_PUBLISH=true
GTM_MCP_ENABLE_DELETES=true
可用工具
账号
| 工具 | 描述 |
|---|---|
accounts_list | 列出所有可访问的 GTM 账号 |
accounts_get | 获取指定账号 |
容器
| 工具 | 描述 |
|---|---|
containers_list | 列出账号中的容器(自动分页) |
containers_get | 获取指定容器 |
containers_create | ✏️ 创建新容器 |
containers_snippet | 获取容器的 GTM 安装代码片段 |
containers_lookup | 根据关联的目标位置/标签 ID 查找容器(例如 G-XXXX) |
containers_combine | ✏️ 将另一个容器合并到此容器中 |
containers_move_tag_id | ✏️ 将 Tag ID 移出并放入新容器 |
目标位置
| 工具 | 描述 |
|---|---|
destinations_list | 列出容器关联的目标位置(Google 标签/GA4) |
destinations_get | 获取指定目标位置 |
destinations_link | ✏️ 将目标位置关联到容器 |
工作区
| 工具 | 描述 |
|---|---|
workspaces_list | 列出容器中的工作区(自动分页) |
workspaces_get | 获取指定工作区 |
workspaces_create | ✏️ 创建新工作区 |
workspace_get_status | 在创建版本前查看变更差异(已变更实体和合并冲突) |
workspace_sync | ✏️ 将工作区同步到最新容器版本 |
workspace_resolve_conflict | ✏️ 解决合并冲突 |
workspace_quick_preview | 生成预览链接(只读安全) |
workspace_create_version_and_publish | 🚀 一步创建版本并发布 |
标签
| 工具 | 描述 |
|---|---|
tags_list | 列出工作区中的所有标签 |
tags_get | 获取指定标签 |
tags_create | ✏️ 创建标签 |
tags_update | ✏️ 更新标签 |
tags_delete | 🗑️ 删除标签 |
触发器
| 工具 | 描述 |
|---|---|
triggers_list | 列出所有触发器 |
triggers_get | 获取指定触发器 |
triggers_create | ✏️ 创建触发器 |
triggers_update | ✏️ 更新触发器 |
triggers_delete | 🗑️ 删除触发器 |
变量
| 工具 | 描述 |
|---|---|
variables_list | 列出所有用户定义的变量 |
variables_get | 获取指定变量 |
variables_create | ✏️ 创建变量 |
variables_update | ✏️ 更新变量 |
variables_delete | 🗑️ 删除变量 |
文件夹
| 工具 | 描述 |
|---|---|
folders_list | 列出所有文件夹 |
folders_get | 获取指定文件夹 |
folders_entities | 列出文件夹中的实体(自动分页) |
folders_create | ✏️ 创建文件夹 |
folders_update | ✏️ 更新文件夹 |
folders_delete | 🗑️ 删除文件夹 |
folders_move_entities | ✏️ 将实体移入文件夹 |
内置变量
| 工具 | 描述 |
|---|---|
built_in_variables_list | 列出已启用的内置变量 |
built_in_variables_enable | ✏️ 启用内置变量 |
built_in_variables_disable | 🗑️ 禁用内置变量 |
built_in_variables_revert | ✏️ 将内置变量还原为基础版本 |
版本
| 工具 | 描述 |
|---|---|
versions_list | 列出版本标题 |
versions_get | 获取某个版本(传入 "live" 可获取当前线上版本) |
versions_create | ✏️ 从工作区创建检查点版本 |
versions_set_latest | ✏️ 将某个版本设为最新版本 |
versions_publish | 🚀 发布指定版本 |
versions_undelete | ✏️ 恢复已删除的版本 |
versions_delete | 🗑️ 删除版本 |
环境
| 工具 | 描述 |
|---|---|
environments_list | 列出容器中的环境(自动分页) |
environments_get | 获取指定环境 |
environments_create | ✏️ 创建环境 |
environments_update | ✏️ 更新环境 |
environments_reauthorize | 🚀 重新生成环境授权令牌(影响重大) |
environments_delete | 🗑️ 删除环境 |
用户权限(账户级)
| 工具 | 描述 |
|---|---|
user_permissions_list | 列出账户的用户权限(自动分页) |
user_permissions_get | 获取指定用户权限 |
user_permissions_create | ✏️ 授予用户对账户/容器的访问权限 |
user_permissions_update | ✏️ 更新用户的访问级别 |
user_permissions_delete | 🗑️ 撤销用户的访问权限 |
服务器端和高级容器资源
这些是来自 GTM API v2、作用域为工作区的资源。由于请求体嵌套层级较深,创建/更新操作需要以 JSON 字符串(bodyJson)形式传入完整资源。每种资源都支持 *_list(自动分页)、*_get、*_create ✏️、*_update ✏️、*_delete 🗑️,以及(gtag_config 除外)*_revert ✏️。
| 资源 | 工具 | 备注 |
|---|---|---|
| 客户端 | clients_* | 服务器容器请求客户端 |
| 转换 | transformations_* | 服务器容器事件转换 |
| 区域 | zones_* | 区域委派 |
| 模板 | templates_* | 自定义/从图库安装的模板 |
| Gtag 配置 | gtag_config_* | Google tag(gtag)配置 — 不支持 revert |
分析与导出
| 工具 | 描述 |
|---|---|
audit_container | 检查工作区中的分析问题 |
export_container | 将工作区导出为结构化 JSON |
GA4 管理(只读)
基于 Google Analytics Admin API(v1beta)的只读封装(增强型衡量功能使用一次 v1alpha 调用)。这些工具不会写入、更新或删除 GA4 资源,也不需要 confirm 标志。它们为高级审计框架中的 GA4_ADMIN 检查提供支持(自定义维度/指标、数据流和衡量 ID、数据保留期限、增强型衡量、关键事件、Google Ads 链接)。
需要 https://www.googleapis.com/auth/analytics.readonly 范围,并且必须在 Google Cloud 项目中启用 Google Analytics Admin API。如果 403 错误提到范围,请重新运行 npm run auth:google。
| 工具 | 描述 |
|---|---|
ga4_account_summaries_list | 列出 GA4 账号及其媒体资源摘要(最佳发现入口) |
ga4_properties_list | 列出父账号下的媒体资源(显示名称、时区、货币、服务级别) |
ga4_property_get | 按 ID 获取单个媒体资源 |
ga4_data_streams_list | 列出数据流(Web/Android/iOS),包括 Web 衡量 ID |
ga4_enhanced_measurement_get | 获取 Web 数据流的增强型衡量设置(v1alpha) |
ga4_custom_dimensions_list | 列出自定义维度(参数、范围) |
ga4_custom_metrics_list | 列出自定义指标(参数、单位、范围) |
ga4_data_retention_get | 获取事件数据保留设置 |
ga4_key_events_list | 列出关键事件(以前称为“转化事件”——这是当前 Admin 命名) |
ga4_google_ads_links_list | 列出 Google Ads 链接(客户 ID、自动标记/广告个性化标志) |
凡是需要媒体资源或账号的地方,均可使用纯数字 ID(123456789)或完整限定格式(properties/123456789、accounts/123456)。
已知限制(GA4 Admin API v1beta 未提供,因而有意不实现,而非伪造):
- 内部流量/不需要的引荐来源数据过滤器——没有公开的
dataFilters集合;按数据流配置。 - 引荐排除项——没有专用的 Admin API 资源。
- 渠道组和受众群体——仅存在于 v1alpha 接口,不在此只读 v1beta 范围内。
GA4 Data API(只读报告)
基于 Google Analytics Data API(v1beta)的只读封装。它们不会写入数据,也不需要 confirm 标志。可用它们核对意图与实际情况——将容器配置为发送的事件与 GA4 实际报告的事件进行比较(已配置事件的报告活动为零是一个警示信号)。
这些工具与 GA4 Admin 工具使用相同的 https://www.googleapis.com/auth/analytics.readonly 范围,因此无需额外授权。在 Google Cloud 项目中启用 Google Analytics Data API。
| 工具 | 描述 |
|---|---|
ga4_run_report | 按日期范围运行报告(维度 + 指标,例如按 eventName 统计 eventCount);支持 limit、offset 和排序 |
ga4_run_realtime_report | 运行实时报告(约显示最近 30 分钟内的事件),用于实时 QA |
已知缺口(有意不提供,而非伪造):透视报告、群组和漏斗。
分页
所有由 GTM 分页端点支持的列表工具(accounts_* 范围的容器、
工作区、代码、触发器、变量、文件夹、文件夹实体、环境、
用户权限、客户端、转换、区域、模板、gtag 配置)默认会自动跟进分页并返回所有结果。可选参数:
maxPages— 限制获取的 API 页面数(默认值为 50)。如果还有更多页面, 响应中会包含"truncated": true和nextPageToken。pageToken— 从之前被截断的结果继续获取。
未截断的响应保持原有的 { <key>: [...], count } 结构不变。
有两个工具有所不同,因为其中一个列表键无法说明它们返回的内容:
folders_entities返回三个并行集合(tag、trigger、variable;始终存在,文件夹中没有对应内容时为空)以及一个counts对象;只有达到页面上限时才会添加truncated/nextPageToken。export_container分别对五个集合进行分页,因此接受maxPages(对每个集合分别应用),但不接受pageToken。如果导出未完成,会在所有格式(包括默认的summary)中标记incomplete: true,并附带truncatedCollections、每个集合对应的nextPageTokens和warning。
图例:✏️ 需要 GTM_MCP_ENABLE_WRITES=true | 🗑️ 需要 GTM_MCP_ENABLE_DELETES=true | 🚀 需要 GTM_MCP_ENABLE_PUBLISH=true
所有 ✏️ 🗑️ 🚀 工具还要求在工具参数中设置 confirm: true。
云部署
传输方式
对于云部署,请使用 GTM_MCP_TRANSPORT=http。服务会公开以下端点:
POST /mcp— Streamable HTTP MCP 端点GET /mcp— 现有会话的 SSE 流DELETE /mcp— 终止会话GET /health— 健康检查
此服务没有 /oauth/callback 路由。npm run auth:google 会在 127.0.0.1:3001 上自行启动一个短时监听器来处理重定向;托管传输上的未认证回调可能会覆盖服务存储的 Google 凭据,因此已移除此路由。
连接远程客户端
支持 Streamable HTTP 的客户端可以直接连接 /mcp 端点。对于仅支持 stdio 的客户端(如 Claude Desktop),请使用 mcp-remote 作为代理:
{
"mcpServers": {
"samarth-gtm-remote": {
"command": "npx",
"args": ["mcp-remote@next", "https://your-server.com/mcp"]
}
}
}
Vercel
限制:Vercel Serverless Functions 的超时时间为 10 秒(hobby)/60 秒(pro)。有状态的 SSE 会话需要持久连接,而 Vercel 对此支持不佳。Vercel 仅适用于无状态 MCP 交互。推荐的替代方案:Vercel + 外部会话存储(Redis/Upstash),或改用 Render/Fly.io。
对于 Vercel,请将 Express 应用导出为无服务器处理程序:
// api/mcp.ts
export default app; // where app is the Express instance
在 Vercel Dashboard → Settings → Environment Variables 中设置环境变量。
Render
- 在 Render 上创建新的 Web Service
- 连接你的 GitHub 仓库
- 构建命令:
npm install && npm run build - 启动命令:
GTM_MCP_TRANSPORT=http node dist/index.js - 在 Render Dashboard 中添加环境变量
- 重要:设置
RENDER=true环境变量,并确保健康检查访问/health
Render 支持持久的长连接,适合 SSE/流式传输,推荐使用。
Fly.io
fly launch
fly secrets set GOOGLE_CLIENT_ID=xxx GOOGLE_CLIENT_SECRET=xxx GOOGLE_REFRESH_TOKEN=xxx
fly secrets set GTM_MCP_TRANSPORT=http GTM_MCP_HTTP_PORT=3001
fly deploy
Fly.io 没有请求超时限制,并支持持久的 WebSocket/SSE 连接。推荐用于生产环境。
Docker
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY dist/ ./dist/
ENV GTM_MCP_TRANSPORT=http
ENV GTM_MCP_HTTP_PORT=3001
EXPOSE 3001
CMD ["node", "dist/index.js"]
安全注意事项
-
绝不提交
.env— 其中包含 OAuth 令牌。.env已列入.gitignore。 -
定期轮换令牌 — OAuth 刷新令牌的有效期较长,但可以撤销。请前往 myaccount.google.com/permissions 撤销。
-
最小权限范围 — 如果只需要读取权限,请从 OAuth 同意屏幕中移除写入权限范围并重新授权。服务器仅使用
tagmanager.readonly也能正常读取。 -
云端部署:请将密钥存储在平台的密钥管理器中(Render Secrets、Fly.io Secrets、Vercel Env Vars),切勿将其放入代码或 Docker 镜像中。
-
HTTP 传输:
/mcp内置两种身份验证模式 —GTM_MCP_HTTP_AUTH_TOKEN(一个共享的 bearer 令牌,用于标识部署)和STYTCH_PROJECT_ID(按用户进行 OAuth 身份验证,每个请求都会解析为该用户自己的 Google 授权)。若两者均未设置,传输将拒绝启动;GTM_MCP_HTTP_ALLOW_UNAUTHENTICATED=true可覆盖此行为,以供本地开发使用,且仅绑定到回环地址。 -
发布保护:除非明确打算通过 AI 客户端发布,否则请保持
GTM_MCP_ENABLE_PUBLISH=false。向生产环境发布错误标签是风险最高的操作。 -
审计日志:服务器会将所有会话事件记录到 stderr。生产环境中请将日志传输到日志服务。
开发
# Install dependencies
npm install
# TypeScript type check (no emit)
npm run typecheck
# Build
npm run build
# Watch mode
npm run build:watch
# Run dev server (stdio, with hot-reload)
npm run dev
# Run HTTP dev server
npm run dev:http
# Tests (run `npm run build` first — some suites test the compiled dist)
npm test
# Smoke test: server boots and answers tools/list
npm run smoke -- --mcp dist/index.js
# Full-surface smoke test: invokes ALL registered tools with a sanitized,
# credential-free env — every handler must respond cleanly (no crash/hang)
npm run smoke:all
# MCP Inspector (interactive tool debugging)
npm run inspector
项目结构
samarth-gtm-mcp/
├── src/
│ ├── index.ts # Entry point — stdio/HTTP transport setup
│ ├── server.ts # MCP server factory + tool registration
│ ├── auth/
│ │ └── googleAuth.ts # OAuth2 / service account auth
│ ├── tools/
│ │ ├── index.ts # Tool registration aggregator
│ │ ├── accounts.ts # accounts/list, accounts/get
│ │ ├── containers.ts # containers/list/get/create
│ │ ├── workspaces.ts # workspaces + sync/resolve_conflict
│ │ ├── tags.ts # tags CRUD
│ │ ├── triggers.ts # triggers CRUD
│ │ ├── variables.ts # variables CRUD
│ │ ├── folders.ts # folders CRUD + move_entities
│ │ ├── builtInVariables.ts # enable/disable/revert built-ins
│ │ ├── versions.ts # versions list/get/create/publish/delete
│ │ ├── publish.ts # quick_preview, versions_publish, create+publish
│ │ ├── audit.ts # audit_container analytics checks
│ │ ├── export.ts # export_container JSON dump
│ │ ├── environments.ts # environments CRUD + reauthorize
│ │ ├── userPermissions.ts # account-level user permissions
│ │ ├── serverSide.ts # clients, transformations, zones, templates, gtag config
│ │ ├── ga4Admin.ts # read-only GA4 Admin tools (ga4_*)
│ │ └── ga4Data.ts # read-only GA4 Data API reporting
│ ├── utils/
│ │ ├── guardrails.ts # Guardrail enforcement, error formatting
│ │ ├── gtmClient.ts # googleapis GTM v2 client factory
│ │ ├── ga4Client.ts # GA4 Admin/Data client factories
│ │ ├── apiRetry.ts # retry/backoff config (429/5xx, reads only)
│ │ ├── pagination.ts # transparent nextPageToken following
│ │ ├── schemas.ts # shared Zod input schemas
│ │ └── toolResponse.ts # standard tool result shaping
│ ├── types/
│ │ ├── gtm.ts # GTM API type definitions
│ │ └── index.ts
│ ├── scripts/
│ │ ├── auth-google.ts # Browser-based OAuth onboarding (`npm run auth:google`)
│ │ └── oauth-setup.ts # Interactive OAuth token helper (legacy paste-the-code flow)
│ └── __tests__/
│ ├── guardrails.node.test.mjs # guardrails + buildPath
│ ├── auth.node.test.mjs # env/auth resolution + token file paths
│ ├── pagination.node.test.mjs # paginate/buildListResult
│ ├── ga4Admin.node.test.mjs # GA4 tool registration (tests compiled dist)
│ └── apiRetry.node.test.mjs # retry/backoff config (tests compiled dist)
├── scripts/
│ ├── smoke-test.mjs # health probe: portal endpoints + MCP tools/list
│ └── smoke-all-tools.mjs # invokes all tools with sanitized env
├── .env.example
├── .gitignore
├── package.json
├── tsconfig.json
└── README.md
发布版本
发布完全通过 semantic-release 和 GitHub Actions 自动完成。每次推送到 main 都会触发 release.yml 工作流,该工作流会:
- 安装依赖、进行类型检查、构建并运行测试。
- 使用 Conventional Commits 规范检查自上一个标签以来的提交。
- 确定下一个语义化版本(
MAJOR.MINOR.PATCH)。 - 更新
CHANGELOG.md,并递增package.json/package-lock.json中的version。 - 将这些文件提交回
main,提交信息为chore(release): x.y.z [skip ci]([skip ci]标记可避免无限循环发布)。 - 创建 Git 标签(
vX.Y.Z)和附带自动生成说明的 GitHub Release。
该工作流使用内置的 GITHUB_TOKEN,无需额外密钥。npm publish 已禁用 — 此软件包通过 GitHub 仓库和发布版本以二进制文件形式分发,而非通过 npm 注册表分发。
Conventional Commit 示例
提交信息决定版本递增方式:
| 提交前缀 | 效果 | 示例 |
|---|---|---|
fix: | 补丁版本发布(x.y.Z) | fix: handle empty workspace in audit tool |
feat: | 次版本发布(x.Y.0) | feat: add bulk tag import tool |
perf: | 补丁版本发布 | perf: cache GTM client between tool calls |
docs: / chore: / refactor: / test: / style: / ci: / build: | 不发布 | docs: clarify OAuth setup steps |
BREAKING CHANGE: 页脚或类型后加 ! | 主版本发布(X.0.0) | 见下文 |
重大变更示例
feat!: drop support for Node.js 18
BREAKING CHANGE: minimum required Node version is now 20.
或:
refactor(auth): rename GOOGLE_REFRESH_TOKEN env var
BREAKING CHANGE: GOOGLE_REFRESH_TOKEN is now GTM_GOOGLE_REFRESH_TOKEN.
Update your .env file accordingly.
在本地试运行
若要预览下一次发布的内容,而不实际发布:
GITHUB_TOKEN=<a-token-with-no-perms-is-fine-for-dry-run> \
npx semantic-release --dry-run --no-ci
手动跳过发布
若要有意提交变更但不触发发布,请使用不会触发发布的类型(chore:、docs: 等),或在提交主题末尾添加 [skip ci]。
故障排除
“调用方没有权限”(403)
- 你的 Google 账号可能无权访问此 GTM 账号/容器
- 服务账号未添加到 GTM — 请参阅服务账号限制
- 检查同意屏幕上的 OAuth 权限范围
“invalid_grant” 或 “Token has been expired or revoked”
- 重新运行
npm run auth:google以刷新令牌文件 - 如果更倾向于通过环境变量管理令牌,也可以直接在
.env中设置GOOGLE_REFRESH_TOKEN - 如果陷入 Google 不再返回
refresh_token的循环,请前往 myaccount.google.com/permissions 撤销之前的访问权限,然后重新运行身份验证脚本
“Write operations are disabled”
- 在
.env中设置GTM_MCP_ENABLE_WRITES=true - 重启服务 / 桌面应用
Stdio 服务没有输出
- Stdio 服务有意不向 stdout 写入任何内容(stdout 是 JSON-RPC 通道)
- 诊断输出会写入 stderr — 请查看终端或 Claude Desktop 日志
桌面应用:运行 npm run dev 时出现 Error: Electron uninstall
- Electron 二进制文件已下载,但未完成解压 — 请参阅 apps/desktop/INSTALL.md 中可靠的重新解压修复方法
googleapis 类型出现 TypeScript 错误
- 运行
npm install,确保安装了所有依赖项 googleapis包自带类型定义 — 无需安装@types/googleapis
待办事项 / 已知限制
workspace_resolve_conflict:GTM API 的 resolve_conflict 端点接受完整的实体主体 — 请求主体的确切架构较复杂。目前的实现会直接传递用户提供的 JSON;调用前请根据实体类型验证该 JSON。containers_create:usageContext枚举值可能会因 GTM 区域 / 版本而略有不同。请参阅 GTM API 文档,了解最新的有效值。- 单身份 HTTP 身份验证使用共享密钥:
GTM_MCP_HTTP_AUTH_TOKEN使用一个适用于所有客户端的 bearer 令牌保护/mcp,因此它标识的是部署,而非调用者。若要使用按用户区分的身份,请设置STYTCH_PROJECT_ID以启用多用户模式 — 请参阅安全说明。 - HTTP 会话存储在内存中:会话存在于服务进程中,因此水平扩展需要粘性会话。对于单个团队实例而言足够使用;目前尚未实现多实例负载均衡。
- 每次部署仅支持一个 OAuth 身份 — 仅限单身份模式:未设置
STYTCH_PROJECT_ID时,所有请求共用一个 Google 身份,因此也共用一个 Google API 配额池。通过单次部署承受大量多用户请求会耗尽配额;使用退避策略重试可以缓解问题,但无法消除配额上限。多用户模式则可避开这一限制 — 每位成员使用自己的 Google 授权和配额。
由 Samarth Analytics 的 Swapnil Jaykar 和 Sarthak Mandage 构建
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。