whitemagic-mcp 9.2.7 → 9.2.9

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.
Files changed (3) hide show
  1. package/README.md +24 -17
  2. package/bin/lib.mjs +57 -11
  3. package/package.json +14 -6
package/README.md CHANGED
@@ -1,19 +1,30 @@
1
1
  # whitemagic-mcp
2
2
 
3
- [WhiteMagic](https://whitemagic.dev): local-first, governed memory and
4
- session continuity for AI coding agents, over MCP. One static Rust binary,
5
- no telemetry by default. MIT.
3
+ Persistent memory and session continuity for AI coding agents, over MCP.
4
+ [WhiteMagic](https://whitemagic.dev) is one static Rust binary — local-first,
5
+ no telemetry by default, MIT — and every handoff can be signed as a
6
+ verifiable [continuity receipt](https://www.whitemagic.dev/trust).
6
7
 
7
- Optional: a read-only hosted evaluation lane runs at
8
- `https://mcp.whitemagic.dev/mcp` (free evaluation keys), and the receipt
9
- format with its live verifier is documented at
10
- https://www.whitemagic.dev/trust.
8
+ Works with Claude Code, Claude Desktop, Cursor, Codex, VS Code, opencode,
9
+ Antigravity, and Devin Desktop — per-client configs:
10
+ https://www.whitemagic.dev/whitemagic/guide
11
11
 
12
12
  This package installs and runs the official `wm` binary from the
13
13
  [GitHub releases](https://github.com/lbailey94/whitemagic/releases)
14
14
  (checksum-verified at install time) so an MCP client can launch it
15
15
  without a manual download step.
16
16
 
17
+ ## Try it without installing (hosted read-only lane)
18
+
19
+ The evaluation lane runs at `https://mcp.whitemagic.dev/mcp`
20
+ (streamable-http; keyless discovery, free evaluation keys, no SLA):
21
+
22
+ ```bash
23
+ claude mcp add whitemagic-mcp --transport http https://mcp.whitemagic.dev/mcp
24
+ ```
25
+
26
+ The npm package remains the local, full-write path.
27
+
17
28
  ## Use
18
29
 
19
30
  Point any MCP client (Claude Desktop, Cursor, Codex, Gemini CLI,
@@ -32,7 +43,7 @@ opencode) at:
32
43
  Or try it directly:
33
44
 
34
45
  ```bash
35
- npx whitemagic-mcp --version # wm 9.2.7
46
+ npx whitemagic-mcp --version # wm 9.2.9
36
47
  npx whitemagic-mcp doctor # environment health check
37
48
  ```
38
49
 
@@ -41,17 +52,13 @@ The binary is cached under `~/.cache/whitemagic/bin/<release-tag>/`
41
52
  release tag (the `v9` tag line). Pin a different release with
42
53
  `WHITEMAGIC_RELEASE`.
43
54
 
44
- ## Hosted option (read-only beta)
45
-
46
- For evaluation without a local install there is a read-only hosted
47
- endpoint at `https://mcp.whitemagic.dev/mcp` (streamable-http; keyless
48
- discovery, free evaluation keys, no SLA). The npm package remains the
49
- local, full-write path.
50
-
51
55
  ## Platforms
52
56
 
53
- Linux x86-64 (static musl), macOS arm64/x64, Windows x64. No asset for
54
- your platform? Build from source:
57
+ Linux x86-64 (static musl), Linux arm64 (static musl), and macOS arm64 are
58
+ install-gated. macOS x64 and Windows x64 binaries are published, but their
59
+ install paths are not gated yet. Downloads prefer the compressed `.gz`
60
+ distributable when the release ships one (~58% smaller) and fall back to the
61
+ raw binary otherwise. No asset for your platform? Build from source:
55
62
  https://github.com/lbailey94/whitemagic#install
56
63
 
57
64
  ## Privacy
package/bin/lib.mjs CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  } from "node:fs";
21
21
  import { homedir, platform, arch, tmpdir } from "node:os";
22
22
  import { join } from "node:path";
23
+ import { gunzipSync } from "node:zlib";
23
24
 
24
25
  export const REPO = "lbailey94/whitemagic";
25
26
  const SHA256_RE = /^[0-9a-f]{64}$/i;
@@ -120,10 +121,32 @@ export async function fetchTo(url, dest, fetchImpl) {
120
121
  writeFileSync(dest, Buffer.from(await res.arrayBuffer()));
121
122
  }
122
123
 
124
+ /**
125
+ * Parse a release `.sha256` sidecar (first whitespace-delimited token) and
126
+ * refuse anything that is not a well-formed digest.
127
+ */
128
+ function parseDigestFile(path, label) {
129
+ const expected = (readFileSync(path, "utf8").trim().split(/\s+/)[0] ?? "").toLowerCase();
130
+ if (!SHA256_RE.test(expected)) {
131
+ throw new Error(`release checksum for ${label} is malformed — refusing to install it`);
132
+ }
133
+ return expected;
134
+ }
135
+
136
+ function checksumMismatch(label, expected, actual) {
137
+ return new Error(
138
+ `checksum mismatch for ${label} (expected ${expected.slice(0, 12)}…, got ${actual.slice(0, 12)}…) — the download may be corrupted; retry`,
139
+ );
140
+ }
141
+
123
142
  /**
124
143
  * Ensure a verified `wm` binary for this platform exists in the cache and
125
144
  * return its path. Fresh downloads go temp -> checksum -> chmod -> rename;
126
145
  * a cache entry that fails re-verification is replaced (self-healing).
146
+ *
147
+ * The launcher prefers the gzipped distributable (~58% smaller; published
148
+ * for Linux/macOS) exactly like `scripts/install.sh` does. Windows `.exe`
149
+ * assets ship raw, and releases that predate the `.gz` fall back on a 404.
127
150
  */
128
151
  export async function ensureBinary({
129
152
  fetchImpl = fetch,
@@ -155,22 +178,45 @@ export async function ensureBinary({
155
178
  const tmp = mkdtempSync(join(binDir, ".download-"));
156
179
  try {
157
180
  const tmpBin = join(tmp, asset);
158
- const tmpSha = join(tmp, `${asset}.sha256`);
159
- await fetchTo(`${BASE_URL(resolvedTag)}/${asset}`, tmpBin, fetchImpl);
160
- await fetchTo(`${BASE_URL(resolvedTag)}/${asset}.sha256`, tmpSha, fetchImpl);
161
- const expected = (readFileSync(tmpSha, "utf8").trim().split(/\s+/)[0] ?? "").toLowerCase();
162
- if (!SHA256_RE.test(expected)) {
163
- throw new Error(`release checksum for ${asset} is malformed — refusing to install it`);
181
+ let compressed = false;
182
+ if (!asset.endsWith(".exe")) {
183
+ try {
184
+ await fetchTo(`${BASE_URL(resolvedTag)}/${asset}.gz`, join(tmp, `${asset}.gz`), fetchImpl);
185
+ await fetchTo(
186
+ `${BASE_URL(resolvedTag)}/${asset}.gz.sha256`,
187
+ join(tmp, `${asset}.gz.sha256`),
188
+ fetchImpl,
189
+ );
190
+ compressed = true;
191
+ } catch (err) {
192
+ if (!String(err?.message ?? "").includes("HTTP 404")) throw err;
193
+ }
164
194
  }
165
- const actual = digestFile(tmpBin);
166
- if (actual !== expected) {
167
- throw new Error(
168
- `checksum mismatch for ${asset} (expected ${expected.slice(0, 12)}…, got ${actual.slice(0, 12)}…) — the download may be corrupted; retry`,
195
+ if (compressed) {
196
+ const gzPath = join(tmp, `${asset}.gz`);
197
+ const expectedGz = parseDigestFile(join(tmp, `${asset}.gz.sha256`), `${asset}.gz`);
198
+ const actualGz = digestFile(gzPath);
199
+ if (actualGz !== expectedGz) {
200
+ throw checksumMismatch(`${asset}.gz`, expectedGz, actualGz);
201
+ }
202
+ writeFileSync(tmpBin, gunzipSync(readFileSync(gzPath)));
203
+ log(`whitemagic-mcp: using the compressed distributable (${asset}.gz)`);
204
+ } else {
205
+ await fetchTo(`${BASE_URL(resolvedTag)}/${asset}`, tmpBin, fetchImpl);
206
+ await fetchTo(
207
+ `${BASE_URL(resolvedTag)}/${asset}.sha256`,
208
+ join(tmp, `${asset}.sha256`),
209
+ fetchImpl,
169
210
  );
211
+ const expected = parseDigestFile(join(tmp, `${asset}.sha256`), asset);
212
+ const actual = digestFile(tmpBin);
213
+ if (actual !== expected) {
214
+ throw checksumMismatch(asset, expected, actual);
215
+ }
170
216
  }
171
217
  chmodSync(tmpBin, 0o755);
172
218
  renameSync(tmpBin, cached);
173
- writeFileSync(sidecarFor(cached), `${expected}\n`);
219
+ writeFileSync(sidecarFor(cached), `${digestFile(cached)}\n`);
174
220
  return cached;
175
221
  } finally {
176
222
  rmSync(tmp, { recursive: true, force: true });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "whitemagic-mcp",
3
- "version": "9.2.7",
4
- "description": "WhiteMagic MCP server: local-first, governed memory and session continuity for AI coding agents. Installs and runs the wm binary; no telemetry by default; optional read-only hosted evaluation lane.",
3
+ "version": "9.2.9",
4
+ "description": "Local-first persistent memory and session continuity for AI coding agents (Claude Code, Cursor, Codex), over MCP - one static Rust binary, no telemetry by default, verifiable handoffs.",
5
5
  "license": "MIT",
6
6
  "bin": {
7
7
  "whitemagic-mcp": "./bin/cli.mjs"
@@ -17,13 +17,21 @@
17
17
  "keywords": [
18
18
  "mcp",
19
19
  "mcp-server",
20
+ "memory",
20
21
  "agent-memory",
21
- "ai-agents",
22
- "local-first",
23
- "whitemagic",
22
+ "ai-memory",
23
+ "persistent-memory",
24
24
  "session-continuity",
25
+ "context",
26
+ "local-first",
27
+ "claude-code",
28
+ "cursor",
29
+ "codex",
30
+ "model-context-protocol",
31
+ "ai-agents",
25
32
  "governance",
26
- "receipts"
33
+ "receipts",
34
+ "whitemagic"
27
35
  ],
28
36
  "repository": {
29
37
  "type": "git",