The GSC Wizard MCP server is a remote, OAuth-protected Model Context Protocol resource that exposes Google Search Console, Bing Webmaster, GA4 and Merchant Center data to Claude. This page is the technical reference: transport, the authentication chain, the tool surface, the response contract, how reads are routed, and what the limits are.
If you want the click-by-click setup instead, use the Claude connection walkthrough. For the product overview across all clients, see the Google Search Console MCP.
https://mcp.gscwizard.com/mcp
Streamable HTTP
OAuth 2.1 (DCR + PKCE) or Bearer key
125 · 93 read / 32 write
The server speaks MCP over Streamable HTTP. There is no SSE-only fallback endpoint; clients that still assume the deprecated HTTP+SSE pair should be pointed at the single /mcp path, which negotiates streaming per request.
| Path | Auth | Purpose |
|---|---|---|
POST /mcp | Required | JSON-RPC over Streamable HTTP |
/v1/* | Required | REST surface for non-MCP callers |
GET /health | Public | Returns { ok, sessions } |
GET /, /docs | Public | Rendered tool catalog |
/.well-known/oauth-protected-resource | Public | RFC 9728 resource metadata |
Session continuity rides on the Mcp-Session-Id response header, which the client echoes on subsequent requests. Each session is pinned server-side to the user_id that opened it. Re-presenting a session id with a different credential is rejected rather than silently rebound, so a leaked session id is not on its own sufficient to read an account.
MCP stdio, MCP Streamable HTTP and the REST API at /v1 all execute through the same runTool() pipeline. Authorization, argument validation, per-property grant enforcement, the subscription gate, the rate limiter and the audit trail are applied in that one place, so they cannot drift apart between transports. A tool added to the registry is reachable, and governed identically, on all three.
Two mechanisms, chosen by client capability. Claude's Connectors UI uses OAuth 2.1; config-file and headless clients present a static API key.
The MCP server is the resource server; the app at tool.gscwizard.com is the authorization server. Claude walks the chain unattended:
An unauthenticated GET on the resource names the authorization server and the scopes.
Claude fetches /.well-known/oauth-authorization-server from the issuer to locate the endpoints.
Claude registers itself and receives its own client ID. This is why the client ID and secret fields are left blank when adding the connector: filling them in pre-empts registration and breaks the flow.
An authorization_code grant with S256 challenge, refreshable. Google sign-in and consent happen on the authorization server, never in Claude.
Resource metadata
GET https://mcp.gscwizard.com/.well-known/oauth-protected-resource
{
"resource": "https://mcp.gscwizard.com/mcp",
"authorization_servers": ["https://tool.gscwizard.com"],
"scopes_supported": ["mcp:read", "mcp:write"],
"bearer_methods_supported": ["header"]
}Authorization-server metadata
GET https://tool.gscwizard.com/.well-known/oauth-authorization-server
{
"issuer": "https://tool.gscwizard.com",
"authorization_endpoint": "https://tool.gscwizard.com/oauth/authorize",
"token_endpoint": "https://tool.gscwizard.com/api/oauth/token",
"registration_endpoint": "https://tool.gscwizard.com/api/oauth/register",
"revocation_endpoint": "https://tool.gscwizard.com/api/oauth/revoke",
"scopes_supported": ["mcp:read", "mcp:write"],
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code", "refresh_token"],
"code_challenge_methods_supported": ["S256"],
"token_endpoint_auth_methods_supported": [
"none", "client_secret_post", "client_secret_basic"
]
}Two gates before a token is issued. The authorize endpoint requires an active subscription and at least one connected Search Console property. An account that has neither is sent to complete those first rather than handed a token that every subsequent tool call would reject.
Keys are prefixed gscw_live_, created under Account → API keys, and presented as Authorization: Bearer. Only a SHA-256 hash is stored, so the plaintext is shown once at creation and cannot be recovered afterwards; rotation means issuing a new key and revoking the old one.
Each key carries a scope fixed at creation. A read-scoped key cannot invoke a mutation tool: the check runs in the pipeline before the handler, so read-only is a structural property of the credential rather than an instruction the model could be talked out of.
Four Claude surfaces, three different wiring mechanisms.
Settings → Connectors → Add custom connector. Enter the URL and leave both OAuth fields empty.
URL: https://mcp.gscwizard.com/mcp
OAuth Client ID: (leave blank)
OAuth Secret: (leave blank)One command registers the remote server with a key header. Verify with /mcp inside a session.
claude mcp add --transport http gsc-wizard \
https://mcp.gscwizard.com/mcp \
--header "Authorization: Bearer gscw_live_..."The desktop config file launches local stdio servers only, so a "type": "http" entry fails validation. Bridge the remote server through mcp-remote (requires Node.js) if you need a static key rather than OAuth.
{
"mcpServers": {
"gsc-wizard": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://mcp.gscwizard.com/mcp",
"--header", "Authorization: Bearer gscw_live_..."
]
}
}
}Declare it as an HTTP MCP server in the agent options; the SDK handles the JSON-RPC handshake.
mcpServers: {
"gsc-wizard": {
type: "http",
url: "https://mcp.gscwizard.com/mcp",
headers: { Authorization: `Bearer ${process.env.GSCW_API_KEY}` }
}
}Use a read-scoped key for anything unattended. If the agent only needs a handful of tools, restrict the allowed tool list client-side as well: a smaller surface is cheaper per turn and narrows what a prompt injection in fetched page content could reach.
125 registered tools: 93 reads and 32 mutations. Fourteen are staged and reachable only by the admin account. Every tool advertises MCP annotations (readOnlyHint, destructiveHint, openWorldHint, title), so a client can present or gate them without hard-coding names.
| Group | Representative tools | Scope |
|---|---|---|
| Search analytics | query_search_analytics, query_top_queries, query_top_pages, query_countries, query_devices | read |
| Analysis | find_decaying_content, analyze_cannibalization, get_ranking_changes, score_opportunities, analyze_ctr_curve | read |
| Detection | detect_anomalies, detect_change_points, forecast_traffic, get_decay_overview | read |
| Indexing | inspect_url, bulk_inspect_urls, get_indexing_tracker, list_sitemaps | read |
| Other sources | Bing Webmaster, GA4, Yandex, Merchant Center, Core Web Vitals | read |
| Mutations | submit_sitemap, submit_indexnow_urls, create_topic_cluster, create_annotation, add_site | write |
Analysis runs server-side. Decay, cannibalization, CTR-curve modelling, change-point detection and opportunity scoring are computed in the server and returned as results. The model receives conclusions and the rows behind them, not a raw dump to reason over statistically, which is both cheaper per turn and not subject to arithmetic drift.
The full per-tool catalog with argument schemas and example payloads is rendered at mcp.gscwizard.com and is coverage-tested against the registry, so it cannot silently fall behind the tools actually registered.
Row caps are not the risk; undisclosed caps are. A model handed exactly limit rows cannot tell a complete answer from a clipped one, and will confidently report "your site has 100 queries". The row-capped tools therefore over-fetch one probe row, return at most limit, and attach a block stating the window, whether more exists, and the exact next call.
"pagination": {
"limit": 100,
"offset": 0,
"returned": 100,
"hasMore": true,
"note": "Showing rows 1-100. Call again with offset: 100 for the next page."
}query_search_analytics defaults to 100 rows rather than its original 1,000: at 1,000 a single call returned roughly 58k tokens, more context than the entire tool list. Ranked analysis tools cap inside the shared analytics core and do not carry a pagination block.
No tool requires the caller to know today's date. Omitted windows default to the last 28 settled days, accounting for the roughly three-day Search Console reporting lag, and a comparison baseline defaults to the prior same-length period. The date parser also coerces the null, "null" and "" values LLM clients commonly emit into "use the default" instead of failing validation, which removes a whole class of retry loops.
| Field | Meaning |
|---|---|
dataSource | clickhouse or api: which path served this read |
settledThrough | Last date with complete data |
dataMaturity | First incomplete date, basis timezone, probe used |
note | Freshness caveat in prose for the model to relay |
These exist so an answer can be attributed. When Claude says traffic fell last week, settledThrough is what distinguishes a real decline from the reporting lag, which is the single most common false alarm in automated Search Console analysis.
Most reads do not hit the Search Console API. Historical performance data is ingested into a ClickHouse warehouse, and eligible reads are served from there: longer history than the API's 16-month window, and no API-side sampling on high-cardinality properties.
Eight search-analytics tools (query_search_analytics, query_top_queries, query_top_pages, query_countries, query_devices, get_site_summary, get_query_performance, get_page_performance) and eleven analysis tools.
Requests needing searchAppearance, the googleNews type, three or more distinct dimensions, or pagination. Also any property whose backfill has not completed.
Routing is automatic and per request; the caller does not choose. Warehouse reads use a read-only role and a row policy keyed to the account, so the tenant boundary is enforced by the database rather than only by the query builder. The server never writes to the warehouse on a read path.
Practical consequence for Claude: the warehouse lags roughly two days behind real time while the live API lags about three, and warehouse-served responses say so in note. Ask for "last week" and you get complete weeks, not a partial tail presented as a drop.
| Surface | Per minute | Per hour |
|---|---|---|
| MCP | 60 | 1,000 |
REST /v1 | 180 | 2,000 |
Counted per user per surface. A throttled call returns which window tripped and how many seconds to wait, so an agent can back off precisely instead of guessing. URL inspections carry a separate daily quota from Google, readable with get_inspection_quota.
| Condition | Behaviour |
|---|---|
| Read key calls a write tool | Rejected before the handler runs |
| Property not connected or not granted | Grant enforcement rejects with the reason |
| Integration not configured | Returns notConfigured: true with a reason rather than erroring |
| Session id replayed with other credentials | Rejected, not rebound |
| Fresh Google OAuth, property not propagated | Google returns 403 for a short window; retry shortly after connecting |
The notConfigured convention matters for agents: an unconfigured GA4 or Merchant Center connection is a state to report, not an exception to retry, and distinguishing the two stops a loop burning its rate limit on a condition no retry can fix.
Google credentials never reach Claude. Search Console tokens are held server-side, encrypted at rest, and refreshed by the server. Claude holds a token or key scoped to GSC Wizard, not to Google.
Scope is structural. A read-scoped credential cannot reach a mutation handler. This is enforced in the shared pipeline, so it holds identically on MCP and REST.
Keys are hashed. SHA-256 only; plaintext shown once. Revocation is immediate.
Every call is audit-logged, success or failure: reads without arguments, writes with them. An agent's actions are reconstructable after the fact.
Property access is per grant. Claude sees only the properties connected to the account, and shared properties carry their own per-grant permissions, including read-only grantees who cannot spend an owner's crawl budget.
For an unattended agent the recommended configuration is a read-scoped key plus a client-side allowlist of the specific tools the job needs. That combination bounds the blast radius of a prompt injection arriving through any content the agent fetches.
Most often a client ID or secret was filled in. The server uses dynamic client registration, so both fields must be blank. Remove the connector, re-add it with only the URL, and let Claude register itself.
Check the two gates the authorize endpoint enforces: an active subscription, and at least one Search Console property connected to the account. A token issued to an account with no connected property has nothing it is allowed to read.
The config file launches local stdio processes only, so "type": "http" is not a valid entry. Use the Connectors UI, or bridge through npx -y mcp-remote as shown above.
Google needs a short window to propagate a newly granted Search Console authorization. A 403 in the first minutes after connecting is usually propagation rather than a permissions error; retry before re-running the OAuth flow.
Check dataSource and settledThrough on the response. A warehouse-served read and a UI view of the same nominal range can end on different dates, and the UI itself samples high-cardinality query reports where the warehouse does not.
Usually a retry loop against a notConfigured response, which no retry can resolve, or per-page iteration where one analysis tool would answer in a single call. Prefer the server-side analysis tools over fetching rows and reasoning over them.
Streamable HTTP at https://mcp.gscwizard.com/mcp. Session continuity is carried by the Mcp-Session-Id response header, and each session is pinned server-side to the user that opened it, so a session id replayed with different credentials is rejected. A stdio entry point exists for local builds, and a REST surface at /v1 serves plain HTTP+JSON through the same pipeline.
The MCP server is the OAuth 2.1 resource server and publishes RFC 9728 protected-resource metadata naming tool.gscwizard.com as the authorization server. Claude then reads RFC 8414 metadata from that issuer, registers itself through RFC 7591 dynamic client registration, and runs an authorization_code flow with PKCE S256. That is why the client ID and secret fields are left blank.
mcp:read and mcp:write. Bearer tokens are accepted in the Authorization header only. API keys carry the equivalent distinction as a scope fixed at creation: a read key cannot invoke a mutation tool, so the gate is structural rather than a prompt instruction.
125 registered tools: 93 reads and 32 mutations. Fourteen are staged and reachable only by the admin account. All three surfaces execute through one runTool() pipeline, so authorization, validation, grant enforcement and the audit trail cannot drift between them.
The Claude Desktop config file launches local stdio servers only, so a remote HTTP entry fails validation. Either use the Connectors UI, which speaks Streamable HTTP over OAuth natively, or bridge the remote server through npx mcp-remote, which requires Node.js and lets you present a static gscw_live_ API key instead.
The MCP surface allows 60 calls per minute and 1,000 per hour per user. The REST surface at /v1 allows 180 per minute and 2,000 per hour. Limits are counted per user per surface, and a throttled call returns the number of seconds to wait before retrying.
Not for most reads. Eight search-analytics tools and eleven analysis tools auto-route to a ClickHouse warehouse holding the account's historical Search Console data, which gives longer history and avoids the API's sampling. Every response carries a dataSource field of clickhouse or api, plus settledThrough and a freshness note when warehouse-served. Requests needing searchAppearance, the googleNews type, three or more distinct dimensions, or pagination always fall back to the live API.
Row-capped tools over-fetch a single probe row and return a pagination block stating the window, whether more rows exist and the exact next call. Silent truncation is the failure mode being designed out: a model handed exactly limit rows cannot distinguish a complete answer from a clipped one. query_search_analytics defaults to 100 rows because at 1,000 a single call returned roughly 58k tokens, more context than the entire tool list.
The step-by-step setup walkthrough for Claude web, desktop and Claude Code.
The product overview: what the server does across every MCP client.
The same server's GA4 surface: sessions, key events, ecommerce and LLM traffic.
Cursor, VS Code, Windsurf, Gemini, Grok and ChatGPT alongside Claude.
A worked unattended agent built on this server plus a crawler MCP.
How the first-party data servers compare with the third-party platforms.
One endpoint, OAuth or a scoped key, and 125 tools against the properties you already own.
Practical GSC and GA4 workflows, product updates and SEO experiments. No spam, unsubscribe anytime.