@classcad/mcp 0.2.2 → 0.3.0

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 (72) hide show
  1. package/README.md +128 -87
  2. package/dist/app/SOURCE.txt +4 -0
  3. package/dist/app/assets/index-54a14bc0.css +8 -0
  4. package/dist/app/assets/index-c650c783.js +11257 -0
  5. package/dist/app/assets/troika-three-text.esm-188d86b5.js +220 -0
  6. package/dist/app/favicon.svg +98 -0
  7. package/dist/app/index.html +19 -0
  8. package/dist/app/manifest.json +14 -0
  9. package/dist/auth.d.ts +8 -0
  10. package/dist/auth.js +49 -10
  11. package/dist/auth.js.map +1 -1
  12. package/dist/backend.d.ts +8 -0
  13. package/dist/backend.js +39 -0
  14. package/dist/backend.js.map +1 -0
  15. package/dist/client.d.ts +48 -11
  16. package/dist/client.js +152 -167
  17. package/dist/client.js.map +1 -1
  18. package/dist/daemon.d.ts +0 -2
  19. package/dist/daemon.js +77 -62
  20. package/dist/daemon.js.map +1 -1
  21. package/dist/engine/key.d.ts +29 -0
  22. package/dist/engine/key.js +145 -0
  23. package/dist/engine/key.js.map +1 -0
  24. package/dist/engine/wasm-worker.js +7 -7
  25. package/dist/engine/wasm-worker.js.map +1 -1
  26. package/dist/engine/wasm.d.ts +16 -14
  27. package/dist/engine/wasm.js +22 -30
  28. package/dist/engine/wasm.js.map +1 -1
  29. package/dist/mcp-server.d.ts +4 -4
  30. package/dist/mcp-server.js +72 -28
  31. package/dist/mcp-server.js.map +1 -1
  32. package/dist/queue.js +1 -1
  33. package/dist/queue.js.map +1 -1
  34. package/dist/server.js +69 -36
  35. package/dist/server.js.map +1 -1
  36. package/dist/share/hub.d.ts +70 -0
  37. package/dist/share/hub.js +494 -0
  38. package/dist/share/hub.js.map +1 -0
  39. package/dist/share/protocol.d.ts +87 -0
  40. package/dist/share/protocol.js +54 -0
  41. package/dist/share/protocol.js.map +1 -0
  42. package/dist/share/relay.d.ts +45 -0
  43. package/dist/share/relay.js +230 -0
  44. package/dist/share/relay.js.map +1 -0
  45. package/dist/share/server.d.ts +27 -0
  46. package/dist/share/server.js +399 -0
  47. package/dist/share/server.js.map +1 -0
  48. package/dist/share/session.d.ts +120 -0
  49. package/dist/share/session.js +336 -0
  50. package/dist/share/session.js.map +1 -0
  51. package/dist/tools/auth.js +1 -1
  52. package/dist/tools/auth.js.map +1 -1
  53. package/dist/tools/docs.js +3 -2
  54. package/dist/tools/docs.js.map +1 -1
  55. package/dist/tools/lifecycle.js +36 -9
  56. package/dist/tools/lifecycle.js.map +1 -1
  57. package/dist/tools/share.d.ts +18 -0
  58. package/dist/tools/share.js +277 -0
  59. package/dist/tools/share.js.map +1 -0
  60. package/dist/tools/viewer.d.ts +1 -1
  61. package/dist/tools/viewer.js +11 -6
  62. package/dist/tools/viewer.js.map +1 -1
  63. package/package.json +4 -3
  64. package/dist/bridge/protocol.d.ts +0 -87
  65. package/dist/bridge/protocol.js +0 -14
  66. package/dist/bridge/protocol.js.map +0 -1
  67. package/dist/bridge/server.d.ts +0 -35
  68. package/dist/bridge/server.js +0 -236
  69. package/dist/bridge/server.js.map +0 -1
  70. package/dist/tools/bridge.d.ts +0 -4
  71. package/dist/tools/bridge.js +0 -115
  72. package/dist/tools/bridge.js.map +0 -1
@@ -6,14 +6,14 @@
6
6
  // • the assets of one ClassCAD release (~16 MB compressed, ~85 MB unpacked: glue, main module, three
7
7
  // side modules, class file, filter config), downloaded once from
8
8
  // awvstatic.com into CLASSCAD_WASM_DIR (default ~/.classcad-mcp/wasm/<version>),
9
- // • a ClassCAD key whose allowed origins include the origin the engine is
10
- // told it runs on (CLASSCAD_WASM_ORIGIN, default http://localhost:3000).
11
- // A six-month key is built in (DEV_WASM_KEY); CLASSCAD_WASM_KEY
12
- // overrides it. Keys and origins are managed on classcad.ch/user.
9
+ // • a ClassCAD key for the origin the engine is told it runs on
10
+ // (http://localhost). The backend issues it for the signed-in account, or
11
+ // for CLASSCAD_TOKEN on CI (engine/key.ts); keys for local use name
12
+ // `localhost`, which the engine matches on any port.
13
13
  //
14
- // One engine = one drawing = one MCP session. execute() has the same shape
15
- // as the app bridge's engine.execute (messages + inflated binary packages),
16
- // so the client treats both the same way.
14
+ // One engine = one drawing = one MCP session. Apps dock into that session
15
+ // through share/hub.ts, which speaks a ClassCAD server's session protocol
16
+ // for this engine.
17
17
  import { Worker } from 'node:worker_threads';
18
18
  import { createWriteStream, existsSync, mkdirSync, renameSync, statSync, unlinkSync } from 'node:fs';
19
19
  import { pipeline } from 'node:stream/promises';
@@ -21,27 +21,20 @@ import { Readable } from 'node:stream';
21
21
  import { homedir } from 'node:os';
22
22
  import { join, dirname } from 'node:path';
23
23
  import { fileURLToPath } from 'node:url';
24
+ import { engineKey } from './key.js';
24
25
  /** The ClassCAD release the MCP hosts (the same the buerli apps load). */
25
26
  export const DEFAULT_WASM_VERSION = '21.2.0';
26
- /**
27
- * The MCP's built-in key: wasm, enterprise, allowed origin http://localhost:3000,
28
- * valid for six months (issued 2026-09-30). Built in so the local engine needs
29
- * no configuration; CLASSCAD_WASM_KEY overrides it. Renew it before
30
- * DEV_WASM_KEY_EXPIRES with buerli-backend/functions/scripts/appkey.mjs and
31
- * ship a release: the engine refuses an expired key.
32
- */
33
- export const DEV_WASM_KEY = 'MS4xLlZZUG51VkNpOGdjQm50RXB0VkE1RnQ1ekVVazNOR1dYMk9weHlxRGJjazRSdGYwTFRPTFl5NVdjYmY4VnFOOXlWTDQ0OUNzSExTbmhQRHZpNEVidXRubFJhZUpQVVA3aW1xZFBlWXlIcFRocFVlamVSZmJUaVM3aWcwWnlpdXNjSm5OaHFnTDhmN2EvSVRsZWxFQy9BRXJSQzZ5VUNLUC9UbFBiTTFINk10UlhNbkYwZm5QN2J0bE5DSWdWWW5RTldFSjFNcGYzaEJ4VjBjTHZlcW9tUXY0bklzVFFWSVl5T0hZVHM4ZU8vbENlaTZhdGxFbERycy9WVldoZHIwNm5DdWRvVEhTNGlmSGRWQ2FSak5QSmVNc1BmK1ZMYm5WVFI4aXl2MENadW1MbEsra2N3L0tqc0hLanZTUXJBTG5EQjcvOWpjcFhwbHlHNkFYRVppeVVESFZ0Ly9EL1VKdndMZ2E3S1ZFcFNRTStmS0xSZDR0RFYrVU41VHBrZ0wvYk5uK2huR3FHU2FtUExybXVGdXQ0T0EycHhiSlNZakZvYjFqbUZEbG5hVk1BTW11c1RqblVyQklGWGFxOUJDZnZRck13eHlGeE1RdEtCdGpnQUd5b1VSNmZmaFRXWVhpOGVtL2ZkU3hMNjFRamF4ejdLVExPS3pFOXJVMVgzcXBPQVo1NEFVenFVVzg0Zk9BeUZ0KzRMT2M0dzJMMWJ1U0YxUkZFby9CZXZ4UGRzQ3A4ZWUxMUxiTDRCQ0pFUEZJMGQyYU9JU0grN0NqOFZhVEpHb2JKVys3cktPemUyTTE4V3hOZnJMWVlhZXJzdDEwdDl1YTFja3lPdUZzRjMwdWFiejUvdGRVeENRRjhhcysxNFR2Slo4THowd1lxRkx2RTgrcG12N2VpT1ZUTzRtVSsvWXpLYkljVXFoNjNRdllkOU5jeWx3c0ZqRkZ4NGJlbGxrcHFuQjFNNHcvZVVmQ2VpNzRXT256ZGtNQzJiYWx2US9VWWJvS3ltbjZHVWtzbjZJczd0ZU5RMGs2TGovTm5mcFllcldNUXQxeEhjWnVySlZxd2hDRjBTTVRhSmhHWFNQODkwd3RFdkNRSS8zSHNYdUpseWFkWkpmZDZHRmJhNTRldEdoNUIveE80aWdNMEVuekVUMWVKa0tWMWhtbTduZjlZZzRwZmw4QnI5Z0ZZdFlPV080S2hWTjczYTB5Y0g5SlpMUUJydmlBVFowQm1uL3RNYnlKWitadmZjYzN1S2lvdXl4VC9ONlJwejlycFdrUmJvSHZSaHF4VkdjY3B4bG1nbnZudkNVaHZSZktFNTYvaDh0eEZXcXFncEo4VFR4cndFQVo3R0liRlVYVWN6TUhoQW9FV2lSWnVMTWxQck0zTVJWQkJ4YXA5a1BUeWVGaUFXU0tzZ2krUHRQbVp4ZTJldlRkekYzTEpvSkc4R25mQjZ5MVE4VWE5Q09wU3pMN05aamFpak9NRmU0dXBFaVI0andrOTUxMDVkcW9TTFExY0JoU2J0MytiNjkxcE1YYmNFZGNjU1ZYSnE5ejdubUJCeGs1THdUaURRdjdDTkQyZGNmejdKa0hXSENFcklvN2ZyMVFKU1V2dG5RRk5YUGxPNWhsTnZGVU9qWngwQkNDMGc2UDFrQUxVUEoweWtaZ3pQSnRYckdHL09XQjFUaERtTVNvMVpmdE1vbTlCdENjVGhMeGJuWDJmODlEcTNHZFE4RUd2UVV0cFRCNkVkeTdBOEE1aVNMemR1OEJhek5nYUwrclFlNk9CTko4VVEweEMzdmUrTFFoTmtVMTVzQWlycmtVdDJmL3JkMDM2bHd5d3ZnZTg2Umlvc1pnOVQ2RHVhNWRoQ1N3L0ZTQmpCOUo0QmI2Kys2TmNEOS9OTGFXNUIwUXJzdDRXYjR0cDEzL3Q3RXlxWEZiV3JLMVdiQlZtMnVhd3pzLzZ4RklR';
34
- export const DEV_WASM_KEY_EXPIRES = '2027-03-30T09:25:07Z';
35
- export const DEFAULT_WASM_ORIGIN = 'http://localhost:3000';
27
+ export const DEFAULT_WASM_ORIGIN = 'http://localhost';
36
28
  /** Files of one release under https://awvstatic.com/classcad/download/release/<version>/wasm/. */
37
29
  export const WASM_ASSETS = ['ClassCADWasm.js', 'ClassCADWasm.wasm', 'lgs2d.wasm', 'lgs3d.wasm', 'ExpWasm.wasm', 'classcad.cfe', 'filterconfig.json'];
38
- /** Resolves the local engine settings from the environment (the built-in key unless CLASSCAD_WASM_KEY is set). */
30
+ /** Resolves the local engine settings from the environment; the key is fetched at each engine start. */
39
31
  export function wasmOptionsFromEnv(env = process.env) {
40
- const key = env.CLASSCAD_WASM_KEY || DEV_WASM_KEY;
41
- if (!key)
32
+ if (env.CLASSCAD_WASM === 'off')
42
33
  return null;
43
34
  return {
44
- key,
35
+ // A key of one's own wins; otherwise each engine start asks the backend
36
+ key: env.CLASSCAD_WASM_KEY || undefined,
37
+ getKey: () => engineKey(),
45
38
  origin: env.CLASSCAD_WASM_ORIGIN,
46
39
  version: env.CLASSCAD_WASM_VERSION,
47
40
  dir: env.CLASSCAD_WASM_DIR,
@@ -88,8 +81,10 @@ export async function ensureWasmAssets(opts = {}) {
88
81
  }
89
82
  /** Downloads (if needed) and boots one engine in its own worker thread. */
90
83
  export async function startLocalEngine(opts) {
91
- if (!opts.key)
92
- throw new Error('no ClassCAD key for the local WASM engine (CLASSCAD_WASM_KEY)');
84
+ const fetched = opts.key ? null : opts.getKey ? await opts.getKey() : null;
85
+ const key = opts.key ?? fetched?.key;
86
+ if (!key)
87
+ throw new Error('no ClassCAD key for the local WASM engine');
93
88
  const version = opts.version ?? DEFAULT_WASM_VERSION;
94
89
  const origin = opts.origin ?? DEFAULT_WASM_ORIGIN;
95
90
  const log = opts.log ?? (() => { });
@@ -127,18 +122,15 @@ export async function startLocalEngine(opts) {
127
122
  else if (m?.type === 'error') {
128
123
  worker.off('message', onMessage);
129
124
  // The engine refuses a bad key by exiting without a word: name the likely cause.
130
- const expired = opts.key === DEV_WASM_KEY && Date.now() > Date.parse(DEV_WASM_KEY_EXPIRES);
131
- const hint = expired
132
- ? ` The MCP's built-in engine key expired on ${DEV_WASM_KEY_EXPIRES.slice(0, 10)}: update the MCP (or set CLASSCAD_WASM_KEY).`
133
- : opts.key !== DEV_WASM_KEY
134
- ? ' Check CLASSCAD_WASM_KEY: the engine refuses an expired key or one whose allowed origins do not include ' + origin + '.'
135
- : '';
125
+ const hint = process.env.CLASSCAD_WASM_KEY
126
+ ? ' Check CLASSCAD_WASM_KEY: the engine refuses an expired key or one whose allowed origins do not include ' + origin + '.'
127
+ : ' The engine refused its key; signing out and in again (`login` with logout, then `login`) fetches a new one.';
136
128
  reject(new Error(`WASM engine failed to start: ${m.message}.${hint}`));
137
129
  }
138
130
  };
139
131
  worker.on('message', onMessage);
140
132
  worker.once('error', err => reject(new Error(`WASM engine failed to start: ${err.message}`)));
141
- worker.postMessage({ type: 'init', dir, key: opts.key, origin });
133
+ worker.postMessage({ type: 'init', dir, key, origin });
142
134
  }).catch(err => {
143
135
  worker.terminate().catch(() => { });
144
136
  throw err;
@@ -1 +1 @@
1
- {"version":3,"file":"wasm.js","sourceRoot":"","sources":["../../src/engine/wasm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wasm.js","sourceRoot":"","sources":["../../src/engine/wasm.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,18 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { type Client, type EnginePolicy } from './client.js';
3
3
  import { type LocalWasmOptions } from './engine/wasm.js';
4
- import type { BridgeRegistry } from './bridge/server.js';
5
- export declare const VERSION = "0.2.2";
4
+ import { type Show } from './share/session.js';
5
+ export declare const VERSION = "0.3.0";
6
6
  export declare const DEFAULT_WS_URL = "ws://0.0.0.0:9094/";
7
7
  export type McpServerOptions = {
8
8
  /** ClassCAD worker this instance connects to (lazily, on the first tool call). */
9
9
  wsUrl: string;
10
- /** The shared bridge registry (apps announcing share tokens); null when no listener runs. */
11
- bridge: () => BridgeRegistry | null;
12
10
  /** Engine policy when nothing else decides: 'auto' (worker, else local WASM), 'drogon', 'wasm'. Default 'auto'. */
13
11
  engine?: EnginePolicy;
14
12
  /** Local WASM engine settings (key, origin, …); null = not available. */
15
13
  wasm?: LocalWasmOptions | null;
14
+ /** How the session's app reaches the user (share/session.ts). Default: what this process's environment says. */
15
+ show?: Show;
16
16
  /** Where the instance reports engine decisions. */
17
17
  log?: (msg: string) => void;
18
18
  };
@@ -12,28 +12,46 @@ import { registerStateTools } from './tools/state.js';
12
12
  import { DAEMON_NOTE, registerDocsTools, serverInstructions } from './tools/docs.js';
13
13
  import { registerSnapshotTool } from './tools/snapshot.js';
14
14
  import { registerScriptTool } from './tools/script.js';
15
- import { registerBridgeTools } from './tools/bridge.js';
16
15
  import { serializeTools } from './queue.js';
17
16
  import { registerAuthTool, requireSignIn, SIGN_IN_NOTE } from './tools/auth.js';
18
17
  import { authStatus } from './auth.js';
19
- import { attachViewer, registerViewerTool, VIEWER_NOTE } from './tools/viewer.js';
20
- export const VERSION = '0.2.2';
18
+ import { attachViewer, VIEWER_NOTE } from './tools/viewer.js';
19
+ import { appNote, attachShare, registerSelectionTools, registerShareTool, registerViewTool } from './tools/share.js';
20
+ import { appAvailable, joinedHere, listen as listenForApps, waitForPage, SESSION_PATH } from './share/server.js';
21
+ import { sharingFromEnv, showFromEnv } from './share/session.js';
22
+ export const VERSION = '0.3.0';
23
+ /** True for the address sessions are joined on on this machine (share/server.ts): an app's own engine, or another agent's. */
24
+ const hostedOnThisMachine = (url) => {
25
+ try {
26
+ return new URL(url).pathname.replace(/\/+$/, '') === SESSION_PATH;
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ };
21
32
  export const DEFAULT_WS_URL = 'ws://0.0.0.0:9094/';
22
33
  /** Builds a connected-ready MCP server: the engine client plus all tools. Nothing is opened yet. */
23
34
  export async function createMcpServer(opts) {
24
- const bridgeRegistry = opts.bridge();
25
35
  // Build the client without opening the WS. The first tool call that needs
26
36
  // the worker will open it — either use_session (with a named session) or
27
37
  // any geometry tool (with no session header). This keeps the MCP passive
28
38
  // at startup so it never creates a stray ephemeral session.
29
- const client = await connect(opts.wsUrl, { graphics: true, bridge: opts.bridge, engine: opts.engine, wasm: opts.wasm, log: opts.log });
39
+ const client = await connect(opts.wsUrl, { graphics: true, engine: opts.engine, wasm: opts.wasm, log: opts.log });
40
+ // What the session shows the user: the app docked into it, where this build
41
+ // carries the app; the read-only 3D view otherwise.
42
+ const viewMode = process.env.CLASSCAD_VIEWER;
43
+ const withApp = (appAvailable() || !!process.env.CLASSCAD_APP_URL) && viewMode !== 'off' && viewMode !== 'readonly';
44
+ // How the app reaches the user: the agent is told from the first turn on, and again with the first model.
45
+ const show = opts.show ?? showFromEnv();
46
+ // Whether, and when, the session gets a link that works beyond this machine: only the app can be shared.
47
+ const sharing = withApp ? sharingFromEnv() : 'off';
30
48
  const server = new McpServer({
31
49
  name: 'classcad',
32
50
  version: VERSION,
33
51
  },
34
52
  // The initialize-handshake instructions carry the full v1 method index —
35
53
  // hosts surface them to the agent, so it knows every method from turn one.
36
- { instructions: `${SIGN_IN_NOTE}\n\n${VIEWER_NOTE}\n\n${serverInstructions()}` });
54
+ { instructions: `${SIGN_IN_NOTE}\n\n${withApp ? appNote(show, sharing) : VIEWER_NOTE}\n\n${serverInstructions()}` });
37
55
  // One tool call at a time: every tool below shares this client's single
38
56
  // engine connection and drawing (see queue.ts for the reasoning, incl.
39
57
  // subagents). Must run before the first registerTool.
@@ -42,19 +60,26 @@ export async function createMcpServer(opts) {
42
60
  // Registered after the queue patch, so the check runs before queueing.
43
61
  requireSignIn(server);
44
62
  registerAuthTool(server);
45
- // The session's live 3D view. Patched in last, so it sits innermost: it
46
- // hears of a change inside the queue, after the tool that made it.
47
- const viewer = await attachViewer(server, client, opts.log);
48
- registerViewerTool(server, viewer);
63
+ // The session's company: the app docked into it, whoever else is in it, and
64
+ // what they have selected. Patched in last, so it sits innermost: it hears
65
+ // of a change inside the queue, after the tool that made it.
66
+ const share = await attachShare(server, client, VERSION, show, sharing, opts.log);
67
+ const viewer = share.url ? null : await attachViewer(server, client, opts.log);
68
+ registerViewTool(server, share, viewer);
69
+ registerShareTool(server, share);
70
+ registerSelectionTools(server, client, share);
49
71
  server.registerTool('session_info', {
50
72
  title: 'Session info',
51
- description: 'Return ClassCAD MCP session status: the link of the live 3D view (viewer), sign-in (auth), transport (ws = ClassCAD worker, bridge = an app\'s in-page engine, wasm = the MCP\'s own local engine), engine policy, whether a local WASM engine is available, WS URL, current session id, share token, connection state, package version. ' + DAEMON_NOTE,
73
+ description: 'Return ClassCAD MCP session status: the link of the app docked into this session (app) or of the read-only 3D view (viewer), the link the session is shared with others under (shared; null while it is not), who else is in the session (peers), sign-in (auth), transport (ws = ClassCAD worker, wasm = the MCP\'s own local engine), engine policy, whether a local WASM engine is available, WS URL, current session id, the invite this session joined with (shareToken), connection state, package version. ' + DAEMON_NOTE,
52
74
  inputSchema: {},
53
75
  }, async () => {
54
76
  const local = client.localEngine;
55
77
  const auth = await authStatus();
56
78
  const info = {
79
+ app: share.url,
57
80
  viewer: viewer?.url ?? null,
81
+ shared: share.sharedUrl,
82
+ peers: share.peers().map(p => ({ app: p.identity?.app ?? null, name: p.identity?.name ?? p.inviteName ?? null, kind: p.identity?.kind ?? null, role: p.role ?? null })),
58
83
  auth: auth.signedIn ? { signedIn: true, email: auth.account.email, ...(auth.offline ? { offline: true } : {}) } : { signedIn: false, reason: auth.reason },
59
84
  transport: client.transport,
60
85
  enginePolicy: client.engine,
@@ -76,7 +101,7 @@ export async function createMcpServer(opts) {
76
101
  });
77
102
  server.registerTool('use_session', {
78
103
  title: 'Switch session',
79
- description: 'Call this BEFORE any other classcad tool when the user names a session or hands you a session/token URL — the MCP opens its engine link lazily, so the first tool call decides which session is used. Modes: (1) sessionId — attaches to a named ClassCAD session (ClassCAD-Session-Id header) on the configured worker; empty/omitted = fresh worker-assigned session. (2) url — a ws(s):// URL from a multi-client server, typically carrying an invite token (wss://host/?invite=…); connected VERBATIM. (3) an http(s):// APP SHARE LINK from a buerli app\'s Session Management: with ?invite=… the token is applied to the configured worker URL (the app runs against a ClassCAD server); with ?bridge=… the app runs the engine IN-PAGE (WASM) and the MCP attaches to it through the bridge listener — every command then runs inside that app, and the app must stay open. Without either, the MCP runs its own session. (4) engine — WHICH ENGINE runs that own session: "drogon" = the configured ClassCAD worker (server), "wasm" = the MCP\'s OWN local engine (the published WASM build hosted in this process, no server and no browser needed; requires a configured key), "auto" (default) = the worker if reachable, otherwise the local engine. Use "drogon" when the user says to connect to their (Drogon/ClassCAD) server, "wasm" when they say WASM/local/offline; a token or URL always decides by itself. Reconnecting clears cached structure/graphic state — the next tool call repopulates it.',
104
+ description: 'Call this BEFORE any other classcad tool when the user names a session or hands you a session/token URL — the MCP opens its engine link lazily, so the first tool call decides which session is used. Modes: (1) sessionId — attaches to a named ClassCAD session (ClassCAD-Session-Id header) on the configured worker; empty/omitted = fresh worker-assigned session. (2) url — a ws(s):// URL from a multi-client server, typically carrying an invite token (wss://host/?invite=…); connected VERBATIM. (3) an http(s):// APP SHARE LINK from a buerli app\'s Session Management (…?invite=…): the MCP joins the app\'s session as a guest, wherever its engine runs — on a ClassCAD server (the token is applied to the configured worker URL) or in the app\'s own page (WASM; the app must stay open, on this machine). Without a url the MCP runs its own session — and the user\'s app docks into THAT with the link `view` returns. (4) engine — WHICH ENGINE runs that own session: "drogon" = the configured ClassCAD worker (server), "wasm" = the MCP\'s OWN local engine (the published WASM build hosted in this process, no server and no browser needed; requires a configured key), "auto" (default) = the worker if reachable, otherwise the local engine. Use "drogon" when the user says to connect to their (Drogon/ClassCAD) server, "wasm" when they say WASM/local/offline; a token or URL always decides by itself. Reconnecting clears cached structure/graphic state — the next tool call repopulates it.',
80
105
  inputSchema: {
81
106
  sessionId: z.string().optional()
82
107
  .describe('Target session id (named-session model, worker only). Empty string or omitted = no header (worker-assigned session).'),
@@ -89,27 +114,49 @@ export async function createMcpServer(opts) {
89
114
  const target = sessionId && sessionId.length > 0 ? sessionId : null;
90
115
  try {
91
116
  let wsUrl = url && url.length > 0 ? url : null;
117
+ let joined = false;
92
118
  // App share links (http/https) point at the WEB APP, not the CAD
93
119
  // server — carry over only the invite token onto the worker base URL.
94
120
  if (wsUrl && /^https?:\/\//i.test(wsUrl)) {
95
121
  const params = new URL(wsUrl).searchParams;
96
- const bridge = params.get('bridge');
97
- if (bridge) {
98
- // In-app engine: attach through the bridge, no worker involved.
99
- await client.reconnectBridge(bridge);
100
- return {
101
- content: [{ type: 'text', text: JSON.stringify({ ok: true, transport: 'bridge', shareToken: bridge }) }],
102
- };
122
+ // Links of apps that run the engine in their own page (older buerli builds): there is no session to join.
123
+ if (params.get('bridge')) {
124
+ throw new Error('This link is of an app that runs ClassCAD in its own page; such an engine cannot be joined. ' +
125
+ 'Work the other way round: build in this MCP session and let the user open its app with `view` — it docks into this session.');
103
126
  }
104
127
  const invite = params.get('invite');
105
128
  if (!invite) {
106
- throw new Error(`"${wsUrl}" is an http(s) app link without an ?invite= or ?bridge= token. ` +
107
- 'Pass the ws(s):// URL of the ClassCAD server (optionally with ?invite=…), or an app share link that carries ?invite= / ?bridge=.');
129
+ throw new Error(`"${wsUrl}" is an http(s) app link without an ?invite= token. ` +
130
+ 'Pass the ws(s):// URL of the ClassCAD server (optionally with ?invite=…), or an app share link that carries ?invite=.');
108
131
  }
109
- const base = client.baseUrl.replace(/\/+$/, '');
110
- wsUrl = `${base}/?invite=${encodeURIComponent(invite)}`;
132
+ // Whose session the invite is for, the link does not say. An app that
133
+ // runs the engine in its own page offers its invites on this machine's
134
+ // listener, and so does every MCP session; any other invite is a
135
+ // ClassCAD server's.
136
+ const local = async () => `ws://127.0.0.1:${(await listenForApps()).port}${SESSION_PATH}/?invite=${encodeURIComponent(invite)}`;
137
+ if (joinedHere(invite))
138
+ wsUrl = await local();
139
+ else {
140
+ const base = client.baseUrl.replace(/\/+$/, '');
141
+ try {
142
+ await client.reconnectUrl(`${base}/?invite=${encodeURIComponent(invite)}`);
143
+ wsUrl = null;
144
+ joined = true;
145
+ }
146
+ catch (err) {
147
+ // Not the server's: a page may be about to offer it (it finds a restarted MCP within seconds).
148
+ if (!(await waitForPage(invite, 8_000))) {
149
+ throw new Error(`Nobody shares a session under this invite: the ClassCAD server at ${base} refused it (${err instanceof Error ? err.message : err}), ` +
150
+ 'and no app on this machine offers it. Is the app still open, and is the invite still there in its session panel?');
151
+ }
152
+ wsUrl = await local();
153
+ }
154
+ }
155
+ }
156
+ if (joined) {
157
+ /* already in the server's session */
111
158
  }
112
- if (wsUrl)
159
+ else if (wsUrl)
113
160
  await client.reconnectUrl(wsUrl);
114
161
  else
115
162
  await client.reconnect(target, engine);
@@ -127,7 +174,7 @@ export async function createMcpServer(opts) {
127
174
  text: JSON.stringify({
128
175
  ok: true,
129
176
  transport: client.transport,
130
- engine: client.transport === 'wasm' ? 'wasm (local, in this process)' : 'drogon (ClassCAD worker)',
177
+ engine: client.transport === 'wasm' ? 'wasm (local, in this process)' : hostedOnThisMachine(client.url) ? 'the engine of the app that shared the session (it must stay open)' : 'drogon (ClassCAD worker)',
131
178
  sessionId: client.sessionId,
132
179
  wsUrl: client.transport === 'ws' ? client.url : null,
133
180
  }),
@@ -139,9 +186,6 @@ export async function createMcpServer(opts) {
139
186
  registerDocsTools(server);
140
187
  registerSnapshotTool(server, client);
141
188
  registerScriptTool(server, client);
142
- // Bridge tools (app-state read/write) — only when the listener is up.
143
- if (bridgeRegistry)
144
- registerBridgeTools(server, client, bridgeRegistry);
145
189
  return { server, client };
146
190
  }
147
191
  //# sourceMappingURL=mcp-server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
package/dist/queue.js CHANGED
@@ -23,7 +23,7 @@
23
23
  /** Tools that only read package data (no engine access) and stay unqueued. */
24
24
  const busyChecks = new WeakMap();
25
25
  export function setDrawingBusy(server, check) { busyChecks.set(server, check); }
26
- export const UNQUEUED_TOOLS = new Set(['list_methods', 'describe_method', 'docs', 'session_info', 'view']);
26
+ export const UNQUEUED_TOOLS = new Set(['list_methods', 'describe_method', 'docs', 'session_info', 'view', 'share']);
27
27
  /**
28
28
  * Patches `server.registerTool` so every handler registered afterwards runs
29
29
  * through the shared queue (except the tools in `exclude`). Call it once,
package/dist/queue.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,qEAAqE;AACrE,8EAA8E;AAC9E,4EAA4E;AAC5E,2EAA2E;AAC3E,8EAA8E;AAC9E,8EAA8E;AAC9E,0EAA0E;AAC1E,uDAAuD;AACvD,EAAE;AACF,yEAAyE;AACzE,yEAAyE;AACzE,2EAA2E;AAC3E,kCAAkC;AAClC,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,6EAA6E;AAC7E,sBAAsB;AAItB,8EAA8E;AAC9E,MAAM,UAAU,GAAG,IAAI,OAAO,EAA4B,CAAA;AAC1D,MAAM,UAAU,cAAc,CAAC,MAAiB,EAAE,KAAoB,IAAU,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA,CAAC,CAAC;AAE/G,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAA;AAE1G;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAiB,EAAE,UAAuB,cAAc;IACrF,8EAA8E;IAC9E,IAAI,IAAI,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAA;IAC9C,MAAM,IAAI,GAAG,CAAI,IAA0B,EAAc,EAAE;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B,oEAAoE;QACpE,IAAI,GAAG,GAAG,CAAC,IAAI,CACb,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAA;QACD,OAAO,GAAG,CAAA;IACZ,CAAC,CAAA;IACD,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACxB,MAAM,QAAQ,GAAI,MAAM,CAAC,YAAwC,CAAC,IAAI,CAAC,MAAM,CAAC,CAC7E;IAAC,MAAc,CAAC,YAAY,GAAG,CAAC,IAAY,EAAE,MAAe,EAAE,OAAgC,EAAE,EAAE;QAClG,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;QAC7D,MAAM,MAAM,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE,CAChC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE;YACnC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,6FAA6F,EAAE,CAAC,EAAE;YACrJ,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;QACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,CAAC,CAAA;AACH,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,OAAO,EAA4D,CAAA;AAEtF;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAI,MAAiB,EAAE,IAA0B;IACtE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC/B,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzD,CAAC"}
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,qEAAqE;AACrE,8EAA8E;AAC9E,4EAA4E;AAC5E,2EAA2E;AAC3E,8EAA8E;AAC9E,8EAA8E;AAC9E,0EAA0E;AAC1E,uDAAuD;AACvD,EAAE;AACF,yEAAyE;AACzE,yEAAyE;AACzE,2EAA2E;AAC3E,kCAAkC;AAClC,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,6EAA6E;AAC7E,sBAAsB;AAItB,8EAA8E;AAC9E,MAAM,UAAU,GAAG,IAAI,OAAO,EAA4B,CAAA;AAC1D,MAAM,UAAU,cAAc,CAAC,MAAiB,EAAE,KAAoB,IAAU,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA,CAAC,CAAC;AAE/G,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAEnH;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAiB,EAAE,UAAuB,cAAc;IACrF,8EAA8E;IAC9E,IAAI,IAAI,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAA;IAC9C,MAAM,IAAI,GAAG,CAAI,IAA0B,EAAc,EAAE;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B,oEAAoE;QACpE,IAAI,GAAG,GAAG,CAAC,IAAI,CACb,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAA;QACD,OAAO,GAAG,CAAA;IACZ,CAAC,CAAA;IACD,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACxB,MAAM,QAAQ,GAAI,MAAM,CAAC,YAAwC,CAAC,IAAI,CAAC,MAAM,CAAC,CAC7E;IAAC,MAAc,CAAC,YAAY,GAAG,CAAC,IAAY,EAAE,MAAe,EAAE,OAAgC,EAAE,EAAE;QAClG,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;QAC7D,MAAM,MAAM,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE,CAChC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE;YACnC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,6FAA6F,EAAE,CAAC,EAAE;YACrJ,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;QACvB,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,CAAC,CAAA;AACH,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,OAAO,EAA4D,CAAA;AAEtF;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAI,MAAiB,EAAE,IAA0B;IACtE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC/B,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzD,CAAC"}
package/dist/server.js CHANGED
@@ -4,13 +4,16 @@
4
4
  // It is a thin shim: it finds the ClassCAD MCP daemon on this machine (or
5
5
  // starts it, detached) and forwards its host's JSON-RPC to the daemon over
6
6
  // HTTP (MCP Streamable HTTP). Every tab therefore gets its own session in the
7
- // ONE daemon process that owns the bridge listener — see daemon.ts for why.
7
+ // ONE daemon process — see daemon.ts for why.
8
8
  //
9
9
  // If no daemon can be reached at all (the port is held by a foreign program
10
- // and cannot be freed), the shim serves the MCP in-process as before, minus
11
- // the bridge listener, so a Drogon-only user is never blocked.
10
+ // and cannot be freed), the shim serves the MCP in-process: the same MCP, with
11
+ // a listener of its own for the app (on a free port if the usual one is taken).
12
12
  import { spawn } from 'node:child_process';
13
+ import { request as httpRequest } from 'node:http';
14
+ import { request as httpsRequest } from 'node:https';
13
15
  import { connect as tcpConnect } from 'node:net';
16
+ import { homedir } from 'node:os';
14
17
  import { fileURLToPath } from 'node:url';
15
18
  import { dirname, join } from 'node:path';
16
19
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
@@ -18,6 +21,7 @@ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/
18
21
  import { createMcpServer, DEFAULT_WS_URL, VERSION } from './mcp-server.js';
19
22
  import { DAEMON_HOST, DEFAULT_DAEMON_PORT, defaultDaemonLogFile, daemonBuildStamp } from './daemon.js';
20
23
  import { wasmOptionsFromEnv } from './engine/wasm.js';
24
+ import { showFromEnv } from './share/session.js';
21
25
  import { authStatus, beginLogin, logout, waitForLogin } from './auth.js';
22
26
  const WS_URL = process.env.CLASSCAD_WS_URL ?? DEFAULT_WS_URL;
23
27
  /** Engine policy for this tab's session: auto (worker, else local WASM) | drogon | wasm. */
@@ -28,12 +32,43 @@ const DAEMON_PORT = Number(process.env.CLASSCAD_MCP_PORT ?? DEFAULT_DAEMON_PORT)
28
32
  const DAEMON_URL = process.env.CLASSCAD_MCP_URL ?? `http://${DAEMON_HOST}:${DAEMON_PORT}`;
29
33
  const SPAWN_TIMEOUT_MS = 10_000;
30
34
  const log = (msg) => process.stderr.write(`[classcad-mcp] ${msg}\n`);
35
+ /**
36
+ * One question to the daemon (is it there, please go), on a connection of its
37
+ * own, answered or given up within `timeoutMs`: null when nobody answered.
38
+ *
39
+ * Plain http, not fetch. fetch keeps its connections: one that sat idle answers
40
+ * late on some Node versions (seen: up to 1.5 s on 26.7, which reads as "no
41
+ * daemon"). And told to close the connection, it may never settle when the
42
+ * other side hangs up at once (seen on Node 20, with a foreign program on the
43
+ * port): with nothing else left to wait for, the process then simply ends.
44
+ */
45
+ function ask(method, path, timeoutMs = 1500) {
46
+ return new Promise(resolve => {
47
+ const url = new URL(`${DAEMON_URL}${path}`);
48
+ const send = url.protocol === 'https:' ? httpsRequest : httpRequest;
49
+ const settle = (answer) => {
50
+ clearTimeout(timer);
51
+ resolve(answer);
52
+ };
53
+ const req = send(url, { method, agent: false }, res => {
54
+ const chunks = [];
55
+ res.on('data', (chunk) => chunks.push(chunk));
56
+ res.on('end', () => settle({ status: res.statusCode ?? 0, body: Buffer.concat(chunks).toString('utf8') }));
57
+ res.on('error', () => settle(null));
58
+ });
59
+ const timer = setTimeout(() => req.destroy(new Error('no answer in time')), timeoutMs);
60
+ req.on('error', () => settle(null));
61
+ req.end();
62
+ });
63
+ }
64
+ /** True for an answer in the 200s. */
65
+ const answeredOk = (res) => !!res && res.status >= 200 && res.status < 300;
31
66
  async function health() {
67
+ const res = await ask('GET', '/health');
68
+ if (!answeredOk(res))
69
+ return null;
32
70
  try {
33
- const res = await fetch(`${DAEMON_URL}/health`, { signal: AbortSignal.timeout(1500) });
34
- if (!res.ok)
35
- return null;
36
- const j = (await res.json());
71
+ const j = JSON.parse(res.body);
37
72
  return j && j.name === 'classcad-mcp' ? j : null;
38
73
  }
39
74
  catch {
@@ -61,6 +96,8 @@ async function spawnDaemon() {
61
96
  const daemonPath = join(dirname(fileURLToPath(import.meta.url)), 'daemon.js');
62
97
  const child = spawn(process.execPath, [daemonPath], {
63
98
  detached: true,
99
+ // Not this shim's folder, which can go away while the daemon still runs (see daemon.ts).
100
+ cwd: homedir(),
64
101
  stdio: 'ignore',
65
102
  windowsHide: true,
66
103
  env: {
@@ -101,29 +138,19 @@ async function ensureDaemon() {
101
138
  if (h && stale(h)) {
102
139
  // An older daemon (previous install or previous build) — ask it to leave when idle.
103
140
  log(`daemon ${h.version} (build ${h.build ?? '?'}) running, this MCP is ${VERSION} (build ${daemonBuildStamp()}): asking it to shut down`);
104
- try {
105
- const res = await fetch(`${DAEMON_URL}/shutdown`, { method: 'POST', signal: AbortSignal.timeout(1500) });
106
- if (res.ok) {
107
- for (let i = 0; i < 25 && (await health()); i++)
108
- await sleep(200);
109
- h = await health();
110
- }
111
- }
112
- catch {
113
- /* fall through: use it as is */
141
+ // No answer, or a refusal (it is busy): fall through and use it as is.
142
+ if (answeredOk(await ask('POST', '/shutdown'))) {
143
+ for (let i = 0; i < 25 && (await health()); i++)
144
+ await sleep(200);
145
+ h = await health();
114
146
  }
115
147
  if (h && stale(h)) {
116
148
  // Busy with other tabs. Tell it to drain (newer daemons stop taking
117
149
  // sessions and exit after the last one) and run THIS tab on the new
118
- // code in-process — without the bridge listener, which the old daemon
119
- // still holds. The next tab after the old one is gone starts a fresh daemon.
120
- try {
121
- await fetch(`${DAEMON_URL}/shutdown?drain=1`, { method: 'POST', signal: AbortSignal.timeout(1500) });
122
- }
123
- catch {
124
- /* an old daemon without drain support: it leaves when idle */
125
- }
126
- log(`daemon ${h.version} (build ${h.build ?? '?'}) still serves ${h.sessions ?? '?'} other tab(s) — this tab runs the current build in-process (no bridge listener until that daemon is gone; restart the other tabs to move them)`);
150
+ // code in-process. The next tab after the old one is gone starts a fresh daemon.
151
+ // An old daemon without drain support leaves when idle.
152
+ await ask('POST', '/shutdown?drain=1');
153
+ log(`daemon ${h.version} (build ${h.build ?? '?'}) still serves ${h.sessions ?? '?'} other tab(s) — this tab runs the current build in-process (restart the other tabs to move them)`);
127
154
  return null;
128
155
  }
129
156
  }
@@ -168,7 +195,11 @@ async function proxyToDaemon() {
168
195
  headers: {
169
196
  'x-classcad-ws-url': WS_URL,
170
197
  'x-classcad-engine': ENGINE,
171
- ...(WASM ? { 'x-classcad-wasm-key': WASM.key, ...(WASM.origin ? { 'x-classcad-wasm-origin': WASM.origin } : {}) } : {}),
198
+ // How this host shows the session's app: its own browser pane, or the user's browser.
199
+ 'x-classcad-show': showFromEnv(),
200
+ // A key of this host's own (CLASSCAD_WASM_KEY); without one the daemon fetches the session's key from the sign-in
201
+ ...(WASM?.key ? { 'x-classcad-wasm-key': WASM.key } : {}),
202
+ ...(WASM?.origin ? { 'x-classcad-wasm-origin': WASM.origin } : {}),
172
203
  },
173
204
  },
174
205
  });
@@ -291,9 +322,9 @@ async function proxyToDaemon() {
291
322
  process.stdin.on('close', () => void finish('host closed stdin'));
292
323
  await stdio.start();
293
324
  }
294
- /** Last resort: the MCP in this process, without a bridge listener. */
325
+ /** Last resort: the MCP in this process. */
295
326
  async function serveInProcess() {
296
- const { server, client } = await createMcpServer({ wsUrl: WS_URL, bridge: () => null, engine: ENGINE, wasm: WASM, log });
327
+ const { server, client } = await createMcpServer({ wsUrl: WS_URL, engine: ENGINE, wasm: WASM, log });
297
328
  const shutdown = () => {
298
329
  try {
299
330
  client.close();
@@ -310,13 +341,11 @@ async function serveInProcess() {
310
341
  async function main() {
311
342
  const h = await ensureDaemon();
312
343
  if (h) {
313
- log(`using daemon ${h.version} (pid ${h.pid}, ${h.sessions} session(s), bridge ${h.bridge ?? 'none'}) at ${DAEMON_URL}; daemon log: ${h.logFile ?? defaultDaemonLogFile()}`);
314
- if (!h.bridge)
315
- log(`WARNING: the daemon has no bridge listener (${h.bridgeListen ?? 'unknown'} is taken, probably by an MCP of an older build in another tab) — in-app engines cannot attach until that process is gone; the daemon retries by itself`);
344
+ log(`using daemon ${h.version} (pid ${h.pid}, ${h.sessions} session(s)) at ${DAEMON_URL}; daemon log: ${h.logFile ?? defaultDaemonLogFile()}`);
316
345
  await proxyToDaemon();
317
346
  return;
318
347
  }
319
- log('serving in-process (no bridge listener: in-app engines cannot attach; the worker and the local WASM engine work as usual)');
348
+ log('serving in-process');
320
349
  await serveInProcess();
321
350
  }
322
351
  const USAGE = `classcad-mcp — ClassCAD MCP server (stdio). Hosts start it without arguments.
@@ -358,13 +387,17 @@ async function stopDaemon(force) {
358
387
  return 0;
359
388
  }
360
389
  if (!force) {
361
- const res = await fetch(`${DAEMON_URL}/shutdown`, { method: 'POST', signal: AbortSignal.timeout(1500) });
390
+ const res = await ask('POST', '/shutdown');
391
+ if (!res) {
392
+ console.error(`daemon pid ${h.pid} did not answer`);
393
+ return 1;
394
+ }
362
395
  if (res.status === 409) {
363
396
  console.error(`daemon pid ${h.pid} has ${h.sessions} active session(s) — not stopped.\n` +
364
397
  `\`classcad-mcp stop --force\` ends them: every connected tab loses its drawing and reconnects on its next tool call.`);
365
398
  return 1;
366
399
  }
367
- if (!res.ok) {
400
+ if (!answeredOk(res)) {
368
401
  console.error(`daemon refused to stop: HTTP ${res.status}`);
369
402
  return 1;
370
403
  }
@@ -374,7 +407,7 @@ async function stopDaemon(force) {
374
407
  console.error('daemon did not report its pid — cannot force it');
375
408
  return 1;
376
409
  }
377
- // SIGTERM runs the daemon's own shutdown: sessions closed, bridge and port released.
410
+ // SIGTERM runs the daemon's own shutdown: sessions closed, ports released.
378
411
  process.kill(h.pid, 'SIGTERM');
379
412
  }
380
413
  if (await waitGone(h.pid, 5000)) {