pptx-viewer-mcp 2.5.8 → 2.6.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/CHANGELOG.md +16 -0
- package/LICENSE +202 -0
- package/README.md +8 -0
- package/dist/codec/index.d.ts +4 -49
- package/dist/codec/index.d.ts.map +1 -1
- package/dist/codec/index.js +7 -357
- package/dist/codec/index.mjs +7 -357
- package/dist/index.d.ts +192 -1277
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +90 -3204
- package/dist/index.mjs +89 -3204
- package/dist/mcp/cli.d.ts +1 -0
- package/dist/mcp/cli.js +2288 -0
- package/dist/mcp/cli.mjs +2286 -0
- package/dist/mcp/index.d.ts +18 -1
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +240 -3313
- package/dist/mcp/index.mjs +239 -3313
- package/dist/types-BUuwyzY-.d.ts +11 -0
- package/dist/types-BUuwyzY-.d.ts.map +1 -0
- package/package.json +4 -4
package/dist/mcp/cli.mjs
ADDED
|
@@ -0,0 +1,2286 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { apiToolsChartFormattingTools, apiToolsChartTools, apiToolsChartUserShapeTools, apiToolsContentTools, apiToolsConversionTools, apiToolsElementTools, apiToolsExportTools, apiToolsGeometryTools, apiToolsHyperlinkTools, apiToolsJsonTools, apiToolsLayoutTools, apiToolsLockTools, apiToolsMetadataTools, apiToolsOleTools, apiToolsPresentationTools, apiToolsSectionTools, apiToolsSlideTools, apiToolsSmartartTools, apiToolsStyleTools, apiToolsTableStyleTools, apiToolsTableTools, apiToolsTemplateTools, apiToolsThemeTools, apiToolsValidationTools, apiExecution } from 'ooxml-core/pptx/automation';
|
|
6
|
+
import { writeFile, readFile } from 'fs/promises';
|
|
7
|
+
import { resolve, isAbsolute, sep } from 'path';
|
|
8
|
+
|
|
9
|
+
var GetSlideSchema = z.object({
|
|
10
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
11
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index")
|
|
12
|
+
});
|
|
13
|
+
var AddSlideSchema = z.object({
|
|
14
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
15
|
+
insertAfterIndex: z.number().int().min(0).optional().describe("Insert after this slide index"),
|
|
16
|
+
backgroundColor: z.string().optional().describe("Background color (hex)")
|
|
17
|
+
});
|
|
18
|
+
var DeleteSlidesSchema = z.object({
|
|
19
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
20
|
+
slideIndexes: z.array(z.number().int().min(0)).min(1).describe("Slide indexes to delete")
|
|
21
|
+
});
|
|
22
|
+
var ReorderSlidesSchema = z.object({
|
|
23
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
24
|
+
newOrder: z.array(z.number().int().min(0)).min(1).describe("New slide order as array of indexes")
|
|
25
|
+
});
|
|
26
|
+
var DuplicateSlideSchema = z.object({
|
|
27
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
28
|
+
slideIndex: z.number().int().min(0).describe("Slide to duplicate"),
|
|
29
|
+
targetIndex: z.number().int().min(0).optional().describe("Where to insert the duplicate")
|
|
30
|
+
});
|
|
31
|
+
var UpdateSlidePropertiesSchema = z.object({
|
|
32
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
33
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
34
|
+
backgroundColor: z.string().optional().describe("Background color (hex)"),
|
|
35
|
+
backgroundGradient: z.string().optional().describe("Background gradient CSS"),
|
|
36
|
+
backgroundImage: z.string().optional().describe("Background image data URL"),
|
|
37
|
+
notes: z.string().optional().describe("Speaker notes text"),
|
|
38
|
+
hidden: z.boolean().optional().describe("Whether slide is hidden")
|
|
39
|
+
});
|
|
40
|
+
var SetSlideTransitionSchema = z.object({
|
|
41
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
42
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
43
|
+
type: z.string().describe('Transition type (e.g. "fade", "wipe", "none")'),
|
|
44
|
+
durationMs: z.number().int().min(0).optional().describe("Duration in ms"),
|
|
45
|
+
direction: z.string().optional().describe('Direction (e.g. "left", "right")'),
|
|
46
|
+
advanceOnClick: z.boolean().optional().describe("Advance on mouse click"),
|
|
47
|
+
advanceAfterMs: z.number().int().min(0).optional().describe("Auto-advance after ms")
|
|
48
|
+
});
|
|
49
|
+
var SetCanvasSizeSchema = z.object({
|
|
50
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
51
|
+
width: z.number().positive().describe("Canvas width in points"),
|
|
52
|
+
height: z.number().positive().describe("Canvas height in points")
|
|
53
|
+
});
|
|
54
|
+
var ConvertToMarkdownSchema = z.object({
|
|
55
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
56
|
+
outputDir: z.string().optional().describe("Output directory for markdown and media"),
|
|
57
|
+
mediaFolderName: z.string().optional().describe("Name for extracted media folder"),
|
|
58
|
+
includeMetadata: z.boolean().optional().describe("Include presentation metadata"),
|
|
59
|
+
slideRange: z.object({
|
|
60
|
+
start: z.number().int().min(0).optional(),
|
|
61
|
+
end: z.number().int().min(0).optional()
|
|
62
|
+
}).optional().describe("Slide range to convert"),
|
|
63
|
+
includeSpeakerNotes: z.boolean().optional().describe("Include speaker notes"),
|
|
64
|
+
semanticMode: z.boolean().optional().describe("Use semantic (clean) markdown mode")
|
|
65
|
+
});
|
|
66
|
+
var AccessibilityCheckSchema = z.object({
|
|
67
|
+
filePath: z.string().describe("Path to the PPTX file")
|
|
68
|
+
});
|
|
69
|
+
var ThemeColorRefSchema = z.object({
|
|
70
|
+
scheme: z.enum([
|
|
71
|
+
"dk1",
|
|
72
|
+
"lt1",
|
|
73
|
+
"dk2",
|
|
74
|
+
"lt2",
|
|
75
|
+
"accent1",
|
|
76
|
+
"accent2",
|
|
77
|
+
"accent3",
|
|
78
|
+
"accent4",
|
|
79
|
+
"accent5",
|
|
80
|
+
"accent6",
|
|
81
|
+
"hlink",
|
|
82
|
+
"folHlink",
|
|
83
|
+
"bg1",
|
|
84
|
+
"tx1",
|
|
85
|
+
"bg2",
|
|
86
|
+
"tx2",
|
|
87
|
+
"phClr"
|
|
88
|
+
]),
|
|
89
|
+
lumMod: z.number().optional().describe("Multiply HSL luminance (0..1)"),
|
|
90
|
+
lumOff: z.number().optional().describe("Add to HSL luminance after lumMod (0..1)"),
|
|
91
|
+
tint: z.number().optional().describe("Blend towards white (0..1)"),
|
|
92
|
+
shade: z.number().optional().describe("Blend towards black (0..1)"),
|
|
93
|
+
alpha: z.number().optional().describe("Opacity fraction, 1 = opaque")
|
|
94
|
+
});
|
|
95
|
+
var AddElementSchema = z.object({
|
|
96
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
97
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
98
|
+
type: z.enum(["text", "shape", "image", "table", "connector"]).describe("Element type to add"),
|
|
99
|
+
x: z.number().optional().describe("X position in points"),
|
|
100
|
+
y: z.number().optional().describe("Y position in points"),
|
|
101
|
+
width: z.number().optional().describe("Width in points"),
|
|
102
|
+
height: z.number().optional().describe("Height in points"),
|
|
103
|
+
text: z.string().optional().describe("Text content"),
|
|
104
|
+
fontSize: z.number().optional().describe("Font size in points"),
|
|
105
|
+
fontFamily: z.string().optional().describe("Font family name"),
|
|
106
|
+
fontColor: z.string().optional().describe("Font color (hex)"),
|
|
107
|
+
bold: z.boolean().optional().describe("Bold text"),
|
|
108
|
+
italic: z.boolean().optional().describe("Italic text"),
|
|
109
|
+
underline: z.boolean().optional().describe("Underline text"),
|
|
110
|
+
alignment: z.enum(["left", "center", "right", "justify"]).optional().describe("Text alignment"),
|
|
111
|
+
shapeType: z.string().optional().describe('Shape type (e.g. "rect", "ellipse")'),
|
|
112
|
+
fillColor: z.string().optional().describe("Fill color (hex)"),
|
|
113
|
+
strokeColor: z.string().optional().describe("Stroke color (hex)"),
|
|
114
|
+
strokeWidth: z.number().optional().describe("Stroke width in points"),
|
|
115
|
+
imageData: z.string().optional().describe("Image as base64 data URL"),
|
|
116
|
+
altText: z.string().optional().describe("Alt text for accessibility"),
|
|
117
|
+
rows: z.number().int().min(1).optional().describe("Number of table rows"),
|
|
118
|
+
columns: z.number().int().min(1).optional().describe("Number of table columns"),
|
|
119
|
+
cellData: z.array(z.array(z.string())).optional().describe("Table cell data as 2D array"),
|
|
120
|
+
headerRow: z.boolean().optional().describe("Style first row as header"),
|
|
121
|
+
startArrow: z.string().optional().describe("Start arrow type"),
|
|
122
|
+
endArrow: z.string().optional().describe("End arrow type"),
|
|
123
|
+
startShapeId: z.string().optional().describe("Connect start to shape ID"),
|
|
124
|
+
endShapeId: z.string().optional().describe("Connect end to shape ID")
|
|
125
|
+
});
|
|
126
|
+
var UpdateElementSchema = z.object({
|
|
127
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
128
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
129
|
+
elementId: z.string().describe("Element ID to update"),
|
|
130
|
+
x: z.number().optional(),
|
|
131
|
+
y: z.number().optional(),
|
|
132
|
+
width: z.number().optional(),
|
|
133
|
+
height: z.number().optional(),
|
|
134
|
+
rotation: z.number().optional(),
|
|
135
|
+
text: z.string().optional(),
|
|
136
|
+
textSegments: z.array(
|
|
137
|
+
z.object({
|
|
138
|
+
text: z.string(),
|
|
139
|
+
style: z.record(z.string(), z.any())
|
|
140
|
+
}).passthrough()
|
|
141
|
+
).optional().describe(
|
|
142
|
+
"Rich text segments, including paragraph and bullet metadata. Takes precedence over text."
|
|
143
|
+
),
|
|
144
|
+
fontSize: z.number().optional(),
|
|
145
|
+
fontFamily: z.string().optional(),
|
|
146
|
+
fontColor: z.string().optional(),
|
|
147
|
+
/**
|
|
148
|
+
* A theme colour for the run text. Wins on save; resolves `fontColor`
|
|
149
|
+
* immediately when `fontColor` was not also given. Passing `fontColor`
|
|
150
|
+
* alone clears a previously-set text theme colour.
|
|
151
|
+
*/
|
|
152
|
+
fontThemeColor: ThemeColorRefSchema.optional(),
|
|
153
|
+
bold: z.boolean().optional(),
|
|
154
|
+
italic: z.boolean().optional(),
|
|
155
|
+
underline: z.boolean().optional(),
|
|
156
|
+
alignment: z.enum(["left", "center", "right", "justify"]).optional(),
|
|
157
|
+
fillColor: z.string().optional(),
|
|
158
|
+
strokeColor: z.string().optional(),
|
|
159
|
+
strokeWidth: z.number().optional(),
|
|
160
|
+
opacity: z.number().min(0).max(1).optional(),
|
|
161
|
+
hidden: z.boolean().optional(),
|
|
162
|
+
flipH: z.boolean().optional(),
|
|
163
|
+
flipV: z.boolean().optional(),
|
|
164
|
+
altText: z.string().optional().describe(
|
|
165
|
+
"Accessibility description (p:cNvPr/@descr) for image, picture, table, chart, smartArt, ole, media, text, shape and connector elements"
|
|
166
|
+
),
|
|
167
|
+
title: z.string().optional().describe(
|
|
168
|
+
"Accessibility title (p:cNvPr/@title) for table, chart, smartArt, ole, media, text, shape and connector elements (not pictures)"
|
|
169
|
+
)
|
|
170
|
+
});
|
|
171
|
+
var RenameElementSchema = z.object({
|
|
172
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
173
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
174
|
+
elementId: z.string().describe("Element ID to rename"),
|
|
175
|
+
name: z.string().describe("New element name (empty string clears the name)")
|
|
176
|
+
});
|
|
177
|
+
var DeleteElementsSchema = z.object({
|
|
178
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
179
|
+
slideIndex: z.number().int().min(0),
|
|
180
|
+
elementIds: z.array(z.string()).min(1).describe("Element IDs to delete")
|
|
181
|
+
});
|
|
182
|
+
var ArrangeElementsSchema = z.object({
|
|
183
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
184
|
+
slideIndex: z.number().int().min(0),
|
|
185
|
+
action: z.enum(["align", "reorderLayer"]),
|
|
186
|
+
elementIds: z.array(z.string()).optional().describe("Element IDs (for align)"),
|
|
187
|
+
alignment: z.enum(["left", "right", "top", "bottom", "centerH", "centerV"]).optional(),
|
|
188
|
+
elementId: z.string().optional().describe("Element ID (for reorderLayer)"),
|
|
189
|
+
layerAction: z.enum(["bringForward", "sendBackward", "bringToFront", "sendToBack"]).optional()
|
|
190
|
+
});
|
|
191
|
+
var CloneElementSchema = z.object({
|
|
192
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
193
|
+
slideIndex: z.number().int().min(0),
|
|
194
|
+
elementId: z.string(),
|
|
195
|
+
targetSlideIndexes: z.array(z.number().int().min(0)).optional(),
|
|
196
|
+
offsetX: z.number().optional(),
|
|
197
|
+
offsetY: z.number().optional()
|
|
198
|
+
});
|
|
199
|
+
var SetElementAnimationSchema = z.object({
|
|
200
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
201
|
+
slideIndex: z.number().int().min(0),
|
|
202
|
+
elementId: z.string(),
|
|
203
|
+
entrance: z.string().optional(),
|
|
204
|
+
exit: z.string().optional(),
|
|
205
|
+
durationMs: z.number().optional(),
|
|
206
|
+
delayMs: z.number().optional(),
|
|
207
|
+
order: z.number().optional()
|
|
208
|
+
});
|
|
209
|
+
var GroupElementsSchema = z.object({
|
|
210
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
211
|
+
slideIndex: z.number().int().min(0),
|
|
212
|
+
elementIds: z.array(z.string()).min(2).describe("At least 2 element IDs to group")
|
|
213
|
+
});
|
|
214
|
+
var UngroupElementsSchema = z.object({
|
|
215
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
216
|
+
slideIndex: z.number().int().min(0),
|
|
217
|
+
groupElementId: z.string().describe("Group element ID to ungroup")
|
|
218
|
+
});
|
|
219
|
+
var BatchUpdateElementsSchema = z.object({
|
|
220
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
221
|
+
slideIndex: z.number().int().min(0),
|
|
222
|
+
elementIds: z.array(z.string()).min(1),
|
|
223
|
+
x: z.number().optional(),
|
|
224
|
+
y: z.number().optional(),
|
|
225
|
+
width: z.number().optional(),
|
|
226
|
+
height: z.number().optional(),
|
|
227
|
+
rotation: z.number().optional(),
|
|
228
|
+
opacity: z.number().min(0).max(1).optional(),
|
|
229
|
+
hidden: z.boolean().optional()
|
|
230
|
+
});
|
|
231
|
+
var ThemeColorRefSchema2 = z.object({
|
|
232
|
+
scheme: z.enum([
|
|
233
|
+
"dk1",
|
|
234
|
+
"lt1",
|
|
235
|
+
"dk2",
|
|
236
|
+
"lt2",
|
|
237
|
+
"accent1",
|
|
238
|
+
"accent2",
|
|
239
|
+
"accent3",
|
|
240
|
+
"accent4",
|
|
241
|
+
"accent5",
|
|
242
|
+
"accent6",
|
|
243
|
+
"hlink",
|
|
244
|
+
"folHlink",
|
|
245
|
+
"bg1",
|
|
246
|
+
"tx1",
|
|
247
|
+
"bg2",
|
|
248
|
+
"tx2",
|
|
249
|
+
"phClr"
|
|
250
|
+
]),
|
|
251
|
+
lumMod: z.number().optional().describe("Multiply HSL luminance (0..1)"),
|
|
252
|
+
lumOff: z.number().optional().describe("Add to HSL luminance after lumMod (0..1)"),
|
|
253
|
+
tint: z.number().optional().describe("Blend towards white (0..1)"),
|
|
254
|
+
shade: z.number().optional().describe("Blend towards black (0..1)"),
|
|
255
|
+
alpha: z.number().optional().describe("Opacity fraction, 1 = opaque")
|
|
256
|
+
});
|
|
257
|
+
var UpdateTableCellsSchema = z.object({
|
|
258
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
259
|
+
slideIndex: z.number().int().min(0),
|
|
260
|
+
elementId: z.string().describe("Table element ID"),
|
|
261
|
+
cells: z.array(
|
|
262
|
+
z.object({
|
|
263
|
+
row: z.number().int().min(0),
|
|
264
|
+
col: z.number().int().min(0),
|
|
265
|
+
text: z.string()
|
|
266
|
+
})
|
|
267
|
+
).min(1).describe("Cells to update")
|
|
268
|
+
});
|
|
269
|
+
var ManageTableStructureSchema = z.object({
|
|
270
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
271
|
+
slideIndex: z.number().int().min(0),
|
|
272
|
+
elementId: z.string().describe("Table element ID"),
|
|
273
|
+
action: z.enum(["insertRow", "deleteRow", "insertColumn", "deleteColumn"]),
|
|
274
|
+
position: z.number().int().min(0).optional().describe("Insertion position index"),
|
|
275
|
+
referenceIndex: z.number().int().min(0).optional(),
|
|
276
|
+
cellTexts: z.array(z.string()).optional()
|
|
277
|
+
});
|
|
278
|
+
var UpdateElementStyleSchema = z.object({
|
|
279
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
280
|
+
slideIndex: z.number().int().min(0),
|
|
281
|
+
elementId: z.string(),
|
|
282
|
+
fillColor: z.string().optional(),
|
|
283
|
+
/**
|
|
284
|
+
* A theme colour for the fill (e.g. `{ scheme: 'accent1', lumMod: 0.8 }`
|
|
285
|
+
* for "Accent 1, Lighter 80%"). When set, the shape saves as
|
|
286
|
+
* `<a:schemeClr>` and keeps following the theme after a later theme
|
|
287
|
+
* change, instead of freezing today's resolved hex. Setting `fillColor`
|
|
288
|
+
* without this clears any previously-set fill theme colour.
|
|
289
|
+
*/
|
|
290
|
+
fillThemeColor: ThemeColorRefSchema2.optional(),
|
|
291
|
+
fillMode: z.string().optional(),
|
|
292
|
+
fillGradientStops: z.array(
|
|
293
|
+
z.object({
|
|
294
|
+
color: z.string(),
|
|
295
|
+
position: z.number(),
|
|
296
|
+
opacity: z.number().optional()
|
|
297
|
+
})
|
|
298
|
+
).optional(),
|
|
299
|
+
fillGradientAngle: z.number().optional(),
|
|
300
|
+
fillGradientType: z.string().optional(),
|
|
301
|
+
fillOpacity: z.number().optional(),
|
|
302
|
+
strokeColor: z.string().optional(),
|
|
303
|
+
/** A theme colour for the outline; see `fillThemeColor` above. */
|
|
304
|
+
strokeThemeColor: ThemeColorRefSchema2.optional(),
|
|
305
|
+
strokeWidth: z.number().optional(),
|
|
306
|
+
strokeDash: z.string().optional(),
|
|
307
|
+
strokeOpacity: z.number().optional(),
|
|
308
|
+
shadowColor: z.string().optional(),
|
|
309
|
+
shadowBlur: z.number().optional(),
|
|
310
|
+
shadowOffsetX: z.number().optional(),
|
|
311
|
+
shadowOffsetY: z.number().optional(),
|
|
312
|
+
shadowOpacity: z.number().optional(),
|
|
313
|
+
glowColor: z.string().optional(),
|
|
314
|
+
glowRadius: z.number().optional(),
|
|
315
|
+
glowOpacity: z.number().optional(),
|
|
316
|
+
softEdgeRadius: z.number().optional(),
|
|
317
|
+
cropLeft: z.number().optional(),
|
|
318
|
+
cropTop: z.number().optional(),
|
|
319
|
+
cropRight: z.number().optional(),
|
|
320
|
+
cropBottom: z.number().optional(),
|
|
321
|
+
brightness: z.number().optional(),
|
|
322
|
+
contrast: z.number().optional(),
|
|
323
|
+
grayscale: z.boolean().optional(),
|
|
324
|
+
altText: z.string().optional().describe(
|
|
325
|
+
"Accessibility description (p:cNvPr/@descr) for image, picture, table, chart, smartArt, ole, media, text, shape and connector elements"
|
|
326
|
+
),
|
|
327
|
+
title: z.string().optional().describe(
|
|
328
|
+
"Accessibility title (p:cNvPr/@title) for table, chart, smartArt, ole, media, text, shape and connector elements (not pictures)"
|
|
329
|
+
)
|
|
330
|
+
});
|
|
331
|
+
var FindTextSchema = z.object({
|
|
332
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
333
|
+
query: z.string().describe("Text to search for"),
|
|
334
|
+
useRegex: z.boolean().optional().describe("Treat query as regex"),
|
|
335
|
+
caseSensitive: z.boolean().optional().describe("Case-sensitive search"),
|
|
336
|
+
slideIndexes: z.array(z.number().int().min(0)).optional().describe("Limit search to specific slides")
|
|
337
|
+
});
|
|
338
|
+
var ReplaceTextSchema = z.object({
|
|
339
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
340
|
+
query: z.string().describe("Text to find"),
|
|
341
|
+
replacement: z.string().describe("Replacement text"),
|
|
342
|
+
useRegex: z.boolean().optional(),
|
|
343
|
+
caseSensitive: z.boolean().optional(),
|
|
344
|
+
slideIndexes: z.array(z.number().int().min(0)).optional()
|
|
345
|
+
});
|
|
346
|
+
var ManageCommentsSchema = z.object({
|
|
347
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
348
|
+
action: z.enum(["list", "add", "delete", "resolve"]),
|
|
349
|
+
slideIndex: z.number().int().min(0).optional(),
|
|
350
|
+
text: z.string().optional(),
|
|
351
|
+
author: z.string().optional(),
|
|
352
|
+
commentId: z.string().optional(),
|
|
353
|
+
resolved: z.boolean().optional(),
|
|
354
|
+
includeResolved: z.boolean().optional()
|
|
355
|
+
});
|
|
356
|
+
var TABLE_STYLE_SECTIONS = [
|
|
357
|
+
"wholeTbl",
|
|
358
|
+
"band1H",
|
|
359
|
+
"band2H",
|
|
360
|
+
"band1V",
|
|
361
|
+
"band2V",
|
|
362
|
+
"lastCol",
|
|
363
|
+
"firstCol",
|
|
364
|
+
"lastRow",
|
|
365
|
+
"seCell",
|
|
366
|
+
"swCell",
|
|
367
|
+
"firstRow",
|
|
368
|
+
"neCell",
|
|
369
|
+
"nwCell"
|
|
370
|
+
];
|
|
371
|
+
var TableStyleSimpleColorSchema = z.object({
|
|
372
|
+
schemeColor: z.string().describe('Theme colour key (e.g. "accent1"), or "" for a non-scheme fill'),
|
|
373
|
+
tint: z.number().optional().describe("0-100000"),
|
|
374
|
+
shade: z.number().optional().describe("0-100000"),
|
|
375
|
+
color: z.string().optional().describe('Explicit hex colour, e.g. "#FF8800"')
|
|
376
|
+
});
|
|
377
|
+
var TableStyleFillSchema = z.object({
|
|
378
|
+
schemeColor: z.string(),
|
|
379
|
+
tint: z.number().optional(),
|
|
380
|
+
shade: z.number().optional(),
|
|
381
|
+
color: z.string().optional(),
|
|
382
|
+
noFill: z.boolean().optional(),
|
|
383
|
+
gradient: z.object({
|
|
384
|
+
type: z.enum(["linear", "radial"]),
|
|
385
|
+
angle: z.number().optional(),
|
|
386
|
+
stops: z.array(z.object({ position: z.number(), fill: TableStyleSimpleColorSchema }))
|
|
387
|
+
}).optional(),
|
|
388
|
+
pattern: z.object({
|
|
389
|
+
preset: z.string(),
|
|
390
|
+
foreground: TableStyleSimpleColorSchema.optional(),
|
|
391
|
+
background: TableStyleSimpleColorSchema.optional()
|
|
392
|
+
}).optional(),
|
|
393
|
+
image: z.object({ path: z.string().optional(), data: z.string().optional() }).optional()
|
|
394
|
+
});
|
|
395
|
+
var TableStyleTextSchema = z.object({
|
|
396
|
+
bold: z.boolean().optional(),
|
|
397
|
+
italic: z.boolean().optional(),
|
|
398
|
+
underline: z.boolean().optional(),
|
|
399
|
+
fontSchemeColor: z.string().optional(),
|
|
400
|
+
fontTint: z.number().optional(),
|
|
401
|
+
fontShade: z.number().optional(),
|
|
402
|
+
fontColor: z.string().optional(),
|
|
403
|
+
fontFace: z.string().optional(),
|
|
404
|
+
fontRefIdx: z.string().optional()
|
|
405
|
+
});
|
|
406
|
+
var TableStyleBorderSideSchema = z.object({
|
|
407
|
+
width: z.number().optional(),
|
|
408
|
+
dash: z.string().optional(),
|
|
409
|
+
fill: TableStyleSimpleColorSchema.optional(),
|
|
410
|
+
color: z.string().optional(),
|
|
411
|
+
noFill: z.boolean().optional()
|
|
412
|
+
});
|
|
413
|
+
var TableStyleBordersSchema = z.object({
|
|
414
|
+
left: TableStyleBorderSideSchema.optional(),
|
|
415
|
+
right: TableStyleBorderSideSchema.optional(),
|
|
416
|
+
top: TableStyleBorderSideSchema.optional(),
|
|
417
|
+
bottom: TableStyleBorderSideSchema.optional(),
|
|
418
|
+
insideH: TableStyleBorderSideSchema.optional(),
|
|
419
|
+
insideV: TableStyleBorderSideSchema.optional(),
|
|
420
|
+
tl2br: TableStyleBorderSideSchema.optional(),
|
|
421
|
+
tr2bl: TableStyleBorderSideSchema.optional()
|
|
422
|
+
});
|
|
423
|
+
var TableStyleCell3DSchema = z.object({
|
|
424
|
+
bevelWidth: z.number().optional(),
|
|
425
|
+
bevelHeight: z.number().optional(),
|
|
426
|
+
bevelPreset: z.string().optional(),
|
|
427
|
+
material: z.string().optional(),
|
|
428
|
+
lightRig: z.string().optional(),
|
|
429
|
+
lightRigDirection: z.string().optional()
|
|
430
|
+
});
|
|
431
|
+
var SetTableStyleSectionSchema = z.object({
|
|
432
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
433
|
+
styleId: z.string().describe('Table style GUID, e.g. "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}"'),
|
|
434
|
+
section: z.enum(TABLE_STYLE_SECTIONS).describe("Which of the 13 CT_TableStyle parts to patch"),
|
|
435
|
+
styleName: z.string().optional().describe("Rename the style"),
|
|
436
|
+
fill: TableStyleFillSchema.optional(),
|
|
437
|
+
text: TableStyleTextSchema.optional(),
|
|
438
|
+
borders: TableStyleBordersSchema.optional(),
|
|
439
|
+
cell3D: TableStyleCell3DSchema.optional()
|
|
440
|
+
});
|
|
441
|
+
var CreateTableStyleSchema = z.object({
|
|
442
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
443
|
+
styleName: z.string().describe("Display name for the new style"),
|
|
444
|
+
basedOnStyleId: z.string().optional().describe("Deep-clone every section from this existing style GUID as the starting point"),
|
|
445
|
+
setAsDefault: z.boolean().optional().describe("Repoint ppt/tableStyles.xml's default style at the new one")
|
|
446
|
+
});
|
|
447
|
+
var DeleteTableStyleSchema = z.object({
|
|
448
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
449
|
+
styleId: z.string().describe("Table style GUID to remove"),
|
|
450
|
+
force: z.boolean().optional().describe("Delete even though a table on this deck still references the style")
|
|
451
|
+
});
|
|
452
|
+
var AssignTableStyleSchema = z.object({
|
|
453
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
454
|
+
slideIndex: z.number().int().min(0),
|
|
455
|
+
elementId: z.string().describe("Table element ID"),
|
|
456
|
+
styleId: z.string().optional().describe(
|
|
457
|
+
"Table style GUID to assign. Defaults to the presentation's current default table style when omitted."
|
|
458
|
+
),
|
|
459
|
+
bandedRows: z.boolean().optional(),
|
|
460
|
+
bandedColumns: z.boolean().optional(),
|
|
461
|
+
firstRowHeader: z.boolean().optional(),
|
|
462
|
+
lastRow: z.boolean().optional(),
|
|
463
|
+
firstCol: z.boolean().optional(),
|
|
464
|
+
lastCol: z.boolean().optional()
|
|
465
|
+
});
|
|
466
|
+
var GetThemeInfoSchema = z.object({
|
|
467
|
+
filePath: z.string().describe("Path to the PPTX file")
|
|
468
|
+
});
|
|
469
|
+
var ApplyThemePresetSchema = z.object({
|
|
470
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
471
|
+
presetName: z.string().describe(
|
|
472
|
+
'Theme preset name (e.g. "OFFICE", "MODERN_BLUE", "EARTH", "MONOCHROME", "VIBRANT", "CORPORATE", "MINIMAL", "DARK")'
|
|
473
|
+
)
|
|
474
|
+
});
|
|
475
|
+
var UpdateThemeColorsSchema = z.object({
|
|
476
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
477
|
+
dk1: z.string().optional().describe("Dark 1 color (hex)"),
|
|
478
|
+
lt1: z.string().optional().describe("Light 1 color (hex)"),
|
|
479
|
+
dk2: z.string().optional().describe("Dark 2 color (hex)"),
|
|
480
|
+
lt2: z.string().optional().describe("Light 2 color (hex)"),
|
|
481
|
+
accent1: z.string().optional().describe("Accent 1 color (hex)"),
|
|
482
|
+
accent2: z.string().optional().describe("Accent 2 color (hex)"),
|
|
483
|
+
accent3: z.string().optional().describe("Accent 3 color (hex)"),
|
|
484
|
+
accent4: z.string().optional().describe("Accent 4 color (hex)"),
|
|
485
|
+
accent5: z.string().optional().describe("Accent 5 color (hex)"),
|
|
486
|
+
accent6: z.string().optional().describe("Accent 6 color (hex)"),
|
|
487
|
+
hlink: z.string().optional().describe("Hyperlink color (hex)"),
|
|
488
|
+
folHlink: z.string().optional().describe("Followed hyperlink color (hex)")
|
|
489
|
+
});
|
|
490
|
+
var UpdateThemeFontsSchema = z.object({
|
|
491
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
492
|
+
majorFont: z.string().optional().describe("Heading (major) font family"),
|
|
493
|
+
minorFont: z.string().optional().describe("Body (minor) font family")
|
|
494
|
+
});
|
|
495
|
+
var MarkerSymbolSchema = z.enum([
|
|
496
|
+
"circle",
|
|
497
|
+
"dash",
|
|
498
|
+
"diamond",
|
|
499
|
+
"dot",
|
|
500
|
+
"none",
|
|
501
|
+
"picture",
|
|
502
|
+
"plus",
|
|
503
|
+
"square",
|
|
504
|
+
"star",
|
|
505
|
+
"triangle",
|
|
506
|
+
"x",
|
|
507
|
+
"auto"
|
|
508
|
+
]);
|
|
509
|
+
var DataLabelPositionSchema = z.enum([
|
|
510
|
+
"bestFit",
|
|
511
|
+
"b",
|
|
512
|
+
"ctr",
|
|
513
|
+
"inBase",
|
|
514
|
+
"inEnd",
|
|
515
|
+
"l",
|
|
516
|
+
"outEnd",
|
|
517
|
+
"r",
|
|
518
|
+
"t"
|
|
519
|
+
]);
|
|
520
|
+
var FormatChartDataPointSchema = z.object({
|
|
521
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
522
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
523
|
+
elementId: z.string().describe("Chart element ID"),
|
|
524
|
+
seriesIndex: z.number().int().min(0).describe("Zero-based series index"),
|
|
525
|
+
pointIndex: z.number().int().min(0).describe("Zero-based data point (category) index"),
|
|
526
|
+
fillColor: z.string().optional().describe("Fill colour (hex) for this point only"),
|
|
527
|
+
strokeColor: z.string().optional().describe("Outline colour (hex) for this point only"),
|
|
528
|
+
strokeWidth: z.number().optional().describe("Outline width in points"),
|
|
529
|
+
strokeDashStyle: z.string().optional().describe("Outline dash style, e.g. solid, dash, dashDot, sysDot"),
|
|
530
|
+
clearStyle: z.boolean().optional().describe("Remove all per-point shape formatting"),
|
|
531
|
+
explosion: z.number().nullable().optional().describe("Pie/doughnut slice pull-out distance 0-100; null clears it"),
|
|
532
|
+
marker: z.object({
|
|
533
|
+
symbol: MarkerSymbolSchema.optional(),
|
|
534
|
+
size: z.number().optional(),
|
|
535
|
+
fillColor: z.string().optional()
|
|
536
|
+
}).nullable().optional().describe("Per-point marker override (line/scatter/bubble); null clears it")
|
|
537
|
+
});
|
|
538
|
+
var FormatChartDataLabelSchema = z.object({
|
|
539
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
540
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
541
|
+
elementId: z.string().describe("Chart element ID"),
|
|
542
|
+
seriesIndex: z.number().int().min(0).describe("Zero-based series index"),
|
|
543
|
+
pointIndex: z.number().int().min(0).describe("Zero-based data point (category) index"),
|
|
544
|
+
remove: z.boolean().optional().describe("Remove the per-point label override entirely"),
|
|
545
|
+
showValue: z.boolean().optional(),
|
|
546
|
+
showCategory: z.boolean().optional(),
|
|
547
|
+
showSeriesName: z.boolean().optional(),
|
|
548
|
+
showPercent: z.boolean().optional(),
|
|
549
|
+
showLegendKey: z.boolean().optional(),
|
|
550
|
+
position: DataLabelPositionSchema.optional(),
|
|
551
|
+
text: z.string().optional().describe("Custom label text override; '' clears it"),
|
|
552
|
+
spPr: z.object({
|
|
553
|
+
fillColor: z.string().optional(),
|
|
554
|
+
strokeColor: z.string().optional(),
|
|
555
|
+
strokeWidth: z.number().optional(),
|
|
556
|
+
strokeDashStyle: z.string().optional()
|
|
557
|
+
}).nullable().optional().describe("This label's own fill/line formatting; null removes it"),
|
|
558
|
+
txPr: z.object({
|
|
559
|
+
fontFamily: z.string().optional(),
|
|
560
|
+
fontSize: z.number().optional(),
|
|
561
|
+
bold: z.boolean().optional(),
|
|
562
|
+
italic: z.boolean().optional(),
|
|
563
|
+
color: z.string().optional()
|
|
564
|
+
}).nullable().optional().describe("This label's own font; null removes it")
|
|
565
|
+
});
|
|
566
|
+
var FormatChartSeriesSchema = z.object({
|
|
567
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
568
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
569
|
+
elementId: z.string().describe("Chart element ID"),
|
|
570
|
+
seriesIndex: z.number().int().min(0).describe("Zero-based series index"),
|
|
571
|
+
marker: z.object({
|
|
572
|
+
symbol: MarkerSymbolSchema.optional(),
|
|
573
|
+
size: z.number().optional(),
|
|
574
|
+
fillColor: z.string().optional(),
|
|
575
|
+
strokeColor: z.string().optional(),
|
|
576
|
+
strokeWidth: z.number().optional(),
|
|
577
|
+
strokeDashStyle: z.string().optional()
|
|
578
|
+
}).nullable().optional().describe("Series marker (line/scatter/bubble/radar); null removes it"),
|
|
579
|
+
trendline: z.object({
|
|
580
|
+
trendlineType: z.enum([
|
|
581
|
+
"linear",
|
|
582
|
+
"exponential",
|
|
583
|
+
"logarithmic",
|
|
584
|
+
"polynomial",
|
|
585
|
+
"power",
|
|
586
|
+
"movingAvg"
|
|
587
|
+
]),
|
|
588
|
+
color: z.string().optional(),
|
|
589
|
+
lineWidth: z.number().optional().describe("Trendline width in points"),
|
|
590
|
+
lineDashStyle: z.string().optional(),
|
|
591
|
+
order: z.number().optional().describe("Polynomial order, 2-6"),
|
|
592
|
+
period: z.number().optional().describe("Moving-average period"),
|
|
593
|
+
displayEq: z.boolean().optional(),
|
|
594
|
+
displayRSq: z.boolean().optional()
|
|
595
|
+
}).nullable().optional().describe("Series trendline; null removes it"),
|
|
596
|
+
errorBars: z.object({
|
|
597
|
+
direction: z.enum(["x", "y"]),
|
|
598
|
+
barType: z.enum(["both", "minus", "plus"]),
|
|
599
|
+
valType: z.enum(["cust", "fixedVal", "percentage", "stdDev", "stdErr"]),
|
|
600
|
+
val: z.number().optional(),
|
|
601
|
+
customPlus: z.array(z.number()).optional(),
|
|
602
|
+
customMinus: z.array(z.number()).optional(),
|
|
603
|
+
noEndCap: z.boolean().optional(),
|
|
604
|
+
color: z.string().optional(),
|
|
605
|
+
width: z.number().optional().describe("Error-bar line width in points"),
|
|
606
|
+
dashStyle: z.string().optional()
|
|
607
|
+
}).nullable().optional().describe("Series error bars; null removes them")
|
|
608
|
+
});
|
|
609
|
+
var SetChartHelperLineSchema = z.object({
|
|
610
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
611
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
612
|
+
elementId: z.string().describe("Chart element ID"),
|
|
613
|
+
line: z.enum(["dropLines", "hiLowLines"]).describe("Which helper line to set"),
|
|
614
|
+
style: z.object({
|
|
615
|
+
color: z.string().optional(),
|
|
616
|
+
width: z.number().optional(),
|
|
617
|
+
dashStyle: z.string().optional()
|
|
618
|
+
}).nullable().describe("Line colour/width/dash; {} shows the line with defaults, null removes it")
|
|
619
|
+
});
|
|
620
|
+
var SetChartColorMapOverrideSchema = z.object({
|
|
621
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
622
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
623
|
+
elementId: z.string().describe("Chart element ID"),
|
|
624
|
+
overrides: z.record(z.string(), z.string()).nullable().describe(
|
|
625
|
+
'Theme colour role remap (bg1/tx1/bg2/tx2/accent1-6/hlink/folHlink -> role), e.g. { "accent1": "accent2" }; null removes the override'
|
|
626
|
+
)
|
|
627
|
+
});
|
|
628
|
+
var UpdateChartSchema = z.object({
|
|
629
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
630
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
631
|
+
elementId: z.string().describe("Chart element ID"),
|
|
632
|
+
chartType: z.string().optional().describe(
|
|
633
|
+
'New chart type (bar, line, pie, scatter, area, doughnut, radar, histogram, waterfall, funnel, treemap, sunburst, boxWhisker, regionMap). "pareto" is also accepted: it is authored as a histogram chart with an added cumulative-percentage line series.'
|
|
634
|
+
),
|
|
635
|
+
title: z.string().optional().describe("Chart title"),
|
|
636
|
+
grouping: z.enum(["clustered", "stacked", "percentStacked"]).optional().describe("Bar/column grouping"),
|
|
637
|
+
legend: z.object({
|
|
638
|
+
show: z.boolean().optional(),
|
|
639
|
+
position: z.string().optional().describe("Legend position: b, t, l, r, tr")
|
|
640
|
+
}).optional().describe("Legend configuration"),
|
|
641
|
+
dataLabels: z.object({
|
|
642
|
+
show: z.boolean().optional(),
|
|
643
|
+
showValue: z.boolean().optional(),
|
|
644
|
+
showCategory: z.boolean().optional(),
|
|
645
|
+
showSeriesName: z.boolean().optional(),
|
|
646
|
+
showPercent: z.boolean().optional()
|
|
647
|
+
}).optional().describe("Data label configuration"),
|
|
648
|
+
axis: z.object({
|
|
649
|
+
type: z.string().describe("Axis type: valAx, catAx, dateAx, serAx"),
|
|
650
|
+
edit: z.object({
|
|
651
|
+
min: z.number().nullable().optional(),
|
|
652
|
+
max: z.number().nullable().optional(),
|
|
653
|
+
majorUnit: z.number().nullable().optional(),
|
|
654
|
+
title: z.string().nullable().optional(),
|
|
655
|
+
numberFormat: z.string().optional(),
|
|
656
|
+
majorGridlines: z.boolean().optional(),
|
|
657
|
+
minorGridlines: z.boolean().optional()
|
|
658
|
+
})
|
|
659
|
+
}).optional().describe("Axis configuration"),
|
|
660
|
+
categories: z.array(z.string()).optional().describe("Category axis labels")
|
|
661
|
+
});
|
|
662
|
+
var AddChartSeriesSchema = z.object({
|
|
663
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
664
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
665
|
+
elementId: z.string().describe("Chart element ID"),
|
|
666
|
+
name: z.string().describe("Series name"),
|
|
667
|
+
values: z.array(z.number()).describe("Data values"),
|
|
668
|
+
color: z.string().optional().describe("Series color (hex)")
|
|
669
|
+
});
|
|
670
|
+
var RemoveChartSeriesSchema = z.object({
|
|
671
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
672
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
673
|
+
elementId: z.string().describe("Chart element ID"),
|
|
674
|
+
seriesIndex: z.number().int().min(0).describe("Zero-based series index to remove")
|
|
675
|
+
});
|
|
676
|
+
var UpdateChartSeriesDataSchema = z.object({
|
|
677
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
678
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
679
|
+
elementId: z.string().describe("Chart element ID"),
|
|
680
|
+
seriesIndex: z.number().int().min(0).describe("Zero-based series index"),
|
|
681
|
+
values: z.array(z.number()).describe("New data values")
|
|
682
|
+
});
|
|
683
|
+
var CreateChartSchema = z.object({
|
|
684
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
685
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
686
|
+
chartType: z.string().describe(
|
|
687
|
+
'Chart type (bar, line, pie, scatter, area, doughnut, radar, histogram, waterfall, funnel, treemap, sunburst, boxWhisker, regionMap). "pareto" is also accepted: it is authored as a histogram chart with an added cumulative-percentage line series.'
|
|
688
|
+
),
|
|
689
|
+
x: z.number().optional().describe("X position in points"),
|
|
690
|
+
y: z.number().optional().describe("Y position in points"),
|
|
691
|
+
width: z.number().optional().describe("Width in points"),
|
|
692
|
+
height: z.number().optional().describe("Height in points"),
|
|
693
|
+
title: z.string().optional().describe("Chart title"),
|
|
694
|
+
categories: z.array(z.string()).optional().describe("Category labels"),
|
|
695
|
+
series: z.array(
|
|
696
|
+
z.object({
|
|
697
|
+
name: z.string(),
|
|
698
|
+
values: z.array(z.number()),
|
|
699
|
+
color: z.string().optional()
|
|
700
|
+
})
|
|
701
|
+
).optional().describe("Data series"),
|
|
702
|
+
legend: z.object({
|
|
703
|
+
show: z.boolean(),
|
|
704
|
+
position: z.string().optional()
|
|
705
|
+
}).optional().describe("Legend configuration")
|
|
706
|
+
});
|
|
707
|
+
var PointSchema = z.object({ x: z.number(), y: z.number() });
|
|
708
|
+
var ExtentSchema = z.object({ cx: z.number(), cy: z.number() });
|
|
709
|
+
var ChartUserShapeInputSchema = z.object({
|
|
710
|
+
kind: z.enum(["sp", "cxnSp"]).optional().describe('Overlay shape kind: "sp" (text/preset shape, default) or "cxnSp" (connector).'),
|
|
711
|
+
anchor: z.enum(["rel", "abs"]).optional().describe(
|
|
712
|
+
'Anchor kind: "rel" (default, resizes with the chart; needs `to`) or "abs" (fixed EMU size; needs `ext`).'
|
|
713
|
+
),
|
|
714
|
+
from: PointSchema.describe("Top-left corner as chart-relative fractions (0-1 each)."),
|
|
715
|
+
to: PointSchema.optional().describe(
|
|
716
|
+
"Bottom-right corner as chart-relative fractions; rel anchors only."
|
|
717
|
+
),
|
|
718
|
+
ext: ExtentSchema.optional().describe("Width/height in EMU; abs anchors only."),
|
|
719
|
+
prst: z.string().optional().describe('Preset geometry name (e.g. "rect", "roundRect"); default "rect".'),
|
|
720
|
+
fill: z.string().optional().describe('Solid fill colour, hex (e.g. "#FFFF00").'),
|
|
721
|
+
stroke: z.string().optional().describe("Line colour, hex."),
|
|
722
|
+
strokeWidth: z.number().optional().describe("Line width in points."),
|
|
723
|
+
text: z.string().optional().describe("Plain text content, centred in the shape.")
|
|
724
|
+
});
|
|
725
|
+
var ListChartUserShapesSchema = z.object({
|
|
726
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
727
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
728
|
+
elementId: z.string().describe("Chart element ID")
|
|
729
|
+
});
|
|
730
|
+
var AddChartUserShapeSchema = z.object({
|
|
731
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
732
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
733
|
+
elementId: z.string().describe("Chart element ID"),
|
|
734
|
+
shape: ChartUserShapeInputSchema.describe("The overlay shape to add.")
|
|
735
|
+
});
|
|
736
|
+
var UpdateChartUserShapeSchema = z.object({
|
|
737
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
738
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
739
|
+
elementId: z.string().describe("Chart element ID"),
|
|
740
|
+
index: z.number().int().min(0).describe("Zero-based overlay-shape index (from chart_user_shape_list)"),
|
|
741
|
+
patch: ChartUserShapeInputSchema.partial().describe(
|
|
742
|
+
"Fields to overwrite; anything omitted is left as-is."
|
|
743
|
+
)
|
|
744
|
+
});
|
|
745
|
+
var RemoveChartUserShapeSchema = z.object({
|
|
746
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
747
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
748
|
+
elementId: z.string().describe("Chart element ID"),
|
|
749
|
+
index: z.number().int().min(0).describe("Zero-based overlay-shape index to remove")
|
|
750
|
+
});
|
|
751
|
+
var ManageSmartArtSchema = z.object({
|
|
752
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
753
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
754
|
+
elementId: z.string().describe("SmartArt element ID"),
|
|
755
|
+
action: z.enum([
|
|
756
|
+
"getNodes",
|
|
757
|
+
"addNode",
|
|
758
|
+
"removeNode",
|
|
759
|
+
"updateNodeText",
|
|
760
|
+
"reorderNode",
|
|
761
|
+
"promoteNode",
|
|
762
|
+
"demoteNode",
|
|
763
|
+
"decompose"
|
|
764
|
+
]).describe("SmartArt action"),
|
|
765
|
+
nodeId: z.string().optional().describe("Node ID (required for most actions)"),
|
|
766
|
+
text: z.string().optional().describe("Text for addNode or updateNodeText"),
|
|
767
|
+
afterNodeId: z.string().optional().describe("Insert after this node ID"),
|
|
768
|
+
direction: z.number().optional().describe("Reorder direction: 1 (forward) or -1 (backward)")
|
|
769
|
+
});
|
|
770
|
+
var FindPlaceholdersSchema = z.object({
|
|
771
|
+
filePath: z.string().describe("Path to the PPTX file")
|
|
772
|
+
});
|
|
773
|
+
var ApplyTemplateSchema = z.object({
|
|
774
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
775
|
+
data: z.record(z.string(), z.unknown()).describe("Template data: keys are placeholder names, values are replacement values")
|
|
776
|
+
});
|
|
777
|
+
var GetMetadataSchema = z.object({
|
|
778
|
+
filePath: z.string().describe("Path to the PPTX file")
|
|
779
|
+
});
|
|
780
|
+
var UpdateMetadataSchema = z.object({
|
|
781
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
782
|
+
title: z.string().optional().describe("Presentation title"),
|
|
783
|
+
subject: z.string().optional().describe("Subject"),
|
|
784
|
+
creator: z.string().optional().describe("Creator/author name"),
|
|
785
|
+
keywords: z.string().optional().describe("Keywords (comma-separated)"),
|
|
786
|
+
description: z.string().optional().describe("Description/comments"),
|
|
787
|
+
lastModifiedBy: z.string().optional().describe("Last modified by"),
|
|
788
|
+
category: z.string().optional().describe("Category"),
|
|
789
|
+
company: z.string().optional().describe("Company name"),
|
|
790
|
+
manager: z.string().optional().describe("Manager name"),
|
|
791
|
+
customProperties: z.array(
|
|
792
|
+
z.object({
|
|
793
|
+
name: z.string(),
|
|
794
|
+
value: z.union([z.string(), z.number(), z.boolean()])
|
|
795
|
+
})
|
|
796
|
+
).optional().describe("Custom properties to set")
|
|
797
|
+
});
|
|
798
|
+
var ManageSectionsSchema = z.object({
|
|
799
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
800
|
+
action: z.enum(["list", "add", "remove", "reorder", "moveSlides", "getForSlide"]).describe("Section action"),
|
|
801
|
+
name: z.string().optional().describe("Section name (for add)"),
|
|
802
|
+
slideIndices: z.array(z.number().int().min(0)).optional().describe("Slide indices (for add, moveSlides)"),
|
|
803
|
+
sectionId: z.string().optional().describe("Section ID (for remove, moveSlides)"),
|
|
804
|
+
sectionIds: z.array(z.string()).optional().describe("Ordered section IDs (for reorder)"),
|
|
805
|
+
slideIndex: z.number().int().min(0).optional().describe("Slide index (for getForSlide)")
|
|
806
|
+
});
|
|
807
|
+
var ExportToSvgSchema = z.object({
|
|
808
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
809
|
+
slideIndices: z.array(z.number().int().min(0)).optional().describe("Specific slides to export (all if omitted)"),
|
|
810
|
+
includeHidden: z.boolean().optional().describe("Include hidden slides"),
|
|
811
|
+
defaultFontFamily: z.string().optional().describe("Default font family for SVG"),
|
|
812
|
+
defaultFontSize: z.number().optional().describe("Default font size")
|
|
813
|
+
});
|
|
814
|
+
var ExportSlideSvgSchema = z.object({
|
|
815
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
816
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index to export"),
|
|
817
|
+
defaultFontFamily: z.string().optional().describe("Default font family for SVG"),
|
|
818
|
+
defaultFontSize: z.number().optional().describe("Default font size")
|
|
819
|
+
});
|
|
820
|
+
var ExportToJsonSchema = z.object({
|
|
821
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
822
|
+
pretty: z.boolean().optional().describe("Pretty-print the JSON document with 2-space indentation (default true)")
|
|
823
|
+
});
|
|
824
|
+
var ImportFromJsonSchema = z.object({
|
|
825
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
826
|
+
json: z.string().describe("The pptx-viewer-json document text to import (replaces the deck content)")
|
|
827
|
+
});
|
|
828
|
+
var ManageHyperlinksSchema = z.object({
|
|
829
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
830
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
831
|
+
action: z.enum(["list", "set", "remove"]).describe("Hyperlink action"),
|
|
832
|
+
elementId: z.string().optional().describe("Element ID (for set/remove)"),
|
|
833
|
+
trigger: z.enum(["click", "hover"]).optional().describe("Action trigger (default: click)"),
|
|
834
|
+
url: z.string().optional().describe("URL for the hyperlink"),
|
|
835
|
+
tooltip: z.string().optional().describe("Tooltip text"),
|
|
836
|
+
targetSlideIndex: z.number().int().min(0).optional().describe("Target slide index for internal links"),
|
|
837
|
+
actionType: z.enum(["url", "slide", "nextSlide", "prevSlide", "firstSlide", "lastSlide", "endShow"]).optional().describe("Link action type")
|
|
838
|
+
});
|
|
839
|
+
var ReplaceGeometrySchema = z.object({
|
|
840
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
841
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
842
|
+
elementId: z.string().describe("Shape element ID"),
|
|
843
|
+
shapeType: z.string().optional().describe('Preset shape type (e.g. "roundRect", "star5", "ellipse", "diamond")'),
|
|
844
|
+
svgPath: z.string().optional().describe("Custom SVG path data (mutually exclusive with shapeType)"),
|
|
845
|
+
pathWidth: z.number().optional().describe("Width of SVG path coordinate space"),
|
|
846
|
+
pathHeight: z.number().optional().describe("Height of SVG path coordinate space"),
|
|
847
|
+
adjustments: z.record(z.string(), z.number()).optional().describe("Shape adjustment values")
|
|
848
|
+
});
|
|
849
|
+
var SetElementLockSchema = z.object({
|
|
850
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
851
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
852
|
+
elementId: z.string().describe("Element ID to lock/unlock"),
|
|
853
|
+
locked: z.boolean().describe("Whether the element should be locked"),
|
|
854
|
+
noMove: z.boolean().optional().describe("Prevent moving"),
|
|
855
|
+
noResize: z.boolean().optional().describe("Prevent resizing"),
|
|
856
|
+
noRotation: z.boolean().optional().describe("Prevent rotation"),
|
|
857
|
+
noSelect: z.boolean().optional().describe("Prevent selection"),
|
|
858
|
+
noTextEdit: z.boolean().optional().describe("Prevent text editing")
|
|
859
|
+
});
|
|
860
|
+
var ValidatePresentationSchema = z.object({
|
|
861
|
+
filePath: z.string().describe("Path to the PPTX file")
|
|
862
|
+
});
|
|
863
|
+
var RepairPresentationSchema = z.object({
|
|
864
|
+
filePath: z.string().describe("Path to the PPTX file")
|
|
865
|
+
});
|
|
866
|
+
var GetPresentationPropertiesSchema = z.object({
|
|
867
|
+
filePath: z.string().describe("Path to the PPTX file")
|
|
868
|
+
});
|
|
869
|
+
var UpdatePresentationPropertiesSchema = z.object({
|
|
870
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
871
|
+
showType: z.enum(["presented", "browsed", "kiosk"]).optional().describe("Slideshow mode"),
|
|
872
|
+
loopContinuously: z.boolean().optional().describe("Loop the slideshow"),
|
|
873
|
+
showWithNarration: z.boolean().optional().describe("Play narration"),
|
|
874
|
+
showWithAnimation: z.boolean().optional().describe("Play animations"),
|
|
875
|
+
advanceMode: z.enum(["manual", "useTimings"]).optional().describe("Slide advance mode"),
|
|
876
|
+
showSlidesMode: z.enum(["all", "customShow", "range"]).optional().describe("Which slides to show"),
|
|
877
|
+
showSlidesFrom: z.number().int().min(1).optional().describe("Range start (1-based)"),
|
|
878
|
+
showSlidesTo: z.number().int().min(1).optional().describe("Range end (1-based)"),
|
|
879
|
+
penColor: z.string().optional().describe("Annotation pen color (hex)")
|
|
880
|
+
});
|
|
881
|
+
var GetLayoutsSchema = z.object({
|
|
882
|
+
filePath: z.string().describe("Path to the PPTX file")
|
|
883
|
+
});
|
|
884
|
+
var ApplyLayoutSchema = z.object({
|
|
885
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
886
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
887
|
+
layoutName: z.string().optional().describe("Layout name to apply"),
|
|
888
|
+
layoutType: z.string().optional().describe("Layout type to apply (alternative to name)")
|
|
889
|
+
});
|
|
890
|
+
var GetOleContentSchema = z.object({
|
|
891
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
892
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
893
|
+
elementId: z.string().describe("OLE element ID")
|
|
894
|
+
});
|
|
895
|
+
var SetOleSheetCellSchema = z.object({
|
|
896
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
897
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
898
|
+
elementId: z.string().describe("OLE element ID (Excel payload: .xlsx or .xls)"),
|
|
899
|
+
row: z.number().int().min(0).describe("Zero-based row index on the first worksheet"),
|
|
900
|
+
col: z.number().int().min(0).describe("Zero-based column index on the first worksheet"),
|
|
901
|
+
value: z.string().describe("New cell value")
|
|
902
|
+
});
|
|
903
|
+
var SetOleDocumentParagraphSchema = z.object({
|
|
904
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
905
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
906
|
+
elementId: z.string().describe("OLE element ID (Word payload: .docx)"),
|
|
907
|
+
paragraphIndex: z.number().int().min(0).describe("Zero-based paragraph index"),
|
|
908
|
+
text: z.string().describe("New paragraph text")
|
|
909
|
+
});
|
|
910
|
+
var SetOleDeckSlideTitleSchema = z.object({
|
|
911
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
912
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
913
|
+
elementId: z.string().describe("OLE element ID (nested-deck payload: .pptx)"),
|
|
914
|
+
deckSlideIndex: z.number().int().min(0).describe("Zero-based slide index within the nested deck"),
|
|
915
|
+
deckElementId: z.string().describe(
|
|
916
|
+
"ID of the text-bearing shape to edit within the nested slide, from ole_get_content's deckSlides[n].elements[i].elementId"
|
|
917
|
+
),
|
|
918
|
+
title: z.string().describe("New text for the chosen shape")
|
|
919
|
+
});
|
|
920
|
+
var ReplaceOleFileSchema = z.object({
|
|
921
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
922
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
923
|
+
elementId: z.string().describe("OLE element ID"),
|
|
924
|
+
fileData: z.string().describe('New payload as a base64 data URL (e.g. "data:application/pdf;base64,...")'),
|
|
925
|
+
fileName: z.string().optional().describe("Optional new file name (also updates the resolved MIME type)")
|
|
926
|
+
});
|
|
927
|
+
var SetOleObjectNameSchema = z.object({
|
|
928
|
+
filePath: z.string().describe("Path to the PPTX file"),
|
|
929
|
+
slideIndex: z.number().int().min(0).describe("Zero-based slide index"),
|
|
930
|
+
elementId: z.string().describe("OLE element ID"),
|
|
931
|
+
name: z.string().describe("New Object Name (p:oleObj/@name); blank/whitespace clears it")
|
|
932
|
+
});
|
|
933
|
+
var formatChartDataPoint = apiToolsChartFormattingTools.formatChartDataPoint;
|
|
934
|
+
var formatChartDataLabel = apiToolsChartFormattingTools.formatChartDataLabel;
|
|
935
|
+
var formatChartSeries = apiToolsChartFormattingTools.formatChartSeries;
|
|
936
|
+
var setChartHelperLineT = apiToolsChartFormattingTools.setChartHelperLineT;
|
|
937
|
+
var setChartColorMapOverrideT = apiToolsChartFormattingTools.setChartColorMapOverrideT;
|
|
938
|
+
var updateChart = apiToolsChartTools.updateChart;
|
|
939
|
+
var addChartSeriesT = apiToolsChartTools.addChartSeriesT;
|
|
940
|
+
var removeChartSeriesT = apiToolsChartTools.removeChartSeriesT;
|
|
941
|
+
var updateChartSeriesData = apiToolsChartTools.updateChartSeriesData;
|
|
942
|
+
var createChart = apiToolsChartTools.createChart;
|
|
943
|
+
var listChartUserShapesT = apiToolsChartUserShapeTools.listChartUserShapesT;
|
|
944
|
+
var addChartUserShapeT = apiToolsChartUserShapeTools.addChartUserShapeT;
|
|
945
|
+
var updateChartUserShapeT = apiToolsChartUserShapeTools.updateChartUserShapeT;
|
|
946
|
+
var removeChartUserShapeT = apiToolsChartUserShapeTools.removeChartUserShapeT;
|
|
947
|
+
var findText = apiToolsContentTools.findText;
|
|
948
|
+
var replaceText = apiToolsContentTools.replaceText;
|
|
949
|
+
var manageComments = apiToolsContentTools.manageComments;
|
|
950
|
+
var convertToMarkdown = apiToolsConversionTools.convertToMarkdown;
|
|
951
|
+
var addElement = apiToolsElementTools.addElement;
|
|
952
|
+
var updateElement = apiToolsElementTools.updateElement;
|
|
953
|
+
var renameElement = apiToolsElementTools.renameElement;
|
|
954
|
+
var deleteElements = apiToolsElementTools.deleteElements;
|
|
955
|
+
var arrangeElements = apiToolsElementTools.arrangeElements;
|
|
956
|
+
var cloneElement = apiToolsElementTools.cloneElement;
|
|
957
|
+
var setElementAnimation = apiToolsElementTools.setElementAnimation;
|
|
958
|
+
var groupElements = apiToolsElementTools.groupElements;
|
|
959
|
+
var ungroupElements = apiToolsElementTools.ungroupElements;
|
|
960
|
+
var batchUpdateElements = apiToolsElementTools.batchUpdateElements;
|
|
961
|
+
var exportToSvg = apiToolsExportTools.exportToSvg;
|
|
962
|
+
var exportSlideSvg = apiToolsExportTools.exportSlideSvg;
|
|
963
|
+
var replaceGeometry = apiToolsGeometryTools.replaceGeometry;
|
|
964
|
+
var manageHyperlinks = apiToolsHyperlinkTools.manageHyperlinks;
|
|
965
|
+
var exportToJson = apiToolsJsonTools.exportToJson;
|
|
966
|
+
var importFromJson = apiToolsJsonTools.importFromJson;
|
|
967
|
+
var getLayouts = apiToolsLayoutTools.getLayouts;
|
|
968
|
+
var applyLayout = apiToolsLayoutTools.applyLayout;
|
|
969
|
+
var setElementLockT = apiToolsLockTools.setElementLockT;
|
|
970
|
+
var getMetadata = apiToolsMetadataTools.getMetadata;
|
|
971
|
+
var updateMetadata = apiToolsMetadataTools.updateMetadata;
|
|
972
|
+
var getOleContent = apiToolsOleTools.getOleContent;
|
|
973
|
+
var setOleSheetCell = apiToolsOleTools.setOleSheetCell;
|
|
974
|
+
var setOleDocumentParagraph = apiToolsOleTools.setOleDocumentParagraph;
|
|
975
|
+
var setOleDeckSlideTitle = apiToolsOleTools.setOleDeckSlideTitle;
|
|
976
|
+
var setOleObjectNameT = apiToolsOleTools.setOleObjectNameT;
|
|
977
|
+
var replaceOleFileT = apiToolsOleTools.replaceOleFileT;
|
|
978
|
+
var getPresentationProperties = apiToolsPresentationTools.getPresentationProperties;
|
|
979
|
+
var updatePresentationProperties = apiToolsPresentationTools.updatePresentationProperties;
|
|
980
|
+
var manageSections = apiToolsSectionTools.manageSections;
|
|
981
|
+
var getSlide = apiToolsSlideTools.getSlide;
|
|
982
|
+
var addSlide = apiToolsSlideTools.addSlide;
|
|
983
|
+
var deleteSlides = apiToolsSlideTools.deleteSlides;
|
|
984
|
+
var reorderSlides = apiToolsSlideTools.reorderSlides;
|
|
985
|
+
var duplicateSlide = apiToolsSlideTools.duplicateSlide;
|
|
986
|
+
var updateSlideProperties = apiToolsSlideTools.updateSlideProperties;
|
|
987
|
+
var setSlideTransition = apiToolsSlideTools.setSlideTransition;
|
|
988
|
+
var setCanvasSize = apiToolsSlideTools.setCanvasSize;
|
|
989
|
+
var manageSmartArt = apiToolsSmartartTools.manageSmartArt;
|
|
990
|
+
apiToolsStyleTools.ALT_TEXT_ELEMENT_TYPES;
|
|
991
|
+
apiToolsStyleTools.TITLE_ELEMENT_TYPES;
|
|
992
|
+
apiToolsStyleTools.applyElementAltText;
|
|
993
|
+
apiToolsStyleTools.applyElementTitle;
|
|
994
|
+
var updateElementStyle = apiToolsStyleTools.updateElementStyle;
|
|
995
|
+
var runAccessibilityCheck = apiToolsStyleTools.runAccessibilityCheck;
|
|
996
|
+
var setTableStyleSection = apiToolsTableStyleTools.setTableStyleSection;
|
|
997
|
+
var createTableStyle = apiToolsTableStyleTools.createTableStyle;
|
|
998
|
+
var deleteTableStyle = apiToolsTableStyleTools.deleteTableStyle;
|
|
999
|
+
var assignTableStyle = apiToolsTableStyleTools.assignTableStyle;
|
|
1000
|
+
var updateTableCells = apiToolsTableTools.updateTableCells;
|
|
1001
|
+
var manageTableStructure = apiToolsTableTools.manageTableStructure;
|
|
1002
|
+
var findPlaceholdersT = apiToolsTemplateTools.findPlaceholdersT;
|
|
1003
|
+
var applyTemplateT = apiToolsTemplateTools.applyTemplateT;
|
|
1004
|
+
var getThemeInfo = apiToolsThemeTools.getThemeInfo;
|
|
1005
|
+
var applyThemePreset = apiToolsThemeTools.applyThemePreset;
|
|
1006
|
+
var updateThemeColors = apiToolsThemeTools.updateThemeColors;
|
|
1007
|
+
var updateThemeFonts = apiToolsThemeTools.updateThemeFonts;
|
|
1008
|
+
var validatePresentation = apiToolsValidationTools.validatePresentation;
|
|
1009
|
+
var repairPresentation = apiToolsValidationTools.repairPresentation;
|
|
1010
|
+
apiExecution.loadPresentation;
|
|
1011
|
+
apiExecution.savePresentation;
|
|
1012
|
+
var executeToolWithContext = apiExecution.executeToolWithContext;
|
|
1013
|
+
|
|
1014
|
+
// src/mcp/handlers.ts
|
|
1015
|
+
var ALLOWED_EXTENSIONS = /* @__PURE__ */ new Set([".pptx", ".ppt"]);
|
|
1016
|
+
function resolveScopedDir(dir, rootDir) {
|
|
1017
|
+
if (typeof dir !== "string" || dir.length === 0) {
|
|
1018
|
+
throw new Error("MCP tool: path must be a non-empty string");
|
|
1019
|
+
}
|
|
1020
|
+
const root = resolve(process.env["PPTX_TOOLS_ROOT"] ?? process.cwd());
|
|
1021
|
+
const resolved = isAbsolute(dir) ? resolve(dir) : resolve(root, dir);
|
|
1022
|
+
const rootWithSep = root.endsWith(sep) ? root : root + sep;
|
|
1023
|
+
if (resolved !== root && !resolved.startsWith(rootWithSep)) {
|
|
1024
|
+
throw new Error(`MCP tool: path "${dir}" resolves outside the allowed root "${root}"`);
|
|
1025
|
+
}
|
|
1026
|
+
return resolved;
|
|
1027
|
+
}
|
|
1028
|
+
function resolveScopedFilePath(filePath, rootDir) {
|
|
1029
|
+
if (typeof filePath !== "string" || filePath.length === 0) {
|
|
1030
|
+
throw new Error("MCP tool: filePath must be a non-empty string");
|
|
1031
|
+
}
|
|
1032
|
+
const resolved = resolveScopedDir(filePath);
|
|
1033
|
+
const lower = resolved.toLowerCase();
|
|
1034
|
+
let isAllowed = false;
|
|
1035
|
+
for (const ext of ALLOWED_EXTENSIONS) {
|
|
1036
|
+
if (lower.endsWith(ext)) {
|
|
1037
|
+
isAllowed = true;
|
|
1038
|
+
break;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
if (!isAllowed) {
|
|
1042
|
+
throw new Error(
|
|
1043
|
+
`MCP tool: filePath "${filePath}" must end with one of: ${Array.from(ALLOWED_EXTENSIONS).join(", ")}`
|
|
1044
|
+
);
|
|
1045
|
+
}
|
|
1046
|
+
return resolved;
|
|
1047
|
+
}
|
|
1048
|
+
var nodeFs = {
|
|
1049
|
+
readFile: async (path) => new Uint8Array(await readFile(path)),
|
|
1050
|
+
writeFile: async (path, data) => {
|
|
1051
|
+
await writeFile(path, data);
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
function createMcpContext(_options) {
|
|
1055
|
+
return { filesystem: nodeFs };
|
|
1056
|
+
}
|
|
1057
|
+
async function runMcpTool(filePath, fn, options) {
|
|
1058
|
+
const safePath = resolveScopedFilePath(filePath);
|
|
1059
|
+
const ctx = createMcpContext();
|
|
1060
|
+
return executeToolWithContext(safePath, ctx, fn);
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
// src/mcp/server.ts
|
|
1064
|
+
function createServer(options) {
|
|
1065
|
+
const server = new McpServer({
|
|
1066
|
+
name: "pptx-viewer-tools",
|
|
1067
|
+
version: "1.0.0"
|
|
1068
|
+
});
|
|
1069
|
+
registerTools(server);
|
|
1070
|
+
return server;
|
|
1071
|
+
}
|
|
1072
|
+
function registerTools(server, options) {
|
|
1073
|
+
const runMcpTool2 = (filePath, fn) => runMcpTool(filePath, fn);
|
|
1074
|
+
const resolveScopedDir2 = (dir) => resolveScopedDir(dir);
|
|
1075
|
+
const resolveScopedFilePath2 = (filePath) => resolveScopedFilePath(filePath);
|
|
1076
|
+
server.registerTool(
|
|
1077
|
+
"get_slide",
|
|
1078
|
+
{
|
|
1079
|
+
description: "Inspect a single slide: returns layout, notes, elements",
|
|
1080
|
+
inputSchema: GetSlideSchema.shape
|
|
1081
|
+
},
|
|
1082
|
+
async (params) => {
|
|
1083
|
+
const result = await runMcpTool2(
|
|
1084
|
+
params.filePath,
|
|
1085
|
+
(ctx) => getSlide(ctx, { slideIndex: params.slideIndex })
|
|
1086
|
+
);
|
|
1087
|
+
return {
|
|
1088
|
+
content: [
|
|
1089
|
+
{
|
|
1090
|
+
type: "text",
|
|
1091
|
+
text: JSON.stringify(result, null, 2)
|
|
1092
|
+
}
|
|
1093
|
+
]
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
);
|
|
1097
|
+
server.registerTool(
|
|
1098
|
+
"add_slide",
|
|
1099
|
+
{
|
|
1100
|
+
description: "Add a new blank slide to the presentation",
|
|
1101
|
+
inputSchema: AddSlideSchema.shape
|
|
1102
|
+
},
|
|
1103
|
+
async (params) => {
|
|
1104
|
+
const result = await runMcpTool2(params.filePath, (ctx) => addSlide(ctx, params));
|
|
1105
|
+
return {
|
|
1106
|
+
content: [
|
|
1107
|
+
{
|
|
1108
|
+
type: "text",
|
|
1109
|
+
text: JSON.stringify(result, null, 2)
|
|
1110
|
+
}
|
|
1111
|
+
]
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
);
|
|
1115
|
+
server.registerTool(
|
|
1116
|
+
"delete_slides",
|
|
1117
|
+
{
|
|
1118
|
+
description: "Delete one or more slides by index",
|
|
1119
|
+
inputSchema: DeleteSlidesSchema.shape
|
|
1120
|
+
},
|
|
1121
|
+
async (params) => {
|
|
1122
|
+
const result = await runMcpTool2(
|
|
1123
|
+
params.filePath,
|
|
1124
|
+
(ctx) => deleteSlides(ctx, {
|
|
1125
|
+
slideIndexes: params.slideIndexes
|
|
1126
|
+
})
|
|
1127
|
+
);
|
|
1128
|
+
return {
|
|
1129
|
+
content: [
|
|
1130
|
+
{
|
|
1131
|
+
type: "text",
|
|
1132
|
+
text: JSON.stringify(result, null, 2)
|
|
1133
|
+
}
|
|
1134
|
+
]
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
);
|
|
1138
|
+
server.registerTool(
|
|
1139
|
+
"reorder_slides",
|
|
1140
|
+
{
|
|
1141
|
+
description: "Reorder slides by providing a new index array",
|
|
1142
|
+
inputSchema: ReorderSlidesSchema.shape
|
|
1143
|
+
},
|
|
1144
|
+
async (params) => {
|
|
1145
|
+
const result = await runMcpTool2(
|
|
1146
|
+
params.filePath,
|
|
1147
|
+
(ctx) => reorderSlides(ctx, { newOrder: params.newOrder })
|
|
1148
|
+
);
|
|
1149
|
+
return {
|
|
1150
|
+
content: [
|
|
1151
|
+
{
|
|
1152
|
+
type: "text",
|
|
1153
|
+
text: JSON.stringify(result, null, 2)
|
|
1154
|
+
}
|
|
1155
|
+
]
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
);
|
|
1159
|
+
server.registerTool(
|
|
1160
|
+
"duplicate_slide",
|
|
1161
|
+
{
|
|
1162
|
+
description: "Duplicate a slide with new element IDs",
|
|
1163
|
+
inputSchema: DuplicateSlideSchema.shape
|
|
1164
|
+
},
|
|
1165
|
+
async (params) => {
|
|
1166
|
+
const result = await runMcpTool2(
|
|
1167
|
+
params.filePath,
|
|
1168
|
+
(ctx) => duplicateSlide(ctx, params)
|
|
1169
|
+
);
|
|
1170
|
+
return {
|
|
1171
|
+
content: [
|
|
1172
|
+
{
|
|
1173
|
+
type: "text",
|
|
1174
|
+
text: JSON.stringify(result, null, 2)
|
|
1175
|
+
}
|
|
1176
|
+
]
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
);
|
|
1180
|
+
server.registerTool(
|
|
1181
|
+
"update_slide_properties",
|
|
1182
|
+
{
|
|
1183
|
+
description: "Update slide background, notes, or visibility",
|
|
1184
|
+
inputSchema: UpdateSlidePropertiesSchema.shape
|
|
1185
|
+
},
|
|
1186
|
+
async (params) => {
|
|
1187
|
+
const result = await runMcpTool2(
|
|
1188
|
+
params.filePath,
|
|
1189
|
+
(ctx) => updateSlideProperties(ctx, params)
|
|
1190
|
+
);
|
|
1191
|
+
return {
|
|
1192
|
+
content: [
|
|
1193
|
+
{
|
|
1194
|
+
type: "text",
|
|
1195
|
+
text: JSON.stringify(result, null, 2)
|
|
1196
|
+
}
|
|
1197
|
+
]
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
);
|
|
1201
|
+
server.registerTool(
|
|
1202
|
+
"set_slide_transition",
|
|
1203
|
+
{
|
|
1204
|
+
description: "Set or remove a slide transition effect",
|
|
1205
|
+
inputSchema: SetSlideTransitionSchema.shape
|
|
1206
|
+
},
|
|
1207
|
+
async (params) => {
|
|
1208
|
+
const result = await runMcpTool2(
|
|
1209
|
+
params.filePath,
|
|
1210
|
+
(ctx) => setSlideTransition(ctx, params)
|
|
1211
|
+
);
|
|
1212
|
+
return {
|
|
1213
|
+
content: [
|
|
1214
|
+
{
|
|
1215
|
+
type: "text",
|
|
1216
|
+
text: JSON.stringify(result, null, 2)
|
|
1217
|
+
}
|
|
1218
|
+
]
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
);
|
|
1222
|
+
server.registerTool(
|
|
1223
|
+
"set_canvas_size",
|
|
1224
|
+
{
|
|
1225
|
+
description: "Change the presentation canvas dimensions",
|
|
1226
|
+
inputSchema: SetCanvasSizeSchema.shape
|
|
1227
|
+
},
|
|
1228
|
+
async (params) => {
|
|
1229
|
+
const result = await runMcpTool2(
|
|
1230
|
+
params.filePath,
|
|
1231
|
+
(ctx) => setCanvasSize(ctx, params)
|
|
1232
|
+
);
|
|
1233
|
+
return {
|
|
1234
|
+
content: [
|
|
1235
|
+
{
|
|
1236
|
+
type: "text",
|
|
1237
|
+
text: JSON.stringify(result, null, 2)
|
|
1238
|
+
}
|
|
1239
|
+
]
|
|
1240
|
+
};
|
|
1241
|
+
}
|
|
1242
|
+
);
|
|
1243
|
+
server.registerTool(
|
|
1244
|
+
"add_element",
|
|
1245
|
+
{
|
|
1246
|
+
description: "Add a text, shape, image, table, or connector element",
|
|
1247
|
+
inputSchema: AddElementSchema.shape
|
|
1248
|
+
},
|
|
1249
|
+
async (params) => {
|
|
1250
|
+
const result = await runMcpTool2(
|
|
1251
|
+
params.filePath,
|
|
1252
|
+
(ctx) => addElement(ctx, params)
|
|
1253
|
+
);
|
|
1254
|
+
return {
|
|
1255
|
+
content: [
|
|
1256
|
+
{
|
|
1257
|
+
type: "text",
|
|
1258
|
+
text: JSON.stringify(result, null, 2)
|
|
1259
|
+
}
|
|
1260
|
+
]
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
);
|
|
1264
|
+
server.registerTool(
|
|
1265
|
+
"update_element",
|
|
1266
|
+
{
|
|
1267
|
+
description: "Update element position, size, text, or style",
|
|
1268
|
+
inputSchema: UpdateElementSchema.shape
|
|
1269
|
+
},
|
|
1270
|
+
async (params) => {
|
|
1271
|
+
const result = await runMcpTool2(
|
|
1272
|
+
params.filePath,
|
|
1273
|
+
(ctx) => updateElement(ctx, params)
|
|
1274
|
+
);
|
|
1275
|
+
return {
|
|
1276
|
+
content: [
|
|
1277
|
+
{
|
|
1278
|
+
type: "text",
|
|
1279
|
+
text: JSON.stringify(result, null, 2)
|
|
1280
|
+
}
|
|
1281
|
+
]
|
|
1282
|
+
};
|
|
1283
|
+
}
|
|
1284
|
+
);
|
|
1285
|
+
server.registerTool(
|
|
1286
|
+
"rename_element",
|
|
1287
|
+
{
|
|
1288
|
+
description: "Rename an element (the selection pane's display name; cNvPr/@name)",
|
|
1289
|
+
inputSchema: RenameElementSchema.shape
|
|
1290
|
+
},
|
|
1291
|
+
async (params) => {
|
|
1292
|
+
const result = await runMcpTool2(
|
|
1293
|
+
params.filePath,
|
|
1294
|
+
(ctx) => renameElement(ctx, params)
|
|
1295
|
+
);
|
|
1296
|
+
return {
|
|
1297
|
+
content: [
|
|
1298
|
+
{
|
|
1299
|
+
type: "text",
|
|
1300
|
+
text: JSON.stringify(result, null, 2)
|
|
1301
|
+
}
|
|
1302
|
+
]
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
);
|
|
1306
|
+
server.registerTool(
|
|
1307
|
+
"delete_elements",
|
|
1308
|
+
{
|
|
1309
|
+
description: "Delete one or more elements by ID",
|
|
1310
|
+
inputSchema: DeleteElementsSchema.shape
|
|
1311
|
+
},
|
|
1312
|
+
async (params) => {
|
|
1313
|
+
const result = await runMcpTool2(
|
|
1314
|
+
params.filePath,
|
|
1315
|
+
(ctx) => deleteElements(ctx, params)
|
|
1316
|
+
);
|
|
1317
|
+
return {
|
|
1318
|
+
content: [
|
|
1319
|
+
{
|
|
1320
|
+
type: "text",
|
|
1321
|
+
text: JSON.stringify(result, null, 2)
|
|
1322
|
+
}
|
|
1323
|
+
]
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
);
|
|
1327
|
+
server.registerTool(
|
|
1328
|
+
"arrange_elements",
|
|
1329
|
+
{
|
|
1330
|
+
description: "Align elements or change z-order (layer)",
|
|
1331
|
+
inputSchema: ArrangeElementsSchema.shape
|
|
1332
|
+
},
|
|
1333
|
+
async (params) => {
|
|
1334
|
+
const result = await runMcpTool2(
|
|
1335
|
+
params.filePath,
|
|
1336
|
+
(ctx) => arrangeElements(ctx, params)
|
|
1337
|
+
);
|
|
1338
|
+
return {
|
|
1339
|
+
content: [
|
|
1340
|
+
{
|
|
1341
|
+
type: "text",
|
|
1342
|
+
text: JSON.stringify(result, null, 2)
|
|
1343
|
+
}
|
|
1344
|
+
]
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
);
|
|
1348
|
+
server.registerTool(
|
|
1349
|
+
"clone_element",
|
|
1350
|
+
{
|
|
1351
|
+
description: "Clone an element within or across slides",
|
|
1352
|
+
inputSchema: CloneElementSchema.shape
|
|
1353
|
+
},
|
|
1354
|
+
async (params) => {
|
|
1355
|
+
const result = await runMcpTool2(
|
|
1356
|
+
params.filePath,
|
|
1357
|
+
(ctx) => cloneElement(ctx, params)
|
|
1358
|
+
);
|
|
1359
|
+
return {
|
|
1360
|
+
content: [
|
|
1361
|
+
{
|
|
1362
|
+
type: "text",
|
|
1363
|
+
text: JSON.stringify(result, null, 2)
|
|
1364
|
+
}
|
|
1365
|
+
]
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1368
|
+
);
|
|
1369
|
+
server.registerTool(
|
|
1370
|
+
"set_element_animation",
|
|
1371
|
+
{
|
|
1372
|
+
description: "Set entrance/exit animation on an element",
|
|
1373
|
+
inputSchema: SetElementAnimationSchema.shape
|
|
1374
|
+
},
|
|
1375
|
+
async (params) => {
|
|
1376
|
+
const result = await runMcpTool2(
|
|
1377
|
+
params.filePath,
|
|
1378
|
+
(ctx) => setElementAnimation(ctx, params)
|
|
1379
|
+
);
|
|
1380
|
+
return {
|
|
1381
|
+
content: [
|
|
1382
|
+
{
|
|
1383
|
+
type: "text",
|
|
1384
|
+
text: JSON.stringify(result, null, 2)
|
|
1385
|
+
}
|
|
1386
|
+
]
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
);
|
|
1390
|
+
server.registerTool(
|
|
1391
|
+
"group_elements",
|
|
1392
|
+
{
|
|
1393
|
+
description: "Group multiple elements into a group",
|
|
1394
|
+
inputSchema: GroupElementsSchema.shape
|
|
1395
|
+
},
|
|
1396
|
+
async (params) => {
|
|
1397
|
+
const result = await runMcpTool2(
|
|
1398
|
+
params.filePath,
|
|
1399
|
+
(ctx) => groupElements(ctx, params)
|
|
1400
|
+
);
|
|
1401
|
+
return {
|
|
1402
|
+
content: [
|
|
1403
|
+
{
|
|
1404
|
+
type: "text",
|
|
1405
|
+
text: JSON.stringify(result, null, 2)
|
|
1406
|
+
}
|
|
1407
|
+
]
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
);
|
|
1411
|
+
server.registerTool(
|
|
1412
|
+
"ungroup_elements",
|
|
1413
|
+
{
|
|
1414
|
+
description: "Ungroup a group element back to individual elements",
|
|
1415
|
+
inputSchema: UngroupElementsSchema.shape
|
|
1416
|
+
},
|
|
1417
|
+
async (params) => {
|
|
1418
|
+
const result = await runMcpTool2(
|
|
1419
|
+
params.filePath,
|
|
1420
|
+
(ctx) => ungroupElements(ctx, params)
|
|
1421
|
+
);
|
|
1422
|
+
return {
|
|
1423
|
+
content: [
|
|
1424
|
+
{
|
|
1425
|
+
type: "text",
|
|
1426
|
+
text: JSON.stringify(result, null, 2)
|
|
1427
|
+
}
|
|
1428
|
+
]
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
);
|
|
1432
|
+
server.registerTool(
|
|
1433
|
+
"batch_update_elements",
|
|
1434
|
+
{
|
|
1435
|
+
description: "Apply the same properties to multiple elements",
|
|
1436
|
+
inputSchema: BatchUpdateElementsSchema.shape
|
|
1437
|
+
},
|
|
1438
|
+
async (params) => {
|
|
1439
|
+
const result = await runMcpTool2(
|
|
1440
|
+
params.filePath,
|
|
1441
|
+
(ctx) => batchUpdateElements(ctx, params)
|
|
1442
|
+
);
|
|
1443
|
+
return {
|
|
1444
|
+
content: [
|
|
1445
|
+
{
|
|
1446
|
+
type: "text",
|
|
1447
|
+
text: JSON.stringify(result, null, 2)
|
|
1448
|
+
}
|
|
1449
|
+
]
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
);
|
|
1453
|
+
server.registerTool(
|
|
1454
|
+
"update_table_cells",
|
|
1455
|
+
{
|
|
1456
|
+
description: "Update text content of table cells",
|
|
1457
|
+
inputSchema: UpdateTableCellsSchema.shape
|
|
1458
|
+
},
|
|
1459
|
+
async (params) => {
|
|
1460
|
+
const result = await runMcpTool2(
|
|
1461
|
+
params.filePath,
|
|
1462
|
+
(ctx) => updateTableCells(ctx, params)
|
|
1463
|
+
);
|
|
1464
|
+
return {
|
|
1465
|
+
content: [
|
|
1466
|
+
{
|
|
1467
|
+
type: "text",
|
|
1468
|
+
text: JSON.stringify(result, null, 2)
|
|
1469
|
+
}
|
|
1470
|
+
]
|
|
1471
|
+
};
|
|
1472
|
+
}
|
|
1473
|
+
);
|
|
1474
|
+
server.registerTool(
|
|
1475
|
+
"manage_table_structure",
|
|
1476
|
+
{
|
|
1477
|
+
description: "Insert or delete table rows and columns",
|
|
1478
|
+
inputSchema: ManageTableStructureSchema.shape
|
|
1479
|
+
},
|
|
1480
|
+
async (params) => {
|
|
1481
|
+
const result = await runMcpTool2(
|
|
1482
|
+
params.filePath,
|
|
1483
|
+
(ctx) => manageTableStructure(ctx, params)
|
|
1484
|
+
);
|
|
1485
|
+
return {
|
|
1486
|
+
content: [
|
|
1487
|
+
{
|
|
1488
|
+
type: "text",
|
|
1489
|
+
text: JSON.stringify(result, null, 2)
|
|
1490
|
+
}
|
|
1491
|
+
]
|
|
1492
|
+
};
|
|
1493
|
+
}
|
|
1494
|
+
);
|
|
1495
|
+
server.registerTool(
|
|
1496
|
+
"set_table_style_section",
|
|
1497
|
+
{
|
|
1498
|
+
description: "Patch the fill, text, borders, or cell3D of one section (wholeTbl, banding, first/last row/col, or a corner cell) of an existing loaded table style",
|
|
1499
|
+
inputSchema: SetTableStyleSectionSchema.shape
|
|
1500
|
+
},
|
|
1501
|
+
async (params) => {
|
|
1502
|
+
const result = await runMcpTool2(
|
|
1503
|
+
params.filePath,
|
|
1504
|
+
(ctx) => setTableStyleSection(ctx, params)
|
|
1505
|
+
);
|
|
1506
|
+
return {
|
|
1507
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
);
|
|
1511
|
+
server.registerTool(
|
|
1512
|
+
"create_table_style",
|
|
1513
|
+
{
|
|
1514
|
+
description: "Create a new table style (optionally cloned from an existing one) and optionally set it as the default",
|
|
1515
|
+
inputSchema: CreateTableStyleSchema.shape
|
|
1516
|
+
},
|
|
1517
|
+
async (params) => {
|
|
1518
|
+
const result = await runMcpTool2(
|
|
1519
|
+
params.filePath,
|
|
1520
|
+
(ctx) => createTableStyle(ctx, params)
|
|
1521
|
+
);
|
|
1522
|
+
return {
|
|
1523
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
1524
|
+
};
|
|
1525
|
+
}
|
|
1526
|
+
);
|
|
1527
|
+
server.registerTool(
|
|
1528
|
+
"delete_table_style",
|
|
1529
|
+
{
|
|
1530
|
+
description: "Remove a table style from the presentation",
|
|
1531
|
+
inputSchema: DeleteTableStyleSchema.shape
|
|
1532
|
+
},
|
|
1533
|
+
async (params) => {
|
|
1534
|
+
const result = await runMcpTool2(
|
|
1535
|
+
params.filePath,
|
|
1536
|
+
(ctx) => deleteTableStyle(ctx, params)
|
|
1537
|
+
);
|
|
1538
|
+
return {
|
|
1539
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
);
|
|
1543
|
+
server.registerTool(
|
|
1544
|
+
"assign_table_style",
|
|
1545
|
+
{
|
|
1546
|
+
description: "Assign a table style (and row/column emphasis flags) to an existing table",
|
|
1547
|
+
inputSchema: AssignTableStyleSchema.shape
|
|
1548
|
+
},
|
|
1549
|
+
async (params) => {
|
|
1550
|
+
const result = await runMcpTool2(
|
|
1551
|
+
params.filePath,
|
|
1552
|
+
(ctx) => assignTableStyle(ctx, params)
|
|
1553
|
+
);
|
|
1554
|
+
return {
|
|
1555
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1558
|
+
);
|
|
1559
|
+
server.registerTool(
|
|
1560
|
+
"update_element_style",
|
|
1561
|
+
{
|
|
1562
|
+
description: "Update fill, stroke, shadow, glow, or image effects",
|
|
1563
|
+
inputSchema: UpdateElementStyleSchema.shape
|
|
1564
|
+
},
|
|
1565
|
+
async (params) => {
|
|
1566
|
+
const result = await runMcpTool2(
|
|
1567
|
+
params.filePath,
|
|
1568
|
+
(ctx) => updateElementStyle(ctx, params)
|
|
1569
|
+
);
|
|
1570
|
+
return {
|
|
1571
|
+
content: [
|
|
1572
|
+
{
|
|
1573
|
+
type: "text",
|
|
1574
|
+
text: JSON.stringify(result, null, 2)
|
|
1575
|
+
}
|
|
1576
|
+
]
|
|
1577
|
+
};
|
|
1578
|
+
}
|
|
1579
|
+
);
|
|
1580
|
+
server.registerTool(
|
|
1581
|
+
"run_accessibility_check",
|
|
1582
|
+
{
|
|
1583
|
+
description: "Audit the presentation for accessibility issues",
|
|
1584
|
+
inputSchema: AccessibilityCheckSchema.shape
|
|
1585
|
+
},
|
|
1586
|
+
async (params) => {
|
|
1587
|
+
const result = await runMcpTool2(
|
|
1588
|
+
params.filePath,
|
|
1589
|
+
(ctx) => runAccessibilityCheck(ctx)
|
|
1590
|
+
);
|
|
1591
|
+
return {
|
|
1592
|
+
content: [
|
|
1593
|
+
{
|
|
1594
|
+
type: "text",
|
|
1595
|
+
text: JSON.stringify(result, null, 2)
|
|
1596
|
+
}
|
|
1597
|
+
]
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
1600
|
+
);
|
|
1601
|
+
server.registerTool(
|
|
1602
|
+
"find_text",
|
|
1603
|
+
{
|
|
1604
|
+
description: "Search for text across all slides",
|
|
1605
|
+
inputSchema: FindTextSchema.shape
|
|
1606
|
+
},
|
|
1607
|
+
async (params) => {
|
|
1608
|
+
const result = await runMcpTool2(params.filePath, (ctx) => findText(ctx, params));
|
|
1609
|
+
return {
|
|
1610
|
+
content: [
|
|
1611
|
+
{
|
|
1612
|
+
type: "text",
|
|
1613
|
+
text: JSON.stringify(result, null, 2)
|
|
1614
|
+
}
|
|
1615
|
+
]
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1618
|
+
);
|
|
1619
|
+
server.registerTool(
|
|
1620
|
+
"replace_text",
|
|
1621
|
+
{
|
|
1622
|
+
description: "Find and replace text across slides",
|
|
1623
|
+
inputSchema: ReplaceTextSchema.shape
|
|
1624
|
+
},
|
|
1625
|
+
async (params) => {
|
|
1626
|
+
const result = await runMcpTool2(
|
|
1627
|
+
params.filePath,
|
|
1628
|
+
(ctx) => replaceText(ctx, params)
|
|
1629
|
+
);
|
|
1630
|
+
return {
|
|
1631
|
+
content: [
|
|
1632
|
+
{
|
|
1633
|
+
type: "text",
|
|
1634
|
+
text: JSON.stringify(result, null, 2)
|
|
1635
|
+
}
|
|
1636
|
+
]
|
|
1637
|
+
};
|
|
1638
|
+
}
|
|
1639
|
+
);
|
|
1640
|
+
server.registerTool(
|
|
1641
|
+
"manage_comments",
|
|
1642
|
+
{
|
|
1643
|
+
description: "List, add, delete, or resolve slide comments",
|
|
1644
|
+
inputSchema: ManageCommentsSchema.shape
|
|
1645
|
+
},
|
|
1646
|
+
async (params) => {
|
|
1647
|
+
const result = await runMcpTool2(
|
|
1648
|
+
params.filePath,
|
|
1649
|
+
(ctx) => manageComments(ctx, params)
|
|
1650
|
+
);
|
|
1651
|
+
return {
|
|
1652
|
+
content: [
|
|
1653
|
+
{
|
|
1654
|
+
type: "text",
|
|
1655
|
+
text: JSON.stringify(result, null, 2)
|
|
1656
|
+
}
|
|
1657
|
+
]
|
|
1658
|
+
};
|
|
1659
|
+
}
|
|
1660
|
+
);
|
|
1661
|
+
server.registerTool(
|
|
1662
|
+
"convert_to_markdown",
|
|
1663
|
+
{
|
|
1664
|
+
description: "Convert the presentation to Markdown format",
|
|
1665
|
+
inputSchema: ConvertToMarkdownSchema.shape
|
|
1666
|
+
},
|
|
1667
|
+
async (params) => {
|
|
1668
|
+
const result = await runMcpTool2(
|
|
1669
|
+
params.filePath,
|
|
1670
|
+
(ctx) => convertToMarkdown(ctx, { ...params, scopeOutputDir: resolveScopedDir2 })
|
|
1671
|
+
);
|
|
1672
|
+
return {
|
|
1673
|
+
content: [
|
|
1674
|
+
{
|
|
1675
|
+
type: "text",
|
|
1676
|
+
text: JSON.stringify(result, null, 2)
|
|
1677
|
+
}
|
|
1678
|
+
]
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1681
|
+
);
|
|
1682
|
+
server.registerTool(
|
|
1683
|
+
"get_theme_info",
|
|
1684
|
+
{
|
|
1685
|
+
description: "Get current theme information (colors, fonts, available presets)",
|
|
1686
|
+
inputSchema: GetThemeInfoSchema.shape
|
|
1687
|
+
},
|
|
1688
|
+
async (params) => {
|
|
1689
|
+
const result = await runMcpTool2(params.filePath, (ctx) => getThemeInfo(ctx));
|
|
1690
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1691
|
+
}
|
|
1692
|
+
);
|
|
1693
|
+
server.registerTool(
|
|
1694
|
+
"apply_theme_preset",
|
|
1695
|
+
{
|
|
1696
|
+
description: "Apply a built-in theme preset to the presentation",
|
|
1697
|
+
inputSchema: ApplyThemePresetSchema.shape
|
|
1698
|
+
},
|
|
1699
|
+
async (params) => {
|
|
1700
|
+
const result = await runMcpTool2(
|
|
1701
|
+
params.filePath,
|
|
1702
|
+
(ctx) => applyThemePreset(ctx, params)
|
|
1703
|
+
);
|
|
1704
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1705
|
+
}
|
|
1706
|
+
);
|
|
1707
|
+
server.registerTool(
|
|
1708
|
+
"update_theme_colors",
|
|
1709
|
+
{
|
|
1710
|
+
description: "Update individual theme colors (accent1-6, dk1/2, lt1/2, hlink, folHlink)",
|
|
1711
|
+
inputSchema: UpdateThemeColorsSchema.shape
|
|
1712
|
+
},
|
|
1713
|
+
async (params) => {
|
|
1714
|
+
const result = await runMcpTool2(
|
|
1715
|
+
params.filePath,
|
|
1716
|
+
(ctx) => updateThemeColors(ctx, params)
|
|
1717
|
+
);
|
|
1718
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1719
|
+
}
|
|
1720
|
+
);
|
|
1721
|
+
server.registerTool(
|
|
1722
|
+
"update_theme_fonts",
|
|
1723
|
+
{
|
|
1724
|
+
description: "Update theme heading (major) and body (minor) fonts",
|
|
1725
|
+
inputSchema: UpdateThemeFontsSchema.shape
|
|
1726
|
+
},
|
|
1727
|
+
async (params) => {
|
|
1728
|
+
const result = await runMcpTool2(
|
|
1729
|
+
params.filePath,
|
|
1730
|
+
(ctx) => updateThemeFonts(ctx, params)
|
|
1731
|
+
);
|
|
1732
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1733
|
+
}
|
|
1734
|
+
);
|
|
1735
|
+
server.registerTool(
|
|
1736
|
+
"update_chart",
|
|
1737
|
+
{
|
|
1738
|
+
description: "Update chart type, title, legend, data labels, axis, or categories",
|
|
1739
|
+
inputSchema: UpdateChartSchema.shape
|
|
1740
|
+
},
|
|
1741
|
+
async (params) => {
|
|
1742
|
+
const result = await runMcpTool2(
|
|
1743
|
+
params.filePath,
|
|
1744
|
+
(ctx) => updateChart(ctx, params)
|
|
1745
|
+
);
|
|
1746
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1747
|
+
}
|
|
1748
|
+
);
|
|
1749
|
+
server.registerTool(
|
|
1750
|
+
"add_chart_series",
|
|
1751
|
+
{
|
|
1752
|
+
description: "Add a data series to an existing chart",
|
|
1753
|
+
inputSchema: AddChartSeriesSchema.shape
|
|
1754
|
+
},
|
|
1755
|
+
async (params) => {
|
|
1756
|
+
const result = await runMcpTool2(
|
|
1757
|
+
params.filePath,
|
|
1758
|
+
(ctx) => addChartSeriesT(ctx, params)
|
|
1759
|
+
);
|
|
1760
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1761
|
+
}
|
|
1762
|
+
);
|
|
1763
|
+
server.registerTool(
|
|
1764
|
+
"remove_chart_series",
|
|
1765
|
+
{
|
|
1766
|
+
description: "Remove a data series from a chart by index",
|
|
1767
|
+
inputSchema: RemoveChartSeriesSchema.shape
|
|
1768
|
+
},
|
|
1769
|
+
async (params) => {
|
|
1770
|
+
const result = await runMcpTool2(
|
|
1771
|
+
params.filePath,
|
|
1772
|
+
(ctx) => removeChartSeriesT(ctx, params)
|
|
1773
|
+
);
|
|
1774
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1775
|
+
}
|
|
1776
|
+
);
|
|
1777
|
+
server.registerTool(
|
|
1778
|
+
"update_chart_series_data",
|
|
1779
|
+
{
|
|
1780
|
+
description: "Update data values for a chart series",
|
|
1781
|
+
inputSchema: UpdateChartSeriesDataSchema.shape
|
|
1782
|
+
},
|
|
1783
|
+
async (params) => {
|
|
1784
|
+
const result = await runMcpTool2(
|
|
1785
|
+
params.filePath,
|
|
1786
|
+
(ctx) => updateChartSeriesData(ctx, params)
|
|
1787
|
+
);
|
|
1788
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1789
|
+
}
|
|
1790
|
+
);
|
|
1791
|
+
server.registerTool(
|
|
1792
|
+
"create_chart",
|
|
1793
|
+
{
|
|
1794
|
+
description: "Create a new chart element on a slide",
|
|
1795
|
+
inputSchema: CreateChartSchema.shape
|
|
1796
|
+
},
|
|
1797
|
+
async (params) => {
|
|
1798
|
+
const result = await runMcpTool2(
|
|
1799
|
+
params.filePath,
|
|
1800
|
+
(ctx) => createChart(ctx, params)
|
|
1801
|
+
);
|
|
1802
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1803
|
+
}
|
|
1804
|
+
);
|
|
1805
|
+
server.registerTool(
|
|
1806
|
+
"format_chart_data_point",
|
|
1807
|
+
{
|
|
1808
|
+
description: "Set per-data-point chart formatting: fill/stroke colour, stroke width, dash style (c:dPt/c:spPr), explosion, and marker override",
|
|
1809
|
+
inputSchema: FormatChartDataPointSchema.shape
|
|
1810
|
+
},
|
|
1811
|
+
async (params) => {
|
|
1812
|
+
const result = await runMcpTool2(
|
|
1813
|
+
params.filePath,
|
|
1814
|
+
(ctx) => formatChartDataPoint(ctx, params)
|
|
1815
|
+
);
|
|
1816
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1817
|
+
}
|
|
1818
|
+
);
|
|
1819
|
+
server.registerTool(
|
|
1820
|
+
"format_chart_data_label",
|
|
1821
|
+
{
|
|
1822
|
+
description: "Set a per-data-point data-label override (c:dLbl): show flags, position, custom text, and the label's own fill/line formatting (c:spPr) and font (c:txPr)",
|
|
1823
|
+
inputSchema: FormatChartDataLabelSchema.shape
|
|
1824
|
+
},
|
|
1825
|
+
async (params) => {
|
|
1826
|
+
const result = await runMcpTool2(
|
|
1827
|
+
params.filePath,
|
|
1828
|
+
(ctx) => formatChartDataLabel(ctx, params)
|
|
1829
|
+
);
|
|
1830
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1831
|
+
}
|
|
1832
|
+
);
|
|
1833
|
+
server.registerTool(
|
|
1834
|
+
"format_chart_series",
|
|
1835
|
+
{
|
|
1836
|
+
description: "Set a chart series marker (c:marker), trendline (c:trendline, incl. line width/dash), or error bars (c:errBars, incl. line width/dash)",
|
|
1837
|
+
inputSchema: FormatChartSeriesSchema.shape
|
|
1838
|
+
},
|
|
1839
|
+
async (params) => {
|
|
1840
|
+
const result = await runMcpTool2(
|
|
1841
|
+
params.filePath,
|
|
1842
|
+
(ctx) => formatChartSeries(ctx, params)
|
|
1843
|
+
);
|
|
1844
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1845
|
+
}
|
|
1846
|
+
);
|
|
1847
|
+
server.registerTool(
|
|
1848
|
+
"set_chart_helper_line",
|
|
1849
|
+
{
|
|
1850
|
+
description: "Set or remove a chart-level helper line on a line/stock/combo chart: c:dropLines or c:hiLowLines",
|
|
1851
|
+
inputSchema: SetChartHelperLineSchema.shape
|
|
1852
|
+
},
|
|
1853
|
+
async (params) => {
|
|
1854
|
+
const result = await runMcpTool2(
|
|
1855
|
+
params.filePath,
|
|
1856
|
+
(ctx) => setChartHelperLineT(ctx, params)
|
|
1857
|
+
);
|
|
1858
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1859
|
+
}
|
|
1860
|
+
);
|
|
1861
|
+
server.registerTool(
|
|
1862
|
+
"set_chart_color_map_override",
|
|
1863
|
+
{
|
|
1864
|
+
description: "Set or remove a chart's theme colour-map override (c:clrMapOvr), remapping theme colour roles for this chart only",
|
|
1865
|
+
inputSchema: SetChartColorMapOverrideSchema.shape
|
|
1866
|
+
},
|
|
1867
|
+
async (params) => {
|
|
1868
|
+
const result = await runMcpTool2(
|
|
1869
|
+
params.filePath,
|
|
1870
|
+
(ctx) => setChartColorMapOverrideT(ctx, params)
|
|
1871
|
+
);
|
|
1872
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1873
|
+
}
|
|
1874
|
+
);
|
|
1875
|
+
server.registerTool(
|
|
1876
|
+
"chart_user_shape_list",
|
|
1877
|
+
{
|
|
1878
|
+
description: "List a chart's drawing-overlay shapes (c:userShapes)",
|
|
1879
|
+
inputSchema: ListChartUserShapesSchema.shape
|
|
1880
|
+
},
|
|
1881
|
+
async (params) => {
|
|
1882
|
+
const result = await runMcpTool2(
|
|
1883
|
+
params.filePath,
|
|
1884
|
+
(ctx) => listChartUserShapesT(ctx, params)
|
|
1885
|
+
);
|
|
1886
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1887
|
+
}
|
|
1888
|
+
);
|
|
1889
|
+
server.registerTool(
|
|
1890
|
+
"chart_user_shape_add",
|
|
1891
|
+
{
|
|
1892
|
+
description: "Add a drawing-overlay shape (text box or connector) to a chart's c:userShapes",
|
|
1893
|
+
inputSchema: AddChartUserShapeSchema.shape
|
|
1894
|
+
},
|
|
1895
|
+
async (params) => {
|
|
1896
|
+
const result = await runMcpTool2(
|
|
1897
|
+
params.filePath,
|
|
1898
|
+
(ctx) => addChartUserShapeT(ctx, params)
|
|
1899
|
+
);
|
|
1900
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1901
|
+
}
|
|
1902
|
+
);
|
|
1903
|
+
server.registerTool(
|
|
1904
|
+
"chart_user_shape_update",
|
|
1905
|
+
{
|
|
1906
|
+
description: "Move, resize, or restyle one of a chart's drawing-overlay shapes by index",
|
|
1907
|
+
inputSchema: UpdateChartUserShapeSchema.shape
|
|
1908
|
+
},
|
|
1909
|
+
async (params) => {
|
|
1910
|
+
const result = await runMcpTool2(
|
|
1911
|
+
params.filePath,
|
|
1912
|
+
(ctx) => updateChartUserShapeT(ctx, params)
|
|
1913
|
+
);
|
|
1914
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1915
|
+
}
|
|
1916
|
+
);
|
|
1917
|
+
server.registerTool(
|
|
1918
|
+
"chart_user_shape_remove",
|
|
1919
|
+
{
|
|
1920
|
+
description: "Remove one of a chart's drawing-overlay shapes by index",
|
|
1921
|
+
inputSchema: RemoveChartUserShapeSchema.shape
|
|
1922
|
+
},
|
|
1923
|
+
async (params) => {
|
|
1924
|
+
const result = await runMcpTool2(
|
|
1925
|
+
params.filePath,
|
|
1926
|
+
(ctx) => removeChartUserShapeT(ctx, params)
|
|
1927
|
+
);
|
|
1928
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1929
|
+
}
|
|
1930
|
+
);
|
|
1931
|
+
server.registerTool(
|
|
1932
|
+
"manage_smart_art",
|
|
1933
|
+
{
|
|
1934
|
+
description: "Manage SmartArt: get nodes, add/remove/reorder/promote/demote nodes, or decompose to shapes",
|
|
1935
|
+
inputSchema: ManageSmartArtSchema.shape
|
|
1936
|
+
},
|
|
1937
|
+
async (params) => {
|
|
1938
|
+
const result = await runMcpTool2(
|
|
1939
|
+
params.filePath,
|
|
1940
|
+
(ctx) => manageSmartArt(ctx, params)
|
|
1941
|
+
);
|
|
1942
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1943
|
+
}
|
|
1944
|
+
);
|
|
1945
|
+
server.registerTool(
|
|
1946
|
+
"find_placeholders",
|
|
1947
|
+
{
|
|
1948
|
+
description: "Discover all {{placeholder}} tokens in the presentation",
|
|
1949
|
+
inputSchema: FindPlaceholdersSchema.shape
|
|
1950
|
+
},
|
|
1951
|
+
async (params) => {
|
|
1952
|
+
const result = await runMcpTool2(
|
|
1953
|
+
params.filePath,
|
|
1954
|
+
(ctx) => findPlaceholdersT(ctx)
|
|
1955
|
+
);
|
|
1956
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1957
|
+
}
|
|
1958
|
+
);
|
|
1959
|
+
server.registerTool(
|
|
1960
|
+
"apply_template",
|
|
1961
|
+
{
|
|
1962
|
+
description: "Replace {{placeholder}} tokens with provided values (mail merge)",
|
|
1963
|
+
inputSchema: ApplyTemplateSchema.shape
|
|
1964
|
+
},
|
|
1965
|
+
async (params) => {
|
|
1966
|
+
const result = await runMcpTool2(
|
|
1967
|
+
params.filePath,
|
|
1968
|
+
(ctx) => applyTemplateT(ctx, { data: params.data })
|
|
1969
|
+
);
|
|
1970
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1971
|
+
}
|
|
1972
|
+
);
|
|
1973
|
+
server.registerTool(
|
|
1974
|
+
"get_metadata",
|
|
1975
|
+
{
|
|
1976
|
+
description: "Get presentation metadata (title, author, keywords, custom properties)",
|
|
1977
|
+
inputSchema: GetMetadataSchema.shape
|
|
1978
|
+
},
|
|
1979
|
+
async (params) => {
|
|
1980
|
+
const result = await runMcpTool2(params.filePath, (ctx) => getMetadata(ctx));
|
|
1981
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1982
|
+
}
|
|
1983
|
+
);
|
|
1984
|
+
server.registerTool(
|
|
1985
|
+
"update_metadata",
|
|
1986
|
+
{
|
|
1987
|
+
description: "Update presentation metadata (title, author, company, custom properties)",
|
|
1988
|
+
inputSchema: UpdateMetadataSchema.shape
|
|
1989
|
+
},
|
|
1990
|
+
async (params) => {
|
|
1991
|
+
const result = await runMcpTool2(
|
|
1992
|
+
params.filePath,
|
|
1993
|
+
(ctx) => updateMetadata(ctx, params)
|
|
1994
|
+
);
|
|
1995
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
1996
|
+
}
|
|
1997
|
+
);
|
|
1998
|
+
server.registerTool(
|
|
1999
|
+
"manage_sections",
|
|
2000
|
+
{
|
|
2001
|
+
description: "List, add, remove, reorder sections or move slides between sections",
|
|
2002
|
+
inputSchema: ManageSectionsSchema.shape
|
|
2003
|
+
},
|
|
2004
|
+
async (params) => {
|
|
2005
|
+
const result = await runMcpTool2(
|
|
2006
|
+
params.filePath,
|
|
2007
|
+
(ctx) => manageSections(ctx, params)
|
|
2008
|
+
);
|
|
2009
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2010
|
+
}
|
|
2011
|
+
);
|
|
2012
|
+
server.registerTool(
|
|
2013
|
+
"export_to_svg",
|
|
2014
|
+
{
|
|
2015
|
+
description: "Export all or specific slides to SVG strings",
|
|
2016
|
+
inputSchema: ExportToSvgSchema.shape
|
|
2017
|
+
},
|
|
2018
|
+
async (params) => {
|
|
2019
|
+
const result = await runMcpTool2(
|
|
2020
|
+
params.filePath,
|
|
2021
|
+
(ctx) => exportToSvg(ctx, params)
|
|
2022
|
+
);
|
|
2023
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2024
|
+
}
|
|
2025
|
+
);
|
|
2026
|
+
server.registerTool(
|
|
2027
|
+
"export_slide_svg",
|
|
2028
|
+
{
|
|
2029
|
+
description: "Export a single slide to SVG",
|
|
2030
|
+
inputSchema: ExportSlideSvgSchema.shape
|
|
2031
|
+
},
|
|
2032
|
+
async (params) => {
|
|
2033
|
+
const result = await runMcpTool2(
|
|
2034
|
+
params.filePath,
|
|
2035
|
+
(ctx) => exportSlideSvg(ctx, params)
|
|
2036
|
+
);
|
|
2037
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2038
|
+
}
|
|
2039
|
+
);
|
|
2040
|
+
server.registerTool(
|
|
2041
|
+
"export_to_json",
|
|
2042
|
+
{
|
|
2043
|
+
description: "Export the presentation to the portable pptx-viewer-json document format (self-contained, binary assets embedded as base64)",
|
|
2044
|
+
inputSchema: ExportToJsonSchema.shape
|
|
2045
|
+
},
|
|
2046
|
+
async (params) => {
|
|
2047
|
+
const result = await runMcpTool2(
|
|
2048
|
+
params.filePath,
|
|
2049
|
+
(ctx) => exportToJson(ctx, params)
|
|
2050
|
+
);
|
|
2051
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2052
|
+
}
|
|
2053
|
+
);
|
|
2054
|
+
server.registerTool(
|
|
2055
|
+
"import_from_json",
|
|
2056
|
+
{
|
|
2057
|
+
description: "Replace the presentation content with a deck imported from a pptx-viewer-json document",
|
|
2058
|
+
inputSchema: ImportFromJsonSchema.shape
|
|
2059
|
+
},
|
|
2060
|
+
async (params) => {
|
|
2061
|
+
const result = await runMcpTool2(
|
|
2062
|
+
params.filePath,
|
|
2063
|
+
(ctx) => importFromJson(ctx, params)
|
|
2064
|
+
);
|
|
2065
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2066
|
+
}
|
|
2067
|
+
);
|
|
2068
|
+
server.registerTool(
|
|
2069
|
+
"manage_hyperlinks",
|
|
2070
|
+
{
|
|
2071
|
+
description: "List, set, or remove hyperlinks/actions on elements",
|
|
2072
|
+
inputSchema: ManageHyperlinksSchema.shape
|
|
2073
|
+
},
|
|
2074
|
+
async (params) => {
|
|
2075
|
+
const result = await runMcpTool2(
|
|
2076
|
+
params.filePath,
|
|
2077
|
+
(ctx) => manageHyperlinks(ctx, params)
|
|
2078
|
+
);
|
|
2079
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2080
|
+
}
|
|
2081
|
+
);
|
|
2082
|
+
server.registerTool(
|
|
2083
|
+
"replace_geometry",
|
|
2084
|
+
{
|
|
2085
|
+
description: "Replace a shape element geometry with a preset or custom SVG path",
|
|
2086
|
+
inputSchema: ReplaceGeometrySchema.shape
|
|
2087
|
+
},
|
|
2088
|
+
async (params) => {
|
|
2089
|
+
const result = await runMcpTool2(
|
|
2090
|
+
params.filePath,
|
|
2091
|
+
(ctx) => replaceGeometry(ctx, {
|
|
2092
|
+
...params,
|
|
2093
|
+
adjustments: params.adjustments
|
|
2094
|
+
})
|
|
2095
|
+
);
|
|
2096
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2097
|
+
}
|
|
2098
|
+
);
|
|
2099
|
+
server.registerTool(
|
|
2100
|
+
"set_element_lock",
|
|
2101
|
+
{
|
|
2102
|
+
description: "Lock or unlock an element (prevent move, resize, rotation, selection, text edit)",
|
|
2103
|
+
inputSchema: SetElementLockSchema.shape
|
|
2104
|
+
},
|
|
2105
|
+
async (params) => {
|
|
2106
|
+
const result = await runMcpTool2(
|
|
2107
|
+
params.filePath,
|
|
2108
|
+
(ctx) => setElementLockT(ctx, params)
|
|
2109
|
+
);
|
|
2110
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2111
|
+
}
|
|
2112
|
+
);
|
|
2113
|
+
server.registerTool(
|
|
2114
|
+
"validate_presentation",
|
|
2115
|
+
{
|
|
2116
|
+
description: "Validate PPTX structural integrity (content types, relationships, XML)",
|
|
2117
|
+
inputSchema: ValidatePresentationSchema.shape
|
|
2118
|
+
},
|
|
2119
|
+
async (params) => {
|
|
2120
|
+
const { readFile: readFile2 } = await import('fs/promises');
|
|
2121
|
+
const safePath = resolveScopedFilePath2(params.filePath);
|
|
2122
|
+
const bytes = await readFile2(safePath);
|
|
2123
|
+
const result = await validatePresentation(bytes.buffer);
|
|
2124
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2125
|
+
}
|
|
2126
|
+
);
|
|
2127
|
+
server.registerTool(
|
|
2128
|
+
"repair_presentation",
|
|
2129
|
+
{
|
|
2130
|
+
description: "Auto-repair common PPTX structural issues",
|
|
2131
|
+
inputSchema: RepairPresentationSchema.shape
|
|
2132
|
+
},
|
|
2133
|
+
async (params) => {
|
|
2134
|
+
const { readFile: readFile2, writeFile: writeFile2 } = await import('fs/promises');
|
|
2135
|
+
const safePath = resolveScopedFilePath2(params.filePath);
|
|
2136
|
+
const bytes = await readFile2(safePath);
|
|
2137
|
+
const { result, repairedBytes } = await repairPresentation(
|
|
2138
|
+
bytes.buffer
|
|
2139
|
+
);
|
|
2140
|
+
if (result.repairCount > 0) {
|
|
2141
|
+
await writeFile2(safePath, new Uint8Array(repairedBytes));
|
|
2142
|
+
}
|
|
2143
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2144
|
+
}
|
|
2145
|
+
);
|
|
2146
|
+
server.registerTool(
|
|
2147
|
+
"get_presentation_properties",
|
|
2148
|
+
{
|
|
2149
|
+
description: "Get slideshow properties (show type, loop, advance mode, slide range)",
|
|
2150
|
+
inputSchema: GetPresentationPropertiesSchema.shape
|
|
2151
|
+
},
|
|
2152
|
+
async (params) => {
|
|
2153
|
+
const result = await runMcpTool2(
|
|
2154
|
+
params.filePath,
|
|
2155
|
+
(ctx) => getPresentationProperties(ctx)
|
|
2156
|
+
);
|
|
2157
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2158
|
+
}
|
|
2159
|
+
);
|
|
2160
|
+
server.registerTool(
|
|
2161
|
+
"update_presentation_properties",
|
|
2162
|
+
{
|
|
2163
|
+
description: "Update slideshow properties (show type, loop, advance mode, pen color)",
|
|
2164
|
+
inputSchema: UpdatePresentationPropertiesSchema.shape
|
|
2165
|
+
},
|
|
2166
|
+
async (params) => {
|
|
2167
|
+
const result = await runMcpTool2(
|
|
2168
|
+
params.filePath,
|
|
2169
|
+
(ctx) => updatePresentationProperties(ctx, params)
|
|
2170
|
+
);
|
|
2171
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2172
|
+
}
|
|
2173
|
+
);
|
|
2174
|
+
server.registerTool(
|
|
2175
|
+
"get_layouts",
|
|
2176
|
+
{
|
|
2177
|
+
description: "List available slide layouts from the presentation masters",
|
|
2178
|
+
inputSchema: GetLayoutsSchema.shape
|
|
2179
|
+
},
|
|
2180
|
+
async (params) => {
|
|
2181
|
+
const result = await runMcpTool2(params.filePath, (ctx) => getLayouts(ctx));
|
|
2182
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2183
|
+
}
|
|
2184
|
+
);
|
|
2185
|
+
server.registerTool(
|
|
2186
|
+
"apply_layout",
|
|
2187
|
+
{
|
|
2188
|
+
description: "Apply a slide layout to a specific slide",
|
|
2189
|
+
inputSchema: ApplyLayoutSchema.shape
|
|
2190
|
+
},
|
|
2191
|
+
async (params) => {
|
|
2192
|
+
const result = await runMcpTool2(
|
|
2193
|
+
params.filePath,
|
|
2194
|
+
(ctx) => applyLayout(ctx, params)
|
|
2195
|
+
);
|
|
2196
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2197
|
+
}
|
|
2198
|
+
);
|
|
2199
|
+
server.registerTool(
|
|
2200
|
+
"ole_get_content",
|
|
2201
|
+
{
|
|
2202
|
+
description: "Inspect an embedded OLE object's editable content: resolved kind, plus the sheet grid, paragraph list, or nested-deck slide summaries, whichever applies",
|
|
2203
|
+
inputSchema: GetOleContentSchema.shape
|
|
2204
|
+
},
|
|
2205
|
+
async (params) => {
|
|
2206
|
+
const result = await runMcpTool2(
|
|
2207
|
+
params.filePath,
|
|
2208
|
+
(ctx) => getOleContent(ctx, params)
|
|
2209
|
+
);
|
|
2210
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2211
|
+
}
|
|
2212
|
+
);
|
|
2213
|
+
server.registerTool(
|
|
2214
|
+
"ole_set_sheet_cell",
|
|
2215
|
+
{
|
|
2216
|
+
description: "Edit one cell of an embedded Excel OLE object's first worksheet",
|
|
2217
|
+
inputSchema: SetOleSheetCellSchema.shape
|
|
2218
|
+
},
|
|
2219
|
+
async (params) => {
|
|
2220
|
+
const result = await runMcpTool2(
|
|
2221
|
+
params.filePath,
|
|
2222
|
+
(ctx) => setOleSheetCell(ctx, params)
|
|
2223
|
+
);
|
|
2224
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2225
|
+
}
|
|
2226
|
+
);
|
|
2227
|
+
server.registerTool(
|
|
2228
|
+
"ole_set_document_paragraph",
|
|
2229
|
+
{
|
|
2230
|
+
description: "Replace one paragraph's text in an embedded Word (.docx or legacy .doc) OLE object",
|
|
2231
|
+
inputSchema: SetOleDocumentParagraphSchema.shape
|
|
2232
|
+
},
|
|
2233
|
+
async (params) => {
|
|
2234
|
+
const result = await runMcpTool2(
|
|
2235
|
+
params.filePath,
|
|
2236
|
+
(ctx) => setOleDocumentParagraph(ctx, params)
|
|
2237
|
+
);
|
|
2238
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2239
|
+
}
|
|
2240
|
+
);
|
|
2241
|
+
server.registerTool(
|
|
2242
|
+
"ole_set_deck_slide_title",
|
|
2243
|
+
{
|
|
2244
|
+
description: "Edit one text-bearing shape on one slide of an embedded nested-deck (PowerPoint) OLE object, via a full load/save round-trip through the nested deck (call ole_get_content first to discover each slide's elementIds)",
|
|
2245
|
+
inputSchema: SetOleDeckSlideTitleSchema.shape
|
|
2246
|
+
},
|
|
2247
|
+
async (params) => {
|
|
2248
|
+
const result = await runMcpTool2(
|
|
2249
|
+
params.filePath,
|
|
2250
|
+
(ctx) => setOleDeckSlideTitle(ctx, params)
|
|
2251
|
+
);
|
|
2252
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2253
|
+
}
|
|
2254
|
+
);
|
|
2255
|
+
server.registerTool(
|
|
2256
|
+
"ole_replace_file",
|
|
2257
|
+
{
|
|
2258
|
+
description: `Replace an embedded OLE object's payload wholesale with an arbitrary file; works for any OLE kind, including a generic "Package" object or an unsupported format`,
|
|
2259
|
+
inputSchema: ReplaceOleFileSchema.shape
|
|
2260
|
+
},
|
|
2261
|
+
async (params) => {
|
|
2262
|
+
const result = await runMcpTool2(
|
|
2263
|
+
params.filePath,
|
|
2264
|
+
(ctx) => replaceOleFileT(ctx, params)
|
|
2265
|
+
);
|
|
2266
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2267
|
+
}
|
|
2268
|
+
);
|
|
2269
|
+
server.registerTool(
|
|
2270
|
+
"ole_set_object_name",
|
|
2271
|
+
{
|
|
2272
|
+
description: "Rename an OLE object's Object Name (p:oleObj/@name); regenerates the baked-in icon caption too when the object is displayed as an icon",
|
|
2273
|
+
inputSchema: SetOleObjectNameSchema.shape
|
|
2274
|
+
},
|
|
2275
|
+
async (params) => {
|
|
2276
|
+
const result = await runMcpTool2(
|
|
2277
|
+
params.filePath,
|
|
2278
|
+
(ctx) => setOleObjectNameT(ctx, params)
|
|
2279
|
+
);
|
|
2280
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
2281
|
+
}
|
|
2282
|
+
);
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2285
|
+
// src/mcp/cli.ts
|
|
2286
|
+
void createServer().connect(new StdioServerTransport());
|