scanruler-mcp 0.5.0 → 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 +1 -1
- package/src/commands.json +347 -312
- package/src/main.js +14 -8
- package/src/mcp.js +272 -47
- package/src/tools.js +28 -9
- package/src/trace.js +12 -1
package/src/main.js
CHANGED
|
@@ -13,7 +13,7 @@ import { openInBrowser } from './browser.js'
|
|
|
13
13
|
import { configDir, loadConfig, loadFolders, loadLastProject, loadRemembered, saveFolders, saveLastProject, saveRemembered } from './config.js'
|
|
14
14
|
import { CHECKOUT_ENGINE, EngineLink, loadEngine } from './engine.js'
|
|
15
15
|
import { originAllowed } from './link.js'
|
|
16
|
-
import { ANSWER_WITHIN_MS, createMcpServer,
|
|
16
|
+
import { ANSWER_WITHIN_MS, createMcpServer, parseToolMode } from './mcp.js'
|
|
17
17
|
import { SharedLink } from './relay.js'
|
|
18
18
|
import { createTrace } from './trace.js'
|
|
19
19
|
import { httpServer } from './serve.js'
|
|
@@ -42,12 +42,17 @@ Usage: scanruler-mcp [options]
|
|
|
42
42
|
--tools <mode> full (the default) lists each of ScanRuler's commands as a tool;
|
|
43
43
|
compact lists the server's own and the commands that return a
|
|
44
44
|
picture, the rest read through scanruler_tools and run through
|
|
45
|
-
scanruler_batch — for a small context window
|
|
45
|
+
scanruler_batch — for a small context window; or namespaces,
|
|
46
|
+
comma-separated — the part of a tool's name before its first
|
|
47
|
+
underscore — to list alone (scan,element,view) or, each with a
|
|
48
|
+
leading -, to leave out (-flat,-thickness,-dimension): the
|
|
49
|
+
server's own tools either way, the rest as full lists them,
|
|
50
|
+
for an agent whose task stays in one or two workspaces
|
|
46
51
|
--trace <dir> write a line per tool call — tool, ms, bytes each way, error,
|
|
47
52
|
whether the tab was hidden — to a new file in <dir>, for
|
|
48
53
|
measuring a run (scripts/trace-summary.mjs in the ScanRuler
|
|
49
54
|
repository sums it up); off by default
|
|
50
|
-
--trace-args with --trace, also write each call's arguments (otherwise
|
|
55
|
+
--trace-args with --trace, also write each call's arguments and the head of its answer (otherwise
|
|
51
56
|
only their size)
|
|
52
57
|
--answer-within <s> hold a call at most this many seconds (default ${ANSWER_WITHIN_MS / 1000}): a change,
|
|
53
58
|
a batch or a long read still running then answers with its job
|
|
@@ -95,6 +100,7 @@ async function headless(file, { cwd, outDir, tools, trace, answerWithinMs, updat
|
|
|
95
100
|
serverInfo: () => ({ name: 'scanruler-mcp', version: VERSION, ...updates.info(), backend: 'headless', engine: file, tools, outDir, ...(trace ? { trace: trace.file } : {}) }),
|
|
96
101
|
remembered: null,
|
|
97
102
|
tools,
|
|
103
|
+
log,
|
|
98
104
|
trace,
|
|
99
105
|
answerWithinMs,
|
|
100
106
|
})
|
|
@@ -144,10 +150,9 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
144
150
|
}
|
|
145
151
|
const port = Number(values.port ?? process.env.SCANRULER_MCP_PORT ?? DEFAULT_PORT)
|
|
146
152
|
if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error(`--port ${values.port} is not a port.`)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
153
|
+
// full, compact, or namespaces; refused here when mixed or empty, kept
|
|
154
|
+
// as given for the status to report.
|
|
155
|
+
const tools = parseToolMode(values.tools ?? (process.env.SCANRULER_MCP_TOOLS || 'full'), values.tools === undefined ? 'SCANRULER_MCP_TOOLS' : '--tools').text
|
|
151
156
|
const within = values['answer-within'] ?? process.env.SCANRULER_MCP_ANSWER_WITHIN
|
|
152
157
|
const answerWithinMs = within === undefined || within === '' ? ANSWER_WITHIN_MS : Number(within) * 1000
|
|
153
158
|
if (!Number.isFinite(answerWithinMs) || answerWithinMs < 0) {
|
|
@@ -158,7 +163,7 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
158
163
|
const app = values.app ?? (values.serve ? `http://127.0.0.1:${port}/` : HOSTED_APP)
|
|
159
164
|
const pairing = `${app.replace(/#.*$/, '')}#agent=${port}:${token}`
|
|
160
165
|
const connectHelp = () =>
|
|
161
|
-
`Open ScanRuler — ${app} — in Chrome, Edge or Firefox and either open this pairing link once: ${pairing} — or in ScanRuler go to Settings → Agents, switch on "Local agent connection", and enter port ${port} and token ${token}.`
|
|
166
|
+
`Open ScanRuler — ${app} — in Chrome, Edge or Firefox and either open this pairing link once: ${pairing} — or in ScanRuler go to Settings → Agents, switch on "Local agent connection", and enter port ${port} and token ${token}. The first time, ScanRuler warns that what the agent reads goes to the agent and its model, and connects only once the warning is accepted.`
|
|
162
167
|
if (values.pair) {
|
|
163
168
|
process.stdout.write(`Port: ${port}\nToken: ${token}\nLink: ${pairing}\n`)
|
|
164
169
|
return
|
|
@@ -197,6 +202,7 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
197
202
|
folderStore: { load: () => loadFolders(), save: (folders) => saveFolders(folders), loadProject: () => loadLastProject(), saveProject: (project) => saveLastProject(project) },
|
|
198
203
|
openPage: () => openInBrowser(pairing),
|
|
199
204
|
tools,
|
|
205
|
+
log,
|
|
200
206
|
trace,
|
|
201
207
|
answerWithinMs,
|
|
202
208
|
})
|