airmcp 1.0.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/LICENSE +21 -0
- package/README.md +645 -0
- package/dist/calendar/prompts.d.ts +2 -0
- package/dist/calendar/prompts.js +43 -0
- package/dist/calendar/prompts.js.map +1 -0
- package/dist/calendar/scripts.d.ts +20 -0
- package/dist/calendar/scripts.js +286 -0
- package/dist/calendar/scripts.js.map +1 -0
- package/dist/calendar/tools.d.ts +3 -0
- package/dist/calendar/tools.js +252 -0
- package/dist/calendar/tools.js.map +1 -0
- package/dist/cli/doctor.d.ts +7 -0
- package/dist/cli/doctor.js +157 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/init.d.ts +8 -0
- package/dist/cli/init.js +179 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/contacts/scripts.d.ts +22 -0
- package/dist/contacts/scripts.js +220 -0
- package/dist/contacts/scripts.js.map +1 -0
- package/dist/contacts/tools.d.ts +3 -0
- package/dist/contacts/tools.js +173 -0
- package/dist/contacts/tools.js.map +1 -0
- package/dist/cross/prompts.d.ts +2 -0
- package/dist/cross/prompts.js +802 -0
- package/dist/cross/prompts.js.map +1 -0
- package/dist/cross/tools.d.ts +7 -0
- package/dist/cross/tools.js +81 -0
- package/dist/cross/tools.js.map +1 -0
- package/dist/finder/scripts.d.ts +8 -0
- package/dist/finder/scripts.js +127 -0
- package/dist/finder/scripts.js.map +1 -0
- package/dist/finder/tools.d.ts +3 -0
- package/dist/finder/tools.js +134 -0
- package/dist/finder/tools.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +252 -0
- package/dist/index.js.map +1 -0
- package/dist/intelligence/tools.d.ts +3 -0
- package/dist/intelligence/tools.js +210 -0
- package/dist/intelligence/tools.js.map +1 -0
- package/dist/mail/scripts.d.ts +11 -0
- package/dist/mail/scripts.js +256 -0
- package/dist/mail/scripts.js.map +1 -0
- package/dist/mail/tools.d.ts +3 -0
- package/dist/mail/tools.js +188 -0
- package/dist/mail/tools.js.map +1 -0
- package/dist/maps/scripts.d.ts +6 -0
- package/dist/maps/scripts.js +61 -0
- package/dist/maps/scripts.js.map +1 -0
- package/dist/maps/tools.d.ts +3 -0
- package/dist/maps/tools.js +109 -0
- package/dist/maps/tools.js.map +1 -0
- package/dist/messages/scripts.d.ts +6 -0
- package/dist/messages/scripts.js +140 -0
- package/dist/messages/scripts.js.map +1 -0
- package/dist/messages/tools.d.ts +3 -0
- package/dist/messages/tools.js +105 -0
- package/dist/messages/tools.js.map +1 -0
- package/dist/music/scripts.d.ts +13 -0
- package/dist/music/scripts.js +218 -0
- package/dist/music/scripts.js.map +1 -0
- package/dist/music/tools.d.ts +3 -0
- package/dist/music/tools.js +205 -0
- package/dist/music/tools.js.map +1 -0
- package/dist/notes/prompts.d.ts +2 -0
- package/dist/notes/prompts.js +47 -0
- package/dist/notes/prompts.js.map +1 -0
- package/dist/notes/scripts.d.ts +15 -0
- package/dist/notes/scripts.js +348 -0
- package/dist/notes/scripts.js.map +1 -0
- package/dist/notes/tools.d.ts +3 -0
- package/dist/notes/tools.js +317 -0
- package/dist/notes/tools.js.map +1 -0
- package/dist/photos/scripts.d.ts +7 -0
- package/dist/photos/scripts.js +142 -0
- package/dist/photos/scripts.js.map +1 -0
- package/dist/photos/tools.d.ts +3 -0
- package/dist/photos/tools.js +158 -0
- package/dist/photos/tools.js.map +1 -0
- package/dist/podcasts/scripts.d.ts +6 -0
- package/dist/podcasts/scripts.js +116 -0
- package/dist/podcasts/scripts.js.map +1 -0
- package/dist/podcasts/tools.d.ts +3 -0
- package/dist/podcasts/tools.js +96 -0
- package/dist/podcasts/tools.js.map +1 -0
- package/dist/reminders/prompts.d.ts +2 -0
- package/dist/reminders/prompts.js +40 -0
- package/dist/reminders/prompts.js.map +1 -0
- package/dist/reminders/scripts.d.ts +21 -0
- package/dist/reminders/scripts.js +208 -0
- package/dist/reminders/scripts.js.map +1 -0
- package/dist/reminders/tools.d.ts +3 -0
- package/dist/reminders/tools.js +269 -0
- package/dist/reminders/tools.js.map +1 -0
- package/dist/safari/scripts.d.ts +12 -0
- package/dist/safari/scripts.js +203 -0
- package/dist/safari/scripts.js.map +1 -0
- package/dist/safari/tools.d.ts +3 -0
- package/dist/safari/tools.js +188 -0
- package/dist/safari/tools.js.map +1 -0
- package/dist/screen/scripts.d.ts +26 -0
- package/dist/screen/scripts.js +115 -0
- package/dist/screen/scripts.js.map +1 -0
- package/dist/screen/tools.d.ts +3 -0
- package/dist/screen/tools.js +168 -0
- package/dist/screen/tools.js.map +1 -0
- package/dist/semantic/embeddings.d.ts +12 -0
- package/dist/semantic/embeddings.js +101 -0
- package/dist/semantic/embeddings.js.map +1 -0
- package/dist/semantic/service.d.ts +68 -0
- package/dist/semantic/service.js +257 -0
- package/dist/semantic/service.js.map +1 -0
- package/dist/semantic/store.d.ts +56 -0
- package/dist/semantic/store.js +107 -0
- package/dist/semantic/store.js.map +1 -0
- package/dist/semantic/tools.d.ts +10 -0
- package/dist/semantic/tools.js +102 -0
- package/dist/semantic/tools.js.map +1 -0
- package/dist/shared/config.d.ts +41 -0
- package/dist/shared/config.js +152 -0
- package/dist/shared/config.js.map +1 -0
- package/dist/shared/esc.d.ts +10 -0
- package/dist/shared/esc.js +35 -0
- package/dist/shared/esc.js.map +1 -0
- package/dist/shared/hitl-guard.d.ts +8 -0
- package/dist/shared/hitl-guard.js +39 -0
- package/dist/shared/hitl-guard.js.map +1 -0
- package/dist/shared/hitl.d.ts +16 -0
- package/dist/shared/hitl.js +131 -0
- package/dist/shared/hitl.js.map +1 -0
- package/dist/shared/jxa.d.ts +1 -0
- package/dist/shared/jxa.js +52 -0
- package/dist/shared/jxa.js.map +1 -0
- package/dist/shared/modules.d.ts +2 -0
- package/dist/shared/modules.js +43 -0
- package/dist/shared/modules.js.map +1 -0
- package/dist/shared/prompt.d.ts +11 -0
- package/dist/shared/prompt.js +8 -0
- package/dist/shared/prompt.js.map +1 -0
- package/dist/shared/registry.d.ts +9 -0
- package/dist/shared/registry.js +2 -0
- package/dist/shared/registry.js.map +1 -0
- package/dist/shared/resources.d.ts +14 -0
- package/dist/shared/resources.js +222 -0
- package/dist/shared/resources.js.map +1 -0
- package/dist/shared/result.d.ts +23 -0
- package/dist/shared/result.js +19 -0
- package/dist/shared/result.js.map +1 -0
- package/dist/shared/setup.d.ts +3 -0
- package/dist/shared/setup.js +53 -0
- package/dist/shared/setup.js.map +1 -0
- package/dist/shared/share-guard.d.ts +30 -0
- package/dist/shared/share-guard.js +60 -0
- package/dist/shared/share-guard.js.map +1 -0
- package/dist/shared/swift.d.ts +2 -0
- package/dist/shared/swift.js +73 -0
- package/dist/shared/swift.js.map +1 -0
- package/dist/shortcuts/prompts.d.ts +2 -0
- package/dist/shortcuts/prompts.js +148 -0
- package/dist/shortcuts/prompts.js.map +1 -0
- package/dist/shortcuts/scripts.d.ts +10 -0
- package/dist/shortcuts/scripts.js +115 -0
- package/dist/shortcuts/scripts.js.map +1 -0
- package/dist/shortcuts/tools.d.ts +14 -0
- package/dist/shortcuts/tools.js +230 -0
- package/dist/shortcuts/tools.js.map +1 -0
- package/dist/system/scripts.d.ts +17 -0
- package/dist/system/scripts.js +257 -0
- package/dist/system/scripts.js.map +1 -0
- package/dist/system/tools.d.ts +3 -0
- package/dist/system/tools.js +333 -0
- package/dist/system/tools.js.map +1 -0
- package/dist/tv/scripts.d.ts +6 -0
- package/dist/tv/scripts.js +121 -0
- package/dist/tv/scripts.js.map +1 -0
- package/dist/tv/tools.d.ts +3 -0
- package/dist/tv/tools.js +95 -0
- package/dist/tv/tools.js.map +1 -0
- package/dist/ui/scripts.d.ts +24 -0
- package/dist/ui/scripts.js +345 -0
- package/dist/ui/scripts.js.map +1 -0
- package/dist/ui/tools.d.ts +3 -0
- package/dist/ui/tools.js +145 -0
- package/dist/ui/tools.js.map +1 -0
- package/package.json +101 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { userPrompt } from "../shared/prompt.js";
|
|
3
|
+
export function registerShortcutPrompts(server) {
|
|
4
|
+
server.prompt("shortcut-automation", {
|
|
5
|
+
goal: z.string().describe("The automation goal or workflow you want to achieve"),
|
|
6
|
+
input: z.string().optional().describe("Optional initial input data for the workflow"),
|
|
7
|
+
}, ({ goal, input }) => {
|
|
8
|
+
const inputCtx = input ? `\nInitial input data: "${input}"` : "";
|
|
9
|
+
return userPrompt("Guide for creating complex automation workflows by chaining multiple shortcuts.", `Build an automation workflow to achieve: "${goal}"${inputCtx}
|
|
10
|
+
|
|
11
|
+
Execute the following steps using AirMCP tools:
|
|
12
|
+
|
|
13
|
+
1. **Discover available shortcuts**:
|
|
14
|
+
- list_shortcuts to get all available Siri Shortcuts on this Mac
|
|
15
|
+
- search_shortcuts with keywords related to "${goal}" to find relevant shortcuts
|
|
16
|
+
- For each promising match, use get_shortcut_detail to understand what it does and what actions it contains
|
|
17
|
+
|
|
18
|
+
2. **Analyze and plan the workflow**:
|
|
19
|
+
- Identify which shortcuts can be chained together to accomplish the goal
|
|
20
|
+
- Determine the execution order based on input/output dependencies
|
|
21
|
+
- Note which shortcuts accept text input and which produce output
|
|
22
|
+
- Identify any gaps where no existing shortcut covers a needed step
|
|
23
|
+
- Present the proposed workflow plan to me for confirmation
|
|
24
|
+
|
|
25
|
+
3. **Execute the workflow**:
|
|
26
|
+
- Run each shortcut in sequence using run_shortcut with the appropriate name and input
|
|
27
|
+
- Pass the output of one shortcut as the input to the next when chaining
|
|
28
|
+
- If a shortcut fails, report the error and suggest alternatives
|
|
29
|
+
- Track the output at each step for the final summary
|
|
30
|
+
|
|
31
|
+
4. **Report results**:
|
|
32
|
+
- Show the output from each step in the chain
|
|
33
|
+
- Highlight any steps that produced unexpected results
|
|
34
|
+
- Suggest improvements or additional shortcuts that could enhance the workflow
|
|
35
|
+
- If a step failed, explain what went wrong and possible fixes
|
|
36
|
+
|
|
37
|
+
Important:
|
|
38
|
+
- Always use exact shortcut names from list_shortcuts or search_shortcuts — names must match exactly
|
|
39
|
+
- Some shortcuts may trigger UI prompts or require user interaction — warn me before running those
|
|
40
|
+
- Never assume a shortcut exists; always verify with search_shortcuts first
|
|
41
|
+
- Ask for confirmation before running shortcuts that perform destructive or irreversible actions`);
|
|
42
|
+
});
|
|
43
|
+
server.prompt("shortcut-discovery", {
|
|
44
|
+
category: z.string().optional().describe("Optional category or keyword to focus the discovery (e.g. 'productivity', 'media', 'text')"),
|
|
45
|
+
}, ({ category }) => {
|
|
46
|
+
const filterCtx = category
|
|
47
|
+
? `Focus on shortcuts related to "${category}".`
|
|
48
|
+
: "Cover all available shortcuts.";
|
|
49
|
+
return userPrompt("Help users find, understand, and explore their available Siri Shortcuts.", `Help me discover and understand my available Siri Shortcuts. ${filterCtx}
|
|
50
|
+
|
|
51
|
+
Execute the following steps using AirMCP tools:
|
|
52
|
+
|
|
53
|
+
1. **List all shortcuts**:
|
|
54
|
+
- list_shortcuts to get the complete list of Siri Shortcuts on this Mac
|
|
55
|
+
- Report the total count${category ? `\n - search_shortcuts(query: "${category}") to filter for the relevant category` : ""}
|
|
56
|
+
|
|
57
|
+
2. **Categorize shortcuts**:
|
|
58
|
+
- Group shortcuts by inferred purpose based on their names:
|
|
59
|
+
* Productivity (text processing, file operations, data conversion)
|
|
60
|
+
* Communication (messaging, email, sharing)
|
|
61
|
+
* Media (photos, music, video)
|
|
62
|
+
* System (settings, device control, automation)
|
|
63
|
+
* Developer (build, deploy, git, code)
|
|
64
|
+
* Custom/Other
|
|
65
|
+
- Present the categorized list clearly
|
|
66
|
+
|
|
67
|
+
3. **Deep-dive into interesting shortcuts**:
|
|
68
|
+
- For shortcuts with unclear names, use get_shortcut_detail to inspect their actions
|
|
69
|
+
- Identify which shortcuts accept input and what type
|
|
70
|
+
- Identify which shortcuts produce output
|
|
71
|
+
- Flag shortcuts that might interact with external services or perform system changes
|
|
72
|
+
|
|
73
|
+
4. **Provide recommendations**:
|
|
74
|
+
- Suggest useful shortcuts the user might not know they have
|
|
75
|
+
- Identify shortcuts that could be combined for powerful workflows
|
|
76
|
+
- Point out shortcuts that overlap in functionality
|
|
77
|
+
- Suggest common tasks that could be automated with the existing shortcuts
|
|
78
|
+
|
|
79
|
+
5. **Summary report**:
|
|
80
|
+
- Total shortcuts available
|
|
81
|
+
- Breakdown by category
|
|
82
|
+
- Top recommendations for daily use
|
|
83
|
+
- Potential workflow combinations
|
|
84
|
+
|
|
85
|
+
Important:
|
|
86
|
+
- Use get_shortcut_detail on shortcuts with ambiguous names to provide accurate descriptions
|
|
87
|
+
- Do not run any shortcuts during discovery — this is a read-only exploration
|
|
88
|
+
- If the list is very large, focus on the most useful categories first`);
|
|
89
|
+
});
|
|
90
|
+
server.prompt("shortcut-troubleshooting", {
|
|
91
|
+
shortcutName: z.string().describe("Name of the shortcut that is having issues"),
|
|
92
|
+
errorDescription: z.string().optional().describe("Description of the error or unexpected behavior"),
|
|
93
|
+
}, ({ shortcutName, errorDescription }) => {
|
|
94
|
+
const errorCtx = errorDescription
|
|
95
|
+
? `\nReported issue: "${errorDescription}"`
|
|
96
|
+
: "";
|
|
97
|
+
return userPrompt("Diagnose and fix shortcut execution issues.", `Troubleshoot the Siri Shortcut "${shortcutName}".${errorCtx}
|
|
98
|
+
|
|
99
|
+
Execute the following steps using AirMCP tools:
|
|
100
|
+
|
|
101
|
+
1. **Verify the shortcut exists**:
|
|
102
|
+
- search_shortcuts(query: "${shortcutName}") to find the shortcut
|
|
103
|
+
- If not found, list_shortcuts to show all available shortcuts and suggest the closest match
|
|
104
|
+
- Confirm the exact name (names are case-sensitive and must match exactly)
|
|
105
|
+
|
|
106
|
+
2. **Inspect the shortcut**:
|
|
107
|
+
- get_shortcut_detail(name: "${shortcutName}") to examine its actions and structure
|
|
108
|
+
- Identify what the shortcut is designed to do
|
|
109
|
+
- Check what input it expects (if any)
|
|
110
|
+
- Identify actions that depend on external services, apps, or permissions
|
|
111
|
+
|
|
112
|
+
3. **Test execution**:
|
|
113
|
+
- run_shortcut(name: "${shortcutName}") with no input to test basic execution
|
|
114
|
+
- If the shortcut expects input, run_shortcut with a simple test input
|
|
115
|
+
- Capture and analyze any error messages from the output
|
|
116
|
+
|
|
117
|
+
4. **Diagnose the issue**:
|
|
118
|
+
Based on the inspection and test results, check for these common problems:
|
|
119
|
+
- **Name mismatch**: The name used doesn't exactly match the shortcut name
|
|
120
|
+
- **Missing input**: The shortcut requires input but none was provided
|
|
121
|
+
- **Wrong input type**: The shortcut expects a specific input format
|
|
122
|
+
- **Permission issues**: The shortcut needs permissions that haven't been granted
|
|
123
|
+
- **App dependency**: The shortcut relies on an app that isn't installed or available
|
|
124
|
+
- **Network dependency**: The shortcut needs internet access for an API or web request
|
|
125
|
+
- **UI interaction required**: The shortcut triggers a dialog that blocks automation
|
|
126
|
+
- **Timeout**: The shortcut takes too long to complete via CLI
|
|
127
|
+
|
|
128
|
+
5. **Provide solutions**:
|
|
129
|
+
- Explain the diagnosed root cause clearly
|
|
130
|
+
- Suggest specific fixes:
|
|
131
|
+
* Correct name to use with run_shortcut
|
|
132
|
+
* Required input format and example
|
|
133
|
+
* Permission steps to resolve access issues
|
|
134
|
+
* Alternative shortcuts that accomplish the same goal
|
|
135
|
+
- If the shortcut cannot be fixed via MCP, explain what manual steps are needed in the Shortcuts app
|
|
136
|
+
|
|
137
|
+
6. **Verification**:
|
|
138
|
+
- After applying fixes, re-run the shortcut to confirm it works
|
|
139
|
+
- Show the successful output
|
|
140
|
+
|
|
141
|
+
Important:
|
|
142
|
+
- Some shortcuts will trigger UI prompts — warn me before running them
|
|
143
|
+
- If a shortcut consistently fails, it may need to be edited in the Shortcuts app directly
|
|
144
|
+
- Report the exact error output for accurate diagnosis
|
|
145
|
+
- Do not modify or delete any shortcuts — only inspect and run them`);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/shortcuts/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,MAAM,CACX,qBAAqB,EACrB;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;QAChF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;KACtF,EACD,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;QAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,0BAA0B,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,OAAO,UAAU,CACf,iFAAiF,EACjF,6CAA6C,IAAI,IAAI,QAAQ;;;;;;kDAMnB,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;iGA0B2C,CAC1F,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,oBAAoB,EACpB;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4FAA4F,CAAC;KACvI,EACD,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;QACf,MAAM,SAAS,GAAG,QAAQ;YACxB,CAAC,CAAC,kCAAkC,QAAQ,IAAI;YAChD,CAAC,CAAC,gCAAgC,CAAC;QACrC,OAAO,UAAU,CACf,0EAA0E,EAC1E,gEAAgE,SAAS;;;;;;6BAMpD,QAAQ,CAAC,CAAC,CAAC,mCAAmC,QAAQ,wCAAwC,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEAiCzD,CAChE,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,MAAM,CACX,0BAA0B,EAC1B;QACE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;QAC/E,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;KACpG,EACD,CAAC,EAAE,YAAY,EAAE,gBAAgB,EAAE,EAAE,EAAE;QACrC,MAAM,QAAQ,GAAG,gBAAgB;YAC/B,CAAC,CAAC,sBAAsB,gBAAgB,GAAG;YAC3C,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,UAAU,CACf,6CAA6C,EAC7C,mCAAmC,YAAY,KAAK,QAAQ;;;;;gCAKpC,YAAY;;;;;kCAKV,YAAY;;;;;;2BAMnB,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oEAgC6B,CAC7D,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function listShortcutsScript(): string;
|
|
2
|
+
export declare function runShortcutScript(name: string, input?: string): string;
|
|
3
|
+
export declare function searchShortcutsScript(query: string): string;
|
|
4
|
+
export declare function getShortcutDetailScript(name: string): string;
|
|
5
|
+
export declare function deleteShortcutScript(name: string): string;
|
|
6
|
+
export declare function exportShortcutScript(name: string, outputPath: string): string;
|
|
7
|
+
export declare function importShortcutScript(filePath: string): string;
|
|
8
|
+
export declare function duplicateShortcutScript(name: string, newName: string): string;
|
|
9
|
+
export declare function editShortcutScript(name: string): string;
|
|
10
|
+
export declare function createShortcutScript(name: string): string;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// JXA scripts for macOS Shortcuts automation.
|
|
2
|
+
import { esc, escJxaShell } from "../shared/esc.js";
|
|
3
|
+
export function listShortcutsScript() {
|
|
4
|
+
return `
|
|
5
|
+
const app = Application.currentApplication();
|
|
6
|
+
app.includeStandardAdditions = true;
|
|
7
|
+
const output = app.doShellScript('shortcuts list');
|
|
8
|
+
const names = output.split('\\n').filter(n => n.length > 0);
|
|
9
|
+
JSON.stringify({total: names.length, shortcuts: names});
|
|
10
|
+
`;
|
|
11
|
+
}
|
|
12
|
+
export function runShortcutScript(name, input) {
|
|
13
|
+
const inputPart = input !== undefined
|
|
14
|
+
? ` --input-type text --input "${escJxaShell(input)}"`
|
|
15
|
+
: "";
|
|
16
|
+
return `
|
|
17
|
+
const app = Application.currentApplication();
|
|
18
|
+
app.includeStandardAdditions = true;
|
|
19
|
+
const output = app.doShellScript('shortcuts run "${escJxaShell(name)}"${inputPart}');
|
|
20
|
+
JSON.stringify({shortcut: '${esc(name)}', output: output});
|
|
21
|
+
`;
|
|
22
|
+
}
|
|
23
|
+
export function searchShortcutsScript(query) {
|
|
24
|
+
return `
|
|
25
|
+
const app = Application.currentApplication();
|
|
26
|
+
app.includeStandardAdditions = true;
|
|
27
|
+
const output = app.doShellScript('shortcuts list');
|
|
28
|
+
const names = output.split('\\n').filter(n => n.length > 0);
|
|
29
|
+
const q = '${esc(query)}'.toLowerCase();
|
|
30
|
+
const matches = names.filter(n => n.toLowerCase().includes(q));
|
|
31
|
+
JSON.stringify({total: matches.length, shortcuts: matches});
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
export function getShortcutDetailScript(name) {
|
|
35
|
+
return `
|
|
36
|
+
const app = Application.currentApplication();
|
|
37
|
+
app.includeStandardAdditions = true;
|
|
38
|
+
let actions = '';
|
|
39
|
+
try {
|
|
40
|
+
actions = app.doShellScript('shortcuts view "${escJxaShell(name)}" 2>&1 || true');
|
|
41
|
+
} catch(e) {
|
|
42
|
+
actions = 'Details not available';
|
|
43
|
+
}
|
|
44
|
+
JSON.stringify({shortcut: '${esc(name)}', detail: actions});
|
|
45
|
+
`;
|
|
46
|
+
}
|
|
47
|
+
export function deleteShortcutScript(name) {
|
|
48
|
+
return `
|
|
49
|
+
const app = Application.currentApplication();
|
|
50
|
+
app.includeStandardAdditions = true;
|
|
51
|
+
app.doShellScript('shortcuts delete "${escJxaShell(name)}"');
|
|
52
|
+
JSON.stringify({deleted: '${esc(name)}', success: true});
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
export function exportShortcutScript(name, outputPath) {
|
|
56
|
+
return `
|
|
57
|
+
const app = Application.currentApplication();
|
|
58
|
+
app.includeStandardAdditions = true;
|
|
59
|
+
app.doShellScript('shortcuts export "${escJxaShell(name)}" -o "${escJxaShell(outputPath)}"');
|
|
60
|
+
JSON.stringify({shortcut: '${esc(name)}', exportedTo: '${esc(outputPath)}', success: true});
|
|
61
|
+
`;
|
|
62
|
+
}
|
|
63
|
+
export function importShortcutScript(filePath) {
|
|
64
|
+
return `
|
|
65
|
+
const app = Application.currentApplication();
|
|
66
|
+
app.includeStandardAdditions = true;
|
|
67
|
+
app.doShellScript('shortcuts import "${escJxaShell(filePath)}"');
|
|
68
|
+
JSON.stringify({imported: '${esc(filePath)}', success: true});
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
71
|
+
export function duplicateShortcutScript(name, newName) {
|
|
72
|
+
const safeName = escJxaShell(newName).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
73
|
+
return `
|
|
74
|
+
const app = Application.currentApplication();
|
|
75
|
+
app.includeStandardAdditions = true;
|
|
76
|
+
app.doShellScript('shortcuts export "${escJxaShell(name)}" -o "/tmp/${safeName}.shortcut" && shortcuts import "/tmp/${safeName}.shortcut"');
|
|
77
|
+
app.doShellScript('rm -f "/tmp/${safeName}.shortcut"');
|
|
78
|
+
JSON.stringify({original: '${esc(name)}', duplicate: '${esc(newName)}', success: true});
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
export function editShortcutScript(name) {
|
|
82
|
+
return `
|
|
83
|
+
const app = Application.currentApplication();
|
|
84
|
+
app.includeStandardAdditions = true;
|
|
85
|
+
const se = Application('System Events');
|
|
86
|
+
const shortcuts = Application('Shortcuts');
|
|
87
|
+
shortcuts.activate();
|
|
88
|
+
delay(1);
|
|
89
|
+
se.keystroke('f', {using: 'command down'});
|
|
90
|
+
delay(0.5);
|
|
91
|
+
se.keystroke('${esc(name)}');
|
|
92
|
+
delay(1);
|
|
93
|
+
se.keyCode(36);
|
|
94
|
+
delay(0.5);
|
|
95
|
+
JSON.stringify({shortcut: '${esc(name)}', success: true, note: 'Opened shortcut in Shortcuts app for editing. Use the Shortcuts app UI to make changes.'});
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
export function createShortcutScript(name) {
|
|
99
|
+
return `
|
|
100
|
+
const app = Application.currentApplication();
|
|
101
|
+
app.includeStandardAdditions = true;
|
|
102
|
+
const se = Application('System Events');
|
|
103
|
+
const shortcuts = Application('Shortcuts');
|
|
104
|
+
shortcuts.activate();
|
|
105
|
+
delay(1);
|
|
106
|
+
se.keystroke('n', {using: 'command down'});
|
|
107
|
+
delay(1);
|
|
108
|
+
se.keystroke('${esc(name)}');
|
|
109
|
+
delay(0.5);
|
|
110
|
+
se.keyCode(36);
|
|
111
|
+
delay(0.5);
|
|
112
|
+
JSON.stringify({created: '${esc(name)}', success: true, note: 'Shortcut created via Shortcuts app UI automation. Open Shortcuts app to add actions.'});
|
|
113
|
+
`;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=scripts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scripts.js","sourceRoot":"","sources":["../../src/shortcuts/scripts.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAE9C,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,UAAU,mBAAmB;IACjC,OAAO;;;;;;GAMN,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,KAAc;IAC5D,MAAM,SAAS,GAAG,KAAK,KAAK,SAAS;QACnC,CAAC,CAAC,+BAA+B,WAAW,CAAC,KAAK,CAAC,GAAG;QACtD,CAAC,CAAC,EAAE,CAAC;IACP,OAAO;;;uDAG8C,WAAW,CAAC,IAAI,CAAC,IAAI,SAAS;iCACpD,GAAG,CAAC,IAAI,CAAC;GACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,OAAO;;;;;iBAKQ,GAAG,CAAC,KAAK,CAAC;;;GAGxB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO;;;;;qDAK4C,WAAW,CAAC,IAAI,CAAC;;;;iCAIrC,GAAG,CAAC,IAAI,CAAC;GACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO;;;2CAGkC,WAAW,CAAC,IAAI,CAAC;gCAC5B,GAAG,CAAC,IAAI,CAAC;GACtC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,UAAkB;IACnE,OAAO;;;2CAGkC,WAAW,CAAC,IAAI,CAAC,SAAS,WAAW,CAAC,UAAU,CAAC;iCAC3D,GAAG,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,UAAU,CAAC;GACzE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,OAAO;;;2CAGkC,WAAW,CAAC,QAAQ,CAAC;iCAC/B,GAAG,CAAC,QAAQ,CAAC;GAC3C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,OAAe;IACnE,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;IACtE,OAAO;;;2CAGkC,WAAW,CAAC,IAAI,CAAC,cAAc,QAAQ,wCAAwC,QAAQ;qCAC7F,QAAQ;iCACZ,GAAG,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAC,OAAO,CAAC;GACrE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO;;;;;;;;;oBASW,GAAG,CAAC,IAAI,CAAC;;;;iCAII,GAAG,CAAC,IAAI,CAAC;GACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO;;;;;;;;;oBASW,GAAG,CAAC,IAAI,CAAC;;;;gCAIG,GAAG,CAAC,IAAI,CAAC;GACtC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { AirMcpConfig } from "../shared/config.js";
|
|
3
|
+
/**
|
|
4
|
+
* Sanitize a shortcut name into a valid MCP tool name.
|
|
5
|
+
* MCP tool names must be alphanumeric + underscores, no spaces.
|
|
6
|
+
* Returns empty string if the name sanitizes to nothing meaningful.
|
|
7
|
+
*/
|
|
8
|
+
export declare function sanitizeToolName(name: string): string;
|
|
9
|
+
export declare function registerShortcutsTools(server: McpServer, _config: AirMcpConfig): void;
|
|
10
|
+
/**
|
|
11
|
+
* Discover user's Siri Shortcuts at startup and register each as an individual MCP tool.
|
|
12
|
+
* Returns the number of dynamic tools registered. Gracefully returns 0 on failure.
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerDynamicShortcutTools(server: McpServer): Promise<number>;
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
import { runJxa } from "../shared/jxa.js";
|
|
5
|
+
import { ok, toolError } from "../shared/result.js";
|
|
6
|
+
import { listShortcutsScript, runShortcutScript, searchShortcutsScript, getShortcutDetailScript, deleteShortcutScript, exportShortcutScript, importShortcutScript, createShortcutScript, duplicateShortcutScript, editShortcutScript, } from "./scripts.js";
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
const MAX_DYNAMIC_SHORTCUTS = 50;
|
|
9
|
+
/**
|
|
10
|
+
* Sanitize a shortcut name into a valid MCP tool name.
|
|
11
|
+
* MCP tool names must be alphanumeric + underscores, no spaces.
|
|
12
|
+
* Returns empty string if the name sanitizes to nothing meaningful.
|
|
13
|
+
*/
|
|
14
|
+
export function sanitizeToolName(name) {
|
|
15
|
+
const sanitized = name
|
|
16
|
+
.toLowerCase()
|
|
17
|
+
.replace(/[^a-z0-9]+/g, "_")
|
|
18
|
+
.replace(/^_|_$/g, "");
|
|
19
|
+
if (!sanitized)
|
|
20
|
+
return "";
|
|
21
|
+
return `shortcut_${sanitized}`;
|
|
22
|
+
}
|
|
23
|
+
export function registerShortcutsTools(server, _config) {
|
|
24
|
+
server.registerTool("list_shortcuts", {
|
|
25
|
+
title: "List Shortcuts",
|
|
26
|
+
description: "List all available Siri Shortcuts on this Mac.",
|
|
27
|
+
inputSchema: {},
|
|
28
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
29
|
+
}, async () => {
|
|
30
|
+
try {
|
|
31
|
+
return ok(await runJxa(listShortcutsScript()));
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
return toolError("list shortcuts", e);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
server.registerTool("run_shortcut", {
|
|
38
|
+
title: "Run Shortcut",
|
|
39
|
+
description: "Run a Siri Shortcut by name. Optionally provide text input. Returns the shortcut's output. Note: shortcuts may trigger UI prompts or perform system actions.",
|
|
40
|
+
inputSchema: {
|
|
41
|
+
name: z.string().describe("Shortcut name (exact match)"),
|
|
42
|
+
input: z.string().optional().describe("Optional text input for the shortcut"),
|
|
43
|
+
},
|
|
44
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
45
|
+
}, async ({ name, input }) => {
|
|
46
|
+
try {
|
|
47
|
+
return ok(await runJxa(runShortcutScript(name, input)));
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
return toolError("run shortcut", e);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
server.registerTool("search_shortcuts", {
|
|
54
|
+
title: "Search Shortcuts",
|
|
55
|
+
description: "Search Siri Shortcuts by name keyword.",
|
|
56
|
+
inputSchema: {
|
|
57
|
+
query: z.string().describe("Search keyword to match against shortcut names"),
|
|
58
|
+
},
|
|
59
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
60
|
+
}, async ({ query }) => {
|
|
61
|
+
try {
|
|
62
|
+
return ok(await runJxa(searchShortcutsScript(query)));
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
return toolError("search shortcuts", e);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
server.registerTool("get_shortcut_detail", {
|
|
69
|
+
title: "Get Shortcut Detail",
|
|
70
|
+
description: "Get details about a Siri Shortcut including its actions.",
|
|
71
|
+
inputSchema: {
|
|
72
|
+
name: z.string().describe("Shortcut name (exact match)"),
|
|
73
|
+
},
|
|
74
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
75
|
+
}, async ({ name }) => {
|
|
76
|
+
try {
|
|
77
|
+
return ok(await runJxa(getShortcutDetailScript(name)));
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
return toolError("get shortcut detail", e);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
server.registerTool("create_shortcut", {
|
|
84
|
+
title: "Create Shortcut",
|
|
85
|
+
description: "Create a new Siri Shortcut by name. Uses UI automation to open the Shortcuts app and create a new empty shortcut. The shortcut must be further configured in the Shortcuts app.",
|
|
86
|
+
inputSchema: {
|
|
87
|
+
name: z.string().describe("Name for the new shortcut"),
|
|
88
|
+
},
|
|
89
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
90
|
+
}, async ({ name }) => {
|
|
91
|
+
try {
|
|
92
|
+
return ok(await runJxa(createShortcutScript(name)));
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
return toolError("create shortcut", e);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
server.registerTool("delete_shortcut", {
|
|
99
|
+
title: "Delete Shortcut",
|
|
100
|
+
description: "Delete a Siri Shortcut by name. Uses the macOS shortcuts CLI (macOS 13+). This action is permanent and cannot be undone.",
|
|
101
|
+
inputSchema: {
|
|
102
|
+
name: z.string().describe("Shortcut name to delete (exact match)"),
|
|
103
|
+
},
|
|
104
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
|
|
105
|
+
}, async ({ name }) => {
|
|
106
|
+
try {
|
|
107
|
+
return ok(await runJxa(deleteShortcutScript(name)));
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
return toolError("delete shortcut", e);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
server.registerTool("export_shortcut", {
|
|
114
|
+
title: "Export Shortcut",
|
|
115
|
+
description: "Export a Siri Shortcut to a .shortcut file. Uses the macOS shortcuts CLI to save the shortcut to the specified output path.",
|
|
116
|
+
inputSchema: {
|
|
117
|
+
name: z.string().describe("Shortcut name to export (exact match)"),
|
|
118
|
+
outputPath: z.string().describe("File path to export the .shortcut file to (e.g. ~/Desktop/MyShortcut.shortcut)"),
|
|
119
|
+
},
|
|
120
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
121
|
+
}, async ({ name, outputPath }) => {
|
|
122
|
+
try {
|
|
123
|
+
return ok(await runJxa(exportShortcutScript(name, outputPath)));
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
return toolError("export shortcut", e);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
server.registerTool("import_shortcut", {
|
|
130
|
+
title: "Import Shortcut",
|
|
131
|
+
description: "Import a .shortcut file into Siri Shortcuts. Uses the macOS shortcuts CLI to import the shortcut from the specified file path.",
|
|
132
|
+
inputSchema: {
|
|
133
|
+
filePath: z.string().describe("Path to the .shortcut file to import"),
|
|
134
|
+
},
|
|
135
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
136
|
+
}, async ({ filePath }) => {
|
|
137
|
+
try {
|
|
138
|
+
return ok(await runJxa(importShortcutScript(filePath)));
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
return toolError("import shortcut", e);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
server.registerTool("duplicate_shortcut", {
|
|
145
|
+
title: "Duplicate Shortcut",
|
|
146
|
+
description: "Duplicate an existing Siri Shortcut. Exports the shortcut to a temporary file and re-imports it with a new name.",
|
|
147
|
+
inputSchema: {
|
|
148
|
+
name: z.string().describe("Name of the shortcut to duplicate (exact match)"),
|
|
149
|
+
newName: z.string().describe("Name for the duplicated shortcut"),
|
|
150
|
+
},
|
|
151
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
152
|
+
}, async ({ name, newName }) => {
|
|
153
|
+
try {
|
|
154
|
+
return ok(await runJxa(duplicateShortcutScript(name, newName)));
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
return toolError("duplicate shortcut", e);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
server.registerTool("edit_shortcut", {
|
|
161
|
+
title: "Edit Shortcut",
|
|
162
|
+
description: "Open a Siri Shortcut in the Shortcuts app for manual editing. Uses UI automation (System Events) to activate the app, search for the shortcut, and open it. The user can then edit the shortcut in the Shortcuts app UI.",
|
|
163
|
+
inputSchema: {
|
|
164
|
+
name: z.string().describe("Shortcut name to edit (exact match)"),
|
|
165
|
+
},
|
|
166
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
167
|
+
}, async ({ name }) => {
|
|
168
|
+
try {
|
|
169
|
+
return ok(await runJxa(editShortcutScript(name)));
|
|
170
|
+
}
|
|
171
|
+
catch (e) {
|
|
172
|
+
return toolError("open shortcut for editing", e);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Discover user's Siri Shortcuts at startup and register each as an individual MCP tool.
|
|
178
|
+
* Returns the number of dynamic tools registered. Gracefully returns 0 on failure.
|
|
179
|
+
*/
|
|
180
|
+
export async function registerDynamicShortcutTools(server) {
|
|
181
|
+
let output;
|
|
182
|
+
try {
|
|
183
|
+
const result = await execFileAsync("shortcuts", ["list"], { timeout: 10_000 });
|
|
184
|
+
output = result.stdout;
|
|
185
|
+
}
|
|
186
|
+
catch (e) {
|
|
187
|
+
console.error(`[AirMCP] Failed to list shortcuts for dynamic registration: ${e instanceof Error ? e.message : String(e)}`);
|
|
188
|
+
return 0;
|
|
189
|
+
}
|
|
190
|
+
const names = output.split("\n").filter((n) => n.trim().length > 0);
|
|
191
|
+
if (names.length === 0)
|
|
192
|
+
return 0;
|
|
193
|
+
if (names.length > MAX_DYNAMIC_SHORTCUTS) {
|
|
194
|
+
console.error(`[AirMCP] Found ${names.length} shortcuts, registering first ${MAX_DYNAMIC_SHORTCUTS} (limit reached)`);
|
|
195
|
+
}
|
|
196
|
+
const toRegister = names.slice(0, MAX_DYNAMIC_SHORTCUTS);
|
|
197
|
+
const seen = new Set();
|
|
198
|
+
let count = 0;
|
|
199
|
+
for (const name of toRegister) {
|
|
200
|
+
const toolName = sanitizeToolName(name);
|
|
201
|
+
if (!toolName) {
|
|
202
|
+
console.error(`[AirMCP] Skipping shortcut with unsanitizable name: "${name}"`);
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (seen.has(toolName)) {
|
|
206
|
+
console.error(`[AirMCP] Skipping duplicate tool name: ${toolName} (from "${name}")`);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
seen.add(toolName);
|
|
210
|
+
server.registerTool(toolName, {
|
|
211
|
+
title: `Run: ${name}`,
|
|
212
|
+
description: `Run the "${name}" Siri Shortcut. Optionally provide text input.`,
|
|
213
|
+
inputSchema: {
|
|
214
|
+
input: z.string().optional().describe("Optional text input for the shortcut"),
|
|
215
|
+
},
|
|
216
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
217
|
+
}, async ({ input }) => {
|
|
218
|
+
try {
|
|
219
|
+
return ok(await runJxa(runShortcutScript(name, input)));
|
|
220
|
+
}
|
|
221
|
+
catch (e) {
|
|
222
|
+
return toolError(`run shortcut "${name}"`, e);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
console.error(`[AirMCP] Registered dynamic shortcut: ${name}`);
|
|
226
|
+
count++;
|
|
227
|
+
}
|
|
228
|
+
return count;
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/shortcuts/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare function getClipboardScript(): string;
|
|
2
|
+
export declare function setClipboardScript(text: string): string;
|
|
3
|
+
export declare function getVolumeScript(): string;
|
|
4
|
+
export declare function setVolumeScript(volume?: number, muted?: boolean): string;
|
|
5
|
+
export declare function toggleDarkModeScript(): string;
|
|
6
|
+
export declare function getFrontmostAppScript(): string;
|
|
7
|
+
export declare function listRunningAppsScript(): string;
|
|
8
|
+
export declare function getScreenInfoScript(): string;
|
|
9
|
+
export declare function captureScreenshotScript(path: string, region?: string): string;
|
|
10
|
+
export declare function showNotificationScript(message: string, title?: string, subtitle?: string, sound?: string): string;
|
|
11
|
+
export declare function getWifiStatusScript(): string;
|
|
12
|
+
export declare function toggleWifiScript(enable: boolean): string;
|
|
13
|
+
export declare function listBluetoothDevicesScript(): string;
|
|
14
|
+
export declare function getBrightnessScript(): string;
|
|
15
|
+
export declare function setBrightnessScript(level: number): string;
|
|
16
|
+
export declare function getBatteryStatusScript(): string;
|
|
17
|
+
export declare function toggleFocusModeScript(enable: boolean): string;
|