gogcli-mcp-docs 2.23.1 → 2.24.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.
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "metadata": {
9
9
  "description": "Extended Google Docs for Claude via gogcli — auth + full Docs and comments support",
10
- "version": "2.23.1"
10
+ "version": "2.24.0"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,7 +15,7 @@
15
15
  "displayName": "gogcli (Docs)",
16
16
  "source": "./",
17
17
  "description": "Extended Google Docs for Claude via gogcli — auth + full Docs and comments support",
18
- "version": "2.23.1",
18
+ "version": "2.24.0",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gogcli-mcp-docs",
3
3
  "displayName": "gogcli (Docs)",
4
- "version": "2.23.1",
4
+ "version": "2.24.0",
5
5
  "description": "Extended Google Docs for Claude via gogcli — auth + full Docs and comments support",
6
6
  "author": {
7
7
  "name": "Chris Hall",
package/dist/index.js CHANGED
@@ -31542,6 +31542,26 @@ function normalizeTimestamps(text, tz = displayTimeZone(), naiveTz = naiveSource
31542
31542
  return JSON.stringify(parsed, null, detectIndent(text));
31543
31543
  }
31544
31544
 
31545
+ // ../gogcli-mcp/src/pagination.ts
31546
+ function detectIndent2(text) {
31547
+ const match = /\n(\s+)\S/.exec(text);
31548
+ return match ? match[1].replace(/\t/g, " ").length : 0;
31549
+ }
31550
+ function stripConsumedPageToken(text) {
31551
+ const trimmed = text.trim();
31552
+ if (trimmed === "" || !trimmed.startsWith("{")) return text;
31553
+ let parsed;
31554
+ try {
31555
+ parsed = JSON.parse(trimmed);
31556
+ } catch {
31557
+ return text;
31558
+ }
31559
+ const obj = parsed;
31560
+ if (obj.nextPageToken !== "") return text;
31561
+ delete obj.nextPageToken;
31562
+ return JSON.stringify(obj, null, detectIndent2(text));
31563
+ }
31564
+
31545
31565
  // ../gogcli-mcp/src/tools/utils.ts
31546
31566
  var PAYLOAD_INLINE_MAX = 4096;
31547
31567
  function payloadArg(inlineFlag, fileFlag, value, ext) {
@@ -31577,14 +31597,25 @@ var ids = {
31577
31597
  // People API uses fully-qualified resource names ("people/c123") not bare IDs.
31578
31598
  person: external_exports.string().describe("Person resource name (people/...) or email")
31579
31599
  };
31600
+ var pageTokenParam = external_exports.string().optional().describe(
31601
+ "Cursor for the NEXT page. Pass back the nextPageToken from a previous response verbatim, keeping the query and max identical: call once, then call again with pageToken=<that value>. A response with NO nextPageToken is the last page."
31602
+ );
31603
+ var pageAliasParam = external_exports.string().optional().describe(
31604
+ "Deprecated alias for pageToken, accepted so existing callers keep working. Use pageToken \u2014 it matches the nextPageToken field in the response."
31605
+ );
31606
+ function resolvePageToken(p) {
31607
+ return p.pageToken ?? p.page;
31608
+ }
31580
31609
  var paginationParams = {
31581
31610
  max: external_exports.number().int().optional().describe("Max results"),
31582
- page: external_exports.string().optional().describe("Page token"),
31611
+ pageToken: pageTokenParam,
31612
+ page: pageAliasParam,
31583
31613
  all: external_exports.boolean().optional().describe("Fetch all pages")
31584
31614
  };
31585
31615
  function pushPaginationFlags(args, p) {
31586
31616
  if (p.max !== void 0) args.push(`--max=${p.max}`);
31587
- if (p.page) args.push(`--page=${p.page}`);
31617
+ const token = resolvePageToken(p);
31618
+ if (token) args.push(`--page=${token}`);
31588
31619
  if (p.all) args.push("--all");
31589
31620
  }
31590
31621
  function registerRunTool(server, options) {
@@ -31659,7 +31690,7 @@ ${accounts || "(none)"}${hint}`);
31659
31690
  async function runOrDiagnose(args, options) {
31660
31691
  try {
31661
31692
  const raw = await run(args, options);
31662
- return rawTextResult(options.lossless ? raw : normalizeTimestamps(raw));
31693
+ return rawTextResult(options.lossless ? raw : stripConsumedPageToken(normalizeTimestamps(raw)));
31663
31694
  } catch (err) {
31664
31695
  return diagnose(err);
31665
31696
  }
@@ -31709,6 +31740,7 @@ function formatAuthHealth(raw, now) {
31709
31740
  // ../gogcli-mcp/src/tools/auth.ts
31710
31741
  function registerAuthToolsWith(server, defaultServices) {
31711
31742
  const servicesDescribe = `Services to authorize: "all" or comma-separated list (e.g. "sheets,gmail,calendar"). Default: "${defaultServices}". Prefer the narrowest set you need \u2014 requesting a service whose Google API is not enabled on the OAuth client's project makes Google reject the WHOLE request with invalid_scope.`;
31743
+ const extraScopesDescribe = "Additional raw OAuth scope URIs to request, comma-separated, on top of the ones `services` implies. Use for scopes no service covers \u2014 e.g. https://www.googleapis.com/auth/bigquery.readonly, required before gog_sheets_datasource_* can read BigQuery-backed Connected Sheets. Leave unset otherwise: an extra scope whose API is not enabled on the OAuth client project makes Google reject the WHOLE authorization with invalid_scope.";
31712
31744
  server.registerTool("gog_auth_list", {
31713
31745
  description: "List the Google accounts stored in gogcli, with their scopes. This reads local configuration only \u2014 it does not contact Google and does NOT tell you whether an account still works: a signed-out account whose refresh token expired or was revoked is listed here exactly like a healthy one, scopes and all. Use gog_auth_health to check whether an account can actually authenticate.",
31714
31746
  annotations: { readOnlyHint: true },
@@ -31758,11 +31790,14 @@ function registerAuthToolsWith(server, defaultServices) {
31758
31790
  annotations: { destructiveHint: true },
31759
31791
  inputSchema: {
31760
31792
  email: external_exports.string().describe("Google account email to authorize"),
31761
- services: external_exports.string().optional().default(defaultServices).describe(servicesDescribe)
31793
+ services: external_exports.string().optional().default(defaultServices).describe(servicesDescribe),
31794
+ extraScopes: external_exports.string().optional().describe(extraScopesDescribe)
31762
31795
  }
31763
- }, async ({ email: email3, services = defaultServices }) => {
31796
+ }, async ({ email: email3, services = defaultServices, extraScopes }) => {
31764
31797
  try {
31765
- return rawTextResult(await run(["auth", "add", email3, "--services", services], {
31798
+ const args = ["auth", "add", email3, "--services", services];
31799
+ if (extraScopes) args.push(`--extra-scopes=${extraScopes}`, "--force-consent");
31800
+ return rawTextResult(await run(args, {
31766
31801
  interactive: true,
31767
31802
  timeout: 3e5
31768
31803
  }));
@@ -31774,14 +31809,14 @@ function registerAuthToolsWith(server, defaultServices) {
31774
31809
  description: "Begin REMOTE/headless Google authorization (step 1 of 2). Returns a sign-in URL to open in any browser \u2014 no local server or terminal on the gogcli host is needed, so this works over the hosted connector where the interactive gog_auth_add cannot. Hand the URL to the user; after they sign in, the browser is redirected to a localhost URL that fails to load \u2014 that is expected. They copy that full redirected URL (from the address bar) and you pass it to gog_auth_add_complete. The link is valid for 10 minutes. If you pass a custom `services` here, pass the SAME value to gog_auth_add_complete or the second step will not match this one.",
31775
31810
  inputSchema: {
31776
31811
  email: external_exports.string().describe("Google account email to authorize"),
31777
- services: external_exports.string().optional().default(defaultServices).describe(servicesDescribe)
31812
+ services: external_exports.string().optional().default(defaultServices).describe(servicesDescribe),
31813
+ extraScopes: external_exports.string().optional().describe(`${extraScopesDescribe} Pass the SAME value to gog_auth_add_complete.`)
31778
31814
  }
31779
- }, async ({ email: email3, services = defaultServices }) => {
31815
+ }, async ({ email: email3, services = defaultServices, extraScopes }) => {
31780
31816
  try {
31781
- return rawTextResult(await run(
31782
- ["auth", "add", email3, "--remote", "--step", "1", "--services", services, "--force-consent"],
31783
- { redactMode: "tokens" }
31784
- ));
31817
+ const args = ["auth", "add", email3, "--remote", "--step", "1", "--services", services, "--force-consent"];
31818
+ if (extraScopes) args.push(`--extra-scopes=${extraScopes}`);
31819
+ return rawTextResult(await run(args, { redactMode: "tokens" }));
31785
31820
  } catch (err) {
31786
31821
  return errorResult(errorText(err));
31787
31822
  }
@@ -31796,25 +31831,28 @@ function registerAuthToolsWith(server, defaultServices) {
31796
31831
  ),
31797
31832
  services: external_exports.string().optional().default(defaultServices).describe(
31798
31833
  `Services authorized \u2014 MUST match the value passed to gog_auth_add_url. Default: "${defaultServices}".`
31834
+ ),
31835
+ extraScopes: external_exports.string().optional().describe(
31836
+ "Extra OAuth scope URIs \u2014 MUST match the value passed to gog_auth_add_url, for the same reason `services` must: the two steps have to describe the same grant."
31799
31837
  )
31800
31838
  }
31801
- }, async ({ email: email3, redirectUrl, services = defaultServices }) => {
31839
+ }, async ({ email: email3, redirectUrl, services = defaultServices, extraScopes }) => {
31802
31840
  try {
31803
- return rawTextResult(await run(
31804
- [
31805
- "auth",
31806
- "add",
31807
- email3,
31808
- "--remote",
31809
- "--step",
31810
- "2",
31811
- "--auth-url",
31812
- redirectUrl,
31813
- "--services",
31814
- services,
31815
- "--force-consent"
31816
- ]
31817
- ));
31841
+ const args = [
31842
+ "auth",
31843
+ "add",
31844
+ email3,
31845
+ "--remote",
31846
+ "--step",
31847
+ "2",
31848
+ "--auth-url",
31849
+ redirectUrl,
31850
+ "--services",
31851
+ services,
31852
+ "--force-consent"
31853
+ ];
31854
+ if (extraScopes) args.push(`--extra-scopes=${extraScopes}`);
31855
+ return rawTextResult(await run(args));
31818
31856
  } catch (err) {
31819
31857
  return errorResult(errorText(err));
31820
31858
  }
@@ -31939,7 +31977,7 @@ var failIfNotEmptyParam = external_exports.boolean().optional().describe(
31939
31977
  );
31940
31978
 
31941
31979
  // ../gogcli-mcp/src/server.ts
31942
- var VERSION = true ? "2.23.1" : "0.0.0";
31980
+ var VERSION = true ? "2.24.0" : "0.0.0";
31943
31981
 
31944
31982
  // ../gogcli-mcp/src/auth-log.ts
31945
31983
  var FAILURES = /* @__PURE__ */ new Set([
package/manifest.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "manifest_version": "0.3",
4
4
  "name": "gogcli-mcp-docs",
5
5
  "display_name": "gogcli (Docs)",
6
- "version": "2.23.1",
6
+ "version": "2.24.0",
7
7
  "description": "Extended Google Docs for Claude via gogcli — auth + full Docs and comments support",
8
8
  "author": {
9
9
  "name": "Chris Hall",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gogcli-mcp-docs",
3
- "version": "2.23.1",
3
+ "version": "2.24.0",
4
4
  "mcpName": "io.github.chrischall/gogcli-mcp-docs",
5
5
  "description": "Extended Google Docs MCP server via gogcli — all base tools plus full Docs support",
6
6
  "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "source": "github",
8
8
  "subfolder": "packages/gogcli-mcp-docs"
9
9
  },
10
- "version": "2.23.1",
10
+ "version": "2.24.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "gogcli-mcp-docs",
15
- "version": "2.23.1",
15
+ "version": "2.24.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  },