把 GSC 和 GA4 接进 AI:NAS 上跑 MCP 的四个坑

3682 字
18 分钟
把 GSC 和 GA4 接进 AI:NAS 上跑 MCP 的四个坑

让 AI 直接读 Google Search Console(GSC)和 GA4 的数据,用对话做 SEO 复盘、挖关键词。

这篇给出一份在 NAS 上跑通的 compose:两个只读 MCP 服务对外提供 HTTP,局域网内任意 MCP 客户端填个 URL 就能用。费时间的不是部署,是四个坑。

一、先问清楚值不值得做#

有 GSC 有 GA4 的人,问”这些数据怎么接到 AI 里”,通常只会得到一句”有 API,去谷歌云申请”。从申请密钥到真能问出结果,中间是四个坑。

值得做的前提是三条都成立:

  • 你手上有一台常开的 NAS 或小主机,能跑 Docker
  • 你的站在 GSC 和 GA4 里已经有几周数据(新站数据太少,结论不稳)
  • 你能接受只在本机客户端里用

最后一条是这套方案的代价,得先说清楚。

只用内网 IP 接不了网页平台#

Claude.ai、ChatGPT 这类网页平台,是从它们自己的服务器发起连接的,访问不到你的内网。

能接的是本机客户端:LobeHub 桌面端、Cherry Studio、Claude Code、Cursor、Gemini CLI。

以后要给网页平台用,再加域名和隧道即可,服务本身不用动。

二、四种方案,为什么选 NAS 上的远程 MCP#

方案做法优点缺点结论
GSC 自带 Gemini在 GSC 里用自然语言查询零配置不能跨 GA4,不能换模型太弱
托管连接器第三方远程 MCP,OAuth 登录配置最少付费,数据过第三方淘汰
本地 MCP每台电脑用 npx / uvx 跑免费每个客户端配一遍,密钥散落各处可用
NAS 远程 MCP在 NAS 上跑成 HTTP 服务免费、配一次处处用、密钥只在 NAS部署稍麻烦最终选择

最终架构一句话:谷歌服务账号(只读)→ NAS 上两个容器 → 局域网内任意 MCP 客户端。

局域网内的 MCP 客户端

NAS:两个容器

谷歌(只读授权)

注入环境变量

注入环境变量

HTTPS(国内需走代理)

HTTPS(国内需走代理)

Streamable HTTP

Streamable HTTP

Search Console API

Analytics Data API

gsc-mcp

supergateway + mcp-server-gsc

:18001/mcp

ga4-mcp

mcp-proxy + analytics-mcp

:18002/mcp

LobeHub / Cherry Studio

Claude Code / Cursor

服务账号 JSON

只存在 NAS 上

局域网内的 MCP 客户端

NAS:两个容器

谷歌(只读授权)

注入环境变量

注入环境变量

HTTPS(国内需走代理)

HTTPS(国内需走代理)

Streamable HTTP

Streamable HTTP

Search Console API

Analytics Data API

gsc-mcp

supergateway + mcp-server-gsc

:18001/mcp

ga4-mcp

mcp-proxy + analytics-mcp

:18002/mcp

LobeHub / Cherry Studio

Claude Code / Cursor

服务账号 JSON

只存在 NAS 上

⚠️ 图里那条虚线是这套方案的重点:密钥只落在 NAS 上,客户端那边只填一个 URL,不碰任何凭据。

用到的开源组件:GSC 是社区的 mcp-server-gsc(谷歌至今没有官方 GSC MCP),GA4 是谷歌官方的 analytics-mcp。

两个都是 stdio 服务,要包装成 HTTP:GSC 用 supergateway(node 镜像),GA4 用 mcp-proxy(python)。

三、先定好这几个值#

占位符是什么怎么定
NAS的IPNAS 在局域网里的地址路由器后台或 ip a
18001 / 18002宿主机端口,GSC / GA4 各一个没被占用就行
GOOGLE_PROJECT_ID谷歌云项目 ID第一步建项目时记下
代理地址国内访问 googleapis 必须走代理填你自己的,本文写 192.168.1.10:10809
服务账号邮箱形如 xxx@项目ID.iam.gserviceaccount.com建完服务账号自动生成,不用自己想

四、动手:四步接通#

第一步:拿服务账号密钥#

  1. 打开 console.cloud.google.com,新建项目,记下项目 ID
  2. 启用 3 个 API:Google Search Console API、Google Analytics Data API、Google Analytics Admin API
  3. IAM 和管理 → 服务账号 → 创建服务账号,角色一个都不用选
  4. 进入服务账号 → 密钥 → 添加密钥 → JSON,下载得到密钥文件

