scpl-updated-mcp-server 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/index.js +332 -102
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Model Context Protocol server for creating macOS Shortcuts using ScPL (Shortcuts
|
|
|
6
6
|
|
|
7
7
|
- **Create Shortcuts**: Convert ScPL code to .shortcut files
|
|
8
8
|
- **Validate Syntax**: Check ScPL code without creating files
|
|
9
|
-
- **Discover Actions**: Browse
|
|
9
|
+
- **Discover Actions**: Browse 493 available actions with descriptions
|
|
10
10
|
- **Documentation**: Access action reference and examples
|
|
11
11
|
|
|
12
12
|
## ⚠️ Shortcut Signing & Installation
|
package/index.js
CHANGED
|
@@ -8,10 +8,277 @@ import {
|
|
|
8
8
|
ListResourcesRequestSchema,
|
|
9
9
|
ReadResourceRequestSchema,
|
|
10
10
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
import {
|
|
11
|
+
import pkg from "scpl-macos-updated";
|
|
12
|
+
const { convert } = pkg;
|
|
13
|
+
import { writeFileSync, readFileSync, existsSync, mkdirSync } from "fs";
|
|
14
|
+
import { join, dirname } from "path";
|
|
14
15
|
import { homedir } from "os";
|
|
16
|
+
import { fileURLToPath } from "url";
|
|
17
|
+
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = dirname(__filename);
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// HELP
|
|
23
|
+
// ============================================================================
|
|
24
|
+
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
25
|
+
console.log(`
|
|
26
|
+
ScPL Updated MCP Server - Create macOS Shortcuts with AI
|
|
27
|
+
|
|
28
|
+
USAGE:
|
|
29
|
+
npx scpl-updated-mcp-server [OPTIONS]
|
|
30
|
+
|
|
31
|
+
OPTIONS:
|
|
32
|
+
--setup Auto-install for Claude Code (recommended)
|
|
33
|
+
--setup-codex Auto-install for OpenAI Codex CLI
|
|
34
|
+
--help, -h Show this help message
|
|
35
|
+
|
|
36
|
+
EXAMPLES:
|
|
37
|
+
npx scpl-updated-mcp-server --setup # Install for Claude Code
|
|
38
|
+
npx scpl-updated-mcp-server --setup-codex # Install for Codex
|
|
39
|
+
|
|
40
|
+
After setup, restart your AI coding tool and ask:
|
|
41
|
+
"Create a shortcut that starts a timer and plays a sound"
|
|
42
|
+
`);
|
|
43
|
+
process.exit(0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// CODEX SETUP: Run with --setup-codex for OpenAI Codex CLI
|
|
48
|
+
// ============================================================================
|
|
49
|
+
if (process.argv.includes("--setup-codex")) {
|
|
50
|
+
console.log("🚀 Setting up ScPL Shortcuts for Codex...\n");
|
|
51
|
+
|
|
52
|
+
const codexConfigPath = join(homedir(), ".codex", "config.toml");
|
|
53
|
+
const agentsPath = join(homedir(), ".codex", "AGENTS.md");
|
|
54
|
+
|
|
55
|
+
// Step 1: Add MCP server to ~/.codex/config.toml
|
|
56
|
+
console.log("📝 Step 1: Adding MCP server to ~/.codex/config.toml...");
|
|
57
|
+
try {
|
|
58
|
+
let config = "";
|
|
59
|
+
if (existsSync(codexConfigPath)) {
|
|
60
|
+
config = readFileSync(codexConfigPath, "utf-8");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Check if already configured
|
|
64
|
+
if (config.includes('[mcp_servers."scpl-shortcuts"]') || config.includes('[mcp_servers.scpl-shortcuts]')) {
|
|
65
|
+
console.log(" ⏭️ Already configured, skipping...\n");
|
|
66
|
+
} else {
|
|
67
|
+
const tomlBlock = `
|
|
68
|
+
[mcp_servers.scpl-shortcuts]
|
|
69
|
+
command = "npx"
|
|
70
|
+
args = ["-y", "scpl-updated-mcp-server"]
|
|
71
|
+
startup_timeout_sec = 60.0
|
|
72
|
+
`;
|
|
73
|
+
writeFileSync(codexConfigPath, config + tomlBlock);
|
|
74
|
+
console.log(" ✅ MCP server added!\n");
|
|
75
|
+
}
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error(" ❌ Failed to update config:", error.message);
|
|
78
|
+
console.log(" Add this to ~/.codex/config.toml manually:");
|
|
79
|
+
console.log(`
|
|
80
|
+
[mcp_servers.scpl-shortcuts]
|
|
81
|
+
command = "npx"
|
|
82
|
+
args = ["-y", "scpl-updated-mcp-server"]
|
|
83
|
+
startup_timeout_sec = 60.0
|
|
84
|
+
`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Step 2: Add instructions to AGENTS.md
|
|
88
|
+
console.log("📁 Step 2: Adding skill instructions to AGENTS.md...");
|
|
89
|
+
try {
|
|
90
|
+
let agents = "";
|
|
91
|
+
if (existsSync(agentsPath)) {
|
|
92
|
+
agents = readFileSync(agentsPath, "utf-8");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (agents.includes("## ScPL Shortcuts")) {
|
|
96
|
+
console.log(" ⏭️ Already in AGENTS.md, skipping...\n");
|
|
97
|
+
} else {
|
|
98
|
+
const agentBlock = `
|
|
99
|
+
|
|
100
|
+
## ScPL Shortcuts
|
|
101
|
+
|
|
102
|
+
You have access to the ScPL MCP server with 493 actions for creating macOS Shortcuts.
|
|
103
|
+
|
|
104
|
+
**Tools available:**
|
|
105
|
+
- \`create_shortcut\` - Generate a .shortcut file from ScPL code
|
|
106
|
+
- \`validate_scpl\` - Check if ScPL code is valid
|
|
107
|
+
- \`list_actions\` - Search available actions
|
|
108
|
+
|
|
109
|
+
**ScPL syntax example:**
|
|
110
|
+
\`\`\`scpl
|
|
111
|
+
Text "Hello"
|
|
112
|
+
AskLLM model="Apple Intelligence" prompt="Make it fun"
|
|
113
|
+
ShowResult
|
|
114
|
+
\`\`\`
|
|
115
|
+
|
|
116
|
+
When user asks to create a shortcut, write ScPL code, validate it, then create the file.
|
|
117
|
+
`;
|
|
118
|
+
writeFileSync(agentsPath, agents + agentBlock);
|
|
119
|
+
console.log(" ✅ Instructions added!\n");
|
|
120
|
+
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error(" ❌ Failed to update AGENTS.md:", error.message, "\n");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
console.log("🎉 Setup complete! Restart Codex to use the shortcuts tools.\n");
|
|
126
|
+
console.log("Usage: Just ask Codex to create a shortcut!");
|
|
127
|
+
console.log(' Example: "Create a shortcut that starts a timer and plays a sound"\n');
|
|
128
|
+
process.exit(0);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// CLAUDE CODE SETUP: Run with --setup to install everything automatically
|
|
133
|
+
// ============================================================================
|
|
134
|
+
if (process.argv.includes("--setup")) {
|
|
135
|
+
console.log("🚀 Setting up ScPL Shortcuts for Claude Code...\n");
|
|
136
|
+
|
|
137
|
+
const claudeJsonPath = join(homedir(), ".claude.json");
|
|
138
|
+
const pluginsDir = join(homedir(), ".claude", "plugins", "local", "scpl-shortcuts");
|
|
139
|
+
const installedPluginsPath = join(homedir(), ".claude", "plugins", "installed_plugins.json");
|
|
140
|
+
|
|
141
|
+
// Step 1: Add MCP server to ~/.claude.json
|
|
142
|
+
console.log("📝 Step 1: Adding MCP server to ~/.claude.json...");
|
|
143
|
+
try {
|
|
144
|
+
let claudeConfig = {};
|
|
145
|
+
if (existsSync(claudeJsonPath)) {
|
|
146
|
+
claudeConfig = JSON.parse(readFileSync(claudeJsonPath, "utf-8"));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (!claudeConfig.mcpServers) {
|
|
150
|
+
claudeConfig.mcpServers = {};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
claudeConfig.mcpServers["scpl-shortcuts"] = {
|
|
154
|
+
type: "stdio",
|
|
155
|
+
command: "npx",
|
|
156
|
+
args: ["-y", "scpl-updated-mcp-server"]
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
writeFileSync(claudeJsonPath, JSON.stringify(claudeConfig, null, 2));
|
|
160
|
+
console.log(" ✅ MCP server added!\n");
|
|
161
|
+
} catch (error) {
|
|
162
|
+
console.error(" ❌ Failed to update ~/.claude.json:", error.message);
|
|
163
|
+
console.log(" You can manually add this to ~/.claude.json under mcpServers:");
|
|
164
|
+
console.log(` "scpl-shortcuts": { "type": "stdio", "command": "npx", "args": ["-y", "scpl-updated-mcp-server"] }\n`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Step 2: Create plugin directory and files
|
|
168
|
+
console.log("📁 Step 2: Installing plugin files...");
|
|
169
|
+
try {
|
|
170
|
+
mkdirSync(join(pluginsDir, "skills"), { recursive: true });
|
|
171
|
+
|
|
172
|
+
// Write plugin.json
|
|
173
|
+
const pluginJson = {
|
|
174
|
+
name: "scpl-shortcuts",
|
|
175
|
+
version: "1.0.0",
|
|
176
|
+
description: "Create macOS Shortcuts using natural language and ScPL",
|
|
177
|
+
skills: [
|
|
178
|
+
{
|
|
179
|
+
name: "create-shortcut",
|
|
180
|
+
description: "Create a macOS Shortcut using natural language. Guides you through the process and generates a .shortcut file.",
|
|
181
|
+
path: "skills/create-shortcut.md"
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
};
|
|
185
|
+
writeFileSync(join(pluginsDir, "plugin.json"), JSON.stringify(pluginJson, null, 2));
|
|
186
|
+
|
|
187
|
+
// Write skill file
|
|
188
|
+
const skillContent = `---
|
|
189
|
+
description: Create macOS Shortcuts using natural language. Converts your request into ScPL code and generates a .shortcut file.
|
|
190
|
+
tags: [shortcuts, automation, macos, scpl]
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
# Create Shortcut Skill
|
|
194
|
+
|
|
195
|
+
You have access to the ScPL MCP server with 493 actions for creating macOS Shortcuts.
|
|
196
|
+
|
|
197
|
+
## Available Tools
|
|
198
|
+
|
|
199
|
+
1. **create_shortcut** - Generate a .shortcut file from ScPL code
|
|
200
|
+
2. **validate_scpl** - Check if ScPL code is valid before creating
|
|
201
|
+
3. **list_actions** - Search available actions by category or keyword
|
|
202
|
+
|
|
203
|
+
## Popular Action Categories
|
|
204
|
+
|
|
205
|
+
- **AI**: AskLLM (Apple Intelligence), AskChatGPT, AskClaude
|
|
206
|
+
- **Clock**: StartStopwatch, CreateAlarm, GetCurrentTime
|
|
207
|
+
- **Voice Memos**: CreateRecording, PlayRecording
|
|
208
|
+
- **System**: SetDarkMode, TakeScreenshot, LockScreen
|
|
209
|
+
- **Files**: GetFile, SaveFile, RenameFile, RevealInFinder
|
|
210
|
+
- **Scripting**: RunShellScript, RunAppleScript
|
|
211
|
+
|
|
212
|
+
## ScPL Syntax Examples
|
|
213
|
+
|
|
214
|
+
\`\`\`scpl
|
|
215
|
+
# Simple notification
|
|
216
|
+
ShowResult "Hello World!"
|
|
217
|
+
|
|
218
|
+
# Use Apple Intelligence
|
|
219
|
+
Text "Summarize this for me"
|
|
220
|
+
AskLLM model="Apple Intelligence" prompt="Make it shorter"
|
|
221
|
+
ShowResult
|
|
222
|
+
|
|
223
|
+
# Shell script
|
|
224
|
+
RunShellScript shell="/bin/zsh" script="echo Hello"
|
|
225
|
+
ShowResult
|
|
226
|
+
|
|
227
|
+
# Variables
|
|
228
|
+
Text "Hello"
|
|
229
|
+
SetVariable v:greeting
|
|
230
|
+
ShowResult v:greeting
|
|
231
|
+
\`\`\`
|
|
232
|
+
|
|
233
|
+
## Workflow
|
|
234
|
+
|
|
235
|
+
1. User describes what they want
|
|
236
|
+
2. Use \`list_actions\` if you need to find specific actions
|
|
237
|
+
3. Write ScPL code for the shortcut
|
|
238
|
+
4. Use \`validate_scpl\` to check syntax
|
|
239
|
+
5. Use \`create_shortcut\` to generate the .shortcut file
|
|
240
|
+
6. Tell user to drag the file onto Shortcut Source Helper to install
|
|
241
|
+
`;
|
|
242
|
+
writeFileSync(join(pluginsDir, "skills", "create-shortcut.md"), skillContent);
|
|
243
|
+
console.log(" ✅ Plugin files created!\n");
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error(" ❌ Failed to create plugin files:", error.message, "\n");
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Step 3: Register plugin in installed_plugins.json
|
|
249
|
+
console.log("📋 Step 3: Registering plugin...");
|
|
250
|
+
try {
|
|
251
|
+
let installedPlugins = { version: 2, plugins: {} };
|
|
252
|
+
if (existsSync(installedPluginsPath)) {
|
|
253
|
+
installedPlugins = JSON.parse(readFileSync(installedPluginsPath, "utf-8"));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
installedPlugins.plugins["scpl-shortcuts@local"] = [
|
|
257
|
+
{
|
|
258
|
+
scope: "user",
|
|
259
|
+
installPath: pluginsDir,
|
|
260
|
+
version: "1.0.0",
|
|
261
|
+
installedAt: new Date().toISOString(),
|
|
262
|
+
lastUpdated: new Date().toISOString(),
|
|
263
|
+
isLocal: true
|
|
264
|
+
}
|
|
265
|
+
];
|
|
266
|
+
|
|
267
|
+
writeFileSync(installedPluginsPath, JSON.stringify(installedPlugins, null, 2));
|
|
268
|
+
console.log(" ✅ Plugin registered!\n");
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.error(" ❌ Failed to register plugin:", error.message, "\n");
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
console.log("🎉 Setup complete! Restart Claude Code to use the shortcuts tools.\n");
|
|
274
|
+
console.log("Usage: Just ask Claude to create a shortcut!");
|
|
275
|
+
console.log(' Example: "Create a shortcut that starts a timer and plays a sound"\n');
|
|
276
|
+
process.exit(0);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// ============================================================================
|
|
280
|
+
// MCP SERVER
|
|
281
|
+
// ============================================================================
|
|
15
282
|
|
|
16
283
|
const server = new Server(
|
|
17
284
|
{
|
|
@@ -46,7 +313,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
46
313
|
},
|
|
47
314
|
output_dir: {
|
|
48
315
|
type: "string",
|
|
49
|
-
description: "Optional output directory (defaults to ~/
|
|
316
|
+
description: "Optional output directory (defaults to ~/Documents)",
|
|
50
317
|
},
|
|
51
318
|
},
|
|
52
319
|
required: ["scpl_code", "output_name"],
|
|
@@ -68,7 +335,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
68
335
|
},
|
|
69
336
|
{
|
|
70
337
|
name: "list_actions",
|
|
71
|
-
description: "List available ScPL actions
|
|
338
|
+
description: "List available ScPL actions (493 total). Filter by category or search term.",
|
|
72
339
|
inputSchema: {
|
|
73
340
|
type: "object",
|
|
74
341
|
properties: {
|
|
@@ -95,7 +362,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
95
362
|
const { scpl_code, output_name, output_dir } = args;
|
|
96
363
|
|
|
97
364
|
// Convert ScPL to shortcut
|
|
98
|
-
// Note: parse() returns a Buffer directly when makeShortcut: true
|
|
99
365
|
const shortcutBuffer = convert(scpl_code, {
|
|
100
366
|
makePlist: true,
|
|
101
367
|
makeShortcut: true,
|
|
@@ -112,7 +378,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
112
378
|
content: [
|
|
113
379
|
{
|
|
114
380
|
type: "text",
|
|
115
|
-
text: `✅ Shortcut created successfully!\n\nPath: ${outputPath}\n\n📝 To install
|
|
381
|
+
text: `✅ Shortcut created successfully!\n\nPath: ${outputPath}\n\n📝 To install:\n1. Download "Shortcut Source Helper" from RoutineHub\n2. Drag ${output_name}.shortcut onto it\n3. Follow the prompts to sign and import\n\nThe shortcut will be added to your Shortcuts app!`,
|
|
116
382
|
},
|
|
117
383
|
],
|
|
118
384
|
};
|
|
@@ -122,7 +388,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
122
388
|
const { scpl_code } = args;
|
|
123
389
|
|
|
124
390
|
try {
|
|
125
|
-
// Just parse to validate, don't generate output
|
|
126
391
|
convert(scpl_code, {
|
|
127
392
|
makePlist: false,
|
|
128
393
|
makeShortcut: false,
|
|
@@ -152,59 +417,71 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
152
417
|
if (name === "list_actions") {
|
|
153
418
|
const { category, search } = args || {};
|
|
154
419
|
|
|
155
|
-
//
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
"
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
420
|
+
// Embedded action list (top actions for quick reference)
|
|
421
|
+
const topActions = {
|
|
422
|
+
// AI
|
|
423
|
+
"is.workflow.actions.askllm": { Name: "Ask LLM", Category: "AI" },
|
|
424
|
+
"is.workflow.actions.askchatgpt": { Name: "Ask ChatGPT", Category: "AI" },
|
|
425
|
+
"com.anthropic.claudeforipad.AskClaudeIntentExtension": { Name: "Ask Claude", Category: "AI" },
|
|
426
|
+
// Clock
|
|
427
|
+
"com.apple.clock.StartStopwatchIntent": { Name: "Start Stopwatch", Category: "Clock" },
|
|
428
|
+
"com.apple.clock.StopStopwatchIntent": { Name: "Stop Stopwatch", Category: "Clock" },
|
|
429
|
+
"com.apple.clock.CreateAlarmIntent": { Name: "Create Alarm", Category: "Clock" },
|
|
430
|
+
// Voice Memos
|
|
431
|
+
"com.apple.VoiceMemos.CreateRecordingIntent": { Name: "Create Recording", Category: "Voice Memos" },
|
|
432
|
+
"com.apple.VoiceMemos.PlayRecordingIntent": { Name: "Play Recording", Category: "Voice Memos" },
|
|
433
|
+
// System
|
|
434
|
+
"is.workflow.actions.appearance": { Name: "Set Dark/Light Mode", Category: "System" },
|
|
435
|
+
"is.workflow.actions.takescreenshot": { Name: "Take Screenshot", Category: "System" },
|
|
436
|
+
"is.workflow.actions.lockscreen": { Name: "Lock Screen", Category: "System" },
|
|
437
|
+
// Scripting
|
|
438
|
+
"is.workflow.actions.runshellscript": { Name: "Run Shell Script", Category: "Scripting" },
|
|
439
|
+
"is.workflow.actions.runapplescript": { Name: "Run AppleScript", Category: "Scripting" },
|
|
440
|
+
"is.workflow.actions.runjavascriptforautomation": { Name: "Run JavaScript", Category: "Scripting" },
|
|
441
|
+
// Files
|
|
442
|
+
"is.workflow.actions.file.getfile": { Name: "Get File", Category: "Files" },
|
|
443
|
+
"is.workflow.actions.file.savefile": { Name: "Save File", Category: "Files" },
|
|
444
|
+
"is.workflow.actions.file.renamefile": { Name: "Rename File", Category: "Files" },
|
|
445
|
+
"is.workflow.actions.file.revealfile": { Name: "Reveal in Finder", Category: "Files" },
|
|
446
|
+
// Text
|
|
447
|
+
"is.workflow.actions.gettext": { Name: "Get Text", Category: "Text" },
|
|
448
|
+
"is.workflow.actions.showresult": { Name: "Show Result", Category: "Text" },
|
|
449
|
+
"is.workflow.actions.alert": { Name: "Show Alert", Category: "Text" },
|
|
450
|
+
// Variables
|
|
451
|
+
"is.workflow.actions.setvariable": { Name: "Set Variable", Category: "Variables" },
|
|
452
|
+
"is.workflow.actions.getvariable": { Name: "Get Variable", Category: "Variables" },
|
|
453
|
+
// Clipboard
|
|
454
|
+
"is.workflow.actions.getclipboard": { Name: "Get Clipboard", Category: "Clipboard" },
|
|
455
|
+
"is.workflow.actions.setclipboard": { Name: "Set Clipboard", Category: "Clipboard" },
|
|
456
|
+
};
|
|
164
457
|
|
|
165
|
-
let filtered = Object.entries(
|
|
458
|
+
let filtered = Object.entries(topActions);
|
|
166
459
|
|
|
167
|
-
// Filter by category
|
|
168
460
|
if (category) {
|
|
169
461
|
filtered = filtered.filter(
|
|
170
|
-
([_, action]) =>
|
|
171
|
-
action.Category?.toLowerCase() === category.toLowerCase()
|
|
462
|
+
([_, action]) => action.Category?.toLowerCase() === category.toLowerCase()
|
|
172
463
|
);
|
|
173
464
|
}
|
|
174
465
|
|
|
175
|
-
// Filter by search term
|
|
176
466
|
if (search) {
|
|
177
467
|
const searchLower = search.toLowerCase();
|
|
178
468
|
filtered = filtered.filter(
|
|
179
469
|
([id, action]) =>
|
|
180
470
|
id.toLowerCase().includes(searchLower) ||
|
|
181
471
|
action.Name?.toLowerCase().includes(searchLower) ||
|
|
182
|
-
action.
|
|
183
|
-
searchLower
|
|
184
|
-
)
|
|
472
|
+
action.Category?.toLowerCase().includes(searchLower)
|
|
185
473
|
);
|
|
186
474
|
}
|
|
187
475
|
|
|
188
|
-
// Format the results
|
|
189
476
|
const results = filtered
|
|
190
|
-
.
|
|
191
|
-
.
|
|
192
|
-
return `• **${action.Name || id}**\n ID: \`${id}\`\n ${
|
|
193
|
-
action.Description?.DescriptionSummary || "No description"
|
|
194
|
-
}\n Category: ${action.Category || "Unknown"}`;
|
|
195
|
-
})
|
|
196
|
-
.join("\n\n");
|
|
197
|
-
|
|
198
|
-
const total = filtered.length;
|
|
199
|
-
const showing = Math.min(50, total);
|
|
477
|
+
.map(([id, action]) => `• **${action.Name}** - \`${id}\` (${action.Category})`)
|
|
478
|
+
.join("\n");
|
|
200
479
|
|
|
201
480
|
return {
|
|
202
481
|
content: [
|
|
203
482
|
{
|
|
204
483
|
type: "text",
|
|
205
|
-
text: `Found ${
|
|
206
|
-
total !== 1 ? "s" : ""
|
|
207
|
-
} (showing ${showing}):\n\n${results}`,
|
|
484
|
+
text: `Found ${filtered.length} actions:\n\n${results}\n\n💡 This is a subset of 493 total actions. For the full list, see: https://github.com/cavingraves/scpl-macos-updated`,
|
|
208
485
|
},
|
|
209
486
|
],
|
|
210
487
|
};
|
|
@@ -224,22 +501,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
224
501
|
}
|
|
225
502
|
});
|
|
226
503
|
|
|
227
|
-
// Resource handlers
|
|
504
|
+
// Resource handlers
|
|
228
505
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
229
506
|
return {
|
|
230
507
|
resources: [
|
|
231
|
-
{
|
|
232
|
-
uri: "scpl://actions/all",
|
|
233
|
-
name: "All Available Actions",
|
|
234
|
-
description: "Complete list of all 294 ScPL actions",
|
|
235
|
-
mimeType: "text/markdown",
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
uri: "scpl://actions/tahoe",
|
|
239
|
-
name: "macOS Tahoe New Actions",
|
|
240
|
-
description: "22 new actions added for macOS Tahoe",
|
|
241
|
-
mimeType: "text/markdown",
|
|
242
|
-
},
|
|
243
508
|
{
|
|
244
509
|
uri: "scpl://examples",
|
|
245
510
|
name: "ScPL Examples",
|
|
@@ -253,83 +518,48 @@ server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
|
253
518
|
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
254
519
|
const { uri } = request.params;
|
|
255
520
|
|
|
256
|
-
if (uri === "scpl://actions/tahoe") {
|
|
257
|
-
const content = readFileSync(
|
|
258
|
-
join(process.cwd(), "..", "MACOS_TAHOE_UPDATES.md"),
|
|
259
|
-
"utf-8"
|
|
260
|
-
);
|
|
261
|
-
return {
|
|
262
|
-
contents: [
|
|
263
|
-
{
|
|
264
|
-
uri,
|
|
265
|
-
mimeType: "text/markdown",
|
|
266
|
-
text: content,
|
|
267
|
-
},
|
|
268
|
-
],
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
|
|
272
521
|
if (uri === "scpl://examples") {
|
|
273
522
|
const examples = `# ScPL Examples
|
|
274
523
|
|
|
275
|
-
## Apple Intelligence
|
|
524
|
+
## Apple Intelligence
|
|
276
525
|
\`\`\`scpl
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
AskLLM model="Apple Intelligence" prompt="Summarize this in 5 words"
|
|
526
|
+
Text "Summarize this document"
|
|
527
|
+
AskLLM model="Apple Intelligence" prompt="Make it concise"
|
|
280
528
|
ShowResult
|
|
281
529
|
\`\`\`
|
|
282
530
|
|
|
283
|
-
##
|
|
284
|
-
\`\`\`scpl
|
|
285
|
-
# Run a shell script and show the result
|
|
286
|
-
RunShellScript shell="/bin/zsh" script="sw_vers"
|
|
287
|
-
ShowResult "macOS Version"
|
|
288
|
-
\`\`\`
|
|
289
|
-
|
|
290
|
-
## File Operations Example
|
|
531
|
+
## Timer with Sound
|
|
291
532
|
\`\`\`scpl
|
|
292
|
-
#
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
ShowResult "Files on Desktop"
|
|
533
|
+
# Start a 5-minute timer
|
|
534
|
+
StartTimer minutes=5
|
|
535
|
+
ShowAlert title="Timer Started" message="5 minutes"
|
|
296
536
|
\`\`\`
|
|
297
537
|
|
|
298
|
-
##
|
|
538
|
+
## Shell Script
|
|
299
539
|
\`\`\`scpl
|
|
300
|
-
|
|
301
|
-
Text "What is the meaning of life?"
|
|
302
|
-
AskChatGPT
|
|
540
|
+
RunShellScript shell="/bin/zsh" script="echo Hello World"
|
|
303
541
|
ShowResult
|
|
304
542
|
\`\`\`
|
|
305
543
|
|
|
306
|
-
##
|
|
544
|
+
## Clipboard Workflow
|
|
307
545
|
\`\`\`scpl
|
|
308
|
-
# Get clipboard, ask AI to improve it, copy back
|
|
309
546
|
GetClipboard
|
|
310
|
-
SetVariable v:
|
|
311
|
-
|
|
312
|
-
AskLLM model="Apple Intelligence" prompt="Improve this text for clarity and grammar: \\(v:originalText)"
|
|
547
|
+
SetVariable v:text
|
|
548
|
+
AskChatGPT prompt="Improve this: \\(v:text)"
|
|
313
549
|
SetClipboard
|
|
314
|
-
ShowAlert title="
|
|
550
|
+
ShowAlert title="Done" message="Improved text copied!"
|
|
315
551
|
\`\`\`
|
|
316
552
|
`;
|
|
317
553
|
|
|
318
554
|
return {
|
|
319
|
-
contents: [
|
|
320
|
-
{
|
|
321
|
-
uri,
|
|
322
|
-
mimeType: "text/markdown",
|
|
323
|
-
text: examples,
|
|
324
|
-
},
|
|
325
|
-
],
|
|
555
|
+
contents: [{ uri, mimeType: "text/markdown", text: examples }],
|
|
326
556
|
};
|
|
327
557
|
}
|
|
328
558
|
|
|
329
559
|
throw new Error(`Unknown resource: ${uri}`);
|
|
330
560
|
});
|
|
331
561
|
|
|
332
|
-
// Start
|
|
562
|
+
// Start server
|
|
333
563
|
async function main() {
|
|
334
564
|
const transport = new StdioServerTransport();
|
|
335
565
|
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scpl-updated-mcp-server",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "MCP server for
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "AI-powered Apple Shortcuts creation with Claude Code! Generate macOS shortcuts using natural language. 493 actions available. MCP server for text-based shortcut programming. Vibe code your automation workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"scpl-updated-mcp-server": "
|
|
8
|
+
"scpl-updated-mcp-server": "index.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"start": "node index.js"
|