numbersmcp 0.1.1 → 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/dist/index.js +151 -0
- package/dist/tools/addColumn.d.ts +7 -0
- package/dist/tools/addColumn.js +44 -0
- package/dist/tools/addSheet.d.ts +5 -0
- package/dist/tools/addSheet.js +28 -0
- package/dist/tools/addTable.d.ts +6 -0
- package/dist/tools/addTable.js +32 -0
- package/dist/tools/deleteColumn.d.ts +7 -0
- package/dist/tools/deleteColumn.js +32 -0
- package/dist/tools/deleteRow.d.ts +7 -0
- package/dist/tools/deleteRow.js +24 -0
- package/dist/tools/deleteSheet.d.ts +5 -0
- package/dist/tools/deleteSheet.js +17 -0
- package/dist/tools/deleteTable.d.ts +6 -0
- package/dist/tools/deleteTable.js +21 -0
- package/dist/tools/exportDocument.d.ts +6 -0
- package/dist/tools/exportDocument.js +17 -0
- package/dist/tools/mergeCells.d.ts +5 -0
- package/dist/tools/mergeCells.js +15 -0
- package/dist/tools/renameSheet.d.ts +6 -0
- package/dist/tools/renameSheet.js +17 -0
- package/dist/tools/renameTable.d.ts +6 -0
- package/dist/tools/renameTable.js +13 -0
- package/dist/tools/setCellFormat.d.ts +8 -0
- package/dist/tools/setCellFormat.js +53 -0
- package/dist/tools/setCellStyle.d.ts +5 -0
- package/dist/tools/setCellStyle.js +64 -0
- package/dist/tools/sortTable.d.ts +6 -0
- package/dist/tools/sortTable.js +22 -0
- package/dist/tools/unmergeCells.d.ts +5 -0
- package/dist/tools/unmergeCells.js +15 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11,6 +11,21 @@ import { addRow } from "./tools/addRow.js";
|
|
|
11
11
|
import { readTable } from "./tools/readTable.js";
|
|
12
12
|
import { getFormula } from "./tools/getFormula.js";
|
|
13
13
|
import { setFormula } from "./tools/setFormula.js";
|
|
14
|
+
import { addColumn } from "./tools/addColumn.js";
|
|
15
|
+
import { deleteColumn } from "./tools/deleteColumn.js";
|
|
16
|
+
import { deleteRow } from "./tools/deleteRow.js";
|
|
17
|
+
import { addSheet } from "./tools/addSheet.js";
|
|
18
|
+
import { deleteSheet } from "./tools/deleteSheet.js";
|
|
19
|
+
import { renameSheet } from "./tools/renameSheet.js";
|
|
20
|
+
import { addTable } from "./tools/addTable.js";
|
|
21
|
+
import { deleteTable } from "./tools/deleteTable.js";
|
|
22
|
+
import { setCellFormat } from "./tools/setCellFormat.js";
|
|
23
|
+
import { sortTable } from "./tools/sortTable.js";
|
|
24
|
+
import { exportDocument } from "./tools/exportDocument.js";
|
|
25
|
+
import { mergeCells } from "./tools/mergeCells.js";
|
|
26
|
+
import { unmergeCells } from "./tools/unmergeCells.js";
|
|
27
|
+
import { renameTable } from "./tools/renameTable.js";
|
|
28
|
+
import { setCellStyle } from "./tools/setCellStyle.js";
|
|
14
29
|
const server = new McpServer({
|
|
15
30
|
name: "numbersmcp",
|
|
16
31
|
version: "0.1.0",
|
|
@@ -91,5 +106,141 @@ server.tool("set-formula", "Set a formula on a specific cell in a Numbers table
|
|
|
91
106
|
const result = await setFormula(document, cell, formula, sheet, table);
|
|
92
107
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
93
108
|
});
|
|
109
|
+
server.tool("add-column", "Add a new column to a Numbers table", {
|
|
110
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
111
|
+
afterColumn: z.string().optional().describe("Column letter after which to insert (e.g. 'C'). Defaults to last column."),
|
|
112
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
113
|
+
table: z.string().optional().describe("Table name (defaults to first table)"),
|
|
114
|
+
}, async ({ document, afterColumn, sheet, table }) => {
|
|
115
|
+
const result = await addColumn(document, afterColumn, sheet, table);
|
|
116
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
117
|
+
});
|
|
118
|
+
server.tool("delete-column", "Delete a column from a Numbers table", {
|
|
119
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
120
|
+
column: z.string().describe("Column letter to delete (e.g. 'C')"),
|
|
121
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
122
|
+
table: z.string().optional().describe("Table name (defaults to first table)"),
|
|
123
|
+
}, async ({ document, column, sheet, table }) => {
|
|
124
|
+
const result = await deleteColumn(document, column, sheet, table);
|
|
125
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
126
|
+
});
|
|
127
|
+
server.tool("delete-row", "Delete a row from a Numbers table", {
|
|
128
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
129
|
+
row: z.number().int().positive().describe("Row number to delete"),
|
|
130
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
131
|
+
table: z.string().optional().describe("Table name (defaults to first table)"),
|
|
132
|
+
}, async ({ document, row, sheet, table }) => {
|
|
133
|
+
const result = await deleteRow(document, row, sheet, table);
|
|
134
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
135
|
+
});
|
|
136
|
+
server.tool("add-sheet", "Add a new sheet to a Numbers document", {
|
|
137
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
138
|
+
name: z.string().optional().describe("Name for the new sheet"),
|
|
139
|
+
}, async ({ document, name }) => {
|
|
140
|
+
const result = await addSheet(document, name);
|
|
141
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
142
|
+
});
|
|
143
|
+
server.tool("delete-sheet", "Delete a sheet from a Numbers document", {
|
|
144
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
145
|
+
sheet: z.string().describe("Name of the sheet to delete"),
|
|
146
|
+
}, async ({ document, sheet }) => {
|
|
147
|
+
const result = await deleteSheet(document, sheet);
|
|
148
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
149
|
+
});
|
|
150
|
+
server.tool("rename-sheet", "Rename a sheet in a Numbers document", {
|
|
151
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
152
|
+
sheet: z.string().describe("Current name of the sheet"),
|
|
153
|
+
newName: z.string().describe("New name for the sheet"),
|
|
154
|
+
}, async ({ document, sheet, newName }) => {
|
|
155
|
+
const result = await renameSheet(document, sheet, newName);
|
|
156
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
157
|
+
});
|
|
158
|
+
server.tool("add-table", "Add a new table to a sheet in a Numbers document", {
|
|
159
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
160
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
161
|
+
name: z.string().optional().describe("Name for the new table"),
|
|
162
|
+
}, async ({ document, sheet, name }) => {
|
|
163
|
+
const result = await addTable(document, sheet, name);
|
|
164
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
165
|
+
});
|
|
166
|
+
server.tool("delete-table", "Delete a table from a sheet in a Numbers document", {
|
|
167
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
168
|
+
table: z.string().describe("Name of the table to delete"),
|
|
169
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
170
|
+
}, async ({ document, table, sheet }) => {
|
|
171
|
+
const result = await deleteTable(document, table, sheet);
|
|
172
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
173
|
+
});
|
|
174
|
+
server.tool("set-cell-format", "Set the format of a cell (number, currency, percentage, date, text, etc.)", {
|
|
175
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
176
|
+
cell: z.string().describe("Cell reference in A1 notation, e.g. 'B3'"),
|
|
177
|
+
format: z.enum(["automatic", "number", "currency", "percentage", "date", "date-and-time", "duration", "checkbox", "star-rating", "text", "fraction", "scientific", "numeral-system"]).describe("Cell format type"),
|
|
178
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
179
|
+
table: z.string().optional().describe("Table name (defaults to first table)"),
|
|
180
|
+
}, async ({ document, cell, format, sheet, table }) => {
|
|
181
|
+
const result = await setCellFormat(document, cell, format, sheet, table);
|
|
182
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
183
|
+
});
|
|
184
|
+
server.tool("sort-table", "Sort a Numbers table by a column", {
|
|
185
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
186
|
+
column: z.string().describe("Column letter to sort by, e.g. 'B'"),
|
|
187
|
+
direction: z.enum(["ascending", "descending"]).describe("Sort direction"),
|
|
188
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
189
|
+
table: z.string().optional().describe("Table name (defaults to first table)"),
|
|
190
|
+
}, async ({ document, column, direction, sheet, table }) => {
|
|
191
|
+
const result = await sortTable(document, column, direction, sheet, table);
|
|
192
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
193
|
+
});
|
|
194
|
+
server.tool("export-document", "Export a Numbers document to PDF, Excel, or CSV format", {
|
|
195
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
196
|
+
path: z.string().describe("Full output file path, e.g. '/Users/me/output.xlsx'"),
|
|
197
|
+
format: z.enum(["pdf", "excel", "csv"]).describe("Export format"),
|
|
198
|
+
}, async ({ document, path, format }) => {
|
|
199
|
+
const result = await exportDocument(document, path, format);
|
|
200
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
201
|
+
});
|
|
202
|
+
server.tool("merge-cells", "Merge a range of cells in a Numbers table", {
|
|
203
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
204
|
+
range: z.string().describe("Cell range to merge, e.g. 'A1:C1'"),
|
|
205
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
206
|
+
table: z.string().optional().describe("Table name (defaults to first table)"),
|
|
207
|
+
}, async ({ document, range, sheet, table }) => {
|
|
208
|
+
const result = await mergeCells(document, range, sheet, table);
|
|
209
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
210
|
+
});
|
|
211
|
+
server.tool("unmerge-cells", "Unmerge a range of cells in a Numbers table", {
|
|
212
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
213
|
+
range: z.string().describe("Cell range to unmerge, e.g. 'A1:C1'"),
|
|
214
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
215
|
+
table: z.string().optional().describe("Table name (defaults to first table)"),
|
|
216
|
+
}, async ({ document, range, sheet, table }) => {
|
|
217
|
+
const result = await unmergeCells(document, range, sheet, table);
|
|
218
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
219
|
+
});
|
|
220
|
+
server.tool("rename-table", "Rename a table in a Numbers document", {
|
|
221
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
222
|
+
table: z.string().describe("Current name of the table"),
|
|
223
|
+
newName: z.string().describe("New name for the table"),
|
|
224
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
225
|
+
}, async ({ document, table, newName, sheet }) => {
|
|
226
|
+
const result = await renameTable(document, table, newName, sheet);
|
|
227
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
228
|
+
});
|
|
229
|
+
server.tool("set-cell-style", "Set visual styling properties on a cell (font, color, bold, italic, alignment, background)", {
|
|
230
|
+
document: z.string().describe("Name of the open Numbers document"),
|
|
231
|
+
cell: z.string().describe("Cell reference in A1 notation, e.g. 'B3'"),
|
|
232
|
+
sheet: z.string().optional().describe("Sheet name (defaults to first sheet)"),
|
|
233
|
+
table: z.string().optional().describe("Table name (defaults to first table)"),
|
|
234
|
+
fontName: z.string().optional().describe("Font name, e.g. 'Helvetica'"),
|
|
235
|
+
fontSize: z.number().optional().describe("Font size in points"),
|
|
236
|
+
textColor: z.string().optional().describe("Text color as RGB hex, e.g. '#FF0000'"),
|
|
237
|
+
backgroundColor: z.string().optional().describe("Background color as RGB hex, e.g. '#0000FF'"),
|
|
238
|
+
bold: z.boolean().optional().describe("Set bold"),
|
|
239
|
+
italic: z.boolean().optional().describe("Set italic"),
|
|
240
|
+
alignment: z.enum(["left", "center", "right", "justify", "auto"]).optional().describe("Horizontal text alignment"),
|
|
241
|
+
}, async ({ document, cell, sheet, table, fontName, fontSize, textColor, backgroundColor, bold, italic, alignment }) => {
|
|
242
|
+
const result = await setCellStyle(document, cell, sheet, table, fontName, fontSize, textColor, backgroundColor, bold, italic, alignment);
|
|
243
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
244
|
+
});
|
|
94
245
|
const transport = new StdioServerTransport();
|
|
95
246
|
await server.connect(transport);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
function colLetterToNum(col) {
|
|
3
|
+
let n = 0;
|
|
4
|
+
for (const ch of col.toUpperCase()) {
|
|
5
|
+
n = n * 26 + (ch.charCodeAt(0) - 64);
|
|
6
|
+
}
|
|
7
|
+
return n;
|
|
8
|
+
}
|
|
9
|
+
export async function addColumn(document, afterColumn, sheet, table) {
|
|
10
|
+
const docEsc = escapeForAppleScript(document);
|
|
11
|
+
const tableRef = table
|
|
12
|
+
? `table "${escapeForAppleScript(table)}"`
|
|
13
|
+
: "table 1";
|
|
14
|
+
const sheetRef = sheet
|
|
15
|
+
? `sheet "${escapeForAppleScript(sheet)}"`
|
|
16
|
+
: "sheet 1";
|
|
17
|
+
let script;
|
|
18
|
+
if (afterColumn) {
|
|
19
|
+
const colNum = colLetterToNum(afterColumn);
|
|
20
|
+
script = `
|
|
21
|
+
tell application "Numbers"
|
|
22
|
+
tell ${tableRef} of ${sheetRef} of document "${docEsc}"
|
|
23
|
+
add column after column ${colNum}
|
|
24
|
+
end tell
|
|
25
|
+
end tell`;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
script = `
|
|
29
|
+
tell application "Numbers"
|
|
30
|
+
tell ${tableRef} of ${sheetRef} of document "${docEsc}"
|
|
31
|
+
set colCount to column count
|
|
32
|
+
add column after column colCount
|
|
33
|
+
end tell
|
|
34
|
+
end tell`;
|
|
35
|
+
}
|
|
36
|
+
await runAppleScript(script);
|
|
37
|
+
return {
|
|
38
|
+
success: true,
|
|
39
|
+
document,
|
|
40
|
+
sheet: sheet ?? "sheet 1",
|
|
41
|
+
table: table ?? "table 1",
|
|
42
|
+
afterColumn: afterColumn ?? "last",
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
export async function addSheet(document, name) {
|
|
3
|
+
const docEsc = escapeForAppleScript(document);
|
|
4
|
+
let script;
|
|
5
|
+
if (name) {
|
|
6
|
+
const nameEsc = escapeForAppleScript(name);
|
|
7
|
+
script = `
|
|
8
|
+
tell application "Numbers"
|
|
9
|
+
tell document "${docEsc}"
|
|
10
|
+
make new sheet with properties {name:"${nameEsc}"}
|
|
11
|
+
end tell
|
|
12
|
+
end tell`;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
script = `
|
|
16
|
+
tell application "Numbers"
|
|
17
|
+
tell document "${docEsc}"
|
|
18
|
+
make new sheet
|
|
19
|
+
end tell
|
|
20
|
+
end tell`;
|
|
21
|
+
}
|
|
22
|
+
await runAppleScript(script);
|
|
23
|
+
return {
|
|
24
|
+
success: true,
|
|
25
|
+
document,
|
|
26
|
+
name: name ?? null,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
export async function addTable(document, sheet, name) {
|
|
3
|
+
const docEsc = escapeForAppleScript(document);
|
|
4
|
+
const sheetRef = sheet
|
|
5
|
+
? `sheet "${escapeForAppleScript(sheet)}"`
|
|
6
|
+
: "sheet 1";
|
|
7
|
+
let script;
|
|
8
|
+
if (name) {
|
|
9
|
+
const nameEsc = escapeForAppleScript(name);
|
|
10
|
+
script = `
|
|
11
|
+
tell application "Numbers"
|
|
12
|
+
tell ${sheetRef} of document "${docEsc}"
|
|
13
|
+
make new table with properties {name:"${nameEsc}"}
|
|
14
|
+
end tell
|
|
15
|
+
end tell`;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
script = `
|
|
19
|
+
tell application "Numbers"
|
|
20
|
+
tell ${sheetRef} of document "${docEsc}"
|
|
21
|
+
make new table
|
|
22
|
+
end tell
|
|
23
|
+
end tell`;
|
|
24
|
+
}
|
|
25
|
+
await runAppleScript(script);
|
|
26
|
+
return {
|
|
27
|
+
success: true,
|
|
28
|
+
document,
|
|
29
|
+
sheet: sheet ?? "sheet 1",
|
|
30
|
+
name: name ?? null,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
function colLetterToNum(col) {
|
|
3
|
+
let n = 0;
|
|
4
|
+
for (const ch of col.toUpperCase()) {
|
|
5
|
+
n = n * 26 + (ch.charCodeAt(0) - 64);
|
|
6
|
+
}
|
|
7
|
+
return n;
|
|
8
|
+
}
|
|
9
|
+
export async function deleteColumn(document, column, sheet, table) {
|
|
10
|
+
const docEsc = escapeForAppleScript(document);
|
|
11
|
+
const colNum = colLetterToNum(column);
|
|
12
|
+
const tableRef = table
|
|
13
|
+
? `table "${escapeForAppleScript(table)}"`
|
|
14
|
+
: "table 1";
|
|
15
|
+
const sheetRef = sheet
|
|
16
|
+
? `sheet "${escapeForAppleScript(sheet)}"`
|
|
17
|
+
: "sheet 1";
|
|
18
|
+
const script = `
|
|
19
|
+
tell application "Numbers"
|
|
20
|
+
tell ${tableRef} of ${sheetRef} of document "${docEsc}"
|
|
21
|
+
delete column ${colNum}
|
|
22
|
+
end tell
|
|
23
|
+
end tell`;
|
|
24
|
+
await runAppleScript(script);
|
|
25
|
+
return {
|
|
26
|
+
success: true,
|
|
27
|
+
document,
|
|
28
|
+
sheet: sheet ?? "sheet 1",
|
|
29
|
+
table: table ?? "table 1",
|
|
30
|
+
column,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
export async function deleteRow(document, row, sheet, table) {
|
|
3
|
+
const docEsc = escapeForAppleScript(document);
|
|
4
|
+
const tableRef = table
|
|
5
|
+
? `table "${escapeForAppleScript(table)}"`
|
|
6
|
+
: "table 1";
|
|
7
|
+
const sheetRef = sheet
|
|
8
|
+
? `sheet "${escapeForAppleScript(sheet)}"`
|
|
9
|
+
: "sheet 1";
|
|
10
|
+
const script = `
|
|
11
|
+
tell application "Numbers"
|
|
12
|
+
tell ${tableRef} of ${sheetRef} of document "${docEsc}"
|
|
13
|
+
delete row ${row}
|
|
14
|
+
end tell
|
|
15
|
+
end tell`;
|
|
16
|
+
await runAppleScript(script);
|
|
17
|
+
return {
|
|
18
|
+
success: true,
|
|
19
|
+
document,
|
|
20
|
+
sheet: sheet ?? "sheet 1",
|
|
21
|
+
table: table ?? "table 1",
|
|
22
|
+
row,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
export async function deleteSheet(document, sheet) {
|
|
3
|
+
const docEsc = escapeForAppleScript(document);
|
|
4
|
+
const sheetEsc = escapeForAppleScript(sheet);
|
|
5
|
+
const script = `
|
|
6
|
+
tell application "Numbers"
|
|
7
|
+
tell document "${docEsc}"
|
|
8
|
+
delete sheet "${sheetEsc}"
|
|
9
|
+
end tell
|
|
10
|
+
end tell`;
|
|
11
|
+
await runAppleScript(script);
|
|
12
|
+
return {
|
|
13
|
+
success: true,
|
|
14
|
+
document,
|
|
15
|
+
sheet,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
export async function deleteTable(document, table, sheet) {
|
|
3
|
+
const docEsc = escapeForAppleScript(document);
|
|
4
|
+
const tableEsc = escapeForAppleScript(table);
|
|
5
|
+
const sheetRef = sheet
|
|
6
|
+
? `sheet "${escapeForAppleScript(sheet)}"`
|
|
7
|
+
: "sheet 1";
|
|
8
|
+
const script = `
|
|
9
|
+
tell application "Numbers"
|
|
10
|
+
tell ${sheetRef} of document "${docEsc}"
|
|
11
|
+
delete table "${tableEsc}"
|
|
12
|
+
end tell
|
|
13
|
+
end tell`;
|
|
14
|
+
await runAppleScript(script);
|
|
15
|
+
return {
|
|
16
|
+
success: true,
|
|
17
|
+
document,
|
|
18
|
+
sheet: sheet ?? "sheet 1",
|
|
19
|
+
table,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
const FORMAT_MAP = {
|
|
3
|
+
pdf: "PDF",
|
|
4
|
+
excel: "Microsoft Excel",
|
|
5
|
+
csv: "CSV",
|
|
6
|
+
};
|
|
7
|
+
export async function exportDocument(document, path, format) {
|
|
8
|
+
const docEsc = escapeForAppleScript(document);
|
|
9
|
+
const pathEsc = escapeForAppleScript(path);
|
|
10
|
+
const asFormat = FORMAT_MAP[format];
|
|
11
|
+
const script = `
|
|
12
|
+
tell application "Numbers"
|
|
13
|
+
export document "${docEsc}" to POSIX file "${pathEsc}" as ${asFormat}
|
|
14
|
+
end tell`;
|
|
15
|
+
await runAppleScript(script);
|
|
16
|
+
return { success: true, document, path, format };
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
export async function mergeCells(document, range, sheet, table) {
|
|
3
|
+
const docEsc = escapeForAppleScript(document);
|
|
4
|
+
const tableRef = table ? `table "${escapeForAppleScript(table)}"` : "table 1";
|
|
5
|
+
const sheetRef = sheet ? `sheet "${escapeForAppleScript(sheet)}"` : "sheet 1";
|
|
6
|
+
const rangeEsc = escapeForAppleScript(range);
|
|
7
|
+
const script = `
|
|
8
|
+
tell application "Numbers"
|
|
9
|
+
tell ${tableRef} of ${sheetRef} of document "${docEsc}"
|
|
10
|
+
merge range "${rangeEsc}"
|
|
11
|
+
end tell
|
|
12
|
+
end tell`;
|
|
13
|
+
await runAppleScript(script);
|
|
14
|
+
return { success: true, document, range };
|
|
15
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
export async function renameSheet(document, sheet, newName) {
|
|
3
|
+
const docEsc = escapeForAppleScript(document);
|
|
4
|
+
const sheetEsc = escapeForAppleScript(sheet);
|
|
5
|
+
const newNameEsc = escapeForAppleScript(newName);
|
|
6
|
+
const script = `
|
|
7
|
+
tell application "Numbers"
|
|
8
|
+
set name of sheet "${sheetEsc}" of document "${docEsc}" to "${newNameEsc}"
|
|
9
|
+
end tell`;
|
|
10
|
+
await runAppleScript(script);
|
|
11
|
+
return {
|
|
12
|
+
success: true,
|
|
13
|
+
document,
|
|
14
|
+
sheet,
|
|
15
|
+
newName,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
export async function renameTable(document, table, newName, sheet) {
|
|
3
|
+
const docEsc = escapeForAppleScript(document);
|
|
4
|
+
const tableEsc = escapeForAppleScript(table);
|
|
5
|
+
const newNameEsc = escapeForAppleScript(newName);
|
|
6
|
+
const sheetRef = sheet ? `sheet "${escapeForAppleScript(sheet)}"` : "sheet 1";
|
|
7
|
+
const script = `
|
|
8
|
+
tell application "Numbers"
|
|
9
|
+
set name of table "${tableEsc}" of ${sheetRef} of document "${docEsc}" to "${newNameEsc}"
|
|
10
|
+
end tell`;
|
|
11
|
+
await runAppleScript(script);
|
|
12
|
+
return { success: true, document, oldName: table, newName };
|
|
13
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
const FORMAT_MAP = {
|
|
3
|
+
"automatic": "automatic",
|
|
4
|
+
"number": "number",
|
|
5
|
+
"currency": "currency",
|
|
6
|
+
"percentage": "percentage",
|
|
7
|
+
"date": "date and time",
|
|
8
|
+
"date-and-time": "date and time",
|
|
9
|
+
"duration": "duration",
|
|
10
|
+
"checkbox": "checkbox",
|
|
11
|
+
"star-rating": "star rating",
|
|
12
|
+
"text": "text",
|
|
13
|
+
"fraction": "fraction",
|
|
14
|
+
"scientific": "scientific",
|
|
15
|
+
"numeral-system": "numeral system",
|
|
16
|
+
};
|
|
17
|
+
function parseCellRef(ref) {
|
|
18
|
+
const match = ref.match(/^([A-Z]+)(\d+)$/i);
|
|
19
|
+
if (!match)
|
|
20
|
+
throw new Error(`Invalid cell reference: ${ref}`);
|
|
21
|
+
const letters = match[1].toUpperCase();
|
|
22
|
+
let col = 0;
|
|
23
|
+
for (let i = 0; i < letters.length; i++) {
|
|
24
|
+
col = col * 26 + (letters.charCodeAt(i) - 64);
|
|
25
|
+
}
|
|
26
|
+
return { row: parseInt(match[2], 10), col };
|
|
27
|
+
}
|
|
28
|
+
export async function setCellFormat(document, cell, format, sheet, table) {
|
|
29
|
+
const docEsc = escapeForAppleScript(document);
|
|
30
|
+
const tableRef = table
|
|
31
|
+
? `table "${escapeForAppleScript(table)}"`
|
|
32
|
+
: "table 1";
|
|
33
|
+
const sheetRef = sheet
|
|
34
|
+
? `sheet "${escapeForAppleScript(sheet)}"`
|
|
35
|
+
: "sheet 1";
|
|
36
|
+
const { row, col } = parseCellRef(cell);
|
|
37
|
+
const resolved = FORMAT_MAP[format.toLowerCase()] ?? format;
|
|
38
|
+
const script = `
|
|
39
|
+
tell application "Numbers"
|
|
40
|
+
tell ${tableRef} of ${sheetRef} of document "${docEsc}"
|
|
41
|
+
set format of cell ${col} of row ${row} to ${resolved}
|
|
42
|
+
end tell
|
|
43
|
+
end tell`;
|
|
44
|
+
await runAppleScript(script);
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
document,
|
|
48
|
+
cell,
|
|
49
|
+
format: resolved,
|
|
50
|
+
sheet: sheet ?? "sheet 1",
|
|
51
|
+
table: table ?? "table 1",
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function setCellStyle(document: string, cell: string, sheet?: string, table?: string, fontName?: string, fontSize?: number, textColor?: string, backgroundColor?: string, bold?: boolean, italic?: boolean, alignment?: "left" | "center" | "right" | "justify" | "auto"): Promise<{
|
|
2
|
+
success: boolean;
|
|
3
|
+
cell: string;
|
|
4
|
+
appliedStyles: string[];
|
|
5
|
+
}>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
import { parseCellRef } from "./readRange.js";
|
|
3
|
+
function hexToAppleScriptRgb(hex) {
|
|
4
|
+
const h = hex.replace(/^#/, "");
|
|
5
|
+
const r = Math.round((parseInt(h.slice(0, 2), 16) / 255) * 65535);
|
|
6
|
+
const g = Math.round((parseInt(h.slice(2, 4), 16) / 255) * 65535);
|
|
7
|
+
const b = Math.round((parseInt(h.slice(4, 6), 16) / 255) * 65535);
|
|
8
|
+
return `{${r}, ${g}, ${b}}`;
|
|
9
|
+
}
|
|
10
|
+
const ALIGNMENT_MAP = {
|
|
11
|
+
left: "left",
|
|
12
|
+
center: "center",
|
|
13
|
+
right: "right",
|
|
14
|
+
justify: "justify",
|
|
15
|
+
auto: "auto",
|
|
16
|
+
};
|
|
17
|
+
export async function setCellStyle(document, cell, sheet, table, fontName, fontSize, textColor, backgroundColor, bold, italic, alignment) {
|
|
18
|
+
const docEsc = escapeForAppleScript(document);
|
|
19
|
+
const tableRef = table ? `table "${escapeForAppleScript(table)}"` : "table 1";
|
|
20
|
+
const sheetRef = sheet ? `sheet "${escapeForAppleScript(sheet)}"` : "sheet 1";
|
|
21
|
+
const { row, col } = parseCellRef(cell);
|
|
22
|
+
const styleLines = [];
|
|
23
|
+
const appliedStyles = [];
|
|
24
|
+
if (fontName !== undefined) {
|
|
25
|
+
styleLines.push(`set font name of theCell to "${escapeForAppleScript(fontName)}"`);
|
|
26
|
+
appliedStyles.push("fontName");
|
|
27
|
+
}
|
|
28
|
+
if (fontSize !== undefined) {
|
|
29
|
+
styleLines.push(`set font size of theCell to ${fontSize}`);
|
|
30
|
+
appliedStyles.push("fontSize");
|
|
31
|
+
}
|
|
32
|
+
if (textColor !== undefined) {
|
|
33
|
+
styleLines.push(`set text color of theCell to ${hexToAppleScriptRgb(textColor)}`);
|
|
34
|
+
appliedStyles.push("textColor");
|
|
35
|
+
}
|
|
36
|
+
if (backgroundColor !== undefined) {
|
|
37
|
+
styleLines.push(`set background color of theCell to ${hexToAppleScriptRgb(backgroundColor)}`);
|
|
38
|
+
appliedStyles.push("backgroundColor");
|
|
39
|
+
}
|
|
40
|
+
if (bold !== undefined) {
|
|
41
|
+
styleLines.push(`set bold of theCell to ${bold}`);
|
|
42
|
+
appliedStyles.push("bold");
|
|
43
|
+
}
|
|
44
|
+
if (italic !== undefined) {
|
|
45
|
+
styleLines.push(`set italic of theCell to ${italic}`);
|
|
46
|
+
appliedStyles.push("italic");
|
|
47
|
+
}
|
|
48
|
+
if (alignment !== undefined) {
|
|
49
|
+
styleLines.push(`set alignment of theCell to ${ALIGNMENT_MAP[alignment]}`);
|
|
50
|
+
appliedStyles.push("alignment");
|
|
51
|
+
}
|
|
52
|
+
if (styleLines.length === 0) {
|
|
53
|
+
return { success: true, cell, appliedStyles: [] };
|
|
54
|
+
}
|
|
55
|
+
const script = `
|
|
56
|
+
tell application "Numbers"
|
|
57
|
+
tell ${tableRef} of ${sheetRef} of document "${docEsc}"
|
|
58
|
+
set theCell to cell ${col} of row ${row}
|
|
59
|
+
${styleLines.join("\n ")}
|
|
60
|
+
end tell
|
|
61
|
+
end tell`;
|
|
62
|
+
await runAppleScript(script);
|
|
63
|
+
return { success: true, cell, appliedStyles };
|
|
64
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
function colLetterToNum(col) {
|
|
3
|
+
let n = 0;
|
|
4
|
+
for (const ch of col.toUpperCase()) {
|
|
5
|
+
n = n * 26 + (ch.charCodeAt(0) - 64);
|
|
6
|
+
}
|
|
7
|
+
return n;
|
|
8
|
+
}
|
|
9
|
+
export async function sortTable(document, column, direction, sheet, table) {
|
|
10
|
+
const docEsc = escapeForAppleScript(document);
|
|
11
|
+
const tableRef = table ? `table "${escapeForAppleScript(table)}"` : "table 1";
|
|
12
|
+
const sheetRef = sheet ? `sheet "${escapeForAppleScript(sheet)}"` : "sheet 1";
|
|
13
|
+
const colNum = colLetterToNum(column);
|
|
14
|
+
const script = `
|
|
15
|
+
tell application "Numbers"
|
|
16
|
+
tell ${tableRef} of ${sheetRef} of document "${docEsc}"
|
|
17
|
+
sort by column ${colNum} direction ${direction}
|
|
18
|
+
end tell
|
|
19
|
+
end tell`;
|
|
20
|
+
await runAppleScript(script);
|
|
21
|
+
return { success: true, document, column, direction };
|
|
22
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { runAppleScript, escapeForAppleScript } from "@mailappmcp/shared";
|
|
2
|
+
export async function unmergeCells(document, range, sheet, table) {
|
|
3
|
+
const docEsc = escapeForAppleScript(document);
|
|
4
|
+
const tableRef = table ? `table "${escapeForAppleScript(table)}"` : "table 1";
|
|
5
|
+
const sheetRef = sheet ? `sheet "${escapeForAppleScript(sheet)}"` : "sheet 1";
|
|
6
|
+
const rangeEsc = escapeForAppleScript(range);
|
|
7
|
+
const script = `
|
|
8
|
+
tell application "Numbers"
|
|
9
|
+
tell ${tableRef} of ${sheetRef} of document "${docEsc}"
|
|
10
|
+
unmerge range "${rangeEsc}"
|
|
11
|
+
end tell
|
|
12
|
+
end tell`;
|
|
13
|
+
await runAppleScript(script);
|
|
14
|
+
return { success: true, document, range };
|
|
15
|
+
}
|