Skip to main content
Glama
ambo-sk

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
```