mcp-google-gsc 1.1.2 → 1.2.0
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/README.md +57 -15
- package/config.example.json +3 -1
- package/dist/auth-cli.d.ts +10 -0
- package/dist/auth-cli.js +54 -15
- package/dist/authMode.d.ts +22 -0
- package/dist/authMode.js +14 -0
- package/dist/build-info.json +2 -2
- package/dist/credentials.js +4 -4
- package/dist/index.d.ts +52 -0
- package/dist/index.js +61 -14
- package/dist/oauthScope.d.ts +18 -0
- package/dist/oauthScope.js +25 -0
- package/dist/pkce.d.ts +9 -0
- package/dist/pkce.js +24 -0
- package/dist/resilience.js +41 -23
- package/get-refresh-token.cjs +296 -0
- package/package.json +18 -6
- package/dist/auth-cli.js.map +0 -7
- package/dist/credentials.js.map +0 -7
- package/dist/embedded-secrets.js.map +0 -7
- package/dist/errors.js.map +0 -7
- package/dist/index.js.map +0 -7
- package/dist/platform.js.map +0 -7
- package/dist/resilience.js.map +0 -7
- package/dist/tools.js.map +0 -7
- package/dist/updateNotifier.d.ts +0 -7
- package/dist/updateNotifier.js +0 -53
- package/dist/updateNotifier.js.map +0 -7
package/dist/resilience.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/resilience.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n retry,\n circuitBreaker,\n wrap,\n handleWhen,\n timeout,\n TimeoutStrategy,\n ExponentialBackoff,\n ConsecutiveBreaker,\n} from \"cockatiel\";\nimport pino from \"pino\";\n\n// ============================================\n// LOGGER\n// ============================================\n\nexport const logger = pino(\n {\n level: process.env.LOG_LEVEL || \"info\",\n redact: [\"access_token\", \"refresh_token\", \"client_secret\", \"*.access_token\", \"*.refresh_token\", \"*.client_secret\"],\n ...(process.env.NODE_ENV !== \"test\" && process.stderr.isTTY && {\n transport: {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n singleLine: true,\n translateTime: \"SYS:standard\",\n destination: 2, // stderr -- stdout is reserved for MCP JSON-RPC\n },\n },\n }),\n },\n pino.destination(2),\n);\n\n// ============================================\n// SAFE RESPONSE (Response Size Limiting)\n// ============================================\n\nconst MAX_RESPONSE_SIZE = 200_000; // 200KB\n\nexport function safeResponse<T>(data: T, context: string): T {\n let current = data;\n for (let pass = 0; pass < 10; pass++) {\n const jsonStr = JSON.stringify(current);\n const sizeBytes = Buffer.byteLength(jsonStr, \"utf-8\");\n if (sizeBytes <= MAX_RESPONSE_SIZE) return current;\n\n // Deep clone on first truncation pass to avoid mutating the original object\n if (pass === 0 && typeof current === \"object\" && current !== null) {\n current = JSON.parse(JSON.stringify(current)) as T;\n }\n\n logger.warn({ sizeBytes, maxSize: MAX_RESPONSE_SIZE, context, pass }, \"Response exceeds size limit, truncating\");\n\n if (Array.isArray(current)) {\n current = (current as any[]).slice(0, Math.max(1, Math.floor((current as any[]).length * 0.5))) as T;\n continue;\n }\n\n if (typeof current === \"object\" && current !== null) {\n const obj = current as Record<string, any>;\n let truncated = false;\n for (const key of [\"items\", \"results\", \"data\", \"rows\", \"tags\", \"triggers\", \"variables\"]) {\n if (Array.isArray(obj[key]) && obj[key].length > 1) {\n obj[key] = obj[key].slice(0, Math.max(1, Math.floor(obj[key].length * 0.5)));\n if (\"count\" in obj) obj.count = obj[key].length;\n if (\"row_count\" in obj) obj.row_count = obj[key].length;\n obj.truncated = true;\n truncated = true;\n break;\n }\n }\n if (truncated) continue;\n }\n\n break;\n }\n return current;\n}\n\n// ============================================\n// RETRY + CIRCUIT BREAKER + TIMEOUT\n// ============================================\n\nconst backoff = new ExponentialBackoff({\n initialDelay: 100,\n maxDelay: 5_000,\n});\n\nconst isTransient = handleWhen((err) => {\n const msg = (err?.message || \"\").toLowerCase();\n const code = (err as any)?.code || (err as any)?.status;\n if (code === 401 || code === 403 || code === 7 || code === 16) return false;\n if (msg.includes(\"unauthenticated\") || msg.includes(\"permission_denied\") || msg.includes(\"invalid_grant\")) return false;\n if (code === 429 || msg.includes(\"rate\")) return true;\n if (code >= 400 && code < 500) return false;\n return true;\n});\n\nconst retryPolicy = retry(isTransient, {\n maxAttempts: 3,\n backoff,\n});\n\nconst circuitBreakerPolicy = circuitBreaker(isTransient, {\n halfOpenAfter: 60_000,\n breaker: new ConsecutiveBreaker(5),\n});\n\nconst timeoutPolicy = timeout(30_000, TimeoutStrategy.Cooperative);\n\nconst policy = wrap(timeoutPolicy, circuitBreakerPolicy, retryPolicy);\n\n// ============================================\n// WRAPPED API CALL WITH LOGGING\n// ============================================\n\nexport async function withResilience<T>(\n fn: () => Promise<T>,\n operationName: string\n): Promise<T> {\n try {\n logger.debug({ operation: operationName }, \"Starting API call\");\n\n const result = await policy.execute(() => fn());\n\n logger.debug({ operation: operationName }, \"API call succeeded\");\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n logger.error(\n { operation: operationName, error: error.message, stack: error.stack },\n \"API call failed after retries\"\n );\n throw error;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/tools.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/tools.ts"],
|
|
4
|
-
"sourcesContent": ["import { Tool } from \"@modelcontextprotocol/sdk/types.js\";\n\nexport const tools: Tool[] = [\n {\n name: \"gsc_get_client_context\",\n description:\n \"Get the current GSC client context and health status based on working directory. Call this first to confirm which Search Console property you're working with.\",\n inputSchema: {\n additionalProperties: false,\n type: \"object\",\n properties: {\n working_directory: {\n type: \"string\",\n description: \"The current working directory\",\n },\n },\n required: [\"working_directory\"],\n },\n },\n {\n name: \"gsc_list_sites\",\n description:\n \"List all verified sites/properties in Google Search Console.\",\n inputSchema: {\n additionalProperties: false,\n type: \"object\",\n properties: {},\n },\n },\n {\n name: \"gsc_search_analytics\",\n description:\n 'Query Google Search Console search analytics data. Returns clicks, impressions, CTR, and position for queries, pages, devices, countries, or dates.',\n inputSchema: {\n additionalProperties: false,\n type: \"object\",\n properties: {\n start_date: {\n type: \"string\",\n description:\n 'Start date (YYYY-MM-DD or relative like \"90daysAgo\", \"30daysAgo\", \"7daysAgo\", \"today\")',\n },\n end_date: {\n type: \"string\",\n description: 'End date (YYYY-MM-DD or relative like \"today\")',\n },\n dimensions: {\n type: \"string\",\n description:\n \"Comma-separated dimensions: query, page, device, country, date\",\n },\n search_type: {\n type: \"string\",\n description: 'Search type: web, image, video, news (default \"web\")',\n },\n dimension_filter: {\n type: \"string\",\n description:\n 'Optional filter (e.g., \"query contains nonprofit\", \"page contains /blog/\", \"country equals USA\")',\n },\n row_limit: {\n type: \"number\",\n description: \"Max rows to return (default 100, max 25000)\",\n },\n aggregation_type: {\n type: \"string\",\n description:\n 'Aggregation: auto, byPage, byProperty (default \"auto\")',\n },\n site_url: {\n type: \"string\",\n description:\n \"Site URL (optional - auto-detected from working directory config)\",\n },\n },\n },\n },\n {\n name: \"gsc_inspection\",\n description:\n \"Inspect a URL to check if it is indexed in Google Search. Returns index status, mobile usability, and rich results data.\",\n inputSchema: {\n additionalProperties: false,\n type: \"object\",\n properties: {\n url: {\n type: \"string\",\n description:\n 'The fully qualified URL to inspect (e.g., \"https://www.example.com/blog/post\")',\n },\n site_url: {\n type: \"string\",\n description:\n \"Site URL / property (optional - auto-detected from config)\",\n },\n },\n required: [\"url\"],\n },\n },\n];\n"],
|
|
5
|
-
"mappings": "AAEO,MAAM,QAAgB;AAAA,EAC3B;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,sBAAsB;AAAA,MACtB,MAAM;AAAA,MACN,YAAY;AAAA,QACV,mBAAmB;AAAA,UACjB,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,mBAAmB;AAAA,IAChC;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,sBAAsB;AAAA,MACtB,MAAM;AAAA,MACN,YAAY,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,sBAAsB;AAAA,MACtB,MAAM;AAAA,MACN,YAAY;AAAA,QACV,YAAY;AAAA,UACV,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,UAAU;AAAA,UACR,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,YAAY;AAAA,UACV,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,kBAAkB;AAAA,UAChB,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,kBAAkB;AAAA,UAChB,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,UAAU;AAAA,UACR,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,sBAAsB;AAAA,MACtB,MAAM;AAAA,MACN,YAAY;AAAA,QACV,KAAK;AAAA,UACH,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,UAAU;AAAA,UACR,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,MACF;AAAA,MACA,UAAU,CAAC,KAAK;AAAA,IAClB;AAAA,EACF;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/updateNotifier.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export type FetchLatestVersion = () => Promise<string>;
|
|
2
|
-
export interface UpdateNotifierDeps {
|
|
3
|
-
fetchLatestVersion?: FetchLatestVersion;
|
|
4
|
-
log?: (msg: string) => void;
|
|
5
|
-
env?: NodeJS.ProcessEnv;
|
|
6
|
-
}
|
|
7
|
-
export declare function checkForUpdate(pkgName: string, currentVersion: string, deps?: UpdateNotifierDeps): Promise<void>;
|
package/dist/updateNotifier.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
async function checkForUpdate(pkgName, currentVersion, deps = {}) {
|
|
2
|
-
const env = deps.env ?? process.env;
|
|
3
|
-
if (env.MCP_DISABLE_UPDATE_CHECK === "1" || env.NODE_ENV === "test") {
|
|
4
|
-
return;
|
|
5
|
-
}
|
|
6
|
-
const log = deps.log ?? ((msg) => process.stderr.write(msg + "\n"));
|
|
7
|
-
const fetcher = deps.fetchLatestVersion ?? (() => defaultFetch(pkgName));
|
|
8
|
-
let latest;
|
|
9
|
-
try {
|
|
10
|
-
latest = await fetcher();
|
|
11
|
-
} catch {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
if (!latest || !semverLt(currentVersion, latest)) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
log(
|
|
18
|
-
`[update] ${pkgName}@${latest} is available (running ${currentVersion}). Upgrade: npx -y ${pkgName}@latest (and relaunch Claude Desktop).`
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
async function defaultFetch(pkgName) {
|
|
22
|
-
const controller = new AbortController();
|
|
23
|
-
const timer = setTimeout(() => controller.abort(), 2e3);
|
|
24
|
-
try {
|
|
25
|
-
const res = await fetch(`https://registry.npmjs.org/${pkgName}/latest`, {
|
|
26
|
-
signal: controller.signal,
|
|
27
|
-
headers: { Accept: "application/json" }
|
|
28
|
-
});
|
|
29
|
-
if (!res.ok) {
|
|
30
|
-
throw new Error(`HTTP ${res.status}`);
|
|
31
|
-
}
|
|
32
|
-
const body = await res.json();
|
|
33
|
-
if (typeof body.version !== "string") {
|
|
34
|
-
throw new Error("registry response missing version field");
|
|
35
|
-
}
|
|
36
|
-
return body.version;
|
|
37
|
-
} finally {
|
|
38
|
-
clearTimeout(timer);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
function semverLt(a, b) {
|
|
42
|
-
const pa = a.split(".").map((x) => parseInt(x, 10) || 0);
|
|
43
|
-
const pb = b.split(".").map((x) => parseInt(x, 10) || 0);
|
|
44
|
-
for (let i = 0; i < 3; i++) {
|
|
45
|
-
if ((pa[i] ?? 0) < (pb[i] ?? 0)) return true;
|
|
46
|
-
if ((pa[i] ?? 0) > (pb[i] ?? 0)) return false;
|
|
47
|
-
}
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
export {
|
|
51
|
-
checkForUpdate
|
|
52
|
-
};
|
|
53
|
-
//# sourceMappingURL=updateNotifier.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/updateNotifier.ts"],
|
|
4
|
-
"sourcesContent": ["// Fire-and-forget npm registry check at startup. Logs to stderr when a\n// newer version is available. stdout is reserved for MCP JSON-RPC, so the\n// message never goes there. Silent on network error, timeout, or when the\n// installed version is equal to or ahead of the registry latest.\n//\n// Opt out by setting MCP_DISABLE_UPDATE_CHECK=1 (CI, offline, air-gapped).\n// Also skipped when NODE_ENV=test to keep vitest runs silent.\n\nexport type FetchLatestVersion = () => Promise<string>;\n\nexport interface UpdateNotifierDeps {\n fetchLatestVersion?: FetchLatestVersion;\n log?: (msg: string) => void;\n env?: NodeJS.ProcessEnv;\n}\n\nexport async function checkForUpdate(\n pkgName: string,\n currentVersion: string,\n deps: UpdateNotifierDeps = {},\n): Promise<void> {\n const env = deps.env ?? process.env;\n if (env.MCP_DISABLE_UPDATE_CHECK === \"1\" || env.NODE_ENV === \"test\") {\n return;\n }\n const log = deps.log ?? ((msg) => process.stderr.write(msg + \"\\n\"));\n const fetcher = deps.fetchLatestVersion ?? (() => defaultFetch(pkgName));\n let latest: string;\n try {\n latest = await fetcher();\n } catch {\n return;\n }\n if (!latest || !semverLt(currentVersion, latest)) {\n return;\n }\n log(\n `[update] ${pkgName}@${latest} is available (running ${currentVersion}). ` +\n `Upgrade: npx -y ${pkgName}@latest (and relaunch Claude Desktop).`,\n );\n}\n\nasync function defaultFetch(pkgName: string): Promise<string> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 2_000);\n try {\n const res = await fetch(`https://registry.npmjs.org/${pkgName}/latest`, {\n signal: controller.signal,\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n const body = (await res.json()) as { version?: unknown };\n if (typeof body.version !== \"string\") {\n throw new Error(\"registry response missing version field\");\n }\n return body.version;\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction semverLt(a: string, b: string): boolean {\n const pa = a.split(\".\").map((x) => parseInt(x, 10) || 0);\n const pb = b.split(\".\").map((x) => parseInt(x, 10) || 0);\n for (let i = 0; i < 3; i++) {\n if ((pa[i] ?? 0) < (pb[i] ?? 0)) return true;\n if ((pa[i] ?? 0) > (pb[i] ?? 0)) return false;\n }\n return false;\n}\n"],
|
|
5
|
-
"mappings": "AAgBA,eAAsB,eACpB,SACA,gBACA,OAA2B,CAAC,GACb;AACf,QAAM,MAAM,KAAK,OAAO,QAAQ;AAChC,MAAI,IAAI,6BAA6B,OAAO,IAAI,aAAa,QAAQ;AACnE;AAAA,EACF;AACA,QAAM,MAAM,KAAK,QAAQ,CAAC,QAAQ,QAAQ,OAAO,MAAM,MAAM,IAAI;AACjE,QAAM,UAAU,KAAK,uBAAuB,MAAM,aAAa,OAAO;AACtE,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,QAAQ;AAAA,EACzB,QAAQ;AACN;AAAA,EACF;AACA,MAAI,CAAC,UAAU,CAAC,SAAS,gBAAgB,MAAM,GAAG;AAChD;AAAA,EACF;AACA;AAAA,IACE,YAAY,OAAO,IAAI,MAAM,0BAA0B,cAAc,sBAChD,OAAO;AAAA,EAC9B;AACF;AAEA,eAAe,aAAa,SAAkC;AAC5D,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,GAAK;AACxD,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,8BAA8B,OAAO,WAAW;AAAA,MACtE,QAAQ,WAAW;AAAA,MACnB,SAAS,EAAE,QAAQ,mBAAmB;AAAA,IACxC,CAAC;AACD,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI,MAAM,QAAQ,IAAI,MAAM,EAAE;AAAA,IACtC;AACA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,QAAI,OAAO,KAAK,YAAY,UAAU;AACpC,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AACA,WAAO,KAAK;AAAA,EACd,UAAE;AACA,iBAAa,KAAK;AAAA,EACpB;AACF;AAEA,SAAS,SAAS,GAAW,GAAoB;AAC/C,QAAM,KAAK,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,KAAK,CAAC;AACvD,QAAM,KAAK,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,KAAK,CAAC;AACvD,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,SAAK,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,KAAK,GAAI,QAAO;AACxC,SAAK,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,KAAK,GAAI,QAAO;AAAA,EAC1C;AACA,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|