spacepal-mcp 0.4.0 → 0.4.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 +2 -1
- package/index.js +25 -5
- package/package.json +2 -2
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -12,7 +12,8 @@ It runs locally over stdio. It reads the Space list Spacepal writes to
|
|
|
12
12
|
|
|
13
13
|
## Requirements
|
|
14
14
|
|
|
15
|
-
- macOS 14 or later, with Spacepal running (direct or Mac App Store build)
|
|
15
|
+
- macOS 14 or later, with Spacepal running (direct or Mac App Store build).
|
|
16
|
+
[Download Spacepal](https://getspacepal.com/download/?utm_source=mcp-readme&utm_medium=readme): 14-day free trial, no account; names, notes and switching stay free after it.
|
|
16
17
|
- Node.js 18 or later
|
|
17
18
|
|
|
18
19
|
## Tools
|
package/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import { join } from "node:path";
|
|
|
13
13
|
import { promisify } from "node:util";
|
|
14
14
|
|
|
15
15
|
const run = promisify(execFile);
|
|
16
|
-
const VERSION = "0.4.
|
|
16
|
+
const VERSION = "0.4.1";
|
|
17
17
|
|
|
18
18
|
// Direct build writes to Application Support; the App Store build is sandboxed.
|
|
19
19
|
const SUPPORT_DIRS = [
|
|
@@ -26,6 +26,26 @@ const PROFILE_FILES = SUPPORT_DIRS.map((d) => join(d, "profiles.json"));
|
|
|
26
26
|
const TEMPLATES = ["Developer", "Designer", "Freelancer", "Student", "Streamer"];
|
|
27
27
|
|
|
28
28
|
const NOT_RUNNING = "Spacepal is not running. Open Spacepal (getspacepal.com) and try again.";
|
|
29
|
+
const DOWNLOAD_URL = "https://getspacepal.com/download/?utm_source=mcp&utm_medium=tool&utm_campaign=not_installed";
|
|
30
|
+
const NOT_INSTALLED =
|
|
31
|
+
"Spacepal is not installed on this Mac. This MCP server needs the Spacepal app, which names, previews and switches macOS Spaces. " +
|
|
32
|
+
`Download it from ${DOWNLOAD_URL} (14-day free trial, no account; names and switching stay free after the trial), open it once, then try again.`;
|
|
33
|
+
|
|
34
|
+
// Not running and never installed reads differently: the user needs a download link, not "open it".
|
|
35
|
+
async function notRunning() {
|
|
36
|
+
const places = [
|
|
37
|
+
"/Applications/Spacepal.app",
|
|
38
|
+
join(homedir(), "Applications/Spacepal.app"),
|
|
39
|
+
...SUPPORT_DIRS,
|
|
40
|
+
];
|
|
41
|
+
for (const p of places) {
|
|
42
|
+
try {
|
|
43
|
+
await stat(p);
|
|
44
|
+
return NOT_RUNNING;
|
|
45
|
+
} catch {}
|
|
46
|
+
}
|
|
47
|
+
return NOT_INSTALLED;
|
|
48
|
+
}
|
|
29
49
|
|
|
30
50
|
async function isRunning() {
|
|
31
51
|
try {
|
|
@@ -63,7 +83,7 @@ async function readProfiles() {
|
|
|
63
83
|
}
|
|
64
84
|
|
|
65
85
|
async function send(path, query = {}) {
|
|
66
|
-
if (!(await isRunning())) throw new Error(
|
|
86
|
+
if (!(await isRunning())) throw new Error(await notRunning());
|
|
67
87
|
// Encode with %20, not "+": the app reads query values with URLComponents, which keeps "+".
|
|
68
88
|
const qs = Object.entries(query)
|
|
69
89
|
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
|
@@ -119,7 +139,7 @@ Start with list_spaces to learn the Spaces, their numbers, names, notes and the
|
|
|
119
139
|
|
|
120
140
|
Tools that only read: list_spaces, current_space, list_profiles. Tools that change the user's screen or setup: everything else. Ask the user before remove_desktop, apply_template and apply_profile, which replace or remove things; rename_space and set_space_note are easy to undo by calling them again.
|
|
121
141
|
|
|
122
|
-
Every action goes through Spacepal, so it must be running (macOS 14 or later). Nothing is sent over the network. If a tool says Spacepal is not running, tell the user to open it. The overview and sessions need Spacepal's trial or a license; names, notes and switching work in the free version.`;
|
|
142
|
+
Every action goes through Spacepal, so it must be running (macOS 14 or later). Nothing is sent over the network. If a tool says Spacepal is not running, tell the user to open it. If it says Spacepal is not installed, give the user the download link from the message. The overview and sessions need Spacepal's trial or a license; names, notes and switching work in the free version.`;
|
|
123
143
|
|
|
124
144
|
const server = new McpServer({ name: "spacepal", version: VERSION }, { instructions: INSTRUCTIONS });
|
|
125
145
|
|
|
@@ -162,7 +182,7 @@ server.registerTool(
|
|
|
162
182
|
annotations: { title: "List Spaces", ...RO },
|
|
163
183
|
},
|
|
164
184
|
guarded(async () => {
|
|
165
|
-
if (!(await isRunning())) return fail(
|
|
185
|
+
if (!(await isRunning())) return fail(await notRunning());
|
|
166
186
|
const state = await readState();
|
|
167
187
|
if (!state) return fail("Spacepal has not written its Space list yet. Open the Spacepal menu once and try again.");
|
|
168
188
|
const lines = state.spaces.map((s) => {
|
|
@@ -193,7 +213,7 @@ server.registerTool(
|
|
|
193
213
|
annotations: { title: "Current Space", ...RO },
|
|
194
214
|
},
|
|
195
215
|
guarded(async () => {
|
|
196
|
-
if (!(await isRunning())) return fail(
|
|
216
|
+
if (!(await isRunning())) return fail(await notRunning());
|
|
197
217
|
const state = await readState();
|
|
198
218
|
if (!state) return fail("Spacepal has not written its Space list yet. Open the Spacepal menu once and try again.");
|
|
199
219
|
const active = state.spaces.filter((s) => s.isActive);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spacepal-mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "MCP server for Spacepal: list, switch, rename macOS Spaces and move windows between them from Claude, Cursor or any MCP client.",
|
|
5
5
|
"mcpName": "com.getspacepal/spacepal",
|
|
6
6
|
"type": "module",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"homepage": "https://getspacepal.com/integrations/mcp/",
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|
|
34
|
-
"url": "git+https://github.com/
|
|
34
|
+
"url": "git+https://github.com/HalberdLLC/spacepal-mcp.git"
|
|
35
35
|
},
|
|
36
36
|
"author": "Halberd LLC",
|
|
37
37
|
"license": "MIT",
|
package/server.json
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
"name": "com.getspacepal/spacepal",
|
|
4
4
|
"title": "Spacepal",
|
|
5
5
|
"description": "List, switch and rename macOS Spaces and move windows between them. Needs the Spacepal app.",
|
|
6
|
-
"version": "0.4.
|
|
6
|
+
"version": "0.4.2",
|
|
7
7
|
"websiteUrl": "https://getspacepal.com/integrations/mcp/",
|
|
8
8
|
"packages": [
|
|
9
9
|
{
|
|
10
10
|
"registryType": "npm",
|
|
11
11
|
"identifier": "spacepal-mcp",
|
|
12
|
-
"version": "0.4.
|
|
12
|
+
"version": "0.4.2",
|
|
13
13
|
"transport": {
|
|
14
14
|
"type": "stdio"
|
|
15
15
|
}
|