google-tools-mcp 1.2.7 → 1.2.9
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/dist/auth.js +343 -325
- package/dist/clients.js +293 -213
- package/dist/index.js +85 -74
- package/dist/setup.js +422 -235
- package/dist/tools/gmail/messages.js +14 -4
- package/dist/tools/gmail/threads.js +14 -4
- package/dist/tools/sheets/deleteColumns.js +66 -0
- package/dist/tools/sheets/index.js +2 -0
- package/dist/tools/sheets/ungroupAllRows.js +6 -2
- package/package.json +1 -1
|
@@ -373,16 +373,26 @@ export function register(server) {
|
|
|
373
373
|
|
|
374
374
|
server.addTool({
|
|
375
375
|
name: 'trash_message',
|
|
376
|
-
description: 'Move
|
|
376
|
+
description: 'Move one or more messages to the trash or restore them. Pass a single id or an array of ids.',
|
|
377
377
|
parameters: z.object({
|
|
378
|
-
|
|
378
|
+
ids: z.union([z.string(), z.array(z.string())]).describe("Message ID or array of message IDs"),
|
|
379
379
|
action: z.enum(['trash', 'untrash']).describe("'trash' to move to trash, 'untrash' to restore"),
|
|
380
380
|
}),
|
|
381
381
|
execute: async (params) => {
|
|
382
382
|
const gmail = await getGmailClient();
|
|
383
|
+
const ids = Array.isArray(params.ids) ? params.ids : [params.ids];
|
|
383
384
|
const fn = params.action === 'untrash' ? 'untrash' : 'trash';
|
|
384
|
-
const
|
|
385
|
-
|
|
385
|
+
const results = await Promise.all(
|
|
386
|
+
ids.map(async (id) => {
|
|
387
|
+
try {
|
|
388
|
+
const { data } = await gmail.users.messages[fn]({ userId: 'me', id });
|
|
389
|
+
return data;
|
|
390
|
+
} catch (e) {
|
|
391
|
+
return { id, error: e.message || `Failed to ${fn} message` };
|
|
392
|
+
}
|
|
393
|
+
})
|
|
394
|
+
);
|
|
395
|
+
return JSON.stringify(ids.length === 1 ? results[0] : results);
|
|
386
396
|
},
|
|
387
397
|
});
|
|
388
398
|
|
|
@@ -139,16 +139,26 @@ export function register(server) {
|
|
|
139
139
|
|
|
140
140
|
server.addTool({
|
|
141
141
|
name: 'trash_thread',
|
|
142
|
-
description: 'Move
|
|
142
|
+
description: 'Move one or more threads to the trash or restore them. Pass a single id or an array of ids.',
|
|
143
143
|
parameters: z.object({
|
|
144
|
-
|
|
144
|
+
ids: z.union([z.string(), z.array(z.string())]).describe("Thread ID or array of thread IDs"),
|
|
145
145
|
action: z.enum(['trash', 'untrash']).describe("'trash' to move to trash, 'untrash' to restore"),
|
|
146
146
|
}),
|
|
147
147
|
execute: async (params) => {
|
|
148
148
|
const gmail = await getGmailClient();
|
|
149
|
+
const ids = Array.isArray(params.ids) ? params.ids : [params.ids];
|
|
149
150
|
const fn = params.action === 'untrash' ? 'untrash' : 'trash';
|
|
150
|
-
const
|
|
151
|
-
|
|
151
|
+
const results = await Promise.all(
|
|
152
|
+
ids.map(async (id) => {
|
|
153
|
+
try {
|
|
154
|
+
const { data } = await gmail.users.threads[fn]({ userId: 'me', id });
|
|
155
|
+
return data;
|
|
156
|
+
} catch (e) {
|
|
157
|
+
return { id, error: e.message || `Failed to ${fn} thread` };
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
);
|
|
161
|
+
return JSON.stringify(ids.length === 1 ? results[0] : results);
|
|
152
162
|
},
|
|
153
163
|
});
|
|
154
164
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { UserError } from 'fastmcp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getSheetsClient } from '../../clients.js';
|
|
4
|
+
import * as SheetsHelpers from '../../googleSheetsApiHelpers.js';
|
|
5
|
+
export function register(server) {
|
|
6
|
+
server.addTool({
|
|
7
|
+
name: 'deleteColumns',
|
|
8
|
+
description: 'Deletes one or more columns from a Google Sheet. Columns are 1-based. Multiple ranges are processed right-to-left to avoid index shifting.',
|
|
9
|
+
parameters: z.object({
|
|
10
|
+
spreadsheetId: z
|
|
11
|
+
.string()
|
|
12
|
+
.describe('The spreadsheet ID — the long string between /d/ and /edit in a Google Sheets URL.'),
|
|
13
|
+
sheetName: z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('Name of the sheet/tab. Defaults to the first sheet if not provided.'),
|
|
17
|
+
columns: z
|
|
18
|
+
.array(z.object({
|
|
19
|
+
startIndex: z
|
|
20
|
+
.number()
|
|
21
|
+
.int()
|
|
22
|
+
.min(1)
|
|
23
|
+
.describe('1-based column number of the first column to delete (inclusive).'),
|
|
24
|
+
endIndex: z
|
|
25
|
+
.number()
|
|
26
|
+
.int()
|
|
27
|
+
.min(1)
|
|
28
|
+
.describe('1-based column number of the last column to delete (inclusive).'),
|
|
29
|
+
}))
|
|
30
|
+
.min(1)
|
|
31
|
+
.describe('Array of column ranges to delete. Each entry is {startIndex, endIndex} using 1-based column numbers.'),
|
|
32
|
+
}),
|
|
33
|
+
execute: async (args, { log }) => {
|
|
34
|
+
const sheets = await getSheetsClient();
|
|
35
|
+
log.info(`Deleting columns in spreadsheet ${args.spreadsheetId}`);
|
|
36
|
+
try {
|
|
37
|
+
const sheetId = await SheetsHelpers.resolveSheetId(sheets, args.spreadsheetId, args.sheetName);
|
|
38
|
+
// Sort descending so right-to-left deletion avoids index shifting
|
|
39
|
+
const sorted = [...args.columns].sort((a, b) => b.startIndex - a.startIndex);
|
|
40
|
+
const requests = sorted.map(({ startIndex, endIndex }) => ({
|
|
41
|
+
deleteDimension: {
|
|
42
|
+
range: {
|
|
43
|
+
sheetId,
|
|
44
|
+
dimension: 'COLUMNS',
|
|
45
|
+
startIndex: startIndex - 1,
|
|
46
|
+
endIndex: endIndex,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
}));
|
|
50
|
+
await sheets.spreadsheets.batchUpdate({
|
|
51
|
+
spreadsheetId: args.spreadsheetId,
|
|
52
|
+
requestBody: { requests },
|
|
53
|
+
});
|
|
54
|
+
const sheetUrl = `https://docs.google.com/spreadsheets/d/${args.spreadsheetId}/edit`;
|
|
55
|
+
const totalCols = args.columns.reduce((sum, { startIndex, endIndex }) => sum + (endIndex - startIndex + 1), 0);
|
|
56
|
+
return `${sheetUrl}\nSuccessfully deleted ${totalCols} column(s) across ${args.columns.length} range(s).`;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
log.error(`Error deleting columns: ${error.message || error}`);
|
|
60
|
+
if (error instanceof UserError)
|
|
61
|
+
throw error;
|
|
62
|
+
throw new UserError(`Failed to delete columns: ${error.message || 'Unknown error'}`);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
@@ -29,6 +29,7 @@ import { register as updateTableRange } from './updateTableRange.js';
|
|
|
29
29
|
import { register as appendTableRows } from './appendTableRows.js';
|
|
30
30
|
import { register as insertChart } from './insertChart.js';
|
|
31
31
|
import { register as deleteChart } from './deleteChart.js';
|
|
32
|
+
import { register as deleteColumns } from './deleteColumns.js';
|
|
32
33
|
export function registerSheetsTools(server) {
|
|
33
34
|
readSpreadsheet(server);
|
|
34
35
|
writeSpreadsheet(server);
|
|
@@ -61,4 +62,5 @@ export function registerSheetsTools(server) {
|
|
|
61
62
|
appendTableRows(server);
|
|
62
63
|
insertChart(server);
|
|
63
64
|
deleteChart(server);
|
|
65
|
+
deleteColumns(server);
|
|
64
66
|
}
|
|
@@ -39,8 +39,9 @@ export function register(server) {
|
|
|
39
39
|
};
|
|
40
40
|
// deleteDimensionGroup removes one level at a time; call repeatedly until no groups remain
|
|
41
41
|
let removed = 0;
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const MAX_UNGROUP_ITERATIONS = 500;
|
|
43
|
+
let iteration = 0;
|
|
44
|
+
while (iteration++ < MAX_UNGROUP_ITERATIONS) {
|
|
44
45
|
try {
|
|
45
46
|
await sheets.spreadsheets.batchUpdate({
|
|
46
47
|
spreadsheetId: args.spreadsheetId,
|
|
@@ -53,6 +54,9 @@ export function register(server) {
|
|
|
53
54
|
break;
|
|
54
55
|
}
|
|
55
56
|
}
|
|
57
|
+
if (iteration >= MAX_UNGROUP_ITERATIONS) {
|
|
58
|
+
logger.warn(`ungroupAllRows: hit safety cap of ${MAX_UNGROUP_ITERATIONS} iterations — some groups may remain.`);
|
|
59
|
+
}
|
|
56
60
|
const sheetUrl = `https://docs.google.com/spreadsheets/d/${args.spreadsheetId}/edit`;
|
|
57
61
|
return `${sheetUrl}\nSuccessfully removed all row groups (${removed} level(s) cleared).`;
|
|
58
62
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "google-tools-mcp",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9",
|
|
4
4
|
"description": "The easiest MCP server for Google Workspace — Drive, Docs, Sheets, Gmail, Calendar, and Forms. 153 tools with one-click browser auth. Read Word docs, PDFs, and spreadsheets straight from Drive.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|