那三个 API 都免费,不用绑卡,也不用点”免费试用”。

⚠️ 密钥 JSON 等于密码,不要发到群里。泄露了就删掉这把重新建一把。

第二步:给服务账号授权#

把服务账号邮箱加进两个后台。两边的粒度不一样,这点后面会再咬你一次:

路径给什么权限粒度
GSC设置 → 用户和权限 → 添加用户受限每个网站资源都要单独加一次
GA4管理 → 账号访问权限管理 → 添加用户查看者,取消勾选邮件通知在账号级别加一次,旗下所有媒体资源都能读,以后新建的站也自动覆盖

权限不用给大。AI 懂分析,但分析只需要读权限,官方 GA4 MCP 本身就是只读的。GSC 想让 AI 帮你提交站点地图可以给”完整”,但绝不要给”所有者”。

第三步:部署到 NAS#

只需要填两处:密钥全文和项目 ID。

# 内网 GSC + GA4 MCP,局域网内任意 MCP 客户端通过 URL 接入
# 必改:两处 GSA_KEY_JSON(服务账号 JSON 全文)、GOOGLE_PROJECT_ID
# 按需改:宿主机端口 18001 / 18002;代理地址(国内访问 googleapis 必须走代理)
# 不用改:其余全部
# 密钥通过环境变量传入,启动时写到容器内 /tmp/sa.json,不挂载任何文件
# 接入地址:http://NAS的IP:18001/mcp(GSC) http://NAS的IP:18002/mcp(GA4)
services:
gsc-mcp:
image: supercorp/supergateway:latest
container_name: gsc-mcp
restart: unless-stopped
entrypoint: ["sh", "-c"]
command:
- |
printf '%s' "$$GSA_KEY_JSON" > /tmp/sa.json && exec supergateway --stdio "npx -y mcp-server-gsc" --outputTransport streamableHttp --stateful --port 8000 --streamableHttpPath /mcp
ports:
- "18001:8000"
environment:
GOOGLE_APPLICATION_CREDENTIALS: /tmp/sa.json
HTTP_PROXY: http://192.168.1.10:10809
HTTPS_PROXY: http://192.168.1.10:10809
NO_PROXY: localhost,127.0.0.1
GSA_KEY_JSON: | # 必改:把服务账号 JSON 全文粘在下面,保持缩进
{"type": "service_account", "project_id": "...", "private_key": "...", "client_email": "..."}
healthcheck:
test: ["CMD", "node", "-e", "require('net').connect(8000,'127.0.0.1').on('connect',()=>process.exit(0)).on('error',()=>process.exit(1))"]
interval: 30s
timeout: 5s
retries: 3
start_period: 60s
ga4-mcp:
image: ghcr.io/astral-sh/uv:python3.12-bookworm-slim
container_name: ga4-mcp
restart: unless-stopped
depends_on:
- gsc-mcp
entrypoint: ["sh", "-c"]
command:
- |
printf '%s' "$$GSA_KEY_JSON" > /tmp/sa.json && exec uvx --with 'mcp<2' mcp-proxy --host=0.0.0.0 --port=8096 --pass-environment -- uvx analytics-mcp
ports:
- "18002:8096"
environment:
GOOGLE_APPLICATION_CREDENTIALS: /tmp/sa.json
GOOGLE_PROJECT_ID: # 必改:谷歌云项目 ID
HTTP_PROXY: http://192.168.1.10:10809
HTTPS_PROXY: http://192.168.1.10:10809
https_proxy: http://192.168.1.10:10809
NO_PROXY: localhost,127.0.0.1
no_proxy: localhost,127.0.0.1
GSA_KEY_JSON: | # 必改:同上,粘同一份 JSON
{"type": "service_account", "project_id": "...", "private_key": "...", "client_email": "..."}
volumes:
- ./data/uv-cache:/root/.cache/uv
healthcheck:
test: ["CMD", "python", "-c", "import socket;socket.create_connection(('127.0.0.1',8096),3)"]
interval: 30s
timeout: 5s
retries: 3
start_period: 120s

两个健康检查都只探 TCP 端口,不调业务接口——健康检查写错的代价不小,Traefik 会直接跳过 unhealthy 的容器,那次排查记在Traefik 一直 404:问题出在健康检查里。

第四步:在客户端接入#

