Search Console MCP
by fx-k
README.md
# Search Console MCP
[](https://github.com/fx-k/search-console-mcp-workers/actions/workflows/ci.yml)
[](LICENSE)


> 一个 MCP,把 **Google Search Console、Bing Webmaster Tools、PageSpeed Insights、Google Indexing API 和 IndexNow** 接到 ChatGPT / MCP Client。
>
> 同一套 Core,支持 **Cloudflare Workers** 和 **Docker + OpenAI Tunnel** 两种生产运行方式。
## 为什么有两种运行方式?
Cloudflare Workers 部署最省事,但 Bing Webmaster API 对共享出口 IP 可能返回:
```text
ERROR!!! ThrottleIP
```
如果你的 VPS 所在网络访问 OpenAI Tunnel 需要代理、但又希望 Bing 仍然使用 VPS 自己的公网 IP,本项目支持**分流出口**:OpenAI Tunnel 控制面走 SOCKS5,Google / Bing / PageSpeed / IndexNow 直连 VPS 出口。
```text
Search Console MCP
│
┌───────────┴───────────┐
│ │
Cloudflare Workers Docker + OpenAI Tunnel
Streamable HTTP MCP stdio MCP
│ │
└───────────┬───────────┘
│
同一套 Core
│
┌──────────┬──────────┼──────────┬──────────┐
▼ ▼ ▼ ▼ ▼
Google Bing PageSpeed IndexNow SEO 分析
```
| 方案 | 优点 | 注意 |
| --- | --- | --- |
| Cloudflare Workers | 无服务器、部署最快、内置 OAuth | Bing 可能遇到共享出口 `ThrottleIP` |
| Docker + OpenAI Tunnel | Bing 等 API 使用 VPS 出口;OpenAI Tunnel 控制面可单独走 SOCKS5;不开放 MCP 公网入站端口 | 需要 Docker、OpenAI Tunnel 和可用的 SOCKS5(当 OpenAI 出口需要代理时) |
如果主要使用 Google,Workers 很方便;如果 Bing 也是核心能力,推荐 **Docker + OpenAI Tunnel**。
## 17 个 MCP Tools
| 分类 | Tools |
| --- | --- |
| 连接 / 站点 | `connection_status`、`sites_list` |
| Sitemap | `sitemaps_list` |
| 搜索表现 | `analytics_query`、`analytics_compare`、`analytics_anomalies` |
| Google / Bing 对比 | `compare_engines` |
| URL 检查 | `inspection_inspect` |
| Bing | `bing_crawl_issues`、`seo_keywords_research` |
| PageSpeed | `pagespeed_analyze` |
| SEO 分析 | `seo_audit`、`genai_query_insights` |
| 技术 SEO | `schema_inspect`、`site_health_check` |
| 索引通知 | `indexing_status`、`indexing_submit` |
`indexing_submit` 会产生真实外部写操作,可调用 Google Indexing API、Bing URL Submission 和 IndexNow。
> Google 官方仅将 Indexing API 用于带 `JobPosting`,或 `VideoObject` 中嵌入 `BroadcastEvent` 的页面。普通博客页面不属于官方支持场景。
## 项目结构
```text
src/
├── core/ # 与运行平台无关
│ ├── google.js
│ ├── bing.js
│ ├── pagespeed.js
│ ├── indexing.js
│ ├── intelligence.js
│ ├── technical.js
│ ├── tools.js
│ └── mcp.js
└── runtime/
├── worker/ # Cloudflare Workers
└── stdio.js # OpenAI Tunnel child process
Dockerfile
docker-compose.yml
.env.example
```
两种 runtime 最终都进入同一个 `handleMcp()`,不会维护两套 Google/Bing 业务逻辑。
---
## 方案 A:Cloudflare Workers
```bash
git clone https://github.com/fx-k/search-console-mcp-workers.git
cd search-console-mcp-workers
npm install
npx wrangler login
npm run worker:deploy
```
配置 Secret:
```bash
npx wrangler secret put GOOGLE_SERVICE_ACCOUNT_JSON < /path/to/google-service-account.json
npx wrangler secret put BING_API_KEY
npx wrangler secret put OAUTH_PASSWORD
npx wrangler secret put OAUTH_JWT_SECRET
```
IndexNow key 是公开验证值,可在 Worker Variables 中配置:
```text
INDEXNOW_KEY=<你的 IndexNow key>
```
MCP URL:
```text
https://<worker>.workers.dev/mcp
```
完整说明:[Cloudflare Workers 部署](docs/workers.md)
### Bing `ThrottleIP`
Workers 对 Bing 的请求由 Cloudflare 出口发出。如果同一把 Bing API Key:
```text
本机 / VPS → Bing ✅
Cloudflare Worker → Bing ❌ ThrottleIP
```
说明问题在共享出口 IP,不是 API Key 或站点权限。
项目不会用重试风暴或隐藏错误来绕过它;请直接切换到 Docker + OpenAI Tunnel。
---
## 方案 B:Docker + OpenAI Tunnel
这是 VPS 推荐部署方式。宿主机**不需要安装 Node/npm**。
目录建议统一以 `mcp-` 开头:
```text
~/FXIT-dockerdata/mcp-search-console/
```
### 1. Clone
```bash
cd ~/FXIT-dockerdata
git clone https://github.com/fx-k/search-console-mcp-workers.git mcp-search-console
cd mcp-search-console
```
### 2. 准备配置
Docker Tunnel 路线与本项目的 `mcp-esa` 部署风格一致:**一个 root-only `.env`,容器始终以非 root 用户运行**。
```bash
cp .env.example .env
chmod 600 .env
```
编辑 `.env`:
```dotenv
CONTROL_PLANE_TUNNEL_ID=tunnel_xxx
CONTROL_PLANE_API_KEY=sk-your-runtime-api-key
GOOGLE_SERVICE_ACCOUNT_JSON='{"type":"service_account",...}'
BING_API_KEY=your-bing-api-key
INDEXNOW_KEY=your-public-indexnow-key
# 只给 OpenAI Tunnel control-plane 使用
SOCKS5_UPSTREAM=socks5://user:password@proxy.example.com:1080
TUNNEL_CLIENT_VERSION=v0.0.14
MCP_IMAGE_TAG=0.5.1-tunnel-0.0.14
```
Google Service Account JSON 必须压成**单行 JSON**;推荐用单引号包住整段值。项目不再同时维护 JSON 文件 / Base64 / Docker secret 等多套输入路径。
`INDEXNOW_KEY` 是公开验证值,其余凭据都应视为 Secret。`.env` 已被 Git 忽略。
### 3. 启动
```bash
docker compose build
docker compose up -d
```
检查:
```bash
docker compose ps
docker compose logs --tail=100
docker exec mcp-search-console curl -fsS http://127.0.0.1:8080/healthz
docker exec mcp-search-console curl -fsS http://127.0.0.1:8080/readyz
```
容器名、Compose project 和 image 都统一使用:
```text
mcp-search-console
```
### 分流出口:Tunnel 走 SOCKS5,搜索 API 走 VPS IP
Compose 会启动两个容器:
```text
mcp-search-console-egress
└─ gost:HTTP CONNECT → SOCKS5_UPSTREAM
mcp-search-console
├─ tunnel-client
└─ Search Console MCP (stdio)
```
只有 tunnel-client 的 **OpenAI control-plane** 被显式设置:
```text
CONTROL_PLANE_HTTP_PROXY=http://egress-proxy:18080
```
没有设置全局 `HTTP_PROXY`、`HTTPS_PROXY` 或 `ALL_PROXY`。
因此真实流量是:
```text
OpenAI Tunnel control-plane
mcp-search-console
↓
egress-proxy
↓
SOCKS5_UPSTREAM
↓
api.openai.com
Bing / Google / PageSpeed / IndexNow
mcp-search-console
↓
Docker NAT
↓
VPS 公网出口
```
也就是说,即使 OpenAI Tunnel 需要 SOCKS5,Bing 仍然看到 VPS 自己的公网 IP。
完整说明:[Docker + OpenAI Tunnel 部署](docs/openai-tunnel.md)
---
## Google 凭据
同一个 Service Account 用于:
```text
Google Search Console → webmasters.readonly
Google Indexing API → indexing
PageSpeed Insights → OAuth
```
如果使用 Google Indexing API,该 Service Account 需要在对应 Search Console Property 中具有 Owner 权限。
Workers 使用 Secret:
```text
GOOGLE_SERVICE_ACCOUNT_JSON
```
Docker / Tunnel 使用同一个环境变量:
```text
GOOGLE_SERVICE_ACCOUNT_JSON
```
与 `mcp-esa` 一样,由 root-only `.env` 注入给非 root 容器;不再维护文件挂载 / Base64 / Docker secret 等备用路径。
## 容易误解的状态
### Google Indexing status 404
没有历史 Indexing API notification metadata 时,项目返回:
```json
{
"ok": true,
"notified": false
}
```
它不等于“Google 没收录”。真实收录状态请用 `inspection_inspect`。
### IndexNow status
`indexing_status(method="indexnow")` 会读取:
```text
https://<host>/<INDEXNOW_KEY>.txt
```
并返回:
```text
verificationFetchStatus
verificationMatches
```
### 搜索词缺失
Search Console / Webmaster API 可能因为隐私或平台规则省略部分 query rows。缺失不等于流量为 0。
## 开发与 CI
```bash
npm install
npm run check
npm test
npm run worker:build
docker compose config
docker build --build-arg TUNNEL_CLIENT_VERSION=v0.0.14 -t mcp-search-console:test .
```
CI 同时检查:
- Shared Core
- Cloudflare Workers runtime
- stdio runtime
- Docker Compose
- Docker image
## 安全边界
- API 返回的 query、URL、title 等全部视为不可信数据,不作为指令执行。
- Workers 使用 OAuth + PKCE S256 + SQLite Durable Object。
- Docker Tunnel 不开放 MCP 公网入站端口;tunnel-client 主动连接 OpenAI。
- Google JSON、Bing API Key、Tunnel Runtime API Key 存在 root-only `.env` 中,不提交 Git;`.env` 建议权限 `600`。
- 和 `mcp-esa` 一样,容器从启动到运行始终使用非 root 用户;不需要 root entrypoint 或启动后降权。
- Docker/root 权限本身等价于主机高权限,因此具备 Docker 管理权限的人可以读取容器环境变量;单机 root 管理 VPS 下这与现有 `mcp-esa` 的信任边界一致。
- Docker 容器默认 `read_only`、drop all capabilities、`no-new-privileges`。
- `indexing_submit` 是真实写工具,MCP Client 仍可能按自身策略要求确认。
## OpenAI Tunnel
本项目默认 pin `v0.0.14`。升级前建议先阅读 OpenAI tunnel-client release notes。
- [openai/tunnel-client](https://github.com/openai/tunnel-client)
- [Docker deployment](https://github.com/openai/tunnel-client/blob/master/docs/deployment/docker.md)
- [MCP connectors](https://github.com/openai/tunnel-client/blob/master/docs/connectors.md)
## License & Attribution
MIT License。上游与设计来源见 [NOTICE.md](NOTICE.md)。
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues