@mlightcad/cad-mcp-server 1.7.8-preview.1 → 1.7.8-preview.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/README.md CHANGED
@@ -18,10 +18,10 @@ This server follows the design in
18
18
  - **Tools** for clear lifecycle steps (open / blank drawing)
19
19
  - **Scripts** for combining the CAD API into analysis, edits, and verification
20
20
 
21
- The model writes a `cad.*` function body; the headless viewer runs it. Same
22
- runtime as the in-app CAD Agent (`@mlightcad/cad-agent-core`), so external
23
- agents (Claude Code, Cursor, Codex, …) get flexibility without a ballooning
24
- tool list — and with lower token and round-trip cost for bulk work.
21
+ The model writes a `cad.*` function body; the Chromium viewer runs it (headless
22
+ or with a visible window). Same runtime as the in-app CAD Agent
23
+ (`@mlightcad/cad-agent-core`), so external agents get flexibility without a
24
+ ballooning tool list — and with lower token and round-trip cost for bulk work.
25
25
 
26
26
  ## Tools (intentionally small)
27
27
 
@@ -30,15 +30,26 @@ tool list — and with lower token and round-trip cost for bulk work.
30
30
  | `open_drawing` | Open a local/remote DXF/DWG, or omit `path` for a blank ISO template |
31
31
  | `execute_cad_script` | Run a `cad.*` JavaScript function body ([script API](https://mlightcad.github.io/cad-viewer/guide/script/overview.html)) |
32
32
 
33
+ Both tools accept optional `visible`:
34
+
35
+ | `visible` | Browser | Session lifecycle |
36
+ | --- | --- | --- |
37
+ | `false` / omit | Headless Chromium | Reused across tool calls; **auto-closes after idle** (default 30s) |
38
+ | `true` | Visible Chromium window | Stays open so the user can watch the drawing |
39
+
40
+ The agent chooses based on the user prompt (e.g. “open the browser so I can
41
+ see the drawing” → `visible: true`; batch QA → headless). Changing `visible`
42
+ after a session started rebuilds the browser and **resets drawing state**.
43
+
33
44
  There are **no** per-entity `draw_line` / `draw_circle` tools. All drawing,
34
45
  queries, edits, and context live inside one script call.
35
46
 
36
47
  ## Works with cad-simple-viewer and cad-viewer
37
48
 
38
49
  Both products share `AcApDocManager` from `@mlightcad/cad-simple-viewer`. This
39
- server’s headless runner boots that kernel (not the Vue UI package). Scripts
40
- you write for the Script panel or CAD Agent in either product are valid here,
41
- and the reverse is true.
50
+ server’s runner boots that kernel (not the Vue UI package). Scripts you write
51
+ for the Script panel or CAD Agent in either product are valid here, and the
52
+ reverse is true.
42
53
 
43
54
  This package does **not** depend on `@mlightcad/cad-viewer`.
44
55
 
@@ -56,12 +67,19 @@ cad-mcp-server
56
67
  # or: node packages/cad-mcp-server/dist/cli.js
57
68
  ```
58
69
 
70
+ ### Environment variables
71
+
72
+ | Variable | Purpose |
73
+ | --- | --- |
74
+ | `CAD_MCP_VISIBLE=1` | Default headed when tools omit `visible` |
75
+ | `CAD_MCP_IDLE_CLOSE_MS` | Headless idle auto-close delay in ms (default `30000`) |
76
+
59
77
  ## MCP client config
60
78
 
61
- ### Cursor (`.cursor/mcp.json`)
79
+ ### Cursor (this monorepo)
62
80
 
63
- Prefer `${workspaceFolder}` over a hardcoded absolute path or a bare
64
- relative path (MCP cwd is not always the repo root):
81
+ `npx` from the workspace root crashes npm (Arborist + workspace link). Use the
82
+ launcher, which runs npx from the OS temp directory:
65
83
 
66
84
  ```json
67
85
  {
@@ -69,32 +87,71 @@ relative path (MCP cwd is not always the repo root):
69
87
  "cad": {
70
88
  "command": "node",
71
89
  "args": [
72
- "${workspaceFolder}/packages/cad-mcp-server/dist/cli.js"
90
+ "${workspaceFolder}/packages/cad-mcp-server/scripts/run-published.mjs"
73
91
  ]
74
92
  }
75
93
  }
76
94
  }
77
95
  ```
78
96
 
79
- ### Claude Code / Claude Desktop
97
+ Override the pin with `CAD_MCP_SERVER_VERSION` (default `1.7.8-preview.1`).
98
+
99
+ To force a visible browser by default (agent can still pass `visible: false`):
100
+
101
+ ```json
102
+ {
103
+ "mcpServers": {
104
+ "cad": {
105
+ "command": "node",
106
+ "args": [
107
+ "${workspaceFolder}/packages/cad-mcp-server/dist/cli.js"
108
+ ],
109
+ "env": {
110
+ "CAD_MCP_VISIBLE": "1"
111
+ }
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ ### Claude Code / Claude Desktop (outside this repo)
80
118
 
81
119
  ```json
82
120
  {
83
121
  "mcpServers": {
84
122
  "cad": {
85
123
  "command": "npx",
86
- "args": ["-y", "@mlightcad/cad-mcp-server"]
124
+ "args": [
125
+ "-y",
126
+ "--package=@mlightcad/cad-mcp-server@1.7.8-preview.1",
127
+ "cad-mcp-server"
128
+ ]
87
129
  }
88
130
  }
89
131
  }
90
132
  ```
91
133
 
92
- (After the package is published; for local monorepo use the `node …/dist/cli.js` form.)
134
+ For local monorepo development against an unbuilt/unpublished tree, point at
135
+ the built CLI instead:
136
+
137
+ ```json
138
+ {
139
+ "mcpServers": {
140
+ "cad": {
141
+ "command": "node",
142
+ "args": [
143
+ "${workspaceFolder}/packages/cad-mcp-server/dist/cli.js"
144
+ ]
145
+ }
146
+ }
147
+ }
148
+ ```
93
149
 
94
150
  ## Typical flow
95
151
 
96
152
  1. `open_drawing` with `{ "path": "./plan.dxf", "mode": "write" }`
97
- (local path or http(s) URL; omit `path` to start blank).
153
+ (local path or http(s) URL; omit `path` to start blank).
154
+ Add `"visible": true` when the user should see the drawing.
98
155
  2. `execute_cad_script` with a function body:
99
156
 
100
157
  ```js
@@ -111,6 +168,17 @@ return cad.measure.report([
111
168
  `cad.view.capturePreview` is enabled; screenshots are returned as MCP image
112
169
  content.
113
170
 
171
+ Save the drawing after edits:
172
+
173
+ ```js
174
+ cad.file.saveDxf('./plan-out.dxf')
175
+ ```
176
+
177
+ The MCP server writes that path (relative to the server process working
178
+ directory). The DXF text is not sent back to the model; the tool result
179
+ includes `savedFiles` with the absolute path. In the in-app CAD agent the same
180
+ call downloads the file instead.
181
+
114
182
  ## Architecture
115
183
 
116
184
  ```
@@ -118,13 +186,13 @@ MCP client --stdio--> cad-mcp-server (Node)
118
186
  |
119
187
  | Playwright (lazy)
120
188
  v
121
- headless Chromium
189
+ Chromium (headless or headed)
122
190
  cad-simple-viewer + cad-agent-core
123
191
  createCadToolCatalog / execute_cad_script
124
192
  ```
125
193
 
126
- The browser session stays alive for the process lifetime so drawing state
127
- persists across tool calls.
194
+ Headless sessions persist across tool calls until idle timeout. Headed sessions
195
+ stay open until the MCP process exits.
128
196
 
129
197
  ## Library API
130
198
 
@@ -132,7 +200,8 @@ persists across tool calls.
132
200
  import {
133
201
  createCadMcpServer,
134
202
  registerCadMcpTools,
135
- CadMcpSession
203
+ CadMcpSession,
204
+ resolveVisible
136
205
  } from '@mlightcad/cad-mcp-server'
137
206
  ```
138
207
 
@@ -9,6 +9,7 @@ import { z } from 'zod';
9
9
  export declare const executeCadScriptInputSchema: {
10
10
  code: z.ZodString;
11
11
  intent: z.ZodOptional<z.ZodString>;
12
+ visible: z.ZodOptional<z.ZodBoolean>;
12
13
  };
13
14
  /**
14
15
  * Input schema for MCP-only document lifecycle tool `open_drawing`.
@@ -16,6 +17,7 @@ export declare const executeCadScriptInputSchema: {
16
17
  export declare const openDrawingInputSchema: {
17
18
  path: z.ZodOptional<z.ZodString>;
18
19
  mode: z.ZodOptional<z.ZodEnum<["read", "write"]>>;
20
+ visible: z.ZodOptional<z.ZodBoolean>;
19
21
  };
20
22
  export interface RegisterCadMcpToolsOptions {
21
23
  /**
@@ -24,6 +26,7 @@ export interface RegisterCadMcpToolsOptions {
24
26
  openDrawing: (input: {
25
27
  path?: string;
26
28
  mode?: 'read' | 'write';
29
+ visible?: boolean;
27
30
  }) => Promise<{
28
31
  ok: true;
29
32
  title: string;
@@ -35,6 +38,7 @@ export interface RegisterCadMcpToolsOptions {
35
38
  executeCadScript: (input: {
36
39
  code: string;
37
40
  intent?: string;
41
+ visible?: boolean;
38
42
  }) => Promise<unknown>;
39
43
  }
40
44
  /**
@@ -1,6 +1,10 @@
1
1
  import { CAD_SCRIPT_API_SUMMARY } from '@mlightcad/cad-agent-core/script-api';
2
2
  import { z } from 'zod';
3
3
  import { toolResultToMcpContent } from './toolResult.js';
4
+ const visibleField = z
5
+ .boolean()
6
+ .optional()
7
+ .describe('Show a Chromium window so the user can watch the drawing. true = visible window (stays open). false/omit = headless (auto-closes after idle). Use true when the user asks to see the result; use headless for batch work. Changing this after a session started rebuilds the browser and resets drawing state.');
4
8
  /**
5
9
  * Input schema for `execute_cad_script`.
6
10
  *
@@ -16,7 +20,8 @@ export const executeCadScriptInputSchema = {
16
20
  .string()
17
21
  .max(200)
18
22
  .optional()
19
- .describe('Optional short label for the tool result. Never send intent alone — code is required. Prefer emitting code before intent.')
23
+ .describe('Optional short label for the tool result. Never send intent alone — code is required. Prefer emitting code before intent.'),
24
+ visible: visibleField
20
25
  };
21
26
  /**
22
27
  * Input schema for MCP-only document lifecycle tool `open_drawing`.
@@ -29,7 +34,8 @@ export const openDrawingInputSchema = {
29
34
  mode: z
30
35
  .enum(['read', 'write'])
31
36
  .optional()
32
- .describe('Open mode. Default: write when path is omitted, read when path is set. Use write to edit an existing file.')
37
+ .describe('Open mode. Default: write when path is omitted, read when path is set. Use write to edit an existing file.'),
38
+ visible: visibleField
33
39
  };
34
40
  /**
35
41
  * Registers the script-first CAD tool surface on an MCP server.
@@ -46,13 +52,14 @@ export function registerCadMcpTools(server, options) {
46
52
  // MCP SDK + zod generics often hit TS2589; register via a loose shim.
47
53
  const register = server.registerTool.bind(server);
48
54
  register('open_drawing', {
49
- description: 'Open a DXF/DWG drawing (local path or http(s) URL), or omit path to create a blank ISO template. Call before editing an existing file. Drawing ops use execute_cad_script.',
55
+ description: 'Open a DXF/DWG drawing (local path or http(s) URL), or omit path to create a blank ISO template. Call before editing an existing file. Drawing ops use execute_cad_script. Pass visible=true when the user should see the browser/drawing; omit or false for headless (auto-closes after idle).',
50
56
  inputSchema: openDrawingInputSchema
51
57
  }, async (input) => {
52
58
  try {
53
59
  const result = await options.openDrawing({
54
60
  path: input.path,
55
- mode: input.mode
61
+ mode: input.mode,
62
+ visible: input.visible
56
63
  });
57
64
  return {
58
65
  content: [{ type: 'text', text: JSON.stringify(result) }]
@@ -80,7 +87,8 @@ export function registerCadMcpTools(server, options) {
80
87
  try {
81
88
  const raw = await options.executeCadScript({
82
89
  code: input.code,
83
- intent: input.intent
90
+ intent: input.intent,
91
+ visible: input.visible
84
92
  });
85
93
  return toolResultToMcpContent(raw);
86
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"catalogTools.js","sourceRoot":"","sources":["../src/catalogTools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"catalogTools.js","sourceRoot":"","sources":["../src/catalogTools.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -5,12 +5,19 @@ import { createCadMcpServer } from './server.js';
5
5
  * stdio entry for `@mlightcad/cad-mcp-server`.
6
6
  *
7
7
  * stdout is reserved for MCP JSON-RPC — log only to stderr.
8
+ *
9
+ * Env (optional):
10
+ * - `CAD_MCP_VISIBLE=1` — default headed when tools omit `visible`
11
+ * - `CAD_MCP_IDLE_CLOSE_MS` — headless idle auto-close delay (default 30000)
8
12
  */
9
13
  async function main() {
10
14
  const server = createCadMcpServer();
11
15
  const transport = new StdioServerTransport();
12
16
  await server.connect(transport);
13
- console.error('[cad-mcp-server] listening on stdio');
17
+ const visibleDefault = process.env.CAD_MCP_VISIBLE?.trim().toLowerCase() === '1' ||
18
+ process.env.CAD_MCP_VISIBLE?.trim().toLowerCase() === 'true' ||
19
+ process.env.CAD_MCP_VISIBLE?.trim().toLowerCase() === 'yes';
20
+ console.error(`[cad-mcp-server] listening on stdio (default ${visibleDefault ? 'headed' : 'headless'})`);
14
21
  }
15
22
  main().catch(error => {
16
23
  console.error('[cad-mcp-server] fatal:', error instanceof Error ? error.message : error);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAEhF,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD;;;;GAIG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAA;IACnC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/B,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAA;AACtD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CACX,yBAAyB,EACzB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAC/C,CAAA;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAEhF,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD;;;;;;;;GAQG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAA;IACnC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/B,MAAM,cAAc,GAClB,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG;QACzD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,MAAM;QAC5D,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,CAAA;IAC7D,OAAO,CAAC,KAAK,CACX,gDAAgD,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,GAAG,CAC1F,CAAA;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CACX,yBAAyB,EACzB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAC/C,CAAA;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import { type Browser } from 'playwright';
2
2
  /**
3
- * ANGLE / GL backend tried for headless WebGL, in preference order.
3
+ * ANGLE / GL backend tried for WebGL, in preference order.
4
4
  * `swiftshader` is the software renderer used when no hardware backend works.
5
5
  */
6
6
  type GpuBackend = 'd3d11' | 'd3d9' | 'metal' | 'vulkan' | 'gl' | 'egl' | 'gles' | 'swiftshader';
@@ -24,9 +24,15 @@ export interface LaunchHeadlessChromiumOptions {
24
24
  * When hardware is unavailable, falls back to SwiftShader.
25
25
  */
26
26
  useGpu?: boolean;
27
+ /**
28
+ * Show a Chromium window. Default `false` (headless).
29
+ */
30
+ headed?: boolean;
27
31
  }
28
32
  /**
29
- * Launches headless Chromium for WebGL (same strategy as cad-simple-viewer-cli).
33
+ * Launches Chromium for WebGL (same GPU strategy as cad-simple-viewer-cli).
34
+ *
35
+ * Pass `headed: true` to show a visible browser window.
30
36
  */
31
37
  export declare function launchHeadlessChromium(options?: LaunchHeadlessChromiumOptions): Promise<HeadlessGpuLaunch>;
32
38
  export {};
@@ -62,14 +62,17 @@ async function launchSwiftShader(base) {
62
62
  return { browser, renderer, backend: 'swiftshader' };
63
63
  }
64
64
  /**
65
- * Launches headless Chromium for WebGL (same strategy as cad-simple-viewer-cli).
65
+ * Launches Chromium for WebGL (same GPU strategy as cad-simple-viewer-cli).
66
+ *
67
+ * Pass `headed: true` to show a visible browser window.
66
68
  */
67
69
  export async function launchHeadlessChromium(options = {}) {
68
70
  const channel = options.channel;
69
71
  const platform = options.platform ?? process.platform;
70
72
  const useGpu = options.useGpu !== false;
73
+ const headed = options.headed === true;
71
74
  const base = {
72
- headless: true,
75
+ headless: !headed,
73
76
  ...(channel ? { channel } : {})
74
77
  };
75
78
  if (!useGpu) {
@@ -1 +1 @@
1
- {"version":3,"file":"headlessGpu.js","sourceRoot":"","sources":["../src/headlessGpu.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"headlessGpu.js","sourceRoot":"","sources":["../src/headlessGpu.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,6 +6,6 @@
6
6
  * @packageDocumentation
7
7
  */
8
8
  export { executeCadScriptInputSchema, openDrawingInputSchema, registerCadMcpTools, type RegisterCadMcpToolsOptions } from './catalogTools.js';
9
- export { createCadMcpServer } from './server.js';
9
+ export { createCadMcpServer, resolveVisible } from './server.js';
10
10
  export { CadMcpSession, type CadMcpOpenMode, type CadMcpSessionCreateOptions } from './session.js';
11
11
  export { toolResultToMcpContent, type McpContentBlock } from './toolResult.js';
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * @packageDocumentation
7
7
  */
8
8
  export { executeCadScriptInputSchema, openDrawingInputSchema, registerCadMcpTools } from './catalogTools.js';
9
- export { createCadMcpServer } from './server.js';
9
+ export { createCadMcpServer, resolveVisible } from './server.js';
10
10
  export { CadMcpSession } from './session.js';
11
11
  export { toolResultToMcpContent } from './toolResult.js';
12
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EAEpB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EACL,aAAa,EAGd,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,sBAAsB,EAEvB,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EAEpB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,EACL,aAAa,EAGd,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,sBAAsB,EAEvB,MAAM,iBAAiB,CAAA"}
package/dist/server.d.ts CHANGED
@@ -1,7 +1,15 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ /**
3
+ * Resolves whether the browser should be visible.
4
+ *
5
+ * Tool `visible` wins when set; otherwise `CAD_MCP_VISIBLE=1` / `true` / `yes`
6
+ * forces headed as the default for omitted `visible`.
7
+ */
8
+ export declare function resolveVisible(toolVisible?: boolean): boolean;
2
9
  /**
3
10
  * Builds the stdio MCP server that exposes CAD script tools.
4
11
  *
5
- * The headless Chromium session is started lazily on the first tool call.
12
+ * The Chromium session is started lazily on the first tool call (headless or
13
+ * headed depending on `visible` / `CAD_MCP_VISIBLE`).
6
14
  */
7
15
  export declare function createCadMcpServer(): McpServer;
package/dist/server.js CHANGED
@@ -4,10 +4,24 @@ import { registerCadMcpTools } from './catalogTools.js';
4
4
  import { CadMcpSession } from './session.js';
5
5
  const require = createRequire(import.meta.url);
6
6
  const { version: packageVersion } = require('../package.json');
7
+ /**
8
+ * Resolves whether the browser should be visible.
9
+ *
10
+ * Tool `visible` wins when set; otherwise `CAD_MCP_VISIBLE=1` / `true` / `yes`
11
+ * forces headed as the default for omitted `visible`.
12
+ */
13
+ export function resolveVisible(toolVisible) {
14
+ if (typeof toolVisible === 'boolean') {
15
+ return toolVisible;
16
+ }
17
+ const env = process.env.CAD_MCP_VISIBLE?.trim().toLowerCase();
18
+ return env === '1' || env === 'true' || env === 'yes';
19
+ }
7
20
  /**
8
21
  * Builds the stdio MCP server that exposes CAD script tools.
9
22
  *
10
- * The headless Chromium session is started lazily on the first tool call.
23
+ * The Chromium session is started lazily on the first tool call (headless or
24
+ * headed depending on `visible` / `CAD_MCP_VISIBLE`).
11
25
  */
12
26
  export function createCadMcpServer() {
13
27
  const server = new McpServer({
@@ -16,11 +30,15 @@ export function createCadMcpServer() {
16
30
  });
17
31
  registerCadMcpTools(server, {
18
32
  openDrawing: async (input) => {
19
- const session = await CadMcpSession.shared();
33
+ const session = await CadMcpSession.shared({
34
+ headed: resolveVisible(input.visible)
35
+ });
20
36
  return session.openDrawing(input);
21
37
  },
22
38
  executeCadScript: async (input) => {
23
- const session = await CadMcpSession.shared();
39
+ const session = await CadMcpSession.shared({
40
+ headed: resolveVisible(input.visible)
41
+ });
24
42
  return session.executeCadScript(input);
25
43
  }
26
44
  });
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC9C,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAE5D,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,cAAc;KACxB,CAAC,CAAA;IAEF,mBAAmB,CAAC,MAAM,EAAE;QAC1B,WAAW,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YACzB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,CAAA;YAC5C,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QACnC,CAAC;QACD,gBAAgB,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YAC9B,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,CAAA;YAC5C,OAAO,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;QACxC,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC9C,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAE5D,CAAA;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,WAAqB;IAClD,IAAI,OAAO,WAAW,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,WAAW,CAAA;IACpB,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAC7D,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,CAAA;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,cAAc;KACxB,CAAC,CAAA;IAEF,mBAAmB,CAAC,MAAM,EAAE;QAC1B,WAAW,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YACzB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC;gBACzC,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC;aACtC,CAAC,CAAA;YACF,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QACnC,CAAC;QACD,gBAAgB,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YAC9B,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC;gBACzC,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC;aACtC,CAAC,CAAA;YACF,OAAO,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;QACxC,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
package/dist/session.d.ts CHANGED
@@ -3,24 +3,45 @@ export type CadMcpOpenMode = 'read' | 'write';
3
3
  export interface CadMcpSessionCreateOptions {
4
4
  /** Prefer hardware GPU WebGL. Default `true`. */
5
5
  useGpu?: boolean;
6
+ /**
7
+ * Show a Chromium window so the user can watch the drawing.
8
+ * Default `false` (headless).
9
+ */
10
+ headed?: boolean;
11
+ /**
12
+ * Headless-only: close the browser after this many ms of idle time
13
+ * since the last tool call. Default `30000`. Ignored when headed.
14
+ */
15
+ idleCloseMs?: number;
6
16
  }
7
17
  /**
8
- * Long-lived headless Chromium session hosting cad-simple-viewer + agent-core.
18
+ * Long-lived Chromium session hosting cad-simple-viewer + agent-core.
9
19
  *
10
- * Started lazily on the first tool call and kept for the process lifetime so
11
- * drawing state persists across MCP tool invocations.
20
+ * Started lazily on the first tool call. Headless sessions auto-close after
21
+ * idle time; headed sessions stay open so the user can watch the drawing.
12
22
  */
13
23
  export declare class CadMcpSession {
14
24
  private readonly browser;
15
25
  private readonly page;
16
26
  private readonly server;
27
+ readonly headed: boolean;
28
+ private readonly idleCloseMs;
29
+ private idleTimer;
17
30
  private constructor();
18
31
  private static instance;
32
+ /** Resolved session used to detect headed mismatches before await. */
33
+ private static resolved;
19
34
  /**
20
35
  * Returns the shared session, creating it on first call.
36
+ *
37
+ * If an existing session has a different `headed` flag, it is closed and
38
+ * rebuilt (drawing state is lost).
21
39
  */
22
40
  static shared(options?: CadMcpSessionCreateOptions): Promise<CadMcpSession>;
23
41
  static create(options?: CadMcpSessionCreateOptions): Promise<CadMcpSession>;
42
+ private clearIdleClose;
43
+ private scheduleIdleClose;
44
+ private touchActivity;
24
45
  openDrawing(input: {
25
46
  path?: string;
26
47
  mode?: CadMcpOpenMode;