rubien-mcp-server 0.3.0 → 0.3.1

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
@@ -18,7 +18,7 @@ The server is only a wrapper. It needs **Node.js ≥ 20** and the `rubien-cli` b
18
18
  ```
19
19
  Tarball: <https://github.com/devzhk/Rubien-releases/releases>. Don't put the bare binary on `PATH` alone — it loses its resource bundles.
20
20
 
21
- At startup the server checks the CLI's build and exits with an update instruction if it's too old. Update via Rubien.app / Sparkle on Mac, or `rubien-cli self-update` on Linux.
21
+ The server checks the CLI's build (`MIN_CLI_BUILD`). In stdio mode it starts either way: if the CLI is missing or too old, every tool call returns the update instruction as its result, re-checked per call — so updating Rubien mid-session recovers on the next call, with no client restart. (Versions ≤ 0.3.0 exited at startup instead, which Claude Desktop rendered as an opaque "Server disconnected" — see [Troubleshooting](#troubleshooting-server-disconnected-in-claude-desktop).) In `--http` mode the server still exits at startup, where stderr is visible in your terminal. Update via Rubien.app / Sparkle on Mac, or `rubien-cli self-update` on Linux.
22
22
 
23
23
  ## Install
24
24
 
@@ -54,10 +54,17 @@ The `npx -y rubien-mcp-server` install is **unpinned**, so there is nothing to r
54
54
  1. **Update Rubien first** — Sparkle on Mac (Rubien → Settings → Check Now), `rubien-cli self-update` on Linux. The server needs the new `rubien-cli`.
55
55
  2. **Restart your MCP client** — quit/reopen Claude Desktop, or start a new Claude Code session. The respawned server is the latest release.
56
56
 
57
- The pairing is guarded in one direction: a new server against a too-old Rubien **exits at startup with an update instruction** (`MIN_CLI_BUILD`), so a half-upgrade fails fast instead of half-working. The other direction is why upgrading matters — an old server against a new Rubien breaks at tool-call time when it shells subcommands that no longer exist (server < 0.3.0 vs Rubien ≥ 0.4.0: the 0.4.0 CLI cutover removed `import`, `add --identifier`, `views --query`, and the legacy `properties` write flags that 0.1.x/0.2.x servers shell out to; those server versions are deprecated on npm for this reason).
57
+ The pairing is guarded in one direction: a new server against a too-old Rubien **refuses every tool call with an update instruction** (`MIN_CLI_BUILD`), so a half-upgrade fails loudly instead of half-working. The other direction is why upgrading matters — an old server against a new Rubien breaks at tool-call time when it shells subcommands that no longer exist (server < 0.3.0 vs Rubien ≥ 0.4.0: the 0.4.0 CLI cutover removed `import`, `add --identifier`, `views --query`, and the legacy `properties` write flags that 0.1.x/0.2.x servers shell out to; those server versions are deprecated on npm for this reason).
58
58
 
59
59
  If a stale `npx` cache ever keeps serving an old version after a restart, clear it (`rm -rf ~/.npm/_npx`) or pin `rubien-mcp-server@latest` in the config. HTTP mode (below) runs as a long-lived process you started yourself — it does not auto-upgrade; restart it after updating Rubien.
60
60
 
61
+ ### Troubleshooting: "Server disconnected" in Claude Desktop
62
+
63
+ Claude Desktop never shows an MCP server's stderr — the actual error is in `~/Library/Logs/Claude/mcp-server-rubien.log`. Two known causes, both typically surfacing right after a reboot, because Claude Desktop only respawns MCP servers when the app itself relaunches:
64
+
65
+ - **Stale Rubien vs auto-upgraded server.** The unpinned `npx -y` install picks up new server releases at respawn; if Rubien.app hasn't been updated, the log shows `needs build >= N`. Fix: open Rubien.app and let Sparkle update it. Server ≥ 0.3.1 no longer disconnects for this — the instruction is returned to Claude on each tool call instead — but older servers exited at startup with only this log line as evidence.
66
+ - **No network at spawn.** `npx` resolves the package version against the npm registry on *every* spawn, even with a warm cache. If Claude Desktop launches at login before Wi-Fi/VPN is up, the spawn fails (`ENOTFOUND`/`ECONNREFUSED registry.npmjs.org` in the log) and Claude Desktop does not retry. Fix: quit and reopen Claude Desktop once online. To remove the network dependency entirely, install globally and point the config at the absolute path (`npm install -g rubien-mcp-server`, then `which rubien-mcp-server`) — at the cost of upgrading by hand with `npm update -g rubien-mcp-server`.
67
+
61
68
  ## claude.ai web (remote MCP server)
62
69
 
63
70
  claude.ai connects to rubien as a **remote MCP server** over Streamable HTTP — it can't spawn a local process. It's the *same npm package* in HTTP mode: the server still runs on your Mac (where the library and `rubien-cli` live), and claude.ai reaches it through a Cloudflare Tunnel, with a bearer token to keep strangers out.
package/dist/cli.js CHANGED
@@ -110,24 +110,60 @@ function extractFormat(args) {
110
110
  export async function invokeCliTyped(args, options = {}) {
111
111
  return (await invokeCli(args, options));
112
112
  }
113
+ /** Generous because the first exec of a signed binary after a reboot can be
114
+ * slowed by cold caches and Gatekeeper assessment; `rubien-cli version`
115
+ * itself is trivial (prints constants, never opens the database). The env
116
+ * override exists for tests. */
117
+ const PROBE_TIMEOUT_MS = 15_000;
118
+ function probeTimeoutMs() {
119
+ const env = Number(process.env.RUBIEN_MCP_PROBE_TIMEOUT_MS);
120
+ return Number.isFinite(env) && env > 0 ? env : PROBE_TIMEOUT_MS;
121
+ }
113
122
  /**
114
- * Probe `rubien-cli version` with a short timeout. Returns the parsed
115
- * {version, build} or null on any failure (missing subcommand on an old CLI,
116
- * non-zero exit, malformed output, timeout). Never throws.
123
+ * Probe `rubien-cli version` and classify the outcome. Never throws — the
124
+ * result feeds evaluateCliProbe (versionGuard.ts), which turns it into a
125
+ * startup log line or a per-tool-call error message.
117
126
  */
118
- export async function getCliVersion() {
127
+ export async function probeCliVersion() {
128
+ const envOverride = Boolean(process.env.RUBIEN_CLI?.length);
129
+ let cliPath;
130
+ try {
131
+ cliPath = resolveCliPath();
132
+ }
133
+ catch (err) {
134
+ return { kind: "not-found", detail: err.message, envOverride };
135
+ }
136
+ const timeoutMs = probeTimeoutMs();
119
137
  try {
120
- const result = await invokeCli(["version"], { timeoutMs: 5_000 });
121
- if (result &&
122
- typeof result === "object" &&
123
- typeof result.version === "string" &&
124
- typeof result.build === "number") {
125
- return result;
138
+ const { stdout } = await execFileAsync(cliPath, ["version"], {
139
+ timeout: timeoutMs,
140
+ maxBuffer: 1024 * 1024,
141
+ });
142
+ const parsed = JSON.parse(stdout.trim());
143
+ if (parsed &&
144
+ typeof parsed === "object" &&
145
+ typeof parsed.version === "string" &&
146
+ typeof parsed.build === "number") {
147
+ return { kind: "ok", info: parsed, envOverride };
126
148
  }
127
- return null;
149
+ return { kind: "no-version", path: cliPath, envOverride };
128
150
  }
129
- catch {
130
- return null;
151
+ catch (err) {
152
+ const e = err;
153
+ if (e.code === "ENOENT") {
154
+ return {
155
+ kind: "not-found",
156
+ detail: `no rubien-cli at ${cliPath}`,
157
+ envOverride,
158
+ };
159
+ }
160
+ // execFile sets killed:true when IT terminated the child at `timeout`;
161
+ // a child that died of its own signal (e.g. SIGSEGV) has killed:false
162
+ // and falls through to no-version.
163
+ if (e.killed === true) {
164
+ return { kind: "timeout", path: cliPath, timeoutMs, envOverride };
165
+ }
166
+ return { kind: "no-version", path: cliPath, envOverride };
131
167
  }
132
168
  }
133
169
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -6,8 +6,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
6
6
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
7
7
  import { buildServer } from "./server.js";
8
8
  import { requireBearer } from "./auth.js";
9
- import { getCliVersion } from "./cli.js";
10
- import { MIN_CLI_BUILD, evaluateCliVersion } from "./versionGuard.js";
9
+ import { MIN_CLI_BUILD, ensureCliCompatible } from "./versionGuard.js";
11
10
  const USAGE = `Usage:
12
11
  rubien-mcp-server [--stdio]
13
12
  rubien-mcp-server --http --port <port> --bearer-token <token>
@@ -65,6 +64,19 @@ async function runStdio() {
65
64
  const transport = new StdioServerTransport();
66
65
  await server.connect(transport);
67
66
  // MCP stdio transport keeps the process alive via stdin.
67
+ //
68
+ // CLI compatibility is deliberately NOT checked before connecting —
69
+ // buildServer gates every tool call instead (see cliGateError in
70
+ // toolHelpers.ts for why). The startup probe below only logs the verdict
71
+ // to stderr (e.g. ~/Library/Logs/Claude/mcp-server-rubien.log).
72
+ void ensureCliCompatible().then((guard) => {
73
+ process.stderr.write(guard.ok
74
+ ? `rubien-mcp-server: rubien-cli build ${guard.info?.build ?? "?"} >= ${MIN_CLI_BUILD} — compatible\n`
75
+ : `${guard.message}\n`);
76
+ }, () => {
77
+ // ensureCliCompatible never rejects by contract; guard anyway so a
78
+ // bug there can't become an unhandled rejection that kills the server.
79
+ });
68
80
  }
69
81
  async function runHttp(port, bearerToken) {
70
82
  const server = buildServer();
@@ -94,25 +106,26 @@ async function runHttp(port, bearerToken) {
94
106
  }
95
107
  async function main() {
96
108
  const args = parseCliArgs(process.argv.slice(2));
97
- // Version guard: probe the resolved CLI once, before connecting any
98
- // transport. `--help` already exited inside parseCliArgs, so help works
99
- // even with no CLI installed.
100
- const guard = evaluateCliVersion(await getCliVersion(), MIN_CLI_BUILD);
109
+ if (args.mode === "stdio") {
110
+ await runStdio();
111
+ return;
112
+ }
113
+ // HTTP mode keeps the fail-fast startup guard: the process is started by
114
+ // hand in a terminal where stderr is actually visible, and a long-lived
115
+ // degraded server behind a tunnel would be easier to miss than an
116
+ // immediate exit. `--help` already exited inside parseCliArgs, so help
117
+ // works even with no CLI installed.
118
+ const guard = await ensureCliCompatible();
101
119
  if (!guard.ok) {
102
120
  // Set exitCode + return rather than process.exit(1): the async stderr
103
121
  // write to a pipe can truncate if we exit immediately. No transport is
104
122
  // connected and the probe child has finished, so the event loop drains
105
123
  // and the process exits with code 1 after stderr flushes.
106
- process.stderr.write((guard.message ?? "rubien-cli version check failed") + "\n");
124
+ process.stderr.write(guard.message + "\n");
107
125
  process.exitCode = 1;
108
126
  return;
109
127
  }
110
- if (args.mode === "stdio") {
111
- await runStdio();
112
- }
113
- else {
114
- await runHttp(args.port, args.bearerToken);
115
- }
128
+ await runHttp(args.port, args.bearerToken);
116
129
  }
117
130
  main().catch((err) => {
118
131
  process.stderr.write(`fatal: ${err.stack ?? err.message}\n`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { cliGateError } from "./toolHelpers.js";
2
3
  import { registerReferenceTools } from "./tools/references.js";
3
4
  import { registerCitationTools } from "./tools/citations.js";
4
5
  import { registerIOTools } from "./tools/io.js";
@@ -9,12 +10,13 @@ import { registerPdfTools } from "./tools/pdf.js";
9
10
  import { registerReadTools } from "./tools/read.js";
10
11
  export const SERVER_INFO = {
11
12
  name: "rubien-mcp-server",
12
- version: "0.3.0",
13
+ version: "0.3.1",
13
14
  };
14
15
  export function buildServer() {
15
16
  const server = new McpServer(SERVER_INFO, {
16
17
  capabilities: { tools: {} },
17
18
  });
19
+ gateAllTools(server);
18
20
  registerReferenceTools(server);
19
21
  registerCitationTools(server);
20
22
  registerIOTools(server);
@@ -28,4 +30,24 @@ export function buildServer() {
28
30
  registerSyncTools(server);
29
31
  return server;
30
32
  }
33
+ /**
34
+ * Prefix every tool registered after this call with the rubien-cli
35
+ * compatibility gate (cliGateError). Applied at the registration seam so the
36
+ * invariant is structural: every tool shells out to rubien-cli, so none can
37
+ * do anything useful with an incompatible one, and a future bespoke handler
38
+ * that skips runCliAsTool (like rubien_render_pdf_page's typed-image path)
39
+ * cannot silently ship ungated. test/gate-invariant.test.ts enforces this
40
+ * across the whole catalog.
41
+ */
42
+ function gateAllTools(server) {
43
+ const original = server.registerTool.bind(server);
44
+ // registerTool's generic signature doesn't survive a wrapping assignment;
45
+ // the cast is contained here.
46
+ server.registerTool = ((name, config, handler) => original(name, config, (async (...handlerArgs) => {
47
+ const gateError = await cliGateError();
48
+ if (gateError)
49
+ return gateError;
50
+ return handler(...handlerArgs);
51
+ })));
52
+ }
31
53
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE,OAAO;CACR,CAAC;AAEX,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,WAAW,EAAE;QACxC,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;KAC5B,CAAC,CAAC;IAEH,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,eAAe,CAAC,MAAM,CAAC,CAAC;IACxB,wEAAwE;IACxE,sEAAsE;IACtE,6DAA6D;IAC7D,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE1B,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE,OAAO;CACR,CAAC;AAEX,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,WAAW,EAAE;QACxC,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;KAC5B,CAAC,CAAC;IAEH,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,eAAe,CAAC,MAAM,CAAC,CAAC;IACxB,wEAAwE;IACxE,sEAAsE;IACtE,6DAA6D;IAC7D,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE1B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,MAAiB;IACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClD,0EAA0E;IAC1E,8BAA8B;IAC9B,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,WAAsB,EAAE,EAAE;QAC1D,MAAM,SAAS,GAAG,MAAM,YAAY,EAAE,CAAC;QACvC,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;QAChC,OAAQ,OAAwC,CAAC,GAAG,WAAW,CAAC,CAAC;IACnE,CAAC,CAAmB,CAAC,CAA+B,CAAC;AACzD,CAAC"}
@@ -1,4 +1,27 @@
1
1
  import { CliError, invokeCli } from "./cli.js";
2
+ import { ensureCliCompatible } from "./versionGuard.js";
3
+ /** An `isError` CallToolResult carrying plain text. */
4
+ export function errorResult(text) {
5
+ return {
6
+ content: [{ type: "text", text }],
7
+ isError: true,
8
+ };
9
+ }
10
+ /**
11
+ * Version gate applied to every registered tool by buildServer (server.ts):
12
+ * when rubien-cli is missing or too old, return the update instruction as an
13
+ * `isError` tool result instead of failing some other way. Stdio clients
14
+ * (Claude Desktop) hide server stderr behind a generic "Server disconnected",
15
+ * so tool-call text is the only surface the user actually sees; the gate
16
+ * re-probes on every failing call, so updating Rubien mid-session recovers
17
+ * without a client restart. Returns null when the CLI is compatible.
18
+ */
19
+ export async function cliGateError() {
20
+ const guard = await ensureCliCompatible();
21
+ if (guard.ok)
22
+ return null;
23
+ return errorResult(guard.message);
24
+ }
2
25
  /**
3
26
  * Invoke rubien-cli and wrap the result as a CallToolResult. Errors from the
4
27
  * CLI are mapped to `isError: true` with the stderr message. Any other error
@@ -19,10 +42,7 @@ export async function runCliAsTool(args, options = {}) {
19
42
  }
20
43
  catch (err) {
21
44
  if (err instanceof CliError) {
22
- return {
23
- content: [{ type: "text", text: err.message }],
24
- isError: true,
25
- };
45
+ return errorResult(err.message);
26
46
  }
27
47
  throw err;
28
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"toolHelpers.js","sourceRoot":"","sources":["../src/toolHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAmB,MAAM,UAAU,CAAC;AAEhE;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAc,EAAE,UAAsB,EAAE;IACzE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,MAAM,GACV,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACxE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SACnD,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;YAC5B,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;gBACvD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAkE;IAElE,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QACpD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,KAAK;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzB,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"toolHelpers.js","sourceRoot":"","sources":["../src/toolHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAmB,MAAM,UAAU,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,uDAAuD;AACvD,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;QAC1C,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,KAAK,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC1C,IAAI,KAAK,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAc,EAAE,UAAsB,EAAE;IACzE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,MAAM,GACV,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACxE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SACnD,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;YAC5B,OAAO,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAkE;IAElE,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QACpD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,KAAK;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzB,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
package/dist/tools/pdf.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { CliError, invokeCliTyped } from "../cli.js";
3
- import { flagsFromOptions, runCliAsTool } from "../toolHelpers.js";
3
+ import { errorResult, flagsFromOptions, runCliAsTool } from "../toolHelpers.js";
4
4
  export function registerPdfTools(server) {
5
5
  server.registerTool("rubien_get_pdf_info", {
6
6
  title: "Probe PDF metadata + outline",
@@ -70,10 +70,7 @@ export function registerPdfTools(server) {
70
70
  }
71
71
  catch (err) {
72
72
  if (err instanceof CliError) {
73
- return {
74
- content: [{ type: "text", text: err.message }],
75
- isError: true,
76
- };
73
+ return errorResult(err.message);
77
74
  }
78
75
  throw err;
79
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pdf.js","sourceRoot":"","sources":["../../src/tools/pdf.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pdf.js","sourceRoot":"","sources":["../../src/tools/pdf.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { probeCliVersion } from "./cli.js";
1
2
  /**
2
3
  * The minimum rubien-cli build this server requires. Equals the build that
3
4
  * shipped the unified {op}_{target} surface (add --source one-door, update
@@ -8,25 +9,86 @@
8
9
  */
9
10
  export const MIN_CLI_BUILD = 26;
10
11
  const RELEASES = "https://github.com/devzhk/Rubien-releases/releases";
11
- /** Pure decision: is the discovered CLI new enough? `info` is null when the
12
- * CLI has no `version` subcommand (i.e. predates this mechanism). */
13
- export function evaluateCliVersion(info, minBuild) {
14
- if (info === null) {
15
- return {
16
- ok: false,
17
- message: `rubien-mcp-server: cannot determine rubien-cli version ` +
18
- `(your rubien-cli predates the 'version' command). ` +
19
- `Update Rubien.app (Mac) or download a newer rubien-cli from ${RELEASES} (Linux).`,
20
- };
12
+ const UPDATE_HINT = `Update Rubien.app (Mac) or download a newer rubien-cli from ${RELEASES} (Linux).`;
13
+ /** When rubien-cli came from $RUBIEN_CLI, "update the app" is dead advice —
14
+ * the override wins no matter what is installed. */
15
+ function overrideHint(probe) {
16
+ return probe.envOverride
17
+ ? ` Note: rubien-cli is resolved from your RUBIEN_CLI override — point it ` +
18
+ `at a newer binary, or unset it to use the one bundled with Rubien.app.`
19
+ : "";
20
+ }
21
+ /** Pure decision: turn a CLI probe outcome into a verdict + user-facing
22
+ * message. Messages must say what to DO — in stdio mode they are returned
23
+ * as tool-call text, the only surface Claude Desktop users ever see. */
24
+ export function evaluateCliProbe(probe, minBuild) {
25
+ switch (probe.kind) {
26
+ case "ok":
27
+ if (probe.info.build < minBuild) {
28
+ return {
29
+ ok: false,
30
+ message: `rubien-mcp-server: installed rubien-cli is build ${probe.info.build}, ` +
31
+ `but this server needs build >= ${minBuild}. ${UPDATE_HINT}` +
32
+ overrideHint(probe),
33
+ };
34
+ }
35
+ return { ok: true, info: probe.info };
36
+ case "not-found":
37
+ return {
38
+ ok: false,
39
+ message: `rubien-mcp-server: rubien-cli not found (${probe.detail}). ` +
40
+ `Install Rubien.app (Mac) — the CLI ships inside it — or download ` +
41
+ `rubien-cli from ${RELEASES} and set RUBIEN_CLI to its path (Linux).` +
42
+ overrideHint(probe),
43
+ };
44
+ case "timeout":
45
+ return {
46
+ ok: false,
47
+ message: `rubien-mcp-server: rubien-cli at ${probe.path} did not answer ` +
48
+ `'version' within ${Math.round(probe.timeoutMs / 1000)}s. This can ` +
49
+ `happen on the first launch after a reboot — retry in a moment. ` +
50
+ `If it persists, reinstall Rubien.app (Mac) or check the binary (Linux).` +
51
+ overrideHint(probe),
52
+ };
53
+ case "no-version":
54
+ // Reachable both by a genuinely old CLI (no `version` subcommand) and
55
+ // by a binary that ran but failed (crash, EACCES, garbage output) —
56
+ // don't claim to know which.
57
+ return {
58
+ ok: false,
59
+ message: `rubien-mcp-server: the binary at ${probe.path} did not report a ` +
60
+ `version — it either predates the 'version' command or is broken. ` +
61
+ `${UPDATE_HINT}` + overrideHint(probe),
62
+ };
21
63
  }
22
- if (info.build < minBuild) {
23
- return {
24
- ok: false,
25
- message: `rubien-mcp-server: installed rubien-cli is build ${info.build}, ` +
26
- `but this server needs build >= ${minBuild}. ` +
27
- `Update Rubien.app (Mac) or download a newer rubien-cli from ${RELEASES} (Linux).`,
28
- };
64
+ }
65
+ let compatible = false;
66
+ let inFlight = null;
67
+ /**
68
+ * Probe-and-evaluate with success caching: once a compatible CLI is seen the
69
+ * check short-circuits for the life of the process; failures are never
70
+ * cached, so every failing tool call re-probes. Updating Rubien.app
71
+ * mid-session therefore recovers on the next call — important because
72
+ * Claude Desktop only respawns MCP servers when the app itself relaunches.
73
+ *
74
+ * Concurrent callers share one in-flight probe (the startup log probe and a
75
+ * first tool call routinely race, and a degraded server can get a burst of
76
+ * calls) — without collapsing recovery: the shared promise is dropped once
77
+ * settled, so the next call after a failure re-probes.
78
+ */
79
+ export async function ensureCliCompatible() {
80
+ if (compatible)
81
+ return { ok: true };
82
+ if (!inFlight) {
83
+ inFlight = (async () => {
84
+ const verdict = evaluateCliProbe(await probeCliVersion(), MIN_CLI_BUILD);
85
+ if (verdict.ok)
86
+ compatible = true;
87
+ return verdict;
88
+ })().finally(() => {
89
+ inFlight = null;
90
+ });
29
91
  }
30
- return { ok: true };
92
+ return inFlight;
31
93
  }
32
94
  //# sourceMappingURL=versionGuard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"versionGuard.js","sourceRoot":"","sources":["../src/versionGuard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAYhC,MAAM,QAAQ,GAAG,oDAAoD,CAAC;AAEtE;sEACsE;AACtE,MAAM,UAAU,kBAAkB,CAChC,IAAuB,EACvB,QAAgB;IAEhB,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EACL,yDAAyD;gBACzD,oDAAoD;gBACpD,+DAA+D,QAAQ,WAAW;SACrF,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,GAAG,QAAQ,EAAE,CAAC;QAC1B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EACL,oDAAoD,IAAI,CAAC,KAAK,IAAI;gBAClE,kCAAkC,QAAQ,IAAI;gBAC9C,+DAA+D,QAAQ,WAAW;SACrF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"versionGuard.js","sourceRoot":"","sources":["../src/versionGuard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAiB,MAAM,UAAU,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAWhC,MAAM,QAAQ,GAAG,oDAAoD,CAAC;AACtE,MAAM,WAAW,GAAG,+DAA+D,QAAQ,WAAW,CAAC;AAEvG;qDACqD;AACrD,SAAS,YAAY,CAAC,KAAe;IACnC,OAAO,KAAK,CAAC,WAAW;QACtB,CAAC,CAAC,yEAAyE;YACzE,wEAAwE;QAC1E,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED;;yEAEyE;AACzE,MAAM,UAAU,gBAAgB,CAC9B,KAAe,EACf,QAAgB;IAEhB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,IAAI;YACP,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,EAAE,CAAC;gBAChC,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,OAAO,EACL,oDAAoD,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI;wBACxE,kCAAkC,QAAQ,KAAK,WAAW,EAAE;wBAC5D,YAAY,CAAC,KAAK,CAAC;iBACtB,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;QACxC,KAAK,WAAW;YACd,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EACL,4CAA4C,KAAK,CAAC,MAAM,KAAK;oBAC7D,mEAAmE;oBACnE,mBAAmB,QAAQ,0CAA0C;oBACrE,YAAY,CAAC,KAAK,CAAC;aACtB,CAAC;QACJ,KAAK,SAAS;YACZ,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EACL,oCAAoC,KAAK,CAAC,IAAI,kBAAkB;oBAChE,oBAAoB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,cAAc;oBACpE,iEAAiE;oBACjE,yEAAyE;oBACzE,YAAY,CAAC,KAAK,CAAC;aACtB,CAAC;QACJ,KAAK,YAAY;YACf,sEAAsE;YACtE,oEAAoE;YACpE,6BAA6B;YAC7B,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EACL,oCAAoC,KAAK,CAAC,IAAI,oBAAoB;oBAClE,mEAAmE;oBACnE,GAAG,WAAW,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC;aACzC,CAAC;IACN,CAAC;AACH,CAAC;AAED,IAAI,UAAU,GAAG,KAAK,CAAC;AACvB,IAAI,QAAQ,GAAgC,IAAI,CAAC;AAEjD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,IAAI,UAAU;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,CAAC,KAAK,IAAI,EAAE;YACrB,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,eAAe,EAAE,EAAE,aAAa,CAAC,CAAC;YACzE,IAAI,OAAO,CAAC,EAAE;gBAAE,UAAU,GAAG,IAAI,CAAC;YAClC,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAChB,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rubien-mcp-server",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "MCP server wrapping rubien-cli so Claude Code and claude.ai can manage the Rubien reference library.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "devzhk",