@piotr-agier/google-drive-mcp 1.4.0 → 1.5.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 +58 -0
- package/dist/index.js +464 -7
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -569,9 +569,41 @@ Add the server to your Claude Desktop configuration:
|
|
|
569
569
|
- `valueInputOption`: `RAW` or `USER_ENTERED` (optional, default: USER_ENTERED)
|
|
570
570
|
|
|
571
571
|
- **addSpreadsheetSheet** - Add a new sheet/tab to an existing spreadsheet
|
|
572
|
+
- **addSheet** - Alias for `addSpreadsheetSheet`
|
|
572
573
|
- `spreadsheetId`: Spreadsheet ID
|
|
573
574
|
- `sheetTitle`: Title for the new sheet
|
|
574
575
|
|
|
576
|
+
- **listSheets** - List tabs/sheets in a spreadsheet
|
|
577
|
+
- `spreadsheetId`: Spreadsheet ID
|
|
578
|
+
|
|
579
|
+
- **renameSheet** - Rename a sheet/tab by `sheetId`
|
|
580
|
+
- `spreadsheetId`: Spreadsheet ID
|
|
581
|
+
- `sheetId`: Sheet ID
|
|
582
|
+
- `newTitle`: New title
|
|
583
|
+
|
|
584
|
+
- **deleteSheet** - Delete a sheet/tab by `sheetId`
|
|
585
|
+
- `spreadsheetId`: Spreadsheet ID
|
|
586
|
+
- `sheetId`: Sheet ID
|
|
587
|
+
|
|
588
|
+
- **addDataValidation** - Add data validation rules to a range
|
|
589
|
+
- `spreadsheetId`: Spreadsheet ID
|
|
590
|
+
- `range`: A1 range (e.g., `Sheet1!A1:A10`)
|
|
591
|
+
- `conditionType`: `ONE_OF_LIST`, `NUMBER_GREATER`, `NUMBER_LESS`, or `TEXT_CONTAINS`
|
|
592
|
+
- `values`: Condition values (e.g. list items, threshold)
|
|
593
|
+
- `strict`: Reject invalid values (optional, default: `true`)
|
|
594
|
+
- `showCustomUi`: Show dropdown/custom UI (optional, default: `true`)
|
|
595
|
+
|
|
596
|
+
- **protectRange** - Protect a range in a spreadsheet
|
|
597
|
+
- `spreadsheetId`: Spreadsheet ID
|
|
598
|
+
- `range`: A1 range
|
|
599
|
+
- `description`: Protection description (optional)
|
|
600
|
+
- `warningOnly`: Warn instead of enforce (optional, default: `false`)
|
|
601
|
+
|
|
602
|
+
- **addNamedRange** - Create a named range
|
|
603
|
+
- `spreadsheetId`: Spreadsheet ID
|
|
604
|
+
- `name`: Named range name
|
|
605
|
+
- `range`: A1 range
|
|
606
|
+
|
|
575
607
|
- **listGoogleSheets** - List Google Spreadsheets with optional filtering
|
|
576
608
|
- `query`: Search query to filter by name or content (optional)
|
|
577
609
|
- `maxResults`: Maximum spreadsheets to return, 1-100 (optional, default: 20)
|
|
@@ -694,6 +726,32 @@ Add the server to your Claude Desktop configuration:
|
|
|
694
726
|
- `slideIndex`: Slide index (0-based)
|
|
695
727
|
- `notes`: The speaker notes content to set
|
|
696
728
|
|
|
729
|
+
#### Slide Operations and Templating
|
|
730
|
+
- **deleteGoogleSlide** - Delete a slide by object ID
|
|
731
|
+
- `presentationId`: Presentation ID
|
|
732
|
+
- `slideObjectId`: Slide object ID
|
|
733
|
+
|
|
734
|
+
- **duplicateSlide** - Duplicate a slide by object ID
|
|
735
|
+
- `presentationId`: Presentation ID
|
|
736
|
+
- `slideObjectId`: Slide object ID
|
|
737
|
+
|
|
738
|
+
- **reorderSlides** - Reorder slides by object IDs and insertion index
|
|
739
|
+
- `presentationId`: Presentation ID
|
|
740
|
+
- `slideObjectIds`: Array of slide object IDs to move
|
|
741
|
+
- `insertionIndex`: Target insertion index
|
|
742
|
+
|
|
743
|
+
- **replaceAllTextInSlides** - Replace text across a presentation
|
|
744
|
+
- `presentationId`: Presentation ID
|
|
745
|
+
- `containsText`: Text to find
|
|
746
|
+
- `replaceText`: Replacement text
|
|
747
|
+
- `matchCase`: Match case (optional, default: `false`)
|
|
748
|
+
|
|
749
|
+
- **exportSlideThumbnail** - Export a slide thumbnail URL (PNG/JPEG, SMALL/MEDIUM/LARGE)
|
|
750
|
+
- `presentationId`: Presentation ID
|
|
751
|
+
- `slideObjectId`: Slide object ID
|
|
752
|
+
- `mimeType`: `PNG` or `JPEG` (optional, default: `PNG`)
|
|
753
|
+
- `size`: `SMALL`, `MEDIUM`, or `LARGE` (optional, default: `LARGE`)
|
|
754
|
+
|
|
697
755
|
### Google Calendar
|
|
698
756
|
- **listCalendars** - List all accessible Google Calendars
|
|
699
757
|
- `showHidden`: Include hidden calendars (optional, default: false)
|
package/dist/index.js
CHANGED
|
@@ -1589,7 +1589,7 @@ Link: ${response.data.webViewLink}` }],
|
|
|
1589
1589
|
const data = validation.data;
|
|
1590
1590
|
const response = await ctx.getDrive().permissions.list({
|
|
1591
1591
|
fileId: data.fileId,
|
|
1592
|
-
fields: "permissions(id,type,role,emailAddress,domain,displayName)",
|
|
1592
|
+
fields: "permissions(id,type,role,emailAddress,domain,displayName,permissionDetails(inherited,inheritedFrom,permissionType))",
|
|
1593
1593
|
supportsAllDrives: true
|
|
1594
1594
|
});
|
|
1595
1595
|
const permissions = response.data.permissions || [];
|
|
@@ -1598,7 +1598,10 @@ Link: ${response.data.webViewLink}` }],
|
|
|
1598
1598
|
}
|
|
1599
1599
|
const lines = permissions.map((p) => {
|
|
1600
1600
|
const who = p.emailAddress || p.domain || p.displayName || p.type || "unknown";
|
|
1601
|
-
|
|
1601
|
+
const inherited = p.permissionDetails?.some((d) => d.inherited === true) ?? false;
|
|
1602
|
+
const inheritedFrom = p.permissionDetails?.find((d) => d.inheritedFrom)?.inheritedFrom;
|
|
1603
|
+
const inheritedMarker = inherited ? ` [inherited${inheritedFrom ? ` from ${inheritedFrom}` : ""}]` : " [direct]";
|
|
1604
|
+
return `- ${p.id}: ${who} (${p.type}) => ${p.role}${inheritedMarker}`;
|
|
1602
1605
|
});
|
|
1603
1606
|
return { content: [{ type: "text", text: `Permissions for file ${data.fileId}:
|
|
1604
1607
|
${lines.join("\n")}` }], isError: false };
|
|
@@ -3776,6 +3779,41 @@ var AddSpreadsheetSheetSchema = z3.object({
|
|
|
3776
3779
|
spreadsheetId: z3.string().min(1, "Spreadsheet ID is required"),
|
|
3777
3780
|
sheetTitle: z3.string().min(1, "Sheet title is required")
|
|
3778
3781
|
});
|
|
3782
|
+
var AddSheetSchema = z3.object({
|
|
3783
|
+
spreadsheetId: z3.string().min(1, "Spreadsheet ID is required"),
|
|
3784
|
+
title: z3.string().min(1, "Sheet title is required")
|
|
3785
|
+
});
|
|
3786
|
+
var ListSheetsSchema = z3.object({
|
|
3787
|
+
spreadsheetId: z3.string().min(1, "Spreadsheet ID is required")
|
|
3788
|
+
});
|
|
3789
|
+
var RenameSheetSchema = z3.object({
|
|
3790
|
+
spreadsheetId: z3.string().min(1, "Spreadsheet ID is required"),
|
|
3791
|
+
sheetId: z3.number().int(),
|
|
3792
|
+
newTitle: z3.string().min(1, "New title is required")
|
|
3793
|
+
});
|
|
3794
|
+
var DeleteSheetSchema = z3.object({
|
|
3795
|
+
spreadsheetId: z3.string().min(1, "Spreadsheet ID is required"),
|
|
3796
|
+
sheetId: z3.number().int()
|
|
3797
|
+
});
|
|
3798
|
+
var AddDataValidationSchema = z3.object({
|
|
3799
|
+
spreadsheetId: z3.string().min(1, "Spreadsheet ID is required"),
|
|
3800
|
+
range: z3.string().min(1, "Range is required"),
|
|
3801
|
+
conditionType: z3.enum(["ONE_OF_LIST", "NUMBER_GREATER", "NUMBER_LESS", "TEXT_CONTAINS"]),
|
|
3802
|
+
values: z3.array(z3.string()).min(1, "At least one value is required"),
|
|
3803
|
+
strict: z3.boolean().optional().default(true),
|
|
3804
|
+
showCustomUi: z3.boolean().optional().default(true)
|
|
3805
|
+
});
|
|
3806
|
+
var ProtectRangeSchema = z3.object({
|
|
3807
|
+
spreadsheetId: z3.string().min(1, "Spreadsheet ID is required"),
|
|
3808
|
+
range: z3.string().min(1, "Range is required"),
|
|
3809
|
+
description: z3.string().optional(),
|
|
3810
|
+
warningOnly: z3.boolean().optional().default(false)
|
|
3811
|
+
});
|
|
3812
|
+
var AddNamedRangeSchema = z3.object({
|
|
3813
|
+
spreadsheetId: z3.string().min(1, "Spreadsheet ID is required"),
|
|
3814
|
+
name: z3.string().min(1, "Name is required"),
|
|
3815
|
+
range: z3.string().min(1, "Range is required")
|
|
3816
|
+
});
|
|
3779
3817
|
var ListGoogleSheetsSchema = z3.object({
|
|
3780
3818
|
maxResults: z3.number().int().min(1).max(100).optional().default(20),
|
|
3781
3819
|
query: z3.string().optional(),
|
|
@@ -4061,6 +4099,97 @@ var toolDefinitions3 = [
|
|
|
4061
4099
|
required: ["spreadsheetId", "sheetTitle"]
|
|
4062
4100
|
}
|
|
4063
4101
|
},
|
|
4102
|
+
{
|
|
4103
|
+
name: "addSheet",
|
|
4104
|
+
description: "Alias for addSpreadsheetSheet (adds a new sheet/tab)",
|
|
4105
|
+
inputSchema: {
|
|
4106
|
+
type: "object",
|
|
4107
|
+
properties: {
|
|
4108
|
+
spreadsheetId: { type: "string", description: "Spreadsheet ID" },
|
|
4109
|
+
title: { type: "string", description: "Title for the new sheet/tab" }
|
|
4110
|
+
},
|
|
4111
|
+
required: ["spreadsheetId", "title"]
|
|
4112
|
+
}
|
|
4113
|
+
},
|
|
4114
|
+
{
|
|
4115
|
+
name: "listSheets",
|
|
4116
|
+
description: "List tabs/sheets in a Google Spreadsheet",
|
|
4117
|
+
inputSchema: {
|
|
4118
|
+
type: "object",
|
|
4119
|
+
properties: {
|
|
4120
|
+
spreadsheetId: { type: "string", description: "Spreadsheet ID" }
|
|
4121
|
+
},
|
|
4122
|
+
required: ["spreadsheetId"]
|
|
4123
|
+
}
|
|
4124
|
+
},
|
|
4125
|
+
{
|
|
4126
|
+
name: "renameSheet",
|
|
4127
|
+
description: "Rename a sheet/tab by sheetId",
|
|
4128
|
+
inputSchema: {
|
|
4129
|
+
type: "object",
|
|
4130
|
+
properties: {
|
|
4131
|
+
spreadsheetId: { type: "string", description: "Spreadsheet ID" },
|
|
4132
|
+
sheetId: { type: "number", description: "Sheet ID" },
|
|
4133
|
+
newTitle: { type: "string", description: "New title" }
|
|
4134
|
+
},
|
|
4135
|
+
required: ["spreadsheetId", "sheetId", "newTitle"]
|
|
4136
|
+
}
|
|
4137
|
+
},
|
|
4138
|
+
{
|
|
4139
|
+
name: "deleteSheet",
|
|
4140
|
+
description: "Delete a sheet/tab by sheetId",
|
|
4141
|
+
inputSchema: {
|
|
4142
|
+
type: "object",
|
|
4143
|
+
properties: {
|
|
4144
|
+
spreadsheetId: { type: "string", description: "Spreadsheet ID" },
|
|
4145
|
+
sheetId: { type: "number", description: "Sheet ID" }
|
|
4146
|
+
},
|
|
4147
|
+
required: ["spreadsheetId", "sheetId"]
|
|
4148
|
+
}
|
|
4149
|
+
},
|
|
4150
|
+
{
|
|
4151
|
+
name: "addDataValidation",
|
|
4152
|
+
description: "Add data validation rules to a sheet range",
|
|
4153
|
+
inputSchema: {
|
|
4154
|
+
type: "object",
|
|
4155
|
+
properties: {
|
|
4156
|
+
spreadsheetId: { type: "string", description: "Spreadsheet ID" },
|
|
4157
|
+
range: { type: "string", description: "A1 range" },
|
|
4158
|
+
conditionType: { type: "string", enum: ["ONE_OF_LIST", "NUMBER_GREATER", "NUMBER_LESS", "TEXT_CONTAINS"], description: "Validation condition type" },
|
|
4159
|
+
values: { type: "array", items: { type: "string" }, description: "Condition values (e.g. list items, threshold)" },
|
|
4160
|
+
strict: { type: "boolean", description: "Reject invalid values" },
|
|
4161
|
+
showCustomUi: { type: "boolean", description: "Show dropdown/custom UI" }
|
|
4162
|
+
},
|
|
4163
|
+
required: ["spreadsheetId", "range", "conditionType", "values"]
|
|
4164
|
+
}
|
|
4165
|
+
},
|
|
4166
|
+
{
|
|
4167
|
+
name: "protectRange",
|
|
4168
|
+
description: "Protect a range in a spreadsheet",
|
|
4169
|
+
inputSchema: {
|
|
4170
|
+
type: "object",
|
|
4171
|
+
properties: {
|
|
4172
|
+
spreadsheetId: { type: "string", description: "Spreadsheet ID" },
|
|
4173
|
+
range: { type: "string", description: "A1 range" },
|
|
4174
|
+
description: { type: "string", description: "Protection description" },
|
|
4175
|
+
warningOnly: { type: "boolean", description: "Warn instead of enforce" }
|
|
4176
|
+
},
|
|
4177
|
+
required: ["spreadsheetId", "range"]
|
|
4178
|
+
}
|
|
4179
|
+
},
|
|
4180
|
+
{
|
|
4181
|
+
name: "addNamedRange",
|
|
4182
|
+
description: "Create a named range",
|
|
4183
|
+
inputSchema: {
|
|
4184
|
+
type: "object",
|
|
4185
|
+
properties: {
|
|
4186
|
+
spreadsheetId: { type: "string", description: "Spreadsheet ID" },
|
|
4187
|
+
name: { type: "string", description: "Named range name" },
|
|
4188
|
+
range: { type: "string", description: "A1 range" }
|
|
4189
|
+
},
|
|
4190
|
+
required: ["spreadsheetId", "name", "range"]
|
|
4191
|
+
}
|
|
4192
|
+
},
|
|
4064
4193
|
{
|
|
4065
4194
|
name: "listGoogleSheets",
|
|
4066
4195
|
description: "Lists Google Spreadsheets from your Google Drive with optional filtering",
|
|
@@ -4075,6 +4204,19 @@ var toolDefinitions3 = [
|
|
|
4075
4204
|
}
|
|
4076
4205
|
}
|
|
4077
4206
|
];
|
|
4207
|
+
async function resolveGridRange(sheetsService, spreadsheetId, range) {
|
|
4208
|
+
const rangeData = await sheetsService.spreadsheets.get({
|
|
4209
|
+
spreadsheetId,
|
|
4210
|
+
ranges: [range],
|
|
4211
|
+
fields: "sheets(properties(sheetId,title))"
|
|
4212
|
+
});
|
|
4213
|
+
const { sheetName, cellRange: a1Range } = parseA1Range(range);
|
|
4214
|
+
const sheet = rangeData.data.sheets?.find((s) => s.properties?.title === sheetName);
|
|
4215
|
+
if (!sheet || sheet.properties?.sheetId === void 0 || sheet.properties?.sheetId === null) {
|
|
4216
|
+
return `Sheet "${sheetName}" not found`;
|
|
4217
|
+
}
|
|
4218
|
+
return convertA1ToGridRange(a1Range, sheet.properties.sheetId);
|
|
4219
|
+
}
|
|
4078
4220
|
async function handleTool3(toolName, args, ctx) {
|
|
4079
4221
|
switch (toolName) {
|
|
4080
4222
|
case "createGoogleSheet": {
|
|
@@ -4569,20 +4711,23 @@ ID: ${spreadsheet.data.spreadsheetId}` }],
|
|
|
4569
4711
|
isError: false
|
|
4570
4712
|
};
|
|
4571
4713
|
}
|
|
4572
|
-
case "addSpreadsheetSheet":
|
|
4573
|
-
|
|
4714
|
+
case "addSpreadsheetSheet":
|
|
4715
|
+
case "addSheet": {
|
|
4716
|
+
const isAlias = toolName === "addSheet";
|
|
4717
|
+
const validation = isAlias ? AddSheetSchema.safeParse(args) : AddSpreadsheetSheetSchema.safeParse(args);
|
|
4574
4718
|
if (!validation.success) {
|
|
4575
4719
|
return errorResponse(validation.error.errors[0].message);
|
|
4576
4720
|
}
|
|
4577
|
-
const
|
|
4721
|
+
const spreadsheetId = validation.data.spreadsheetId;
|
|
4722
|
+
const sheetTitle = isAlias ? validation.data.title : validation.data.sheetTitle;
|
|
4578
4723
|
const sheets = ctx.google.sheets({ version: "v4", auth: ctx.authClient });
|
|
4579
4724
|
const response = await sheets.spreadsheets.batchUpdate({
|
|
4580
|
-
spreadsheetId
|
|
4725
|
+
spreadsheetId,
|
|
4581
4726
|
requestBody: {
|
|
4582
4727
|
requests: [{
|
|
4583
4728
|
addSheet: {
|
|
4584
4729
|
properties: {
|
|
4585
|
-
title:
|
|
4730
|
+
title: sheetTitle
|
|
4586
4731
|
}
|
|
4587
4732
|
}
|
|
4588
4733
|
}]
|
|
@@ -4597,6 +4742,131 @@ ID: ${spreadsheet.data.spreadsheetId}` }],
|
|
|
4597
4742
|
isError: false
|
|
4598
4743
|
};
|
|
4599
4744
|
}
|
|
4745
|
+
case "listSheets": {
|
|
4746
|
+
const validation = ListSheetsSchema.safeParse(args);
|
|
4747
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
4748
|
+
const a = validation.data;
|
|
4749
|
+
const sheets = ctx.google.sheets({ version: "v4", auth: ctx.authClient });
|
|
4750
|
+
const response = await sheets.spreadsheets.get({
|
|
4751
|
+
spreadsheetId: a.spreadsheetId,
|
|
4752
|
+
fields: "sheets.properties(sheetId,title,index,hidden)"
|
|
4753
|
+
});
|
|
4754
|
+
const tabs = response.data.sheets || [];
|
|
4755
|
+
if (tabs.length === 0) {
|
|
4756
|
+
return { content: [{ type: "text", text: "No sheets found." }], isError: false };
|
|
4757
|
+
}
|
|
4758
|
+
const lines = tabs.map((s) => `- ${s.properties?.title} (id: ${s.properties?.sheetId}, index: ${s.properties?.index}${s.properties?.hidden ? ", hidden" : ""})`);
|
|
4759
|
+
return { content: [{ type: "text", text: `Sheets in spreadsheet ${a.spreadsheetId}:
|
|
4760
|
+
${lines.join("\n")}` }], isError: false };
|
|
4761
|
+
}
|
|
4762
|
+
case "renameSheet": {
|
|
4763
|
+
const validation = RenameSheetSchema.safeParse(args);
|
|
4764
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
4765
|
+
const a = validation.data;
|
|
4766
|
+
const sheets = ctx.google.sheets({ version: "v4", auth: ctx.authClient });
|
|
4767
|
+
await sheets.spreadsheets.batchUpdate({
|
|
4768
|
+
spreadsheetId: a.spreadsheetId,
|
|
4769
|
+
requestBody: {
|
|
4770
|
+
requests: [{
|
|
4771
|
+
updateSheetProperties: {
|
|
4772
|
+
properties: { sheetId: a.sheetId, title: a.newTitle },
|
|
4773
|
+
fields: "title"
|
|
4774
|
+
}
|
|
4775
|
+
}]
|
|
4776
|
+
}
|
|
4777
|
+
});
|
|
4778
|
+
return { content: [{ type: "text", text: `Renamed sheet ${a.sheetId} to "${a.newTitle}".` }], isError: false };
|
|
4779
|
+
}
|
|
4780
|
+
case "deleteSheet": {
|
|
4781
|
+
const validation = DeleteSheetSchema.safeParse(args);
|
|
4782
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
4783
|
+
const a = validation.data;
|
|
4784
|
+
const sheets = ctx.google.sheets({ version: "v4", auth: ctx.authClient });
|
|
4785
|
+
await sheets.spreadsheets.batchUpdate({
|
|
4786
|
+
spreadsheetId: a.spreadsheetId,
|
|
4787
|
+
requestBody: {
|
|
4788
|
+
requests: [{
|
|
4789
|
+
deleteSheet: { sheetId: a.sheetId }
|
|
4790
|
+
}]
|
|
4791
|
+
}
|
|
4792
|
+
});
|
|
4793
|
+
return { content: [{ type: "text", text: `Deleted sheet ${a.sheetId}.` }], isError: false };
|
|
4794
|
+
}
|
|
4795
|
+
case "addDataValidation": {
|
|
4796
|
+
const validation = AddDataValidationSchema.safeParse(args);
|
|
4797
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
4798
|
+
const a = validation.data;
|
|
4799
|
+
const sheets = ctx.google.sheets({ version: "v4", auth: ctx.authClient });
|
|
4800
|
+
const gridRange = await resolveGridRange(sheets, a.spreadsheetId, a.range);
|
|
4801
|
+
if (typeof gridRange === "string") return errorResponse(gridRange);
|
|
4802
|
+
const conditionValues = a.values.map((v) => ({ userEnteredValue: v }));
|
|
4803
|
+
await sheets.spreadsheets.batchUpdate({
|
|
4804
|
+
spreadsheetId: a.spreadsheetId,
|
|
4805
|
+
requestBody: {
|
|
4806
|
+
requests: [{
|
|
4807
|
+
setDataValidation: {
|
|
4808
|
+
range: gridRange,
|
|
4809
|
+
rule: {
|
|
4810
|
+
condition: {
|
|
4811
|
+
type: a.conditionType,
|
|
4812
|
+
values: conditionValues
|
|
4813
|
+
},
|
|
4814
|
+
strict: a.strict,
|
|
4815
|
+
showCustomUi: a.showCustomUi
|
|
4816
|
+
}
|
|
4817
|
+
}
|
|
4818
|
+
}]
|
|
4819
|
+
}
|
|
4820
|
+
});
|
|
4821
|
+
return { content: [{ type: "text", text: `Added data validation (${a.conditionType}) to ${a.range}.` }], isError: false };
|
|
4822
|
+
}
|
|
4823
|
+
case "protectRange": {
|
|
4824
|
+
const validation = ProtectRangeSchema.safeParse(args);
|
|
4825
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
4826
|
+
const a = validation.data;
|
|
4827
|
+
const sheets = ctx.google.sheets({ version: "v4", auth: ctx.authClient });
|
|
4828
|
+
const gridRange = await resolveGridRange(sheets, a.spreadsheetId, a.range);
|
|
4829
|
+
if (typeof gridRange === "string") return errorResponse(gridRange);
|
|
4830
|
+
const response = await sheets.spreadsheets.batchUpdate({
|
|
4831
|
+
spreadsheetId: a.spreadsheetId,
|
|
4832
|
+
requestBody: {
|
|
4833
|
+
requests: [{
|
|
4834
|
+
addProtectedRange: {
|
|
4835
|
+
protectedRange: {
|
|
4836
|
+
range: gridRange,
|
|
4837
|
+
description: a.description,
|
|
4838
|
+
warningOnly: a.warningOnly
|
|
4839
|
+
}
|
|
4840
|
+
}
|
|
4841
|
+
}]
|
|
4842
|
+
}
|
|
4843
|
+
});
|
|
4844
|
+
const protectedRangeId = response.data.replies?.[0]?.addProtectedRange?.protectedRange?.protectedRangeId;
|
|
4845
|
+
return { content: [{ type: "text", text: `Protected range ${a.range}${protectedRangeId ? ` (id: ${protectedRangeId})` : ""}.` }], isError: false };
|
|
4846
|
+
}
|
|
4847
|
+
case "addNamedRange": {
|
|
4848
|
+
const validation = AddNamedRangeSchema.safeParse(args);
|
|
4849
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
4850
|
+
const a = validation.data;
|
|
4851
|
+
const sheets = ctx.google.sheets({ version: "v4", auth: ctx.authClient });
|
|
4852
|
+
const gridRange = await resolveGridRange(sheets, a.spreadsheetId, a.range);
|
|
4853
|
+
if (typeof gridRange === "string") return errorResponse(gridRange);
|
|
4854
|
+
const response = await sheets.spreadsheets.batchUpdate({
|
|
4855
|
+
spreadsheetId: a.spreadsheetId,
|
|
4856
|
+
requestBody: {
|
|
4857
|
+
requests: [{
|
|
4858
|
+
addNamedRange: {
|
|
4859
|
+
namedRange: {
|
|
4860
|
+
name: a.name,
|
|
4861
|
+
range: gridRange
|
|
4862
|
+
}
|
|
4863
|
+
}
|
|
4864
|
+
}]
|
|
4865
|
+
}
|
|
4866
|
+
});
|
|
4867
|
+
const namedRangeId = response.data.replies?.[0]?.addNamedRange?.namedRange?.namedRangeId;
|
|
4868
|
+
return { content: [{ type: "text", text: `Added named range "${a.name}" for ${a.range}${namedRangeId ? ` (id: ${namedRangeId})` : ""}.` }], isError: false };
|
|
4869
|
+
}
|
|
4600
4870
|
case "listGoogleSheets": {
|
|
4601
4871
|
const validation = ListGoogleSheetsSchema.safeParse(args);
|
|
4602
4872
|
if (!validation.success) {
|
|
@@ -4766,6 +5036,31 @@ var UpdateGoogleSlidesSpeakerNotesSchema = z4.object({
|
|
|
4766
5036
|
slideIndex: z4.number().min(0, "Slide index must be non-negative"),
|
|
4767
5037
|
notes: z4.string()
|
|
4768
5038
|
});
|
|
5039
|
+
var DeleteGoogleSlideSchema = z4.object({
|
|
5040
|
+
presentationId: z4.string().min(1, "Presentation ID is required"),
|
|
5041
|
+
slideObjectId: z4.string().min(1, "Slide object ID is required")
|
|
5042
|
+
});
|
|
5043
|
+
var DuplicateSlideSchema = z4.object({
|
|
5044
|
+
presentationId: z4.string().min(1, "Presentation ID is required"),
|
|
5045
|
+
slideObjectId: z4.string().min(1, "Slide object ID is required")
|
|
5046
|
+
});
|
|
5047
|
+
var ReorderSlidesSchema = z4.object({
|
|
5048
|
+
presentationId: z4.string().min(1, "Presentation ID is required"),
|
|
5049
|
+
slideObjectIds: z4.array(z4.string().min(1)).min(1, "At least one slide object ID is required"),
|
|
5050
|
+
insertionIndex: z4.number().int().min(0)
|
|
5051
|
+
});
|
|
5052
|
+
var ReplaceAllTextInSlidesSchema = z4.object({
|
|
5053
|
+
presentationId: z4.string().min(1, "Presentation ID is required"),
|
|
5054
|
+
containsText: z4.string().min(1, "containsText is required"),
|
|
5055
|
+
replaceText: z4.string(),
|
|
5056
|
+
matchCase: z4.boolean().optional().default(false)
|
|
5057
|
+
});
|
|
5058
|
+
var ExportSlideThumbnailSchema = z4.object({
|
|
5059
|
+
presentationId: z4.string().min(1, "Presentation ID is required"),
|
|
5060
|
+
slideObjectId: z4.string().min(1, "Slide object ID is required"),
|
|
5061
|
+
mimeType: z4.enum(["PNG", "JPEG"]).optional().default("PNG"),
|
|
5062
|
+
size: z4.enum(["SMALL", "MEDIUM", "LARGE"]).optional().default("LARGE")
|
|
5063
|
+
});
|
|
4769
5064
|
var toolDefinitions4 = [
|
|
4770
5065
|
{
|
|
4771
5066
|
name: "createGoogleSlides",
|
|
@@ -5014,6 +5309,71 @@ var toolDefinitions4 = [
|
|
|
5014
5309
|
},
|
|
5015
5310
|
required: ["presentationId", "slideIndex", "notes"]
|
|
5016
5311
|
}
|
|
5312
|
+
},
|
|
5313
|
+
{
|
|
5314
|
+
name: "deleteGoogleSlide",
|
|
5315
|
+
description: "Delete a slide from a presentation",
|
|
5316
|
+
inputSchema: {
|
|
5317
|
+
type: "object",
|
|
5318
|
+
properties: {
|
|
5319
|
+
presentationId: { type: "string", description: "Presentation ID" },
|
|
5320
|
+
slideObjectId: { type: "string", description: "Slide object ID" }
|
|
5321
|
+
},
|
|
5322
|
+
required: ["presentationId", "slideObjectId"]
|
|
5323
|
+
}
|
|
5324
|
+
},
|
|
5325
|
+
{
|
|
5326
|
+
name: "duplicateSlide",
|
|
5327
|
+
description: "Duplicate a slide in a presentation",
|
|
5328
|
+
inputSchema: {
|
|
5329
|
+
type: "object",
|
|
5330
|
+
properties: {
|
|
5331
|
+
presentationId: { type: "string", description: "Presentation ID" },
|
|
5332
|
+
slideObjectId: { type: "string", description: "Slide object ID" }
|
|
5333
|
+
},
|
|
5334
|
+
required: ["presentationId", "slideObjectId"]
|
|
5335
|
+
}
|
|
5336
|
+
},
|
|
5337
|
+
{
|
|
5338
|
+
name: "reorderSlides",
|
|
5339
|
+
description: "Reorder one or more slides in a presentation",
|
|
5340
|
+
inputSchema: {
|
|
5341
|
+
type: "object",
|
|
5342
|
+
properties: {
|
|
5343
|
+
presentationId: { type: "string", description: "Presentation ID" },
|
|
5344
|
+
slideObjectIds: { type: "array", items: { type: "string" }, description: "Slide object IDs to move" },
|
|
5345
|
+
insertionIndex: { type: "number", description: "Target insertion index" }
|
|
5346
|
+
},
|
|
5347
|
+
required: ["presentationId", "slideObjectIds", "insertionIndex"]
|
|
5348
|
+
}
|
|
5349
|
+
},
|
|
5350
|
+
{
|
|
5351
|
+
name: "replaceAllTextInSlides",
|
|
5352
|
+
description: "Replace all matching text across presentation slides",
|
|
5353
|
+
inputSchema: {
|
|
5354
|
+
type: "object",
|
|
5355
|
+
properties: {
|
|
5356
|
+
presentationId: { type: "string", description: "Presentation ID" },
|
|
5357
|
+
containsText: { type: "string", description: "Text to find" },
|
|
5358
|
+
replaceText: { type: "string", description: "Replacement text" },
|
|
5359
|
+
matchCase: { type: "boolean", description: "Case-sensitive match" }
|
|
5360
|
+
},
|
|
5361
|
+
required: ["presentationId", "containsText", "replaceText"]
|
|
5362
|
+
}
|
|
5363
|
+
},
|
|
5364
|
+
{
|
|
5365
|
+
name: "exportSlideThumbnail",
|
|
5366
|
+
description: "Export a slide thumbnail URL",
|
|
5367
|
+
inputSchema: {
|
|
5368
|
+
type: "object",
|
|
5369
|
+
properties: {
|
|
5370
|
+
presentationId: { type: "string", description: "Presentation ID" },
|
|
5371
|
+
slideObjectId: { type: "string", description: "Slide object ID" },
|
|
5372
|
+
mimeType: { type: "string", enum: ["PNG", "JPEG"], description: "Thumbnail MIME type" },
|
|
5373
|
+
size: { type: "string", enum: ["SMALL", "MEDIUM", "LARGE"], description: "Thumbnail size" }
|
|
5374
|
+
},
|
|
5375
|
+
required: ["presentationId", "slideObjectId"]
|
|
5376
|
+
}
|
|
5017
5377
|
}
|
|
5018
5378
|
];
|
|
5019
5379
|
async function handleTool4(toolName, args, ctx) {
|
|
@@ -5758,6 +6118,103 @@ Slide ${a.slideIndex ?? index} (ID: ${slide.objectId}):
|
|
|
5758
6118
|
isError: false
|
|
5759
6119
|
};
|
|
5760
6120
|
}
|
|
6121
|
+
case "deleteGoogleSlide": {
|
|
6122
|
+
const validation = DeleteGoogleSlideSchema.safeParse(args);
|
|
6123
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
6124
|
+
const a = validation.data;
|
|
6125
|
+
const slidesService = ctx.google.slides({ version: "v1", auth: ctx.authClient });
|
|
6126
|
+
await slidesService.presentations.batchUpdate({
|
|
6127
|
+
presentationId: a.presentationId,
|
|
6128
|
+
requestBody: {
|
|
6129
|
+
requests: [{ deleteObject: { objectId: a.slideObjectId } }]
|
|
6130
|
+
}
|
|
6131
|
+
});
|
|
6132
|
+
return {
|
|
6133
|
+
content: [{ type: "text", text: `Deleted slide ${a.slideObjectId}` }],
|
|
6134
|
+
isError: false
|
|
6135
|
+
};
|
|
6136
|
+
}
|
|
6137
|
+
case "duplicateSlide": {
|
|
6138
|
+
const validation = DuplicateSlideSchema.safeParse(args);
|
|
6139
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
6140
|
+
const a = validation.data;
|
|
6141
|
+
const slidesService = ctx.google.slides({ version: "v1", auth: ctx.authClient });
|
|
6142
|
+
const response = await slidesService.presentations.batchUpdate({
|
|
6143
|
+
presentationId: a.presentationId,
|
|
6144
|
+
requestBody: {
|
|
6145
|
+
requests: [{ duplicateObject: { objectId: a.slideObjectId } }]
|
|
6146
|
+
}
|
|
6147
|
+
});
|
|
6148
|
+
const dupId = response.data.replies?.[0]?.duplicateObject?.objectId;
|
|
6149
|
+
return {
|
|
6150
|
+
content: [{ type: "text", text: `Duplicated slide ${a.slideObjectId}${dupId ? ` -> ${dupId}` : ""}` }],
|
|
6151
|
+
isError: false
|
|
6152
|
+
};
|
|
6153
|
+
}
|
|
6154
|
+
case "reorderSlides": {
|
|
6155
|
+
const validation = ReorderSlidesSchema.safeParse(args);
|
|
6156
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
6157
|
+
const a = validation.data;
|
|
6158
|
+
const slidesService = ctx.google.slides({ version: "v1", auth: ctx.authClient });
|
|
6159
|
+
await slidesService.presentations.batchUpdate({
|
|
6160
|
+
presentationId: a.presentationId,
|
|
6161
|
+
requestBody: {
|
|
6162
|
+
requests: [{
|
|
6163
|
+
updateSlidesPosition: {
|
|
6164
|
+
slideObjectIds: a.slideObjectIds,
|
|
6165
|
+
insertionIndex: a.insertionIndex
|
|
6166
|
+
}
|
|
6167
|
+
}]
|
|
6168
|
+
}
|
|
6169
|
+
});
|
|
6170
|
+
return {
|
|
6171
|
+
content: [{ type: "text", text: `Reordered ${a.slideObjectIds.length} slide(s) to index ${a.insertionIndex}` }],
|
|
6172
|
+
isError: false
|
|
6173
|
+
};
|
|
6174
|
+
}
|
|
6175
|
+
case "replaceAllTextInSlides": {
|
|
6176
|
+
const validation = ReplaceAllTextInSlidesSchema.safeParse(args);
|
|
6177
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
6178
|
+
const a = validation.data;
|
|
6179
|
+
const slidesService = ctx.google.slides({ version: "v1", auth: ctx.authClient });
|
|
6180
|
+
const response = await slidesService.presentations.batchUpdate({
|
|
6181
|
+
presentationId: a.presentationId,
|
|
6182
|
+
requestBody: {
|
|
6183
|
+
requests: [{
|
|
6184
|
+
replaceAllText: {
|
|
6185
|
+
containsText: {
|
|
6186
|
+
text: a.containsText,
|
|
6187
|
+
matchCase: a.matchCase
|
|
6188
|
+
},
|
|
6189
|
+
replaceText: a.replaceText
|
|
6190
|
+
}
|
|
6191
|
+
}]
|
|
6192
|
+
}
|
|
6193
|
+
});
|
|
6194
|
+
const count = response.data.replies?.[0]?.replaceAllText?.occurrencesChanged ?? 0;
|
|
6195
|
+
return {
|
|
6196
|
+
content: [{ type: "text", text: `Replaced ${count} occurrence(s) of "${a.containsText}" in slides.` }],
|
|
6197
|
+
isError: false
|
|
6198
|
+
};
|
|
6199
|
+
}
|
|
6200
|
+
case "exportSlideThumbnail": {
|
|
6201
|
+
const validation = ExportSlideThumbnailSchema.safeParse(args);
|
|
6202
|
+
if (!validation.success) return errorResponse(validation.error.errors[0].message);
|
|
6203
|
+
const a = validation.data;
|
|
6204
|
+
const slidesService = ctx.google.slides({ version: "v1", auth: ctx.authClient });
|
|
6205
|
+
const response = await slidesService.presentations.pages.getThumbnail({
|
|
6206
|
+
presentationId: a.presentationId,
|
|
6207
|
+
pageObjectId: a.slideObjectId,
|
|
6208
|
+
"thumbnailProperties.mimeType": a.mimeType,
|
|
6209
|
+
"thumbnailProperties.thumbnailSize": a.size
|
|
6210
|
+
});
|
|
6211
|
+
const url = response.data?.contentUrl;
|
|
6212
|
+
if (!url) return errorResponse("No thumbnail URL returned by Google Slides API.");
|
|
6213
|
+
return {
|
|
6214
|
+
content: [{ type: "text", text: `Slide thumbnail URL (${a.mimeType}, ${a.size}): ${url}` }],
|
|
6215
|
+
isError: false
|
|
6216
|
+
};
|
|
6217
|
+
}
|
|
5761
6218
|
default:
|
|
5762
6219
|
return null;
|
|
5763
6220
|
}
|