以 LobeHub 桌面端为例:设置 → 连接器 → 添加自定义 MCP → 类型选 Streamable HTTP,每次添加一个:

{ "mcpServers": { "gsc": { "type": "http", "url": "http://NAS的IP:18001/mcp" } } }
{ "mcpServers": { "ga4": { "type": "http", "url": "http://NAS的IP:18002/mcp" } } }

点”测试连接”,能列出 list_sites、search_analytics、run_report 这些工具就说明通了。

到这里已经能用了——AI 已经可以读你的 GSC 和 GA4 数据。下面四节是那份 compose 为什么长这样。

五、坑一:服务账号密钥创建功能已停用#

报错里给出了政策 ID:

服务账号密钥创建功能已停用
iam.disableServiceAccountKeyCreation

原因:你的谷歌账号挂在一个”组织”下面(控制台顶部显示带大楼图标的组织名)。2024 年之后新建的组织默认禁止创建服务账号密钥。个人 @gmail.com 账号没有组织,不会遇到。

处理(只对这一个项目放开,组织其他地方仍然禁止):

  1. 顶部切到组织 → IAM → 给自己加 Organization Policy Administrator(组织政策管理员)。这个角色必须加在组织层级,加在项目上无效;组织管理员默认也没有它
  2. 顶部切回项目 → 组织政策 → 搜 disableServiceAccountKeyCreation → 管理政策 → 覆盖父级政策 → 添加规则 → 强制执行设为”关闭” → 设置政策
  3. 新版限制也检查一遍,状态是”已实施”就同样处理:
iam.managed.disableServiceAccountKeyCreation
  1. ⚠️ 生效有延迟。 改完立刻去建密钥还是报同样的错,等 10 到 15 分钟再试

更省事的一条路:换一个个人 Gmail 账号去建项目和服务账号。GSC 和 GA4 只认你添加进去的邮箱,不在乎这个服务账号属于哪个谷歌账号。

六、坑二:FileNotFoundError: ‘uvx’#

容器起不来,无限重启,日志里只有一行:

FileNotFoundError: [Errno 2] No such file or directory: 'uvx'

原因:一开始用的是 mcp-proxy 的官方镜像,它只装了 mcp-proxy 本身,没有 uvx,所以启动不了 uvx analytics-mcp。

处理:换成 uv 官方的 Python 镜像 ghcr.io/astral-sh/uv:python3.12-bookworm-slim。这个镜像自带 uvx,mcp-proxy 在启动时现装,依然不需要 build。

七、坑三:ImportError: cannot import name ‘request_ctx’#

容器能起来一下,然后崩:

ImportError: cannot import name 'request_ctx'

原因:mcp 这个 Python 库发布了 2.x 大版本,删掉了 mcp-proxy 还在引用的内部函数。uvx 默认装最新版,于是一启动就崩。

处理:uvx --with 'mcp<2' mcp-proxy,把依赖锁在 1.x。

经验:用 latest 或者不锁版本,就要接受上游随时破坏你的服务。遇到 ImportError 这类报错,先查依赖是不是刚发了大版本。

八、坑四:EISDIR: illegal operation on a directory, read#

容器跑起来了,一调用工具就报错:

EISDIR: illegal operation on a directory, read

意思是”你让我读文件,这却是个目录”。

原因:原本想用部署面板(Coolify)的”文件内容挂载”生成密钥文件,但这个功能没生效。而 Docker 挂载一个不存在的文件时,会自动在宿主机上建一个同名空目录挂进去,程序读到的就是目录。同一台 NAS 上的其他 Coolify 约定记在在 NAS 上用 Coolify 部署自建服务:十条约定。

处理:彻底不挂载文件。密钥 JSON 放进环境变量,启动命令里先用 printf 写成 /tmp/sa.json,再 exec 启动服务。

两个容易漏的细节:

  • compose 里的 $ 要写成 $$,否则会被 compose 当成变量替换掉
  • mcp<2 在 shell 里要加引号,否则 < 会被当成重定向

经验:bind mount 一个文件之前,这个文件必须先存在于宿主机上。这是 Docker 的经典坑。

九、故障速查#

现象原因处理
建密钥报政策 ID组织默认禁止覆盖父级政策,等 10–15 分钟
FileNotFoundError: 'uvx'镜像里没有 uvx换 uv 官方 Python 镜像
ImportError: request_ctxmcp 升到 2.x--with 'mcp<2'
EISDIR挂载的文件不存在,变成目录密钥走环境变量 + printf
客户端 fetch failed容器没跑起来先看容器日志,不要截”测试连接失败”那张结果页

