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 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.0";
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(NOT_RUNNING);
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(NOT_RUNNING);
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(NOT_RUNNING);
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.0",
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/TanKucukhas/spacepal-mcp.git"
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.0",
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.0",
12
+ "version": "0.4.2",
13
13
  "transport": {
14
14
  "type": "stdio"
15
15
  }