@digestseo/mcp-gsc 0.4.19 → 0.4.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +2 -4
- package/SETUP.md +0 -3
- package/package.json +1 -1
- package/src/index.ts +41 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.20] - 2026-09-22
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Modern MCP requests that use the 2026-07-28 `Mcp-Method` header now fail with the required HTTP 400 `HeaderMismatch` error when `MCP-Protocol-Version` is missing, while legacy initialization without the modern header remains compatible.
|
|
14
|
+
- Repo-owned onboarding and support documentation no longer advertises the intentionally unavailable owner-hosted/automatic-weekly-email service, and Cursor guidance now identifies the one-click path as the local npm launcher.
|
|
15
|
+
- `GET /` now returns deployment-neutral discovery text with the derived MCP endpoint and canonical setup link instead of calling every deployment hosted or telling loopback users to connect it directly from Claude.ai.
|
|
16
|
+
|
|
10
17
|
## [0.4.19] - 2026-09-22
|
|
11
18
|
|
|
12
19
|
### Fixed
|
package/README.md
CHANGED
|
@@ -68,8 +68,6 @@ A self-hostable [Model Context Protocol](https://modelcontextprotocol.io) (MCP)
|
|
|
68
68
|
|
|
69
69
|
It runs on [Cloudflare Workers](https://workers.cloudflare.com/) and ships with one-click Google OAuth onboarding: connect the server in your client, sign in with Google once, grant the requested Google Search Console permissions, and you're done. No API keys to copy around and no service-account JSON to manage.
|
|
70
70
|
|
|
71
|
-
> **Prefer zero setup?** The hosted version — with automatic weekly email digests delivered to your inbox — is at **[digestseo.com](https://digestseo.com)**. This repository is the open-source core you can run yourself.
|
|
72
|
-
|
|
73
71
|
## Tools
|
|
74
72
|
|
|
75
73
|
By default (`GSC_ACCESS_MODE=readwrite`), this server exposes 22 tools. Read-only analytics and reporting tools are marked with MCP's `readOnlyHint`; the write tools below can change Search Console properties, sitemaps, or indexing state. Set `GSC_ACCESS_MODE=readonly` to request only the Search Console read-only scope and expose the 16 tools that do not require either write access or the separate Indexing API scope.
|
|
@@ -126,7 +124,7 @@ https://<your-worker>.workers.dev/mcp
|
|
|
126
124
|
```
|
|
127
125
|
|
|
128
126
|
- **Claude.ai / Claude Desktop** — go to **Customize → Connectors**, click **+ → Add custom connector**, enter a name and paste the `/mcp` URL. Leave the optional advanced OAuth Client ID/Secret fields blank. On Team/Enterprise, an Owner or Primary Owner must first add the custom Web connector from **Organization settings → Connectors**; members then connect it from Customize → Connectors. On first connection, Claude opens the Google sign-in flow.
|
|
129
|
-
- **Cursor** — add a remote **Streamable HTTP** MCP server pointing at the same `/mcp` URL; Cursor supports OAuth for remote HTTP MCP servers. The
|
|
127
|
+
- **Cursor** — add a remote **Streamable HTTP** MCP server pointing at the same `/mcp` URL; Cursor supports OAuth for remote HTTP MCP servers. The Add to Cursor button above targets the local npm launcher's loopback endpoint instead.
|
|
130
128
|
- **ChatGPT** — enable **Developer mode**, then create a custom MCP **app** from **Settings → Apps → Create** (admins/owners can also use **Workspace settings → Apps → Create**). Provide the `/mcp` endpoint, select the applicable authentication option, **Scan Tools**, complete OAuth, then create the app. Full MCP including write/modify tools is currently available to Business and Enterprise/Edu; Pro custom MCP access is read/fetch-only, so use `GSC_ACCESS_MODE=readonly` for that path.
|
|
131
129
|
|
|
132
130
|
The `/mcp` endpoint is the same across clients, but each host has its own setup and permission flow.
|
|
@@ -166,4 +164,4 @@ Contributions welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
|
166
164
|
|
|
167
165
|
---
|
|
168
166
|
|
|
169
|
-
*Built and maintained by [Tomi Šeregi](https://tomiseregi.si), the builder behind [
|
|
167
|
+
*Built and maintained by [Tomi Šeregi](https://tomiseregi.si), the builder behind [DigestSEO](https://digestseo.com) - open-source SEO tooling and search visibility software.*
|
package/SETUP.md
CHANGED
|
@@ -84,7 +84,6 @@ npx wrangler login
|
|
|
84
84
|
- The `npx` launcher persists its local KV and Durable Object state in `~/.mcp-gsc/state` by default so npm package upgrades or cache cleanup do not discard the encrypted Google session. Set `MCP_GSC_STATE_DIR` to use another directory, and keep the same `TOKEN_ENCRYPTION_KEY` when reusing existing state. The first release with this stable path may require one Google reconnect because older launcher releases stored local state under the npm package cache.
|
|
85
85
|
- The Worker derives Google's redirect URI from the MCP request URL. Google requires an exact authorized-URI match, so keep the same scheme, host, port, and `/google/callback` path. `localhost` and `127.0.0.1` are different hosts for this check.
|
|
86
86
|
- The path must be exactly `/google/callback` — that's the route this server handles.
|
|
87
|
-
- The DigestSEO-hosted instance also requires this exact callback URI in the OAuth client configured on its Worker: `https://mcp-gsc.digestseo.com/google/callback`.
|
|
88
87
|
4. Click **Create**. Copy the **Client ID** and **Client secret** — you'll set them as secrets in the next step.
|
|
89
88
|
|
|
90
89
|
---
|
|
@@ -208,8 +207,6 @@ To remove all three limits you must move the app to **Publishing status: In prod
|
|
|
208
207
|
|
|
209
208
|
**Bottom line:** for personal use with one or two Google accounts, Testing mode is fine as long as you don't mind reconnecting roughly every 7 days. For anything shared or automated, you'll want to complete Google's verification — and that, not the code, is the heaviest part of self-hosting a Google Search Console MCP.
|
|
210
209
|
|
|
211
|
-
> Don't want to deal with verification at all? The hosted version at **[digestseo.com](https://digestseo.com)** has already been through it (and adds automatic weekly email digests on top).
|
|
212
|
-
|
|
213
210
|
---
|
|
214
211
|
|
|
215
212
|
## Troubleshooting
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -2055,7 +2055,44 @@ export async function createGscMcpServer(
|
|
|
2055
2055
|
}
|
|
2056
2056
|
|
|
2057
2057
|
export const mcpApiHandler = {
|
|
2058
|
-
fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
2058
|
+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
2059
|
+
if (
|
|
2060
|
+
request.method === 'POST' &&
|
|
2061
|
+
request.headers.has('Mcp-Method') &&
|
|
2062
|
+
!request.headers.has('MCP-Protocol-Version')
|
|
2063
|
+
) {
|
|
2064
|
+
let id: string | number | null = null;
|
|
2065
|
+
let isRequest = false;
|
|
2066
|
+
try {
|
|
2067
|
+
const body = (await request.clone().json()) as { id?: unknown };
|
|
2068
|
+
if (Object.prototype.hasOwnProperty.call(body, 'id')) {
|
|
2069
|
+
isRequest = true;
|
|
2070
|
+
if (typeof body.id === 'string' || typeof body.id === 'number') {
|
|
2071
|
+
id = body.id;
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
} catch {
|
|
2075
|
+
// Let the SDK handle malformed bodies; this guard targets valid modern requests.
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
if (isRequest) {
|
|
2079
|
+
return new Response(
|
|
2080
|
+
JSON.stringify({
|
|
2081
|
+
jsonrpc: '2.0',
|
|
2082
|
+
id,
|
|
2083
|
+
error: {
|
|
2084
|
+
code: -32020,
|
|
2085
|
+
message: 'HeaderMismatch: MCP-Protocol-Version header is required for modern MCP requests.',
|
|
2086
|
+
},
|
|
2087
|
+
}),
|
|
2088
|
+
{
|
|
2089
|
+
status: 400,
|
|
2090
|
+
headers: { 'content-type': 'application/json; charset=utf-8' },
|
|
2091
|
+
},
|
|
2092
|
+
);
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2059
2096
|
const handler = createMcpHandler(() => createGscMcpServer(env), {
|
|
2060
2097
|
route: '/mcp',
|
|
2061
2098
|
});
|
|
@@ -2119,9 +2156,9 @@ export const defaultHandler = {
|
|
|
2119
2156
|
});
|
|
2120
2157
|
}
|
|
2121
2158
|
return new Response(
|
|
2122
|
-
'mcp-gsc —
|
|
2123
|
-
|
|
2124
|
-
|
|
2159
|
+
'mcp-gsc — Google Search Console MCP server.\n' +
|
|
2160
|
+
`MCP endpoint: ${url.origin}/mcp\n` +
|
|
2161
|
+
'Setup: https://github.com/AKzar1el/mcp-gsc#readme\n',
|
|
2125
2162
|
{ headers: { 'content-type': 'text/plain; charset=utf-8' } },
|
|
2126
2163
|
);
|
|
2127
2164
|
}
|