@aliceshimada/mica 1.0.2 → 1.0.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.3 - 2026-06-06
4
+
5
+ - Deprecate `mica start`, `mica stop`, and `mica restart` commands.
6
+ - `mica start` and bare `mica` (no args) are now aliases for `mica mcp`.
7
+ - `mica mcp` starts an MCP stdio server, proxying to an existing bridge or starting a new one.
8
+
3
9
  ## 1.0.2 - 2026-06-06
4
10
 
5
11
  - Add `mica mcp` command: starts an MCP stdio server that proxies to an existing bridge or starts a new one.
package/README.md CHANGED
@@ -77,34 +77,32 @@ mica install
77
77
  Then fully quit and restart Wolfram Desktop. Open a notebook, start the MCP server, and connect your MCP client:
78
78
 
79
79
  ```bash
80
- mica start
80
+ mica mcp
81
81
  ```
82
82
 
83
- Or from a release checkout:
83
+ Or from a release checkout:
84
84
 
85
85
  ```bash
86
86
  git clone https://github.com/Alice-Shimada/mica.git
87
87
  cd mica
88
- npm ci
89
- npm run build
90
- node dist/src/cli/index.js install
91
- ```
92
-
93
- Then fully quit and restart Wolfram Desktop. Open a notebook, start the MCP server, and connect your MCP client:
94
-
95
- ```bash
96
- node dist/src/cli/index.js start
97
- ```
98
-
99
- If MICA is installed on your `PATH`, the same release commands are:
100
-
101
- ```bash
102
- mica install
103
- mica start
104
- mica doctor
105
- mica status
106
- mica stop
107
- mica restart
88
+ npm ci
89
+ npm run build
90
+ node dist/src/cli/index.js install
91
+ ```
92
+
93
+ Then fully quit and restart Wolfram Desktop. Open a notebook, start the MCP server, and connect your MCP client:
94
+
95
+ ```bash
96
+ node dist/src/cli/index.js mcp
97
+ ```
98
+
99
+ If MICA is installed on your `PATH`, the same release commands are:
100
+
101
+ ```bash
102
+ mica install
103
+ mica mcp
104
+ mica doctor
105
+ mica status
108
106
  ```
109
107
 
110
108
  Dashboard:
@@ -124,7 +122,7 @@ node dist/src/cli/index.js install --dry-run
124
122
  node dist/src/cli/index.js uninstall
125
123
  ```
126
124
 
127
- `mica status` prints the current session file, server URL, version, PID, live agent/notebook counts, and the token-bearing dashboard URL. If a server is already running, `mica start` prints that same status instead of failing with a port-in-use error, so you can recover the dashboard token at any time.
125
+ `mica status` prints the current session file, server URL, version, PID, live agent/notebook counts, and the token-bearing dashboard URL. If a server is already running, `mica mcp` proxies to it instead of failing with a port-in-use error, so you can recover the dashboard token at any time.
128
126
 
129
127
  The legacy installer entry remains available for compatibility: `node scripts/install.js --dry-run`.
130
128
 
@@ -302,9 +300,9 @@ The doctor checks Node version, package build, session file, auth token, server
302
300
 
303
301
  | Doctor output | Likely cause | Action |
304
302
  | --- | --- | --- |
305
- | `FAIL Session file` | Server never started | `mica start` |
303
+ | `FAIL Session file` | Server never started | `mica mcp` |
306
304
  | `FAIL Auth token` | Token mismatch or expired | Restart the server |
307
- | `FAIL Server /status reachable` | Server not running | `mica start` |
305
+ | `FAIL Server /status reachable` | Server not running | `mica mcp` |
308
306
  | `FAIL Live agent count: 0` | Wolfram not running or bridge not loaded | Restart Wolfram Desktop after install |
309
307
  | `FAIL Live notebook count: 0` | No notebook open or registered | Open a notebook in Wolfram Desktop |
310
308
  | `FAIL Kernel/init.m` | Installer not run | `mica install` |
package/README.zh-CN.md CHANGED
@@ -77,7 +77,7 @@ mica install
77
77
  然后完全退出并重启 Wolfram Desktop。打开一个 Notebook,启动 MCP server,并连接你的 MCP client:
78
78
 
79
79
  ```bash