十、可选:建一个专用 SEO 助手#

前置条件是上面两个 MCP 都已接通。建一个助手,把这段放进系统提示词,绑定 gsc 和 ga4 两个技能,之后每次提问只要一句话。

你是我的英文站 SEO 分析师。我做 web 出海,目标是挖掘关键词、看懂并接住用户搜索意图。
1. 每次先调用 list_sites 确认站点属性名。GSC 数据有 2-3 天延迟,结束日期取 3 天前。
2. 搜索数据用 GSC,落地页行为用 GA4(会话数、互动率、平均互动时长),需要时按页面交叉分析。
3. 每个关键词都要归类意图:信息型、导航型、交易型、比较型,并判断当前排名页面是否满足该意图。
4. 结论必须落到动作:目标 URL、目标关键词、改什么、预期影响,按"改动小、收益大"排序。
5. 用中文回答,关键词和文案用英文原文。先给结论和动作,数据表放后面。

常用的六个提问:

  • 周复盘:对比最近 7 天和前 7 天,列出涨跌最大的词和页面,给出本周要做的 3 件事
  • 差一点上首页的词:平均排名 8 到 20 位、展示量排前 30 的词,逐个说明对应页面缺什么,给出新的 title 和 H2
  • 高展示低点击:CTR 低于同排名平均水平的词,每个给出 3 版 title 和 description
  • 长尾选题:拉 90 天的查询词,把现有页面没覆盖的按主题聚类,给出新页面标题、slug、内链来源
  • 关键词互抢:同一个词被多个页面分流时,判断该合并、重定向还是调整侧重点
  • 意图验证:GSC 点击前 20 的页面对照 GA4 互动率,找出”点得进来但留不住”的页面

两个限制要知道:GSC 只能看到你已经有排名的词,真正的新词要配合联网搜索,去 Google 自动补全和 Reddit 找;新站数据少的时候,日期范围拉长到 28 天或 90 天,结论才稳。

十一、附:GA4 里新增或删除一个网站#

要做什么路径和要点
新增网站管理 → 创建 → 媒体资源(一个网站一个媒体资源,数据不会混)→ 业务目标勾”了解网站流量”和”查看用户互动度和留存率” → 平台选网站 → 拿到 G- 开头的衡量 ID
装衡量代码把 gtag 代码放进所有页面共用的 <head>。Astro 这类框架里 inline 脚本要加 is:inline
验证无痕窗口访问网站,然后看 GA4 的”报告 → 实时”
删除网站切到该媒体资源 → 媒体资源详细信息 → 移至回收站,35 天内可恢复。删之前先看”数据流”确认它没有还在收数据的站
和 MCP 的关系GA4 账号级授权过一次,新媒体资源自动可读;GSC 不一样,每新增一个网站都要把服务账号邮箱再加一次
中文站注意GA4 的脚本在中国大陆基本加载不出来。读者主要在大陆的话,GA4 会严重少算,需要另配国内能用的统计

⚠️ 删之前记得去掉网站上的旧代码,否则数据还在往回收站里的资源发。

十二、五条经验#

架构和排错#

一、先定架构再动手。 本地 MCP 看起来最简单,但每个客户端要配一遍、密钥散落各处。先想清楚”谁来连、从哪里连”,就能避开返工。

二、报错信息就是答案。 上面四个坑,关键信息全写在报错里:政策 ID、找不到 uvx、ImportError、EISDIR。不懂没关系,把完整日志交给 AI 比自己猜快得多。

依赖、权限、节奏#

三、依赖要锁版本,挂载要先有文件。 上游一次大版本升级就能让服务瘫掉;Docker 挂载不存在的文件会变成目录,密钥这类小文件用环境变量传更稳。

四、权限最小化。 AI 分析只需要读权限。只读账号加上内网访问,就算哪个环节泄露,最坏后果也只是数据被别人看到。

五、卡住的时候一步一截图。 谷歌云控制台界面复杂,一次性给十步说明很容易迷路。改成”做一步、看一眼、再下一步”之后,推进反而更快。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

把 GSC 和 GA4 接进 AI:NAS 上跑 MCP 的四个坑
https://blog.always1ov.com/posts/gsc-ga4-mcp-nas-deploy/
作者
薯饼
发布于
2026-09-22
许可协议
CC BY-NC-SA 4.0