gogcli-mcp-sheets 2.0.10 → 2.0.12

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 Sheets for Claude via gogcli — auth + full Sheets support",
10
- "version": "2.0.10"
10
+ "version": "2.0.12"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,7 +15,7 @@
15
15
  "displayName": "gogcli (Sheets)",
16
16
  "source": "./",
17
17
  "description": "Extended Google Sheets for Claude via gogcli — auth + full Sheets support",
18
- "version": "2.0.10",
18
+ "version": "2.0.12",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gogcli-mcp-sheets",
3
3
  "displayName": "gogcli (Sheets)",
4
- "version": "2.0.10",
4
+ "version": "2.0.12",
5
5
  "description": "Extended Google Sheets for Claude via gogcli — auth + full Sheets support",
6
6
  "author": {
7
7
  "name": "Chris Hall",
package/README.md CHANGED
@@ -3,11 +3,11 @@
3
3
  > [!WARNING]
4
4
  > **AI-developed project.** This codebase was built and is actively maintained by [Claude Code](https://www.anthropic.com/claude). Review all code and tool permissions before use.
5
5
 
6
- Extended Google Sheets [MCP](https://modelcontextprotocol.io) server via [gogcli](https://github.com/steipete/gogcli). Includes auth tools plus 22 additional dedicated Sheets tools for tab management, formatting, named ranges, and more.
6
+ Extended Google Sheets [MCP](https://modelcontextprotocol.io) server via [gogcli](https://github.com/openclaw/gogcli). Includes auth tools plus 22 additional dedicated Sheets tools for tab management, formatting, named ranges, and more.
7
7
 
8
8
  ## Requirements
9
9
 
10
- - [gogcli](https://github.com/steipete/gogcli) installed and authenticated
10
+ - [gogcli](https://github.com/openclaw/gogcli) installed and authenticated
11
11
  - Node.js 18+
12
12
 
13
13
  ```bash
package/SKILL.md CHANGED
@@ -5,13 +5,13 @@ description: Use when the user asks to read, write, format, or manage Google She
5
5
 
6
6
  # gogcli-mcp-sheets
7
7
 
8
- Extended Google Sheets MCP server via [gogcli](https://github.com/steipete/gogcli) — 35 tools: auth + 8 base Sheets + 22 extra dedicated Sheets tools.
8
+ Extended Google Sheets MCP server via [gogcli](https://github.com/openclaw/gogcli) — 35 tools: auth + 8 base Sheets + 22 extra dedicated Sheets tools.
9
9
 
10
10
  - **Source:** [github.com/chrischall/gogcli-mcp](https://github.com/chrischall/gogcli-mcp)
11
11
 
12
12
  ## Requirements
13
13
 
14
- - [gogcli](https://github.com/steipete/gogcli) installed and authenticated
14
+ - [gogcli](https://github.com/openclaw/gogcli) installed and authenticated
15
15
  - Node.js 18 or later
16
16
 
17
17
  ## Setup
package/dist/index.js CHANGED
@@ -31063,7 +31063,7 @@ async function run(args, options = {}) {
31063
31063
  settled = true;
31064
31064
  if (err.code === "ENOENT") {
31065
31065
  reject(new Error(
31066
- "gog executable not found. Install gogcli (https://github.com/steipete/gogcli) or set GOG_PATH in your MCP client config to the absolute binary path (run `which gog` in a terminal to find it)."
31066
+ "gog executable not found. Install gogcli (https://github.com/openclaw/gogcli) or set GOG_PATH in your MCP client config to the absolute binary path (run `which gog` in a terminal to find it)."
31067
31067
  ));
31068
31068
  return;
31069
31069
  }
@@ -31309,7 +31309,7 @@ function registerSheetsTools(server2) {
31309
31309
  }
31310
31310
 
31311
31311
  // ../gogcli-mcp/src/server.ts
31312
- var VERSION = true ? "2.0.10" : "0.0.0";
31312
+ var VERSION = true ? "2.0.12" : "0.0.0";
31313
31313
  function createServer(options) {
31314
31314
  return new McpServer({
31315
31315
  name: options?.name ?? "gogcli",
@@ -31707,6 +31707,41 @@ function registerExtraSheetsTools(server2) {
31707
31707
  }, async ({ spreadsheetId, nameOrId, account }) => {
31708
31708
  return runOrDiagnose(["sheets", "named-ranges", "delete", spreadsheetId, nameOrId], { account });
31709
31709
  });
31710
+ server2.registerTool("gog_sheets_batch_update", {
31711
+ description: 'Update values in multiple ranges with one Sheets API request. dataJson is a JSON array of {range, values} objects (or "@/path/to/file.json"). Atomic \u2014 either all ranges update or none do.',
31712
+ annotations: { destructiveHint: true },
31713
+ inputSchema: {
31714
+ spreadsheetId: external_exports.string().describe("Spreadsheet ID"),
31715
+ dataJson: external_exports.string().describe('Value ranges as JSON array, or @file (e.g. [{"range":"Sheet1!A1:B2","values":[["a","b"]]}])'),
31716
+ input: external_exports.enum(["RAW", "USER_ENTERED"]).optional().describe("Value input option (default: USER_ENTERED)"),
31717
+ includeValuesInResponse: external_exports.boolean().optional().describe("Include updated values in the response"),
31718
+ responseRender: external_exports.enum(["FORMATTED_VALUE", "UNFORMATTED_VALUE", "FORMULA"]).optional().describe("Response value render option"),
31719
+ responseDateTimeRender: external_exports.enum(["SERIAL_NUMBER", "FORMATTED_STRING"]).optional().describe("Response date/time render option"),
31720
+ account: accountParam
31721
+ }
31722
+ }, async ({ spreadsheetId, dataJson, input, includeValuesInResponse, responseRender, responseDateTimeRender, account }) => {
31723
+ const args = ["sheets", "batch-update", spreadsheetId, `--data-json=${dataJson}`];
31724
+ if (input) args.push(`--input=${input}`);
31725
+ if (includeValuesInResponse) args.push("--include-values-in-response");
31726
+ if (responseRender) args.push(`--response-render=${responseRender}`);
31727
+ if (responseDateTimeRender) args.push(`--response-date-time-render=${responseDateTimeRender}`);
31728
+ return runOrDiagnose(args, { account });
31729
+ });
31730
+ server2.registerTool("gog_sheets_reorder_tab", {
31731
+ description: "Move a tab to a specific 0-based position. `tab` is the tab name or numeric sheetId; `to=0` is the leftmost slot.",
31732
+ annotations: { destructiveHint: true },
31733
+ inputSchema: {
31734
+ spreadsheetId: external_exports.string().describe("Spreadsheet ID"),
31735
+ tab: external_exports.string().describe("Target tab by name or numeric sheet ID"),
31736
+ to: external_exports.number().int().min(0).describe("Destination final 0-based tab index"),
31737
+ account: accountParam
31738
+ }
31739
+ }, async ({ spreadsheetId, tab, to, account }) => {
31740
+ return runOrDiagnose(
31741
+ ["sheets", "reorder-tab", spreadsheetId, `--tab=${tab}`, `--to=${to}`],
31742
+ { account }
31743
+ );
31744
+ });
31710
31745
  }
31711
31746
 
31712
31747
  // src/index.ts
package/manifest.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "manifest_version": "0.3",
4
4
  "name": "gogcli-mcp-sheets",
5
5
  "display_name": "gogcli (Sheets)",
6
- "version": "2.0.10",
6
+ "version": "2.0.12",
7
7
  "description": "Extended Google Sheets for Claude via gogcli — auth + full Sheets support",
8
8
  "author": {
9
9
  "name": "Chris Hall",
@@ -199,6 +199,14 @@
199
199
  {
200
200
  "name": "gog_sheets_list_tabs",
201
201
  "description": "List tabs in a spreadsheet (sheetId, title, index, gridProperties)"
202
+ },
203
+ {
204
+ "name": "gog_sheets_batch_update",
205
+ "description": "Update values in multiple ranges atomically with one Sheets API request."
206
+ },
207
+ {
208
+ "name": "gog_sheets_reorder_tab",
209
+ "description": "Move a tab to a specific 0-based position."
202
210
  }
203
211
  ],
204
212
  "compatibility": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gogcli-mcp-sheets",
3
- "version": "2.0.10",
3
+ "version": "2.0.12",
4
4
  "mcpName": "io.github.chrischall/gogcli-mcp-sheets",
5
5
  "description": "Extended Google Sheets MCP server via gogcli — all base tools plus full Sheets 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-sheets"
9
9
  },
10
- "version": "2.0.10",
10
+ "version": "2.0.12",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "gogcli-mcp-sheets",
15
- "version": "2.0.10",
15
+ "version": "2.0.12",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  },
@@ -420,4 +420,41 @@ export function registerExtraSheetsTools(server: McpServer): void {
420
420
  }, async ({ spreadsheetId, nameOrId, account }) => {
421
421
  return runOrDiagnose(['sheets', 'named-ranges', 'delete', spreadsheetId, nameOrId], { account });
422
422
  });
423
+
424
+ server.registerTool('gog_sheets_batch_update', {
425
+ description: 'Update values in multiple ranges with one Sheets API request. dataJson is a JSON array of {range, values} objects (or "@/path/to/file.json"). Atomic — either all ranges update or none do.',
426
+ annotations: { destructiveHint: true },
427
+ inputSchema: {
428
+ spreadsheetId: z.string().describe('Spreadsheet ID'),
429
+ dataJson: z.string().describe('Value ranges as JSON array, or @file (e.g. [{"range":"Sheet1!A1:B2","values":[["a","b"]]}])'),
430
+ input: z.enum(['RAW', 'USER_ENTERED']).optional().describe('Value input option (default: USER_ENTERED)'),
431
+ includeValuesInResponse: z.boolean().optional().describe('Include updated values in the response'),
432
+ responseRender: z.enum(['FORMATTED_VALUE', 'UNFORMATTED_VALUE', 'FORMULA']).optional().describe('Response value render option'),
433
+ responseDateTimeRender: z.enum(['SERIAL_NUMBER', 'FORMATTED_STRING']).optional().describe('Response date/time render option'),
434
+ account: accountParam,
435
+ },
436
+ }, async ({ spreadsheetId, dataJson, input, includeValuesInResponse, responseRender, responseDateTimeRender, account }) => {
437
+ const args = ['sheets', 'batch-update', spreadsheetId, `--data-json=${dataJson}`];
438
+ if (input) args.push(`--input=${input}`);
439
+ if (includeValuesInResponse) args.push('--include-values-in-response');
440
+ if (responseRender) args.push(`--response-render=${responseRender}`);
441
+ if (responseDateTimeRender) args.push(`--response-date-time-render=${responseDateTimeRender}`);
442
+ return runOrDiagnose(args, { account });
443
+ });
444
+
445
+ server.registerTool('gog_sheets_reorder_tab', {
446
+ description: 'Move a tab to a specific 0-based position. `tab` is the tab name or numeric sheetId; `to=0` is the leftmost slot.',
447
+ annotations: { destructiveHint: true },
448
+ inputSchema: {
449
+ spreadsheetId: z.string().describe('Spreadsheet ID'),
450
+ tab: z.string().describe('Target tab by name or numeric sheet ID'),
451
+ to: z.number().int().min(0).describe('Destination final 0-based tab index'),
452
+ account: accountParam,
453
+ },
454
+ }, async ({ spreadsheetId, tab, to, account }) => {
455
+ return runOrDiagnose(
456
+ ['sheets', 'reorder-tab', spreadsheetId, `--tab=${tab}`, `--to=${to}`],
457
+ { account },
458
+ );
459
+ });
423
460
  }
@@ -481,3 +481,87 @@ describe('gog_sheets_named_ranges_delete', () => {
481
481
  expect(lib.runOrDiagnose).toHaveBeenCalledWith(['sheets', 'named-ranges', 'delete', 'sid', 'OldRange'], { account: undefined });
482
482
  });
483
483
  });
484
+
485
+ // 23. batch-update (gog 0.18.0)
486
+ describe('gog_sheets_batch_update', () => {
487
+ it('passes --data-json and required spreadsheetId', async () => {
488
+ vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
489
+ const handlers = setupHandlers();
490
+ const data = '[{"range":"Sheet1!A1:B1","values":[["a","b"]]}]';
491
+ await handlers.get('gog_sheets_batch_update')!({ spreadsheetId: 'sid', dataJson: data });
492
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
493
+ ['sheets', 'batch-update', 'sid', `--data-json=${data}`],
494
+ { account: undefined },
495
+ );
496
+ });
497
+
498
+ it('passes optional --input, --include-values-in-response, --response-render, --response-date-time-render', async () => {
499
+ vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
500
+ const handlers = setupHandlers();
501
+ await handlers.get('gog_sheets_batch_update')!({
502
+ spreadsheetId: 'sid',
503
+ dataJson: '[]',
504
+ input: 'RAW',
505
+ includeValuesInResponse: true,
506
+ responseRender: 'FORMULA',
507
+ responseDateTimeRender: 'FORMATTED_STRING',
508
+ account: 'a@b.com',
509
+ });
510
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
511
+ [
512
+ 'sheets', 'batch-update', 'sid',
513
+ '--data-json=[]',
514
+ '--input=RAW',
515
+ '--include-values-in-response',
516
+ '--response-render=FORMULA',
517
+ '--response-date-time-render=FORMATTED_STRING',
518
+ ],
519
+ { account: 'a@b.com' },
520
+ );
521
+ });
522
+
523
+ it('omits --include-values-in-response when false', async () => {
524
+ vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
525
+ const handlers = setupHandlers();
526
+ await handlers.get('gog_sheets_batch_update')!({
527
+ spreadsheetId: 'sid', dataJson: '[]', includeValuesInResponse: false,
528
+ });
529
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
530
+ ['sheets', 'batch-update', 'sid', '--data-json=[]'],
531
+ { account: undefined },
532
+ );
533
+ });
534
+ });
535
+
536
+ // 24. reorder-tab (gog 0.18.0)
537
+ describe('gog_sheets_reorder_tab', () => {
538
+ it('passes --tab and --to', async () => {
539
+ vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
540
+ const handlers = setupHandlers();
541
+ await handlers.get('gog_sheets_reorder_tab')!({ spreadsheetId: 'sid', tab: 'Data', to: 2 });
542
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
543
+ ['sheets', 'reorder-tab', 'sid', '--tab=Data', '--to=2'],
544
+ { account: undefined },
545
+ );
546
+ });
547
+
548
+ it('sends --to=0 explicitly to reach the leftmost position', async () => {
549
+ vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
550
+ const handlers = setupHandlers();
551
+ await handlers.get('gog_sheets_reorder_tab')!({ spreadsheetId: 'sid', tab: '123', to: 0 });
552
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
553
+ ['sheets', 'reorder-tab', 'sid', '--tab=123', '--to=0'],
554
+ { account: undefined },
555
+ );
556
+ });
557
+
558
+ it('forwards account', async () => {
559
+ vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
560
+ const handlers = setupHandlers();
561
+ await handlers.get('gog_sheets_reorder_tab')!({ spreadsheetId: 'sid', tab: 'Data', to: 1, account: 'a@b.com' });
562
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
563
+ ['sheets', 'reorder-tab', 'sid', '--tab=Data', '--to=1'],
564
+ { account: 'a@b.com' },
565
+ );
566
+ });
567
+ });