80
- mica start
80
+ mica mcp
81
81
  ```
82
82
 
83
83
  或者从发布版 checkout 开始:
@@ -93,18 +93,16 @@ node dist/src/cli/index.js install
93
93
  然后完全退出并重启 Wolfram Desktop。打开一个 Notebook,启动 MCP server,并连接你的 MCP client:
94
94
 
95
95
  ```bash
96
- node dist/src/cli/index.js start
96
+ node dist/src/cli/index.js mcp
97
97
  ```
98
98
 
99
99
  如果 MICA 已经安装在你的 `PATH` 中,也可以使用等价的发布版命令:
100
100
 
101
101
  ```bash
102
102
  mica install
103
- mica start
103
+ mica mcp
104
104
  mica doctor
105
105
  mica status
106
- mica stop
107
- mica restart
108
106
  ```
109
107
 
110
108
  Dashboard:
@@ -124,7 +122,7 @@ node dist/src/cli/index.js install --dry-run
124
122
  node dist/src/cli/index.js uninstall
125
123
  ```
126
124
 
127
- `mica status` 会打印当前 session file、server URL、version、PID、live agent/notebook 数量,以及带 token 的 dashboard URL。如果 server 已经在运行,`mica start` 会打印同样的 status,而不是因为端口占用直接失败;因此你随时可以用它找回 dashboard token。
125
+ `mica status` 会打印当前 session file、server URL、version、PID、live agent/notebook 数量,以及带 token 的 dashboard URL。如果 server 已经在运行,`mica mcp` 会代理到已有后端,而不是因为端口占用直接失败;因此你随时可以用它找回 dashboard token。
128
126
 
129
127
  兼容用的 legacy 安装入口仍然可用:`node scripts/install.js --dry-run`。
130
128
 
@@ -302,9 +300,9 @@ Doctor 会检查 Node 版本、package build、session file、auth token、serve
302
300
 
303
301
  | Doctor output | 可能原因 | 操作 |
304
302
  | --- | --- | --- |
305
- | `FAIL Session file` | Server 尚未启动 | `mica start` |
303
+ | `FAIL Session file` | Server 尚未启动 | `mica mcp` |
306
304
  | `FAIL Auth token` | Token 不匹配或已过期 | 重启 server |
307
- | `FAIL Server /status reachable` | Server 未运行 | `mica start` |
305
+ | `FAIL Server /status reachable` | Server 未运行 | `mica mcp` |
308
306
  | `FAIL Live agent count: 0` | Wolfram 未运行或 bridge 未加载 | 安装后重启 Wolfram Desktop |
309
307
  | `FAIL Live notebook count: 0` | 没有打开或注册的 Notebook | 在 Wolfram Desktop 中打开 Notebook |
310
308
  | `FAIL Kernel/init.m` | 尚未运行安装器 | `mica install` |
@@ -3,7 +3,7 @@ import http from "node:http";
3
3
  import { executeBackendMcpTool } from "../mcp/backendTools.js";
4
4
  import { renderDashboard } from "./dashboard.js";
5
5
  const JSON_BODY_LIMIT_BYTES = 1024 * 1024;
