@l22-io/orchard-mcp 0.3.1
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/LICENSE +21 -0
- package/README.md +178 -0
- package/build/bridge.d.ts +15 -0
- package/build/bridge.js +122 -0
- package/build/bridge.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +28 -0
- package/build/index.js.map +1 -0
- package/build/setup.d.ts +1 -0
- package/build/setup.js +362 -0
- package/build/setup.js.map +1 -0
- package/build/tools/calendar.d.ts +2 -0
- package/build/tools/calendar.js +61 -0
- package/build/tools/calendar.js.map +1 -0
- package/build/tools/files.d.ts +2 -0
- package/build/tools/files.js +131 -0
- package/build/tools/files.js.map +1 -0
- package/build/tools/mail.d.ts +2 -0
- package/build/tools/mail.js +152 -0
- package/build/tools/mail.js.map +1 -0
- package/build/tools/reminders.d.ts +2 -0
- package/build/tools/reminders.js +114 -0
- package/build/tools/reminders.js.map +1 -0
- package/build/tools/system.d.ts +2 -0
- package/build/tools/system.js +10 -0
- package/build/tools/system.js.map +1 -0
- package/package.json +63 -0
- package/scripts/postinstall.sh +21 -0
- package/swift/.build/AppleBridge.app/Contents/Info.plist +16 -0
- package/swift/.build/AppleBridge.app/Contents/MacOS/apple-bridge +0 -0
- package/swift/.build/AppleBridge.app/Contents/_CodeSignature/CodeResources +115 -0
- package/swift/Sources/AppleBridge/Info.plist +16 -0
package/build/setup.js
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { resolve, dirname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { createInterface } from "node:readline";
|
|
6
|
+
import { mkdirSync, copyFileSync, existsSync, readFileSync, unlinkSync, } from "node:fs";
|
|
7
|
+
import { randomUUID } from "node:crypto";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
const execFileAsync = promisify(execFile);
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const projectRoot = resolve(__dirname, "..");
|
|
12
|
+
const swiftDir = resolve(projectRoot, "swift");
|
|
13
|
+
const bridgeBin = resolve(swiftDir, ".build", "release", "apple-bridge");
|
|
14
|
+
const appBundle = resolve(swiftDir, ".build", "AppleBridge.app");
|
|
15
|
+
const infoPlist = resolve(swiftDir, "Sources", "AppleBridge", "Info.plist");
|
|
16
|
+
function log(msg) {
|
|
17
|
+
process.stdout.write(` ${msg}\n`);
|
|
18
|
+
}
|
|
19
|
+
function step(n, total, title) {
|
|
20
|
+
process.stdout.write(`\n[${n}/${total}] ${title}\n`);
|
|
21
|
+
}
|
|
22
|
+
async function ask(question) {
|
|
23
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
24
|
+
return new Promise((res) => {
|
|
25
|
+
rl.question(` ${question} `, (answer) => {
|
|
26
|
+
rl.close();
|
|
27
|
+
res(answer.trim());
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async function run(cmd, args, opts) {
|
|
32
|
+
return execFileAsync(cmd, args, {
|
|
33
|
+
timeout: opts?.timeout ?? 120_000,
|
|
34
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
35
|
+
cwd: opts?.cwd,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export async function runSetup(nonInteractive) {
|
|
39
|
+
const total = 6;
|
|
40
|
+
process.stdout.write("\norchard-mcp setup\n================\n");
|
|
41
|
+
const ok1 = await checkPrereqs(total);
|
|
42
|
+
if (!ok1)
|
|
43
|
+
process.exit(1);
|
|
44
|
+
const ok2 = await buildSwift(total);
|
|
45
|
+
if (!ok2)
|
|
46
|
+
process.exit(1);
|
|
47
|
+
await buildAppBundle(total);
|
|
48
|
+
await requestPermissions(total, nonInteractive);
|
|
49
|
+
await printClientConfig(total);
|
|
50
|
+
await validate(total);
|
|
51
|
+
}
|
|
52
|
+
// Step 1: Prerequisites
|
|
53
|
+
async function checkPrereqs(total) {
|
|
54
|
+
step(1, total, "Checking prerequisites...");
|
|
55
|
+
let ok = true;
|
|
56
|
+
try {
|
|
57
|
+
const { stdout } = await run("sw_vers", ["-productVersion"]);
|
|
58
|
+
const ver = stdout.trim();
|
|
59
|
+
const major = parseInt(ver.split(".")[0], 10);
|
|
60
|
+
if (major >= 14) {
|
|
61
|
+
log(`macOS ${ver} -- ok`);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
log(`macOS ${ver} -- requires 14+ (Sonoma or later)`);
|
|
65
|
+
ok = false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
log("Could not detect macOS version");
|
|
70
|
+
ok = false;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const { stdout } = await run("swift", ["--version"]);
|
|
74
|
+
const match = stdout.match(/Swift version ([\d.]+)/);
|
|
75
|
+
const ver = match ? match[1] : "unknown";
|
|
76
|
+
log(`Swift ${ver} -- ok`);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
log("Swift not found -- install Xcode Command Line Tools: xcode-select --install");
|
|
80
|
+
ok = false;
|
|
81
|
+
}
|
|
82
|
+
const nodeVer = process.version;
|
|
83
|
+
const nodeMajor = parseInt(nodeVer.slice(1).split(".")[0], 10);
|
|
84
|
+
if (nodeMajor >= 18) {
|
|
85
|
+
log(`Node.js ${nodeVer} -- ok`);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
log(`Node.js ${nodeVer} -- requires 18+`);
|
|
89
|
+
ok = false;
|
|
90
|
+
}
|
|
91
|
+
return ok;
|
|
92
|
+
}
|
|
93
|
+
// Step 2: Build Swift
|
|
94
|
+
async function buildSwift(total) {
|
|
95
|
+
step(2, total, "Building Swift binary...");
|
|
96
|
+
if (existsSync(bridgeBin)) {
|
|
97
|
+
log("Binary already exists -- skipping build.");
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
await run("swift", [
|
|
102
|
+
"build",
|
|
103
|
+
"-c",
|
|
104
|
+
"release",
|
|
105
|
+
"-Xlinker",
|
|
106
|
+
"-sectcreate",
|
|
107
|
+
"-Xlinker",
|
|
108
|
+
"__TEXT",
|
|
109
|
+
"-Xlinker",
|
|
110
|
+
"__info_plist",
|
|
111
|
+
"-Xlinker",
|
|
112
|
+
"Sources/AppleBridge/Info.plist",
|
|
113
|
+
], { cwd: swiftDir, timeout: 300_000 });
|
|
114
|
+
log("swift build -c release -- ok");
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
119
|
+
log(`Swift build failed: ${msg}`);
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Step 3: Build .app bundle
|
|
124
|
+
async function buildAppBundle(total) {
|
|
125
|
+
step(3, total, "Building AppleBridge.app bundle...");
|
|
126
|
+
const macosDir = resolve(appBundle, "Contents", "MacOS");
|
|
127
|
+
const binaryInApp = resolve(macosDir, "apple-bridge");
|
|
128
|
+
if (existsSync(binaryInApp)) {
|
|
129
|
+
log("App bundle already exists -- skipping build.");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
mkdirSync(macosDir, { recursive: true });
|
|
133
|
+
copyFileSync(bridgeBin, resolve(macosDir, "apple-bridge"));
|
|
134
|
+
copyFileSync(infoPlist, resolve(appBundle, "Contents", "Info.plist"));
|
|
135
|
+
try {
|
|
136
|
+
await run("codesign", ["--force", "--sign", "-", appBundle]);
|
|
137
|
+
log("Created and signed -- ok");
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
141
|
+
log(`codesign failed: ${msg}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Step 4: TCC permissions
|
|
145
|
+
async function requestPermissions(total, nonInteractive) {
|
|
146
|
+
step(4, total, "Requesting permissions...");
|
|
147
|
+
// Helper: parse doctor output
|
|
148
|
+
async function getDoctor() {
|
|
149
|
+
try {
|
|
150
|
+
const { stdout } = await run(bridgeBin, ["doctor"]);
|
|
151
|
+
const parsed = JSON.parse(stdout);
|
|
152
|
+
return parsed.data ?? null;
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Helper: run command via .app bundle, return parsed JSON or null
|
|
159
|
+
async function runViaApp(args) {
|
|
160
|
+
const outputFile = resolve(tmpdir(), `apple-bridge-${randomUUID()}.json`);
|
|
161
|
+
try {
|
|
162
|
+
const child = spawn("open", [
|
|
163
|
+
"-W",
|
|
164
|
+
"-n",
|
|
165
|
+
"-a",
|
|
166
|
+
appBundle,
|
|
167
|
+
"--args",
|
|
168
|
+
...args,
|
|
169
|
+
"--output",
|
|
170
|
+
outputFile,
|
|
171
|
+
]);
|
|
172
|
+
await new Promise((res) => {
|
|
173
|
+
child.on("close", () => res());
|
|
174
|
+
child.on("error", () => res());
|
|
175
|
+
setTimeout(() => {
|
|
176
|
+
child.kill();
|
|
177
|
+
res();
|
|
178
|
+
}, 15_000);
|
|
179
|
+
});
|
|
180
|
+
if (existsSync(outputFile)) {
|
|
181
|
+
const data = JSON.parse(readFileSync(outputFile, "utf-8"));
|
|
182
|
+
try {
|
|
183
|
+
unlinkSync(outputFile);
|
|
184
|
+
}
|
|
185
|
+
catch { }
|
|
186
|
+
return data;
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
try {
|
|
192
|
+
unlinkSync(outputFile);
|
|
193
|
+
}
|
|
194
|
+
catch { }
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const doctor = await getDoctor();
|
|
199
|
+
// Calendar
|
|
200
|
+
if (doctor?.calendar?.granted) {
|
|
201
|
+
log("Calendar: fullAccess -- ok");
|
|
202
|
+
}
|
|
203
|
+
else if (nonInteractive) {
|
|
204
|
+
log("Calendar: not granted (run interactively to trigger prompt)");
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
log("Calendar: requesting access...");
|
|
208
|
+
try {
|
|
209
|
+
await run(bridgeBin, ["calendars"]);
|
|
210
|
+
}
|
|
211
|
+
catch { }
|
|
212
|
+
const d2 = await getDoctor();
|
|
213
|
+
if (d2?.calendar?.granted) {
|
|
214
|
+
log("Calendar: fullAccess -- ok");
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
log("Calendar: not granted -- open System Settings > Privacy & Security > Calendars");
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Reminders (needs .app bundle for TCC on Sequoia)
|
|
221
|
+
if (doctor?.reminders?.granted) {
|
|
222
|
+
log("Reminders: fullAccess -- ok");
|
|
223
|
+
}
|
|
224
|
+
else if (nonInteractive) {
|
|
225
|
+
log("Reminders: not granted (run interactively to trigger prompt)");
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
log("Reminders: requesting access via AppleBridge.app...");
|
|
229
|
+
log("Grant access in the dialog that appears.");
|
|
230
|
+
await runViaApp(["reminder-lists"]);
|
|
231
|
+
await ask("Press Enter after granting access...");
|
|
232
|
+
// Verify via .app bundle (direct binary won't have TCC on Sequoia)
|
|
233
|
+
const result = await runViaApp(["reminder-lists"]);
|
|
234
|
+
if (result?.status === "ok") {
|
|
235
|
+
log("Reminders: fullAccess -- ok");
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
log("Reminders: not granted -- open System Settings > Privacy & Security > Reminders");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Mail
|
|
242
|
+
if (doctor?.mail?.accessible) {
|
|
243
|
+
const count = doctor.mail.accountCount ?? 0;
|
|
244
|
+
log(`Mail: accessible (${count} accounts) -- ok`);
|
|
245
|
+
}
|
|
246
|
+
else if (nonInteractive) {
|
|
247
|
+
log("Mail: not accessible (run interactively to trigger prompt)");
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
log("Mail: requesting access (Mail.app must be running)...");
|
|
251
|
+
try {
|
|
252
|
+
await run(bridgeBin, ["mail-accounts"]);
|
|
253
|
+
}
|
|
254
|
+
catch { }
|
|
255
|
+
const d2 = await getDoctor();
|
|
256
|
+
if (d2?.mail?.accessible) {
|
|
257
|
+
log(`Mail: accessible (${d2.mail.accountCount} accounts) -- ok`);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
log("Mail: not accessible -- ensure Mail.app is running and grant Automation permission");
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Step 5: MCP client config
|
|
265
|
+
async function printClientConfig(total) {
|
|
266
|
+
step(5, total, "MCP client configuration");
|
|
267
|
+
const serverPath = resolve(projectRoot, "build", "index.js");
|
|
268
|
+
const warpExists = existsSync("/Applications/Warp.app");
|
|
269
|
+
if (warpExists) {
|
|
270
|
+
log("Warp detected. Add this MCP server in Warp settings:");
|
|
271
|
+
log(` Command: node`);
|
|
272
|
+
log(` Args: ${serverPath}`);
|
|
273
|
+
}
|
|
274
|
+
let claudeExists = false;
|
|
275
|
+
try {
|
|
276
|
+
await run("which", ["claude"]);
|
|
277
|
+
claudeExists = true;
|
|
278
|
+
}
|
|
279
|
+
catch { }
|
|
280
|
+
if (claudeExists) {
|
|
281
|
+
log("Claude Code detected. Run:");
|
|
282
|
+
log(` claude mcp add --scope user orchard -- node ${serverPath}`);
|
|
283
|
+
}
|
|
284
|
+
if (!warpExists && !claudeExists) {
|
|
285
|
+
log("No supported MCP clients detected (Warp, Claude Code).");
|
|
286
|
+
log("Generic MCP config:");
|
|
287
|
+
log(` Command: node`);
|
|
288
|
+
log(` Args: ${serverPath}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// Step 6: Validation
|
|
292
|
+
async function validate(total) {
|
|
293
|
+
step(6, total, "Validation");
|
|
294
|
+
try {
|
|
295
|
+
const { stdout } = await run(bridgeBin, ["doctor"]);
|
|
296
|
+
const doctor = JSON.parse(stdout);
|
|
297
|
+
const d = doctor.data;
|
|
298
|
+
if (d?.calendarSummary) {
|
|
299
|
+
log(`Calendar: ${d.calendarSummary.count} calendars across ${d.calendarSummary.accounts?.length ?? 0} accounts`);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
log("Calendar: no access");
|
|
303
|
+
}
|
|
304
|
+
// Reminders: try direct first, fall back to .app bundle
|
|
305
|
+
if (d?.remindersSummary && d.remindersSummary.count > 0) {
|
|
306
|
+
log(`Reminders: ${d.remindersSummary.count} lists`);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
const outputFile = resolve(tmpdir(), `apple-bridge-validate-${randomUUID()}.json`);
|
|
310
|
+
try {
|
|
311
|
+
const child = spawn("open", [
|
|
312
|
+
"-W",
|
|
313
|
+
"-n",
|
|
314
|
+
"-a",
|
|
315
|
+
appBundle,
|
|
316
|
+
"--args",
|
|
317
|
+
"reminder-lists",
|
|
318
|
+
"--output",
|
|
319
|
+
outputFile,
|
|
320
|
+
]);
|
|
321
|
+
await new Promise((res) => {
|
|
322
|
+
child.on("close", () => res());
|
|
323
|
+
child.on("error", () => res());
|
|
324
|
+
setTimeout(() => {
|
|
325
|
+
child.kill();
|
|
326
|
+
res();
|
|
327
|
+
}, 10_000);
|
|
328
|
+
});
|
|
329
|
+
if (existsSync(outputFile)) {
|
|
330
|
+
const data = JSON.parse(readFileSync(outputFile, "utf-8"));
|
|
331
|
+
unlinkSync(outputFile);
|
|
332
|
+
if (data.status === "ok" && Array.isArray(data.data)) {
|
|
333
|
+
const items = data.data.reduce((sum, l) => sum + (l.itemCount ?? 0), 0);
|
|
334
|
+
log(`Reminders: ${data.data.length} lists (${items.toLocaleString()} items)`);
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
log("Reminders: no access");
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
log("Reminders: no access");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
log("Reminders: no access");
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (d?.mail?.accessible) {
|
|
349
|
+
log(`Mail: ${d.mail.accountCount} accounts`);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
log("Mail: no access");
|
|
353
|
+
}
|
|
354
|
+
log("");
|
|
355
|
+
log("Ready to use.");
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
359
|
+
log(`Validation failed: ${msg}`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { bridgeData } from "../bridge.js";
|
|
3
|
+
export function registerCalendarTools(server) {
|
|
4
|
+
server.tool("calendar.list_calendars", "List all Apple Calendar calendars with account name, type, color, and read-only status.", {}, async () => {
|
|
5
|
+
const data = await bridgeData(["calendars"]);
|
|
6
|
+
return {
|
|
7
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
8
|
+
};
|
|
9
|
+
});
|
|
10
|
+
server.tool("calendar.list_events", "List calendar events in a date range. Recurring events are properly expanded. Optionally filter by calendar ID.", {
|
|
11
|
+
start: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe("Start date in ISO 8601 format (e.g. 2026-02-17 or 2026-02-17T00:00:00Z)"),
|
|
14
|
+
end: z
|
|
15
|
+
.string()
|
|
16
|
+
.describe("End date in ISO 8601 format"),
|
|
17
|
+
calendarId: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Optional calendar ID to filter by (from calendar.list_calendars)"),
|
|
21
|
+
}, async ({ start, end, calendarId }) => {
|
|
22
|
+
const args = ["events", "--start", start, "--end", end];
|
|
23
|
+
if (calendarId) {
|
|
24
|
+
args.push("--calendar", calendarId);
|
|
25
|
+
}
|
|
26
|
+
const data = await bridgeData(args);
|
|
27
|
+
return {
|
|
28
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
server.tool("calendar.today", "Get all calendar events for today across all calendars.", {}, async () => {
|
|
32
|
+
// Reason: Build today's date range in local timezone for the bridge.
|
|
33
|
+
const now = new Date();
|
|
34
|
+
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
35
|
+
const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
|
|
36
|
+
const start = startOfDay.toISOString();
|
|
37
|
+
const end = endOfDay.toISOString();
|
|
38
|
+
const data = await bridgeData(["events", "--start", start, "--end", end]);
|
|
39
|
+
return {
|
|
40
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
server.tool("calendar.search", "Search calendar events by title, notes, or location within a date range.", {
|
|
44
|
+
query: z.string().describe("Search term to match against event title, notes, or location"),
|
|
45
|
+
start: z.string().describe("Start date in ISO 8601 format"),
|
|
46
|
+
end: z.string().describe("End date in ISO 8601 format"),
|
|
47
|
+
}, async ({ query, start, end }) => {
|
|
48
|
+
const data = await bridgeData([
|
|
49
|
+
"search",
|
|
50
|
+
query,
|
|
51
|
+
"--start",
|
|
52
|
+
start,
|
|
53
|
+
"--end",
|
|
54
|
+
end,
|
|
55
|
+
]);
|
|
56
|
+
return {
|
|
57
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=calendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../src/tools/calendar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { bridgeData } from "../bridge.js";
|
|
3
|
+
export function registerFileTools(server) {
|
|
4
|
+
server.tool("files.list", "List directory contents with metadata (name, size, dates, type). Paths relative to home directory.", {
|
|
5
|
+
path: z
|
|
6
|
+
.string()
|
|
7
|
+
.optional()
|
|
8
|
+
.describe("Directory path relative to ~ (default: home directory)"),
|
|
9
|
+
recursive: z
|
|
10
|
+
.boolean()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("List recursively (default: false)"),
|
|
13
|
+
depth: z
|
|
14
|
+
.number()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Max recursion depth when recursive (default: 3)"),
|
|
17
|
+
}, async ({ path, recursive, depth }) => {
|
|
18
|
+
const args = ["file-list"];
|
|
19
|
+
if (path)
|
|
20
|
+
args.push("--path", path);
|
|
21
|
+
if (recursive)
|
|
22
|
+
args.push("--recursive");
|
|
23
|
+
if (depth !== undefined)
|
|
24
|
+
args.push("--depth", String(depth));
|
|
25
|
+
const data = await bridgeData(args);
|
|
26
|
+
return {
|
|
27
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
server.tool("files.info", "Get detailed metadata for a file or folder, including Spotlight attributes (content type, dimensions, authors, page count).", {
|
|
31
|
+
path: z
|
|
32
|
+
.string()
|
|
33
|
+
.describe("File path relative to ~ or absolute (must be under home directory)"),
|
|
34
|
+
}, async ({ path }) => {
|
|
35
|
+
const data = await bridgeData(["file-info", "--path", path]);
|
|
36
|
+
return {
|
|
37
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
server.tool("files.search", "Search files using macOS Spotlight. Searches file names and content across indexed volumes. Scoped to home directory.", {
|
|
41
|
+
query: z
|
|
42
|
+
.string()
|
|
43
|
+
.describe("Search query (Spotlight syntax, e.g. 'budget 2026' or 'kMDItemAuthor == \"John\"')"),
|
|
44
|
+
kind: z
|
|
45
|
+
.enum([
|
|
46
|
+
"folder",
|
|
47
|
+
"image",
|
|
48
|
+
"pdf",
|
|
49
|
+
"document",
|
|
50
|
+
"audio",
|
|
51
|
+
"video",
|
|
52
|
+
"presentation",
|
|
53
|
+
"spreadsheet",
|
|
54
|
+
])
|
|
55
|
+
.optional()
|
|
56
|
+
.describe("Filter by file kind"),
|
|
57
|
+
scope: z
|
|
58
|
+
.string()
|
|
59
|
+
.optional()
|
|
60
|
+
.describe("Subdirectory to search within (default: entire home directory)"),
|
|
61
|
+
}, async ({ query, kind, scope }) => {
|
|
62
|
+
const args = ["file-search", "--query", query];
|
|
63
|
+
if (kind)
|
|
64
|
+
args.push("--kind", kind);
|
|
65
|
+
if (scope)
|
|
66
|
+
args.push("--scope", scope);
|
|
67
|
+
const data = await bridgeData(args);
|
|
68
|
+
return {
|
|
69
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
server.tool("files.read", "Read and extract text from a file. Handles plain text, PDF (via PDFKit), images (via OCR), and documents (.docx, .rtf, .pages via textutil). Text capped at 1MB.", {
|
|
73
|
+
path: z
|
|
74
|
+
.string()
|
|
75
|
+
.describe("File path relative to ~ or absolute (must be under home directory)"),
|
|
76
|
+
}, async ({ path }) => {
|
|
77
|
+
const data = await bridgeData(["file-read", "--path", path]);
|
|
78
|
+
return {
|
|
79
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
server.tool("files.move", "Move or rename files and folders. Supports batch operations for mass renaming. All paths must be under home directory.", {
|
|
83
|
+
operations: z
|
|
84
|
+
.array(z.object({
|
|
85
|
+
source: z.string().describe("Source path"),
|
|
86
|
+
destination: z.string().describe("Destination path"),
|
|
87
|
+
}))
|
|
88
|
+
.describe("Array of move operations ({source, destination} pairs)"),
|
|
89
|
+
}, async ({ operations }) => {
|
|
90
|
+
const data = await bridgeData([
|
|
91
|
+
"file-move",
|
|
92
|
+
"--items",
|
|
93
|
+
JSON.stringify(operations),
|
|
94
|
+
]);
|
|
95
|
+
return {
|
|
96
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
server.tool("files.copy", "Copy a file or folder to a new location. Both paths must be under home directory.", {
|
|
100
|
+
source: z.string().describe("Source file or folder path"),
|
|
101
|
+
destination: z.string().describe("Destination path"),
|
|
102
|
+
}, async ({ source, destination }) => {
|
|
103
|
+
const data = await bridgeData([
|
|
104
|
+
"file-copy",
|
|
105
|
+
"--source",
|
|
106
|
+
source,
|
|
107
|
+
"--dest",
|
|
108
|
+
destination,
|
|
109
|
+
]);
|
|
110
|
+
return {
|
|
111
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
server.tool("files.create_folder", "Create a new directory with intermediate directories. Path must be under home directory.", {
|
|
115
|
+
path: z.string().describe("Directory path to create"),
|
|
116
|
+
}, async ({ path }) => {
|
|
117
|
+
const data = await bridgeData(["file-create-folder", "--path", path]);
|
|
118
|
+
return {
|
|
119
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
server.tool("files.trash", "Move a file or folder to the Trash (reversible delete). Path must be under home directory.", {
|
|
123
|
+
path: z.string().describe("File or folder path to move to Trash"),
|
|
124
|
+
}, async ({ path }) => {
|
|
125
|
+
const data = await bridgeData(["file-trash", "--path", path]);
|
|
126
|
+
return {
|
|
127
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/tools/files.ts"],"names":[],"mappings":"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"}
|