GSC MCP Worker
by ambo-sk
README.md
# GSC MCP Worker
Google Search Console MCP server hosted on a Cloudflare Worker.
- Tools ported from [AminForou/mcp-gsc](https://github.com/AminForou/mcp-gsc) (TypeScript rewrite, REST API via fetch)
- SEO audit report engine ported from [acamolese/google-search-console-mcp](https://github.com/acamolese/google-search-console-mcp) (translated to English)
- Auth: Google service account (JWT signed with WebCrypto — no googleapis dependency)
- Transports: Streamable HTTP (`/mcp`) and legacy SSE (`/sse`), plus a browser endpoint `/report` for the HTML audit
For security/IT sign-off: [SECURITY-REVIEW.md](SECURITY-REVIEW.md) (architecture, auth model, secrets, egress, risk register, kill switch).
## Setup
### 1. Google Cloud
1. Create (or pick) a GCP project and enable the **Google Search Console API**.
2. Create a **service account** (no roles needed) and download its JSON key.
3. In [Search Console](https://search.google.com/search-console) → Settings → Users and permissions,
add the service account email (`...@...iam.gserviceaccount.com`) as a user
(**Full** permission if you want sitemap submission; **Owner**-added properties needed for add/delete site).
### 2. Deploy
```bash
npm install --legacy-peer-deps
npx wrangler secret put GCP_SERVICE_ACCOUNT_KEY # paste the full JSON key
npx wrangler secret put MCP_AUTH_TOKEN # any long random string, e.g. `openssl rand -hex 32`
npm run deploy
```
### 3. Connect a client
Claude Code:
```bash
claude mcp add --transport http gsc https://gsc-mcp.gtm-ai.workers.dev/mcp \
--header "Authorization: Bearer <MCP_AUTH_TOKEN>"
```
Claude Desktop / other stdio-only clients, via mcp-remote:
```json
{
"mcpServers": {
"gsc": {
"command": "npx",
"args": [
"mcp-remote",
"https://gsc-mcp.gtm-ai.workers.dev/mcp",
"--header",
"Authorization: Bearer <MCP_AUTH_TOKEN>"
]
}
}
}
```
## Tools
| Category | Tools |
|---|---|
| Properties | `list_properties`, `get_site_details`, `add_site`*, `delete_site`* |
| Analytics | `get_search_analytics`, `get_performance_overview`, `get_advanced_search_analytics`, `compare_search_periods`, `get_search_by_page_query` |
| Inspection | `inspect_url_enhanced`, `batch_url_inspection`, `check_indexing_issues` |
| Sitemaps | `list_sitemaps`, `get_sitemap_details`, `submit_sitemap`, `delete_sitemap`* |
| Reporting | `generate_audit_report` |
| Meta | `get_capabilities` |
\* Destructive — disabled unless `GSC_ALLOW_DESTRUCTIVE=true` in `wrangler.jsonc` vars.
## Audit report
`generate_audit_report` returns a self-contained HTML report (KPIs vs previous period, Chart.js
trend/device charts, detected issues with per-issue strategies, quick wins, keyword
cannibalization, page-2 opportunities, 30/60/90-day roadmap).
Also available directly in the browser:
```
https://gsc-mcp.gtm-ai.workers.dev/report?site_url=sc-domain:example.com&date_from=2026-07-01&date_to=2026-07-28&token=<MCP_AUTH_TOKEN>
```
## Config
| Name | Kind | Meaning |
|---|---|---|
| `GCP_SERVICE_ACCOUNT_KEY` | secret | Full service account JSON key |
| `MCP_AUTH_TOKEN` | secret | Bearer token required on every endpoint |
| `GSC_DATA_STATE` | var | `all` (matches GSC dashboard, default) or `final` (confirmed only, 2-3 day lag) |
| `GSC_ALLOW_DESTRUCTIVE` | var | `true` enables add_site / delete_site / delete_sitemap |
| `GSC_BRANDING` | var (optional) | JSON overriding report branding, e.g. `{"brand_name":"Acme","colors":{"primary":"#0f766e"}}` |
## Local dev
```bash
cp .dev.vars.example .dev.vars # or create .dev.vars with the two secrets
npm run dev # http://localhost:8787/mcp
```
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing