scanruler-mcp 0.1.0 → 0.2.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 CHANGED
@@ -1,228 +1,241 @@
1
- # scanruler-mcp
2
-
3
- Drive [ScanRuler](https://scanruler.com/), the browser tool for measuring 3D
4
- scans, from an AI agent. This is a [Model Context Protocol](https://modelcontextprotocol.io)
5
- server: the agent starts it and calls its tools; the ScanRuler tab open in
6
- your browser connects to it over `127.0.0.1` and runs each call there, in
7
- front of you. Every step the agent takes is one step of the tab's undo
8
- history, so you can take any of it back.
9
-
10
- Nothing goes anywhere but your own computer: the scan travels from your disk
11
- to your browser through this server, as it does when you open it yourself.
12
- What the agent reads — the figures, the report — goes to the agent's model
13
- provider, like everything else it reads.
14
-
15
- ## Setting up
16
-
17
- You need [Node.js](https://nodejs.org/) 20 or newer, and Chrome, Edge or
18
- Firefox.
19
-
20
- ### 1. Add the server to your agent
21
-
22
- **Claude Code**
23
-
24
- ```bash
25
- claude mcp add --scope user scanruler -- npx -y scanruler-mcp
26
- ```
27
-
28
- `--scope user` has it in every project; leave it out for this one only.
29
- Exports the agent makes land in the folder Claude Code was started in,
30
- unless the agent names a path.
31
-
32
- **Codex** — the CLI, the IDE extension and the app share one setting:
33
-
34
- ```bash
35
- codex mcp add scanruler -- npx -y scanruler-mcp
36
- ```
37
-
38
- or, in `~/.codex/config.toml`, with room for the first start (npx fetches the
39
- package) and for long calls — Codex gives a server 10 seconds to start and a
40
- call 60 unless told otherwise:
41
-
42
- ```toml
43
- [mcp_servers.scanruler]
44
- command = "npx"
45
- args = ["-y", "scanruler-mcp"]
46
- startup_timeout_sec = 60
47
- tool_timeout_sec = 300
48
- ```
49
-
50
- **Claude Desktop** — Settings → Developer → Edit Config, then in
51
- `claude_desktop_config.json`:
52
-
53
- ```json
54
- {
55
- "mcpServers": {
56
- "scanruler": {
57
- "command": "npx",
58
- "args": ["-y", "scanruler-mcp", "--out", "/Users/you/Documents/ScanRuler"]
59
- }
60
- }
61
- }
62
- ```
63
-
64
- Claude Desktop starts servers in a folder of its own, so give `--out` a folder
65
- for the exports, and name files to the agent by their full path. Quit Claude
66
- Desktop after saving — File → Exit; closing the window leaves it running —
67
- and start it again. It starts the server twice, for its chats and for its
68
- Cowork and Code sessions; the copy that starts first holds the port and the
69
- tab connects to it, and the other sends its calls through that one — see
70
- *Several agents* below.
71
-
72
- **Cursor** — `.cursor/mcp.json` in a project, or `~/.cursor/mcp.json` for all:
73
-
74
- ```json
75
- {
76
- "mcpServers": {
77
- "scanruler": {
78
- "command": "npx",
79
- "args": ["-y", "scanruler-mcp"]
80
- }
81
- }
82
- }
83
- ```
84
-
85
- **From a clone of the ScanRuler repository**, to try a change: run
86
- `npm --prefix mcp ci` once, then use
87
- `node /path/to/scanruler/mcp/bin/scanruler-mcp.js` where the examples say
88
- `npx -y scanruler-mcp` — in Claude Code,
89
- `claude mcp add scanruler -- node /path/to/scanruler/mcp/bin/scanruler-mcp.js`.
90
-
91
- ### 2. Let the agent open ScanRuler
92
-
93
- Ask the agent for something in ScanRuler — or just *"Connect to ScanRuler"*.
94
- With no tab connected, it calls `scanruler_open`, which opens ScanRuler in
95
- your default browser with the pairing in its address: the tab switches the
96
- connection on with this server's port and token, and connects. The first
97
- time, **Chrome and Edge** ask whether scanruler.com may access "apps and
98
- services on this device" — allow it, that is this server. **Firefox** asks
99
- the same. The tab keeps the pairing, so this is done once per browser.
100
-
101
- When the default browser is not the one you use ScanRuler in, or the agent
102
- runs somewhere it cannot open one, pair by hand:
103
-
104
- ```bash
105
- npx -y scanruler-mcp --pair
106
- ```
107
-
108
- prints the port, the pairing token and a link. Open the link once in the
109
- browser you use ScanRuler in, or in ScanRuler go to ⚙ **Settings → Agents**,
110
- switch on **Local agent connection**, and enter the port and the token. The
111
- token is made on the first run and kept in your config folder
112
- (`%APPDATA%\scanruler-mcp` on Windows,
113
- `~/Library/Application Support/scanruler-mcp` on macOS,
114
- `~/.config/scanruler-mcp` elsewhere). `scanruler_status` hands out the same
115
- link.
116
-
117
- A chip in ScanRuler's top bar says where the connection stands: **listening**
118
- while the agent's server is not running, **connected**, or **turned away**
119
- (a wrong token, or another tab connected already — the server takes one tab
120
- at a time). If you denied the browser's question, allow *Local network
121
- access* for the site in the site settings (the icon left of the address) and
122
- reload. **Safari** does not let a page from the web reach the computer it
123
- runs on at all; use `--serve` below.
124
-
125
- ### Several agents
126
-
127
- Any number of copies of the server can share the tab. The first to start
128
- holds the port and the tab's connection; one that finds the port taken
129
- connects to that one, with the same token, and sends its calls through it.
130
- When the copy holding the port stops, another takes the port over, and the
131
- tab — which keeps trying — connects to it within ten seconds.
132
- `scanruler_status` says which this copy is (`server.role`: `holder`,
133
- `relay`, or `none` with `server.error` saying why). Copies with different
134
- tokens cannot share a port: give them the same `SCANRULER_MCP_TOKEN`, or
135
- each its own `--port`. Changes from several agents run one after another in
136
- the tab, each one step of the same undo history.
137
-
138
- ### Serving the app yourself
139
-
140
- ```bash
141
- npx scanruler-mcp --serve /path/to/scanruler/dist
142
- ```
143
-
144
- serves a built ScanRuler (`npm run build` in a clone) at
145
- `http://127.0.0.1:7317/` from the same port the tab connects to — for Safari,
146
- for working offline, and for the open-source build. A page from there needs
147
- no browser permission, and `--pair` then gives a link to it.
148
-
149
- ## Options
150
-
151
- | Option | |
152
- |---|---|
153
- | `--port <n>` | The port the tab connects to; 7317 unless given. Also `SCANRULER_MCP_PORT`. |
154
- | `--out <dir>` | Where exports go when a tool call names no path; the folder the server was started in otherwise. |
155
- | `--serve <dir>` | Also serve a built ScanRuler from `<dir>`. |
156
- | `--allow-origin <url>` | Let a ScanRuler tab from another address connect — a self-hosted copy. Repeatable. scanruler.com and any page on this computer are always allowed. |
157
- | `--app <url>` | The ScanRuler address the pairing link opens. |
158
- | `--pair` | Print the port, the token and the pairing link, and exit. |
159
- | `--help` | The options. |
160
-
161
- `SCANRULER_MCP_TOKEN` overrides the stored token; `SCANRULER_MCP_CONFIG_DIR`
162
- moves the config folder.
163
-
164
- ## Tools
165
-
166
- Every command the ScanRuler tab offers is a tool, its name with dots turned
167
- into underscores — `scan_open`, `element_fit`, `dimension_add`,
168
- `report_get`, `history_undo` and the rest; their descriptions say what each
169
- needs and returns. The list is the tab's while one is connected — a build
170
- with more commands lists more. Before a tab is there it is the list of the
171
- last tab that connected, which the server keeps in its config folder
172
- (`tools.json`), or, the first time, the app's own; a client that lists the
173
- tools once, when it starts, sees them all that way, and one that listens is
174
- told when the list changes. Three more are the server's: `scanruler_status`
175
- (is a tab connected, which version, how to pair one), `scanruler_open` (open
176
- ScanRuler in the default browser, paired, and wait for it) and `scanruler_wait`
177
- (until a tab is connected, or also idle).
178
-
179
- - **Places on the scan** are `{ "point": [x, y, z] }` in millimetres — the
180
- scan vertex nearest it is taken — or `{ "vertex": n }`.
181
- - **Files are paths.** `scan_open`, `deviation_open_reference`,
182
- `flat_open_image` and `project_load` take `path`, a file on this computer;
183
- the server reads it and streams it to the tab. The exports and
184
- `project_save` take an optional `path` — a file, or a folder for the name
185
- ScanRuler gives it — and the server writes the file there and returns where.
186
- - **Pictures.** `view_render` comes back as an image the agent sees — the
187
- 3D view as the tab shows it, after `view_set` has turned it if asked — and
188
- is written to a file only when the call gives `path`.
189
- - **Results** are the session as the tab holds it afterwards, as JSON, in
190
- millimetres and degrees. A refusal comes back as an error with a code —
191
- `no_scan`, `busy`, `invalid_input`, `invalid_state` (something open in a
192
- panel is in the way), `not_found`, `failed`, `unavailable`.
193
-
194
- A session might go: `scanruler_status`, `scanruler_open` if no tab is
195
- connected, `scan_open`, `session_state` (the scan's bounding box says where
196
- the part lies), `element_fit` twice, `dimension_add`, `report_get`,
197
- `view_render`.
198
-
199
- ## How it works
200
-
201
- The tab connects to `ws://127.0.0.1:<port>/`. Before that, a tab from the web
202
- fetches `http://127.0.0.1:<port>/scanruler-mcp`, which is what has Chrome and
203
- Edge ask for the permission a WebSocket alone never asks for. The server lets
204
- in a tab from scanruler.com, from this computer, or from an `--allow-origin`
205
- address, that presents the pairing token — one tab at a time — and, beside
206
- it, other copies of itself that present the token, whose requests it passes
207
- to the tab (`src/relay.js`). Messages are
208
- JSON; a file travels as a binary frame right after the JSON that announces it,
209
- never as base64 (`src/framing.js`, and `src/commands/framing.ts` in the app).
210
- Everything the server logs goes to stderr; stdout is the MCP channel.
211
-
212
- ## Development
213
-
214
- ```bash
215
- npm ci
216
- npm test # node --test: framing, tool generation, the link, an MCP client end to end
217
- ```
218
-
219
- The app's browser check `node scripts/e2e-agent.mjs` (from the repository
220
- root, against a running dev server) drives the whole path with the SDK's own
221
- MCP client. `src/commands.json` is the app's command list as of this version,
222
- for listing the tools before a tab connects; the app's test
223
- `tests/mcpCommands.test.ts` keeps it current
224
- (`UPDATE_MCP_COMMANDS=1 npx vitest run tests/mcpCommands.test.ts`).
225
-
226
- ## Licence
227
-
228
- AGPL-3.0-only, as ScanRuler — see [LICENSE](LICENSE).
1
+ # scanruler-mcp
2
+
3
+ Drive [ScanRuler](https://scanruler.com/), the browser tool for measuring 3D
4
+ scans, from an AI agent. This is a [Model Context Protocol](https://modelcontextprotocol.io)
5
+ server: the agent starts it and calls its tools; the ScanRuler tab open in
6
+ your browser connects to it over `127.0.0.1` and runs each call there, in
7
+ front of you. Every step the agent takes is one step of the tab's undo
8
+ history, so you can take any of it back.
9
+
10
+ Nothing goes anywhere but your own computer: the scan travels from your disk
11
+ to your browser through this server, as it does when you open it yourself.
12
+ What the agent reads — the figures, the report — goes to the agent's model
13
+ provider, like everything else it reads.
14
+
15
+ ## Setting up
16
+
17
+ You need [Node.js](https://nodejs.org/) 22 or newer, and Chrome, Edge or
18
+ Firefox.
19
+
20
+ ### 1. Add the server to your agent
21
+
22
+ **Claude Code**
23
+
24
+ ```bash
25
+ claude mcp add --scope user scanruler -- npx -y scanruler-mcp
26
+ ```
27
+
28
+ `--scope user` has it in every project; leave it out for this one only.
29
+ Exports the agent makes land in the folder Claude Code was started in,
30
+ unless the agent names a path.
31
+
32
+ **Codex** — the CLI, the IDE extension and the app share one setting:
33
+
34
+ ```bash
35
+ codex mcp add scanruler -- npx -y scanruler-mcp
36
+ ```
37
+
38
+ or, in `~/.codex/config.toml`, with room for the first start (npx fetches the
39
+ package) and for long calls — Codex gives a server 10 seconds to start and a
40
+ call 60 unless told otherwise:
41
+
42
+ ```toml
43
+ [mcp_servers.scanruler]
44
+ command = "npx"
45
+ args = ["-y", "scanruler-mcp"]
46
+ startup_timeout_sec = 60
47
+ tool_timeout_sec = 300
48
+ ```
49
+
50
+ **Claude Desktop** — Settings → Developer → Edit Config, then in
51
+ `claude_desktop_config.json`:
52
+
53
+ ```json
54
+ {
55
+ "mcpServers": {
56
+ "scanruler": {
57
+ "command": "npx",
58
+ "args": ["-y", "scanruler-mcp", "--out", "/Users/you/Documents/ScanRuler"]
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ Claude Desktop starts servers in a folder of its own, so give `--out` a folder
65
+ for the exports, and name files to the agent by their full path. Quit Claude
66
+ Desktop after saving — File → Exit; closing the window leaves it running —
67
+ and start it again. It starts the server twice, for its chats and for its
68
+ Cowork and Code sessions; the copy that starts first holds the port and the
69
+ tab connects to it, and the other sends its calls through that one — see
70
+ *Several agents* below.
71
+
72
+ **Cursor** — `.cursor/mcp.json` in a project, or `~/.cursor/mcp.json` for all:
73
+
74
+ ```json
75
+ {
76
+ "mcpServers": {
77
+ "scanruler": {
78
+ "command": "npx",
79
+ "args": ["-y", "scanruler-mcp"]
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ **From a clone of the ScanRuler repository**, to try a change: run
86
+ `npm --prefix mcp ci` once, then use
87
+ `node /path/to/scanruler/mcp/bin/scanruler-mcp.js` where the examples say
88
+ `npx -y scanruler-mcp` — in Claude Code,
89
+ `claude mcp add scanruler -- node /path/to/scanruler/mcp/bin/scanruler-mcp.js`.
90
+
91
+ ### 2. Let the agent open ScanRuler
92
+
93
+ Ask the agent for something in ScanRuler — or just *"Connect to ScanRuler"*.
94
+ With no tab connected, it calls `scanruler_open`, which opens ScanRuler in
95
+ your default browser with the pairing in its address: the tab switches the
96
+ connection on with this server's port and token, and connects. The first
97
+ time, **Chrome and Edge** ask whether scanruler.com may access "apps and
98
+ services on this device" — allow it, that is this server. **Firefox** asks
99
+ the same. The tab keeps the pairing, so this is done once per browser.
100
+
101
+ When the default browser is not the one you use ScanRuler in, or the agent
102
+ runs somewhere it cannot open one, pair by hand:
103
+
104
+ ```bash
105
+ npx -y scanruler-mcp --pair
106
+ ```
107
+
108
+ prints the port, the pairing token and a link. Open the link once in the
109
+ browser you use ScanRuler in, or in ScanRuler go to ⚙ **Settings → Agents**,
110
+ switch on **Local agent connection**, and enter the port and the token. The
111
+ token is made on the first run and kept in your config folder
112
+ (`%APPDATA%\scanruler-mcp` on Windows,
113
+ `~/Library/Application Support/scanruler-mcp` on macOS,
114
+ `$XDG_CONFIG_HOME/scanruler-mcp` elsewhere, `~/.config/scanruler-mcp`
115
+ without it). `scanruler_status` hands out the same
116
+ link.
117
+
118
+ A chip in ScanRuler's top bar says where the connection stands: **listening**
119
+ while the agent's server is not running, **connected**, or **turned away**
120
+ (a wrong token, or another tab connected already — the server takes one tab
121
+ at a time). If you denied the browser's question, allow *Local network
122
+ access* for the site in the site settings (the icon left of the address) and
123
+ reload. **Safari** does not let a page from the web reach the computer it
124
+ runs on at all; use `--serve` below.
125
+
126
+ ### Several agents
127
+
128
+ Any number of copies of the server can share the tab. The first to start
129
+ holds the port and the tab's connection; one that finds the port taken
130
+ connects to that one, with the same token, and sends its calls through it.
131
+ When the copy holding the port stops, another takes the port over, and the
132
+ tab — which keeps trying — connects to it within ten seconds.
133
+ `scanruler_status` says which this copy is (`server.role`: `holder`,
134
+ `relay`, or `none` with `server.error` saying why). Copies with different
135
+ tokens cannot share a port: give them the same `SCANRULER_MCP_TOKEN`, or
136
+ each its own `--port`. Changes from several agents run one after another in
137
+ the tab, each one step of the same undo history.
138
+
139
+ ### Serving the app yourself
140
+
141
+ ```bash
142
+ npx scanruler-mcp --serve /path/to/scanruler/dist
143
+ ```
144
+
145
+ serves a built ScanRuler (`npm run build` in a clone) at
146
+ `http://127.0.0.1:7317/` from the same port the tab connects to — for Safari,
147
+ for working offline, and for the open-source build. A page from there needs
148
+ no browser permission, and `--pair` then gives a link to it.
149
+
150
+ ## Options
151
+
152
+ | Option | |
153
+ |---|---|
154
+ | `--port <n>` | The port the tab connects to; 7317 unless given. Also `SCANRULER_MCP_PORT`. |
155
+ | `--out <dir>` | Where exports go when a tool call names no path; the folder the server was started in otherwise. |
156
+ | `--serve <dir>` | Also serve a built ScanRuler from `<dir>`. |
157
+ | `--allow-origin <url>` | Let a ScanRuler tab from another address connect — a self-hosted copy. Repeatable. scanruler.com and any page on this computer are always allowed. |
158
+ | `--app <url>` | The ScanRuler address the pairing link opens. |
159
+ | `--pair` | Print the port, the token and the pairing link, and exit. |
160
+ | `--help` | The options. |
161
+
162
+ `SCANRULER_MCP_TOKEN` overrides the stored token; `SCANRULER_MCP_CONFIG_DIR`
163
+ moves the config folder.
164
+
165
+ ## Tools
166
+
167
+ Every command the ScanRuler tab offers is a tool, its name with dots turned
168
+ into underscores — `scan_open`, `element_fit`, `dimension_add`,
169
+ `report_get`, `history_undo` and the rest; their descriptions say what each
170
+ needs and returns. The list is the tab's while one is connected — a build
171
+ with more commands lists more. Before a tab is there it is the list of the
172
+ last tab that connected, which the server keeps in its config folder
173
+ (`tools.json`), or, the first time, the app's own; a client that lists the
174
+ tools once, when it starts, sees them all that way, and one that listens is
175
+ told when the list changes. Four more are the server's: `scanruler_status`
176
+ (is a tab connected, which version, how to pair one), `scanruler_open` (open
177
+ ScanRuler in the default browser, paired, and wait for it), `scanruler_wait`
178
+ (until a tab is connected, or also idle) and `scanruler_batch` (several of
179
+ the tab's tools in one call, in order — a run of `scan_nearest` or
180
+ `element_fit` calls — each answer in its place, stopped at the first refused
181
+ unless told to go on).
182
+
183
+ - **Places on the scan** are `{ "point": [x, y, z] }` in millimetres — the
184
+ scan vertex nearest it is taken — or `{ "vertex": n }`. `scan_query` reads
185
+ the scan's own points: the vertices in a box or about a point, with their
186
+ normals, facing a way if asked; `section_get` a section's cut as
187
+ polylines, on the sheet and in the world.
188
+ - **Files are paths.** `scan_open`, `deviation_open_reference`,
189
+ `flat_open_image` and `project_load` take `path`, a file on this computer;
190
+ the server reads it and streams it to the tab. The exports and
191
+ `project_save` take an optional `path` — a file, or a folder for the name
192
+ ScanRuler gives it — and the server writes the file there and returns where.
193
+ - **Pictures.** `view_render` comes back as an image the agent sees — the
194
+ 3D view as the tab shows it, after `view_set` has turned it if asked — and
195
+ is written to a file only when the call gives `path`. `show` puts the
196
+ scan, the reference, the sections, the elements or the labels away for
197
+ the picture (`{ "scan": false }` shows what was built on the scan on its
198
+ own; a workspace adds keys of its own, which `view_set` lists), and
199
+ `frame` looks at a box or a place closely.
200
+ - **Results** are the session as the tab holds it afterwards, as JSON, in
201
+ millimetres and degrees, every number that is not whole kept to six
202
+ significant digits — except in an answer whose numbers are handed back
203
+ as inputs (a plane's frame, say), which keeps every digit. A refusal comes back as an error with a code —
204
+ `no_scan`, `busy`, `invalid_input`, `invalid_state` (something open in a
205
+ panel is in the way), `not_found`, `failed`, `unavailable`.
206
+
207
+ A session might go: `scanruler_status`, `scanruler_open` if no tab is
208
+ connected, `scan_open`, `session_state` (the scan's bounding box says where
209
+ the part lies), `element_fit` twice, `dimension_add`, `report_get`,
210
+ `view_render`.
211
+
212
+ ## How it works
213
+
214
+ The tab connects to `ws://127.0.0.1:<port>/`. Before that, a tab from the web
215
+ fetches `http://127.0.0.1:<port>/scanruler-mcp`, which is what has Chrome and
216
+ Edge ask for the permission a WebSocket alone never asks for. The server lets
217
+ in a tab from scanruler.com, from this computer, or from an `--allow-origin`
218
+ address, that presents the pairing token — one tab at a time — and, beside
219
+ it, other copies of itself that present the token, whose requests it passes
220
+ to the tab (`src/relay.js`). Messages are
221
+ JSON; a file travels as a binary frame right after the JSON that announces it,
222
+ never as base64 (`src/framing.js`, and `src/commands/framing.ts` in the app).
223
+ Everything the server logs goes to stderr; stdout is the MCP channel.
224
+
225
+ ## Development
226
+
227
+ ```bash
228
+ npm ci
229
+ npm test # node --test: framing, tool generation, the link, an MCP client end to end
230
+ ```
231
+
232
+ The app's browser check `node scripts/e2e-agent.mjs` (from the repository
233
+ root, against a running dev server) drives the whole path with the SDK's own
234
+ MCP client. `src/commands.json` is the app's command list as of this version,
235
+ for listing the tools before a tab connects; the app's test
236
+ `tests/mcpCommands.test.ts` keeps it current
237
+ (`UPDATE_MCP_COMMANDS=1 npx vitest run tests/mcpCommands.test.ts`).
238
+
239
+ ## Licence
240
+
241
+ AGPL-3.0-only, as ScanRuler — see [LICENSE](LICENSE).
package/package.json CHANGED
@@ -1,30 +1,30 @@
1
- {
2
- "name": "scanruler-mcp",
3
- "version": "0.1.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": ["mcp", "model-context-protocol", "3d-scan", "metrology", "scanruler"],
15
- "bin": {
16
- "scanruler-mcp": "bin/scanruler-mcp.js"
17
- },
18
- "files": ["bin", "src", "README.md", "LICENSE"],
19
- "engines": {
20
- "node": ">=20"
21
- },
22
- "scripts": {
23
- "start": "node bin/scanruler-mcp.js",
24
- "test": "node --test"
25
- },
26
- "dependencies": {
27
- "@modelcontextprotocol/sdk": "1.32.1",
28
- "ws": "8.22.0"
29
- }
30
- }
1
+ {
2
+ "name": "scanruler-mcp",
3
+ "version": "0.2.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": ["mcp", "model-context-protocol", "3d-scan", "metrology", "scanruler"],
15
+ "bin": {
16
+ "scanruler-mcp": "bin/scanruler-mcp.js"
17
+ },
18
+ "files": ["bin", "src", "README.md", "LICENSE"],
19
+ "engines": {
20
+ "node": ">=22"
21
+ },
22
+ "scripts": {
23
+ "start": "node bin/scanruler-mcp.js",
24
+ "test": "node --test"
25
+ },
26
+ "dependencies": {
27
+ "@modelcontextprotocol/sdk": "1.32.1",
28
+ "ws": "8.22.0"
29
+ }
30
+ }