内容
# Google Tag Manager MCP
一个适用于Google Tag Manager API v2的Python模型上下文协议(MCP)服务器。直接将Claude(或任何兼容MCP的AI客户端)连接到您的GTM账户,以自然语言管理标签、触发器、变量、工作区、版本、环境等。
服务器也是一个OAuth 2.1授权服务器,因此它可以在Claude支持自定义MCP服务器的任何地方作为远程连接器使用——claude.ai(个人)、Claude Desktop和Claude Teams。对于Teams,组织所有者添加一次URL,每个成员在首次使用时单独进行身份验证。
## 工具列表
每个工具接受一个`action`参数,该参数选择操作,以及资源寻址(`parent` / `path`)和可选的`config`、`params`和`confirm`字段。破坏性操作需要`confirm=True`。
| 工具 | 操作 |
| --- | --- |
| `gtm_account` | get, list, update |
| `gtm_container` | create, get, list, update, remove + combine, lookup, move_tag_id, snippet |
| `gtm_workspace` | create, get, list, update, remove + create_version, get_status, sync, quick_preview, resolve_conflict |
| `gtm_tag` | create, get, list, update, remove, revert |
| `gtm_trigger` | create, get, list, update, remove, revert |
| `gtm_variable` | create, get, list, update, remove, revert |
| `gtm_built_in_variable` | create, list, remove, revert |
| `gtm_folder` | create, get, list, update, remove + revert, entities, move_entities_to_folder |
| `gtm_client` | create, get, list, update, remove, revert |
| `gtm_zone` | create, get, list, update, remove, revert |
| `gtm_template` | create, get, list, update, remove + revert, import_from_gallery |
| `gtm_transformation` | create, get, list, update, remove, revert |
| `gtm_gtag_config` | create, get, list, update, remove |
| `gtm_destination` | get, list, link |
| `gtm_environment` | create, get, list, update, remove + reauthorize |
| `gtm_version` | get, live, publish, set_latest, undelete, update, remove |
| `gtm_version_header` | list, latest |
| `gtm_user_permission` | create, get, list, update, remove |
### 统一工具设计
每个工具接受一组统一的参数:
- `action` — 要执行的操作(例如`"list"`、`"create"`、`"publish"`)
- `parent` — 父资源的路径(例如`"accounts/123/containers/456/workspaces/7"`)— 用于创建和列出
- `path` — 资源的完整路径 — 用于获取、更新、删除和其他单资源操作
- `config` — 创建/更新正文的字段字典
- `params` — 额外查询参数的字典
- `confirm` — 布尔值,对于破坏性操作为`True`
示例 — 在工作区中列出标签:
```python
gtm_tag(action="list", parent="accounts/123/containers/456/workspaces/7")
```
示例 — 发布版本(破坏性,需要确认):
```python
gtm_version(action="publish", path="accounts/123/containers/456/versions/9", confirm=True)
```
### 确认防护
以下操作被视为破坏性操作,需要`confirm=True`。如果没有它,工具会立即返回一个结构化消息,要求您使用`confirm=True`重新调用:
> publish, remove, revert, undelete, combine, move_tag_id, move_entities_to_folder, sync, create_version, resolve_conflict, reauthorize, link
这可以防止由于模糊的提示而导致的意外更改。
---
## 认证工作原理
有**两种**模式。请选择一种。
### 模式 A — 本地 STDIO(单个用户,无服务器)
如果您只想在自己的机器上使用它。`setup_local_auth.py`运行一次Google OAuth流程,并将您的令牌存储在`~/.config/gtm-mcp/token.json`中。Claude Desktop启动`server.py`作为子进程。无需Firestore,无需Cloud Run,无需公共URL。
### 模式 B — 远程 HTTP 服务器(Claude Teams,claude.ai,多用户)
MCP服务器也是一个OAuth 2.1授权服务器。当Claude连接时:
1. Claude在`/.well-known/oauth-protected-resource`和`/.well-known/oauth-authorization-server`处发现我们的元数据。
2. Claude通过动态客户端注册(`POST /oauth/register`)注册自己。
3. Claude将用户重定向到`/oauth/authorize`。我们将身份验证委托给Google OAuth。
4. 在Google登录后,我们为Claude颁发自己的不透明承载令牌 — Google凭证从未离开服务器。
5. 在每个`/mcp`请求中,Claude发送我们的承载令牌;我们在服务器端将其映射到正确的用户存储的Google凭证,并调用GTM API。
---
## 先决条件
- Python 3.10+
- 您有权访问的Google Tag Manager账户
- [Google Cloud](https://console.cloud.google.com/)项目
---
## 步骤 1 — 设置 Google Cloud
### 1a. 创建项目并启用 Tag Manager API
1. 前往 [Google Cloud Console](https://console.cloud.google.com/)。
2. 创建或选择项目。
3. **APIs & Services → Library**,启用 **Tag Manager API**。
### 1b. 创建 OAuth 2.0 凭证
1. **APIs & Services → Credentials → Create Credentials → OAuth 2.0 Client ID**。
2. 应用程序类型:**Web application**。
3. 添加 **Authorized redirect URIs**:
- `http://localhost:8080/auth/callback` *(本地开发 / setup_local_auth.py)*
- `https://YOUR-CLOUD-RUN-URL/auth/callback` *(远程部署 — 部署后添加)*
4. 点击 **Create**,然后 **Download JSON** → 保存为 `client_secret.json` 在项目根目录下 *(gitignored)*。您也可以直接将Client ID / Client Secret复制到环境变量中。
### 1c. OAuth 同意屏幕
1. **APIs & Services → OAuth 同意屏幕**。
2. 选择 **Internal** 用于 Google Workspace 组织(团队推荐),或 **External** 用于个人/个人使用。
3. 添加作用域:
- `https://www.googleapis.com/auth/tagmanager.readonly`
- `https://www.googleapis.com/auth/tagmanager.edit.containers`
- `https://www.googleapis.com/auth/tagmanager.delete.containers`
- `https://www.googleapis.com/auth/tagmanager.edit.containerversions`
- `https://www.googleapis.com/auth/tagmanager.publish`
- `https://www.googleapis.com/auth/tagmanager.manage.users`
4. 如果使用 **External** 测试模式,请在 **Test users** 下添加每个用户的电子邮件。
### 1d. 启用 Firestore *(仅限模式 B)*
服务器在Firestore(集合`user_tokens_gtm`)中存储OAuth承载令牌和每个用户的Google凭证。
1. 在Cloud Console中,**Firestore → Create database → Native mode**,选择一个区域。
2. 在 **IAM & Admin → IAM** 下,为Cloud Run服务账号授予 **Cloud Datastore User** 角色。
---
## 步骤 2 — 安装
```bash
git clone https://github.com/dhawalshah/gtm-mcp
cd gtm-mcp
pip install -r requirements.txt
cp .env.example .env # 填写值
```
---
## 步骤 3 — 模式 A:本地 STDIO
```bash
python setup_local_auth.py
```
浏览器打开,您使用Google登录,脚本写入 `~/.config/gtm-mcp/token.json`。
然后添加到 `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
```json
{
"mcpServers": {
"google-tag-manager": {
"command": "python",
"args": ["/absolute/path/to/gtm-mcp/server.py"],
"env": {
"OAUTH_CONFIG_PATH": "/absolute/path/to/client_secret.json",
"MCP_USER_EMAIL": "you@yourcompany.com"
}
}
}
}
```
重启Claude Desktop。完成 — 跳过其余部分。
---
## 步骤 3 — 模式 B:远程 HTTP 服务器(Claude Teams / claude.ai)
### 部署到 Cloud Run
```bash
gcloud run deploy gtm-mcp \
--source . \
--region YOUR_REGION \
--project YOUR_PROJECT_ID \
--platform managed \
--port 8080 \
--allow-unauthenticated \
--set-env-vars "GCP_PROJECT_ID=your-project-id,BASE_URL=https://YOUR-SERVICE-URL.run.app,OAUTHLIB_RELAX_TOKEN_SCOPE=1,ALLOWED_DOMAINS=yourcompany.com" \
--set-secrets "OAUTH_CONFIG_PATH=gtm-mcp-client-secret:latest"
```
**必需:** `OAUTHLIB_RELAX_TOKEN_SCOPE=1` — Google的OAuth响应通常返回所请求作用域的超集;如果没有此环境变量,`google-auth-oauthlib`将在`/auth/callback`引发“作用域已更改”的错误,整个身份验证流程失败。
**推荐:** 从 [Secret Manager](https://cloud.google.com/secret-manager) 加载 `client_secret.json`,而不是将其构建到镜像中或将原始机密作为纯环境变量传递。 将文件存储为机密,然后在运行时通过 `--set-secrets` 挂载。
部署完成后,返回 **APIs & Services → Credentials → 您的OAuth客户端** 并添加实时回调URL:
```
https://YOUR-SERVICE-URL.run.app/auth/callback
```
### 从Claude连接
**Claude Teams(组织所有者为所有人添加一次):**
- 设置 → 连接器 → 添加自定义连接器
- URL:`https://YOUR-SERVICE-URL.run.app/mcp`
- 每个成员点击 **Connect**,使用Google登录,完成。
**claude.ai 个人账户:**
- 设置 → 连接器 → 添加自定义连接器
- URL:`https://YOUR-SERVICE-URL.run.app/mcp`
**使用远程服务器的Claude Desktop:**
```json
{
"mcpServers": {
"google-tag-manager": {
"url": "https://YOUR-SERVICE-URL.run.app/mcp"
}
}
}
```
---
## 环境变量
| 变量 | 必需 | 描述 |
| --- | --- | --- |
| `BASE_URL` | 模式 B | 此服务的公共URL。用于OAuth元数据和作为令牌绑定的规范资源URI。 |
| `GCP_PROJECT_ID` | 模式 B | 托管Firestore的GCP项目。 |
| `OAUTH_CONFIG_PATH` | 两种模式† | 从Google Cloud Console下载的`client_secret.json`路径。 |
| `GOOGLE_CLIENT_ID` | 模式 B† | Google OAuth客户端ID(`OAUTH_CONFIG_PATH`替代方案)。 |
| `GOOGLE_CLIENT_SECRET` | 模式 B† | Google OAuth客户端机密(`OAUTH_CONFIG_PATH`替代方案)。 |
| `OAUTHLIB_RELAX_TOKEN_SCOPE` | 模式 B | 设置为`1`。必需 — Google返回超集作用域,如果没有此环境变量,OAuth回调将失败。 |
| `MCP_USER_EMAIL` | 模式 A | 您的电子邮件 — 在Claude Desktop配置中设置,以便服务器找到您的存储令牌。 |
| `ALLOWED_DOMAINS` | 否 | 以逗号分隔的电子邮件域名允许列表(例如`acme.com,beta.com`)。空 = 无限制。 |
| `PORT` | 否 | HTTP端口(默认`8080`)。 |
| `LOG_LEVEL` | 否 | Python日志级别(默认`INFO`)。 |
† 设置 **任一** `OAUTH_CONFIG_PATH` **或** `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET`。
---
## 配额
GTM API v2具有较低的默认配额:大约 **0.25 QPS**,**15 请求/分钟**,和 **10,000 请求/天**,每个GCP项目。 与Google Ads或Analytics不同,配额不会随着计费自动升级。
如果您遇到配额错误,请通过 **Cloud Console → APIs & Services → Tag Manager API → Quotas & System Limits** 提高限制。
客户端具有内置的速率限制和指数退避,以保持在默认限制内。
---
## OAuth 端点参考(模式 B)
| 端点 | 规范 | 目的 |
| --- | --- | --- |
| `GET /.well-known/oauth-protected-resource` | RFC 9728 | 公告 canonical 资源 URI 和授权服务器。 |
| `GET /.well-known/oauth-authorization-server` | RFC 8414 | 授权服务器元数据。 |
| `POST /oauth/register` | RFC 7591 | 动态客户端注册。 |
| `GET /oauth/authorize` | OAuth 2.1 | 启动具有PKCE的授权码流程;重定向到Google。 |
| `GET /auth/callback` | — | Google重定向到此处;我们颁发授权码并跳转回MCP客户端。 |
| `POST /oauth/token` | OAuth 2.1 | 授权码 + 刷新令牌授权。 |
没有有效承载令牌的`GET /mcp`返回`401`,带有`WWW-Authenticate: Bearer resource_metadata="…"`头部,指向受保护的资源元数据文档,这是符合标准的MCP客户端发现其余部分的方式。
---
## 参考
`reference/`文件夹包含上游 [stape-io/gtm-mcp](https://github.com/stape-io/gtm-mcp) TypeScript服务器,在开发过程中克隆为API形状参考。 它列在`.gitignore`中,并从Docker/Cloud Run构建中排除 — 它不是可部署应用程序的一部分。
---
## 技术栈
- **[FastMCP](https://github.com/jlowin/fastmcp)** — MCP服务器框架
- **FastAPI + uvicorn** — HTTP包装器
- **Google Auth / google-api-python-client** — Google OAuth 和 API访问
- **Firestore** — 每用户令牌存储和OAuth服务器状态(模式B)
- **Google Cloud Run** — 无服务器托管
---
## 许可证
MIT