@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 +6 -0
- package/README.md +23 -25
- package/README.zh-CN.md +6 -8
- package/dist/src/bun/httpServer.js +1 -1
- package/dist/src/bun/index.js +1 -1
- package/dist/src/cli/index.js +3 -53
- package/dist/src/cli/status.js +6 -6
- package/dist/src/mcp/prompts.js +1 -1
- package/package.json +1 -2
- package/src/bun/index.ts +0 -120
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
|
|
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
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
If MICA is installed on your `PATH`, the same release commands are:
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
mica install
|
|
103
|
-
mica
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
303
|
+
| `FAIL Session file` | Server 尚未启动 | `mica mcp` |
|
|
306
304
|
| `FAIL Auth token` | Token 不匹配或已过期 | 重启 server |
|
|
307
|
-
| `FAIL Server /status reachable` | Server 未运行 | `mica
|
|
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.
|
|
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,
|
package/dist/src/bun/index.js
CHANGED
|
@@ -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.
|
|
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;
|
package/dist/src/cli/index.js
CHANGED
|
@@ -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
|
-
|
|
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(),
|
package/dist/src/cli/status.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
70
|
+
lines.push("FIX Run: mica mcp");
|
|
71
71
|
return result(1, lines, false);
|
|
72
72
|
}
|
|
73
73
|
}
|
package/dist/src/mcp/prompts.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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 };
|