scanruler-mcp 0.4.5 → 0.6.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.
- package/README.md +43 -17
- package/package.json +41 -41
- package/src/commands.json +381 -310
- package/src/main.js +14 -8
- package/src/mcp.js +272 -47
- package/src/tools.js +398 -379
- package/src/trace.js +12 -1
package/README.md
CHANGED
|
@@ -95,9 +95,11 @@ Ask the agent for something in ScanRuler — or just *"Connect to ScanRuler"*.
|
|
|
95
95
|
With no tab connected, it calls `scanruler_open`, which opens ScanRuler in
|
|
96
96
|
your default browser with the pairing in its address: the tab switches the
|
|
97
97
|
connection on with this server's port and token, and connects. The first
|
|
98
|
-
time,
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
time, ScanRuler warns that what the agent reads goes to the agent and its model,
|
|
99
|
+
not only this computer, and connects once you accept. Then **Chrome and Edge**
|
|
100
|
+
ask whether scanruler.com may access "apps and services on this device" — allow
|
|
101
|
+
it, that is this server. **Firefox** asks the same. The tab keeps the pairing,
|
|
102
|
+
so this is done once per browser.
|
|
101
103
|
|
|
102
104
|
When the default browser is not the one you use ScanRuler in, or the agent
|
|
103
105
|
runs somewhere it cannot open one, pair by hand:
|
|
@@ -174,7 +176,7 @@ npx -y scanruler-mcp@latest --serve /path/to/scanruler/dist
|
|
|
174
176
|
|
|
175
177
|
serves a built ScanRuler (`npm run build` in a clone) at
|
|
176
178
|
`http://127.0.0.1:7317/` from the same port the tab connects to — for Safari,
|
|
177
|
-
for working offline, and for
|
|
179
|
+
for working offline, and for your own build. A page from there needs
|
|
178
180
|
no browser permission, and `--pair` then gives a link to it.
|
|
179
181
|
|
|
180
182
|
### Without a browser (headless)
|
|
@@ -203,9 +205,8 @@ the engine's are read through `scanruler_tools` and run through
|
|
|
203
205
|
`scanruler_batch` (see *Small local models*).
|
|
204
206
|
### Small local models
|
|
205
207
|
|
|
206
|
-
Listed in full, every command the tab offers is a tool of its own:
|
|
207
|
-
tools and
|
|
208
|
-
50k tokens at scanruler.com, all read before the conversation starts. A
|
|
208
|
+
Listed in full, every command the tab offers is a tool of its own: over a
|
|
209
|
+
hundred tools and 50k tokens of schema, all read before the conversation starts. A
|
|
209
210
|
frontier model takes that in its stride. A local model with a 128k window
|
|
210
211
|
runs out of room within a few tool rounds, and picks less reliably among so
|
|
211
212
|
many. For such a model, start the server with `--tools compact` (or set
|
|
@@ -224,9 +225,10 @@ that return a picture — `view_render`, `section_render`, `flat_render` and
|
|
|
224
225
|
lets the model call a tool it was not given can call them directly too.
|
|
225
226
|
- The tools that return a picture are listed so the model calls them
|
|
226
227
|
directly and sees the picture. In a batch a picture is not shown: it is
|
|
227
|
-
written to a file, the call's `path` or a new file in
|
|
228
|
-
folder (the output folder, `--out`, while no scan or
|
|
229
|
-
from one), and the call's result names it
|
|
228
|
+
written to a file, the call's `path` or a new file in `scanruler-work` in
|
|
229
|
+
the open scan's folder (the output folder, `--out`, while no scan or
|
|
230
|
+
project was opened from one), and the call's result names it and the
|
|
231
|
+
folder. A tab that connects with
|
|
230
232
|
another picture tool has the client list the tools again.
|
|
231
233
|
|
|
232
234
|
**LM Studio**: add `--tools` and `compact` to the server's arguments as two
|
|
@@ -252,6 +254,27 @@ codex mcp add scanruler -- npx -y scanruler-mcp@latest --tools compact
|
|
|
252
254
|
or `args = ["-y", "scanruler-mcp@latest", "--tools", "compact"]` in
|
|
253
255
|
`~/.codex/config.toml`.
|
|
254
256
|
|
|
257
|
+
### Fewer tools
|
|
258
|
+
|
|
259
|
+
An agent whose task stays in one or two workspaces carries the tools of
|
|
260
|
+
every other in each turn. `--tools` also takes namespaces — the part of a
|
|
261
|
+
tool's name before its first underscore: `scan`, `section`, `view`,
|
|
262
|
+
`element`, `align`, `deviation`, `flat`, `thickness`, `dimension`, `export`,
|
|
263
|
+
`session`, `guide`, `project`, `history`, `report`, `workspace`, and what a
|
|
264
|
+
connected tab adds. Written with a leading `-` each, they are the namespaces
|
|
265
|
+
to leave out: `--tools=-flat,-thickness,-dimension` (with the `=`: a value
|
|
266
|
+
starting with a dash is refused otherwise) lists everything but the
|
|
267
|
+
2D sheet, the wall thickness and the dimension tools. Written plain, they are
|
|
268
|
+
the namespaces to list: `--tools scan,element,view,session,guide` and nothing
|
|
269
|
+
else. The two forms do not mix, and the server's own tools (`scanruler_*`)
|
|
270
|
+
are listed either way, every listed command a tool of its own as in `full`.
|
|
271
|
+
The list is fixed when the server starts and never changes mid-chat, so
|
|
272
|
+
give it to the agent whose work is known — in the agent's config, or
|
|
273
|
+
`SCANRULER_MCP_TOOLS=-flat,-thickness,-dimension`. A tool left out is
|
|
274
|
+
unknown to the client: it is not listed, and a call to it by name answers
|
|
275
|
+
`unknown_command`. A namespace the tab does not have is accepted — a tab
|
|
276
|
+
may add one — and the server says so on its stderr when a tab connects.
|
|
277
|
+
|
|
255
278
|
## Options
|
|
256
279
|
|
|
257
280
|
| Option | |
|
|
@@ -263,7 +286,7 @@ or `args = ["-y", "scanruler-mcp@latest", "--tools", "compact"]` in
|
|
|
263
286
|
| `--app <url>` | The ScanRuler address the pairing link opens. |
|
|
264
287
|
| `--engine <file>` | Run ScanRuler headless in the server, from an engine built with `npm run build:engine` — no tab. Also `SCANRULER_ENGINE`. |
|
|
265
288
|
| `--headless` | The same, with the engine built in the checkout the server is part of. |
|
|
266
|
-
| `--tools <mode>` | `full`, the default: every command the tab offers is a tool. `compact`: the server's own and the tab's tools that return a picture; the rest are read through `scanruler_tools` and run through `scanruler_batch` — see *Small local models*. Also `SCANRULER_MCP_TOOLS`. |
|
|
289
|
+
| `--tools <mode>` | `full`, the default: every command the tab offers is a tool. `compact`: the server's own and the tab's tools that return a picture; the rest are read through `scanruler_tools` and run through `scanruler_batch` — see *Small local models*. Or namespaces, comma-separated — the part of a tool's name before its first underscore: `scan,element,view` lists those alone, `-flat,-thickness,-dimension` all but those, the server's own tools either way — see *Fewer tools*. Also `SCANRULER_MCP_TOOLS`. |
|
|
267
290
|
| `--trace <dir>` | Write a line per tool call — tool, ms, bytes each way, error, whether the tab was hidden — into a new file in `<dir>`, for measuring a run; off unless given. `scripts/trace-summary.mjs` in the ScanRuler repository sums a run up. Also `SCANRULER_MCP_TRACE`. |
|
|
268
291
|
| `--trace-args` | With `--trace`, each call's arguments too; otherwise only their size. |
|
|
269
292
|
| `--answer-within <s>` | Hold a call at most this many seconds, 45 unless given: a change, a batch or a long read still running then answers `{ queued: true, job, after }` and runs on, and `scanruler_wait` waits no longer either. A client, or a bridge between it and this computer, may cut a call at a minute; a cut call says nothing. `0` holds every call to its end. Also `SCANRULER_MCP_ANSWER_WITHIN`. |
|
|
@@ -285,7 +308,7 @@ with more commands lists more. Before a tab is there it is the list of the
|
|
|
285
308
|
last tab that connected, which the server keeps in its config folder
|
|
286
309
|
(`tools.json`), or, the first time, the app's own; a client that lists the
|
|
287
310
|
tools once, when it starts, sees them all that way, and one that listens is
|
|
288
|
-
told when the list changes.
|
|
311
|
+
told when the list changes. Seven more are the server's: `scanruler_status`
|
|
289
312
|
(is a tab connected, which version, how to pair one, what the tab's
|
|
290
313
|
session holds — its scan, project, unsaved changes and work counted — the
|
|
291
314
|
time on this computer with its offset from UTC (`server.now`), and,
|
|
@@ -298,12 +321,14 @@ of `scan_nearest` or `element_fit` calls — each answer in its place, stopped
|
|
|
298
321
|
at the first refused unless told to go on), `scanruler_write` (a text
|
|
299
322
|
file — `.md`, `.txt`, `.csv` or `.json`, a report say — written in the folder
|
|
300
323
|
the server last opened a scan or a project from, and nowhere else) and
|
|
301
|
-
`scanruler_files` (that folder's files — name, size, kind — newest first).
|
|
324
|
+
`scanruler_files` (that folder's files — name, size, kind — newest first), `scanruler_read` (a text file there, or an answer too long to carry wherever it was written, in parts: `{ text, offset, nextOffset, size }`, in bytes).
|
|
302
325
|
The folders are kept beside `tools.json` (`folders.json`), so a server
|
|
303
326
|
started afresh still writes and lists there, and `scanruler_status` lists
|
|
304
327
|
them. With `--tools compact` only the tab's tools that return a picture are
|
|
305
|
-
listed; the rest are read through
|
|
306
|
-
`scanruler_tools` — see *Small local models*.
|
|
328
|
+
listed; the rest are read through an eighth of the server's own,
|
|
329
|
+
`scanruler_tools` — see *Small local models*. With `--tools` and a list of
|
|
330
|
+
namespaces, only the tab's tools of those namespaces, or all but those — see
|
|
331
|
+
*Fewer tools*.
|
|
307
332
|
|
|
308
333
|
- **Places on the scan** are `{ "point": [x, y, z] }` in millimetres — the
|
|
309
334
|
scan vertex nearest it is taken — or `{ "vertex": n }`. `scan_query` reads
|
|
@@ -333,8 +358,9 @@ listed; the rest are read through a seventh of the server's own,
|
|
|
333
358
|
folder is numbered past one already there (`-2`, `-3`), never written over.
|
|
334
359
|
- **Long answers.** An answer past what one carries (40 k characters; a
|
|
335
360
|
guide 90 k — several guides asked for together come while they fit about
|
|
336
|
-
80 k, the rest named in `next`) is written whole to a JSON file in
|
|
337
|
-
open scan's folder
|
|
361
|
+
80 k, the rest named in `next`) is written whole to a JSON file in
|
|
362
|
+
`scanruler-work` in the open scan's folder — the server's own files, apart
|
|
363
|
+
from the person's, where an agent that may only read there can open it —
|
|
338
364
|
in the output folder (`--out`) while the scan open now was not opened from
|
|
339
365
|
a folder through this server. The answer says
|
|
340
366
|
`truncated: true`, the `file`, its short fields and the person's notes,
|
package/package.json
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "scanruler-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Drive ScanRuler, the 3D-scan measuring tool, from an AI agent: a local MCP server that reaches the ScanRuler tab open in your browser.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "AGPL-3.0-only",
|
|
7
|
-
"author": "Stefan Hermann (CNC Kitchen) <stefan@cnckitchen.com>",
|
|
8
|
-
"homepage": "https://scanruler.com/",
|
|
9
|
-
"repository": {
|
|
10
|
-
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/CNCKitchen/scanruler.git",
|
|
12
|
-
"directory": "mcp"
|
|
13
|
-
},
|
|
14
|
-
"keywords": [
|
|
15
|
-
"mcp",
|
|
16
|
-
"model-context-protocol",
|
|
17
|
-
"3d-scan",
|
|
18
|
-
"metrology",
|
|
19
|
-
"scanruler"
|
|
20
|
-
],
|
|
21
|
-
"bin": {
|
|
22
|
-
"scanruler-mcp": "bin/scanruler-mcp.js"
|
|
23
|
-
},
|
|
24
|
-
"files": [
|
|
25
|
-
"bin",
|
|
26
|
-
"src",
|
|
27
|
-
"README.md",
|
|
28
|
-
"LICENSE"
|
|
29
|
-
],
|
|
30
|
-
"engines": {
|
|
31
|
-
"node": ">=22"
|
|
32
|
-
},
|
|
33
|
-
"scripts": {
|
|
34
|
-
"start": "node bin/scanruler-mcp.js",
|
|
35
|
-
"test": "node --test"
|
|
36
|
-
},
|
|
37
|
-
"dependencies": {
|
|
38
|
-
"@modelcontextprotocol/sdk": "1.32.1",
|
|
39
|
-
"ws": "8.22.0"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "scanruler-mcp",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Drive ScanRuler, the 3D-scan measuring tool, from an AI agent: a local MCP server that reaches the ScanRuler tab open in your browser.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "AGPL-3.0-only",
|
|
7
|
+
"author": "Stefan Hermann (CNC Kitchen) <stefan@cnckitchen.com>",
|
|
8
|
+
"homepage": "https://scanruler.com/",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/CNCKitchen/scanruler.git",
|
|
12
|
+
"directory": "mcp"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"mcp",
|
|
16
|
+
"model-context-protocol",
|
|
17
|
+
"3d-scan",
|
|
18
|
+
"metrology",
|
|
19
|
+
"scanruler"
|
|
20
|
+
],
|
|
21
|
+
"bin": {
|
|
22
|
+
"scanruler-mcp": "bin/scanruler-mcp.js"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"bin",
|
|
26
|
+
"src",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=22"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"start": "node bin/scanruler-mcp.js",
|
|
35
|
+
"test": "node --test"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@modelcontextprotocol/sdk": "1.32.1",
|
|
39
|
+
"ws": "8.22.0"
|
|
40
|
+
}
|
|
41
|
+
}
|