6
- const DEFAULT_VERSION = "1.0.2";
6
+ const DEFAULT_VERSION = "1.0.3";
7
7
  export async function createBunHttpApp({ state, host = "127.0.0.1", port, authToken, version = DEFAULT_VERSION }) {
8
8
  const runtimeInfo = {
9
9
  host,
@@ -8,7 +8,7 @@ import { loadRuntimeConfig } from "../runtime/config.js";
8
8
  import { writeSessionFile } from "../runtime/session.js";
9
9
  import { createBunHttpApp } from "./httpServer.js";
10
10
  const MCP_SERVER_NAME = "mica-bun";
11
- const MICA_PACKAGE_VERSION = "1.0.2";
11
+ const MICA_PACKAGE_VERSION = "1.0.3";
12
12
  export async function startBunRuntime(deps = {}) {
13
13
  const config = deps.runtimeConfig ?? loadRuntimeConfig();
14
14
  const bridgeOnly = deps.bridgeOnly ?? config.bridgeOnly;
@@ -10,7 +10,6 @@ import { defaultSessionFile } from "../runtime/config.js";
10
10
  import { runConfigCommand } from "./configSnippets.js";
11
11
  import { runDoctor } from "./doctor.js";
12
12
  import { runStatusCommand } from "./status.js";
13
- import { runStopCommand } from "./stop.js";
14
13
  // ---------------------------------------------------------------------------
15
14
  // Helpers
16
15
  // ---------------------------------------------------------------------------
@@ -82,10 +81,7 @@ export function helpText() {
82
81
  return `Usage: mica <command> [options]
83
82
 
84
83
  Commands:
85
- start Start the MICA bridge runtime (default)
86
- stop Stop the running MICA bridge runtime
87
- restart Stop then start the MICA bridge runtime
88
- mcp Start MCP stdio server; proxy to an existing bridge if possible
84
+ mcp Run MCP stdio server (proxy to existing bridge or launch new)
89
85
  install [options] Install MICA bridge into Wolfram
90
86
  uninstall [options] Uninstall MICA bridge from Wolfram
91
87
  doctor Diagnose MICA bridge configuration
@@ -108,7 +104,6 @@ export async function runCli(argv, deps) {
108
104
  const _runDoctor = deps?.runDoctor;
109
105
  const _runStatus = deps?.runStatus;
110
106
  const _runConfig = deps?.runConfig;
111
- const _runStop = deps?.runStop;
112
107
  const _readLiveSession = deps?.readLiveSession ?? (() => readLiveSession(argv.slice(1)));
113
108
  const _startProxyRuntime = deps?.startProxyRuntime ?? ((session) => startProxyMcpRuntime(session));
114
109
  const _sleep = deps?.sleep ?? sleep;
@@ -138,25 +133,8 @@ export async function runCli(argv, deps) {
138
133
  stdout.write(output);
139
134
  return 0;
140
135
  }
141
- // start or no args
142
- if (command === "start" || command === undefined) {
143
- if (_runStatus) {
144
- const status = await _runStatus();
145
- if (status.running) {
146
- stdout.write(status.output);
147
- return status.exitCode;
148
- }
149
- }
150
- if (!startRuntime) {
151
- stderr.write("Error: startRuntime not available\n");
152
- return 1;
153
- }
154
- const runtime = await startRuntime();
155
- await runtime.keepAlive;
156
- return 0;
157
- }
158
- // mcp
159
- if (command === "mcp") {
136
+ // mcp (also start, or no args)
137
+ if (command === "mcp" || command === "start" || command === undefined) {
160
138
  const existingSession = await _readLiveSession();
161
139
  if (existingSession) {
162
140
  const proxyRuntime = await _startProxyRuntime(existingSession);
@@ -219,33 +197,6 @@ export async function runCli(argv, deps) {
219
197
  stdout.write(output);
220
198
  return exitCode;
221
199
  }
222
- // stop
223
- if (command === "stop") {
224
- if (!_runStop) {
225
- stderr.write("Error: runStop not available\n");
226
- return 1;
227
- }
228
- const { exitCode, output } = await _runStop();
229
- stdout.write(output);
230
- return exitCode;
231
- }
232
- // restart
233
- if (command === "restart") {
234
- if (!_runStop) {
235
- stderr.write("Error: runStop not available\n");
236
- return 1;
237
- }
238
- if (!startRuntime) {
239
- stderr.write("Error: startRuntime not available\n");
240
- return 1;
241
- }
242
- const stopResult = await _runStop();
243
- if (stopResult.output)
244
- stdout.write(stopResult.output);
245
- const runtime = await startRuntime();
246
- await runtime.keepAlive;
247
- return 0;
248
- }
249
200
  // Unknown command
250
201
  stderr.write(`Unknown command: ${command}\n`);
251
202
  return 1;
@@ -264,7 +215,6 @@ async function main() {
264
215
  runInstaller,
265
216
  runStatus: async () => runStatusCommand(),
266
217
  runConfig: runConfigCommand,
267
- runStop: async () => runStopCommand(),
268
218
  runDoctor: async () => runDoctor({
269
219
  projectRoot,
270
220
  detectWolframUserBase: () => detectWolframUserBase(),
@@ -14,7 +14,7 @@ export async function runStatusCommand(deps = {}) {
14
14
  const ok = (label, detail) => lines.push(`OK ${label}: ${detail}`);
15
15
  if (!_exists(sessionFile)) {
16
16
  fail("Session file", `${sessionFile} (not found)`);
17
- lines.push("FIX Run: mica start");
17
+ lines.push("FIX Run: mica mcp");
18
18
  return result(1, lines, false);
19
19
  }
20
20
  let session;
@@ -23,7 +23,7 @@ export async function runStatusCommand(deps = {}) {
23
23
  }
24
24
  catch (error) {
25
25
  fail("Session file", error instanceof Error ? error.message : String(error));
26
- lines.push("FIX Run: mica start");
26
+ lines.push("FIX Run: mica mcp");
27
27
  return result(1, lines, false);
28
28
  }
29
29
  const baseUrl = session.baseUrl ?? `http://${session.host ?? "127.0.0.1"}:${session.port ?? 19791}`;
@@ -31,7 +31,7 @@ export async function runStatusCommand(deps = {}) {
31
31
  ok("Session target", baseUrl);
32
32
  if (!session.authToken) {
33
33
  fail("Auth token", "missing in session file");
34
- lines.push("FIX Restart MICA with: mica start");
34
+ lines.push("FIX Restart MICA with: mica mcp");
35
35
  return result(1, lines, false);
36
36
  }
37
37
  if (!_fetch) {
@@ -44,12 +44,12 @@ export async function runStatusCommand(deps = {}) {
44
44
  });
45
45
  if (response.status === 401) {
46
46
  fail("Auth token", "401 Unauthorized");
47
- lines.push("FIX Restart MICA with: mica start");
47
+ lines.push("FIX Restart MICA with: mica mcp");
48
48
  return result(1, lines, false);
49
49
  }
50
50
  if (response.status !== 200) {
51
51
  fail("Server /status reachable", `HTTP ${response.status}`);
52
- lines.push("FIX Run: mica start");
52
+ lines.push("FIX Run: mica mcp");
53
53
  return result(1, lines, false);
54
54
  }
55
55
  const body = (await response.json());
@@ -67,7 +67,7 @@ export async function runStatusCommand(deps = {}) {
67
67
  }
68
68
  catch (error) {
69
69
  fail("Server /status reachable", error instanceof Error ? error.message : String(error));
70
- lines.push("FIX Run: mica start");
70
+ lines.push("FIX Run: mica mcp");
71
71
  return result(1, lines, false);
72
72
  }
73
73
  }
@@ -33,7 +33,7 @@ export const MICA_AGENT_INSTRUCTIONS = [
33
33
  "Tools:",
34
34
  ...TOOL_GUIDE.map(([name, description]) => `- ${name}: ${description}`),
35
35
  ].join("\n");
36
- export function createMicaMcpServer(name, version = "1.0.2") {
36
+ export function createMicaMcpServer(name, version = "1.0.3") {
37
37
  return new McpServer({ name, version }, { instructions: MICA_AGENT_INSTRUCTIONS });
38
38
  }
39
39
  export function registerMicaPrompts(server) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aliceshimada/mica",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Local MCP bridge for controlling live Wolfram Desktop / Mathematica notebooks.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -23,7 +23,6 @@
23
23
  },
24
24
  "files": [
25
25
  "dist/src",
26
- "src/bun/index.ts",
27
26
  "paclet",
28
27
  "README.md",
29
28
  "README.zh-CN.md",
package/src/bun/index.ts DELETED
@@ -1,120 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
- import { randomUUID } from "node:crypto";
4
- import { pathToFileURL } from "node:url";
5
- import { BackendState } from "../backend/backendState.js";
6
- import { registerBackendMcpTools } from "../mcp/backendTools.js";
7
- import { createMicaMcpServer, registerMicaPrompts } from "../mcp/prompts.js";
8
- import type { MicaRuntimeConfig } from "../runtime/config.js";
9
- import { loadRuntimeConfig } from "../runtime/config.js";
10
- import { writeSessionFile } from "../runtime/session.js";
11
- import { createBunHttpApp } from "./httpServer.js";
12
-
13
- const MCP_SERVER_NAME = "mica-bun";
14
- const MICA_PACKAGE_VERSION = "1.0.2";
15
-
16
- export type BunRuntimeDeps = {
17
- bridgeOnly?: boolean;
18
- createHttpApp?: typeof createBunHttpApp;
19
- createMcpServer?: () => Pick<McpServer, "connect" | "prompt" | "tool">;
20
- createTransport?: () => StdioServerTransport;
21
- installSignalHandlers?: (onSignal: (signal: NodeJS.Signals) => void) => () => void;
22
- runtimeConfig?: MicaRuntimeConfig;
23
- state?: BackendState;
24
- version?: string;
25
- writeSessionFile?: typeof writeSessionFile;
26
- };
27
-
28
- export type BunRuntime = {
29
- state: BackendState;
30
- httpApp: Awaited<ReturnType<typeof createBunHttpApp>>;
31
- stop: () => Promise<void>;
32
- keepAlive: Promise<void>;
33
- };
34
-
35
- export async function startBunRuntime(deps: BunRuntimeDeps = {}): Promise<BunRuntime> {
36
- const config = deps.runtimeConfig ?? loadRuntimeConfig();
37
- const bridgeOnly = deps.bridgeOnly ?? config.bridgeOnly;
38
- const state = deps.state ?? new BackendState(() => `notebook-${randomUUID()}`);
39
- const createHttpApp = deps.createHttpApp ?? createBunHttpApp;
40
- const createMcpServer = deps.createMcpServer ?? (() => createMicaMcpServer(MCP_SERVER_NAME));
41
- const createTransport = deps.createTransport ?? (() => new StdioServerTransport());
42
- const writeSession = deps.writeSessionFile ?? writeSessionFile;
43
- const version = deps.version ?? MICA_PACKAGE_VERSION;
44
- const installSignalHandlers =
45
- deps.installSignalHandlers ??
46
- ((onSignal: (signal: NodeJS.Signals) => void) => {
47
- process.once("SIGINT", onSignal);
48
- process.once("SIGTERM", onSignal);
49
- return () => {
50
- process.off("SIGINT", onSignal);
51
- process.off("SIGTERM", onSignal);
52
- };
53
- });
54
- const httpApp = await createHttpApp({ state, host: config.host, port: config.preferredPort, authToken: config.authToken, version });
55
- let cleanupSignals = () => {};
56
- let stopped = false;
57
- let stopPromise: Promise<void> | undefined;
58
-
59
- const stop = async (): Promise<void> => {
60
- if (stopPromise) return stopPromise;
61
- stopPromise = (async () => {
62
- if (stopped) return;
63
- stopped = true;
64
- cleanupSignals();
65
- await httpApp.stop();
66
- })();
67
- return stopPromise;
68
- };
69
-
70
- const onSignal = (signal: NodeJS.Signals) => {
71
- void stop().finally(() => process.exit(0));
72
- };
73
-
74
- try {
75
- cleanupSignals = installSignalHandlers(onSignal);
76
- await writeSession(config.sessionFile, {
77
- host: config.host,
78
- port: httpApp.port,
79
- authToken: config.authToken,
80
- pid: process.pid,
81
- version,
82
- status: "running",
83
- });
84
- const server = createMcpServer();
85
- registerBackendMcpTools(server as McpServer, state);
86
- registerMicaPrompts(server);
87
-
88
- console.error(`Bun HTTP server listening on http://${config.host}:${httpApp.port}`);
89
- console.error(`Dashboard: http://${config.host}:${httpApp.port}/#token=${config.authToken}`);
90
- if (!bridgeOnly) {
91
- console.error("Bun MCP mode enabled; connecting stdio transport.");
92
- await server.connect(createTransport());
93
- }
94
- } catch (error) {
95
- await stop();
96
- throw error;
97
- }
98
-
99
- return {
100
- state,
101
- httpApp,
102
- stop,
103
- keepAlive: new Promise<void>(() => {})
104
- };
105
- }
106
-
107
- async function main(): Promise<void> {
108
- const runtime = await startBunRuntime();
109
- await runtime.keepAlive;
110
- }
111
-
112
- if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
113
- main().catch((error) => {
114
- const message = error instanceof Error ? error.stack ?? error.message : String(error);
115
- console.error(message);
116
- process.exitCode = 1;
117
- });
118
- }
119
-
120
- export { MCP_SERVER_NAME };