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.
- package/README.md +24 -17
- package/bin/lib.mjs +57 -11
- package/package.json +14 -6
package/README.md
CHANGED
|
@@ -1,19 +1,30 @@
|
|
|
1
1
|
# whitemagic-mcp
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
no telemetry by default
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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.
|
|
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),
|
|
54
|
-
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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), `${
|
|
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.
|
|
4
|
-
"description": "
|
|
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-
|
|
22
|
-
"
|
|
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",
|