iwork-mcp 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/tools/numbers.js +55 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,12 +18,20 @@ Ask Claude to build spreadsheets, write documents, and create presentations —
|
|
|
18
18
|
|
|
19
19
|
## Install
|
|
20
20
|
|
|
21
|
+
### Claude Desktop
|
|
22
|
+
|
|
21
23
|
```bash
|
|
22
24
|
npx iwork-mcp install
|
|
23
25
|
```
|
|
24
26
|
|
|
25
27
|
Then restart Claude Desktop (Cmd+Q and reopen). Done.
|
|
26
28
|
|
|
29
|
+
### Claude Code
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
claude mcp add iwork -- npx -y iwork-mcp
|
|
33
|
+
```
|
|
34
|
+
|
|
27
35
|
### Requirements
|
|
28
36
|
|
|
29
37
|
- macOS with Numbers, Pages, or Keynote installed (free on every Mac)
|
package/dist/tools/numbers.js
CHANGED
|
@@ -243,6 +243,61 @@ export function registerNumbersTools(server) {
|
|
|
243
243
|
}
|
|
244
244
|
return JSON.stringify(results);
|
|
245
245
|
`, { documentName, writes, sheetName: sheetName ?? null, tableName: tableName ?? null })));
|
|
246
|
+
server.tool("numbers_write_table", "Bulk write an entire table of data in a single operation. Much faster than writing cells individually. Resizes the table to fit the data automatically.", {
|
|
247
|
+
documentName: z.string().describe("Name of the open document"),
|
|
248
|
+
data: z.array(z.array(z.union([z.string(), z.number(), z.boolean(), z.null()])))
|
|
249
|
+
.describe("2D array of data — first row can be headers. Null cells are skipped."),
|
|
250
|
+
startCell: z.string().optional().describe("Top-left cell to start writing from (default: 'A1')"),
|
|
251
|
+
sheetName: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
252
|
+
tableName: z.string().optional().describe("Table name (defaults to first table)"),
|
|
253
|
+
resizeToFit: z.boolean().optional().describe("Resize table to fit data (default: true)"),
|
|
254
|
+
}, async ({ documentName, data, startCell, sheetName, tableName, resizeToFit }) => handleJXA(() => runJXA(`
|
|
255
|
+
const app = Application("Numbers");
|
|
256
|
+
const doc = app.documents.byName(params.documentName);
|
|
257
|
+
const sheet = params.sheetName ? doc.sheets.byName(params.sheetName) : doc.sheets[0];
|
|
258
|
+
const table = params.tableName ? sheet.tables.byName(params.tableName) : sheet.tables[0];
|
|
259
|
+
|
|
260
|
+
// Parse start cell (e.g. "B3" -> col=1, row=2)
|
|
261
|
+
const cellRef = (params.startCell || "A1").toUpperCase();
|
|
262
|
+
const colMatch = cellRef.match(/^([A-Z]+)/);
|
|
263
|
+
const rowMatch = cellRef.match(/(\\d+)$/);
|
|
264
|
+
let startCol = 0;
|
|
265
|
+
if (colMatch) {
|
|
266
|
+
for (let i = 0; i < colMatch[1].length; i++) {
|
|
267
|
+
startCol = startCol * 26 + (colMatch[1].charCodeAt(i) - 64);
|
|
268
|
+
}
|
|
269
|
+
startCol -= 1;
|
|
270
|
+
}
|
|
271
|
+
const startRow = rowMatch ? parseInt(rowMatch[1]) - 1 : 0;
|
|
272
|
+
|
|
273
|
+
const dataRows = params.data.length;
|
|
274
|
+
const dataCols = Math.max(...params.data.map(r => r.length));
|
|
275
|
+
const needRows = startRow + dataRows;
|
|
276
|
+
const needCols = startCol + dataCols;
|
|
277
|
+
|
|
278
|
+
// Resize table if needed
|
|
279
|
+
if (params.resizeToFit !== false) {
|
|
280
|
+
while (table.rowCount() < needRows) {
|
|
281
|
+
table.rows.push(app.Row());
|
|
282
|
+
}
|
|
283
|
+
while (table.columnCount() < needCols) {
|
|
284
|
+
table.columns.push(app.Column());
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const colCount = table.columnCount();
|
|
289
|
+
let cellsWritten = 0;
|
|
290
|
+
for (let r = 0; r < dataRows; r++) {
|
|
291
|
+
for (let c = 0; c < params.data[r].length; c++) {
|
|
292
|
+
const val = params.data[r][c];
|
|
293
|
+
if (val !== null) {
|
|
294
|
+
table.cells[(startRow + r) * colCount + (startCol + c)].value = val;
|
|
295
|
+
cellsWritten++;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return JSON.stringify({ cellsWritten: cellsWritten, rows: dataRows, columns: dataCols });
|
|
300
|
+
`, { documentName, data, startCell: startCell ?? null, sheetName: sheetName ?? null, tableName: tableName ?? null, resizeToFit: resizeToFit ?? true })));
|
|
246
301
|
server.tool("numbers_set_formula", "Set a formula on a cell (e.g. '=SUM(A1:A10)')", {
|
|
247
302
|
documentName: z.string().describe("Name of the open document"),
|
|
248
303
|
cellRef: z.string().describe("Cell reference, e.g. 'A1'"),
|