@procedures/mcp-dev-tools 0.6.0 → 0.8.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/CHANGELOG.md +39 -0
- package/README.md +20 -13
- package/dist/.tsbuildinfo +1 -1
- package/dist/config.d.ts +4 -4
- package/dist/config.js +1 -1
- package/dist/host.d.ts +6 -3
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +10 -8
- package/dist/host.js.map +1 -1
- package/package.json +6 -6
- package/src/config.ts +4 -4
- package/src/host.ts +13 -9
package/dist/config.d.ts
CHANGED
|
@@ -34,9 +34,9 @@ export interface McpServerConfig {
|
|
|
34
34
|
*/
|
|
35
35
|
programCheck?: boolean | undefined;
|
|
36
36
|
/**
|
|
37
|
-
* The
|
|
38
|
-
* nested
|
|
39
|
-
*
|
|
37
|
+
* The root of the files of the host (roadmap R33). Each procedure keeps its paths in it, also
|
|
38
|
+
* in the nested calls (`lib.scan`, `cue.add`), or the root refuses it. A path outside, and a
|
|
39
|
+
* refused tool, give `FORBIDDEN` with the reason `outside-root`. No value: no root.
|
|
40
40
|
*/
|
|
41
41
|
fsRoot?: string | undefined;
|
|
42
42
|
}
|
|
@@ -52,7 +52,7 @@ export interface McpServerConfig {
|
|
|
52
52
|
* - MCP_READ_ONLY: "true" or "1" gives only the tools that change nothing (default: false)
|
|
53
53
|
* - MCP_HTTP_PORT, MCP_HTTP_HOST, MCP_HTTP_TOKEN: serve over Streamable HTTP, not stdio
|
|
54
54
|
* - MCP_PROGRAM_CHECK: "false" or "0" starts a program without the check before the run
|
|
55
|
-
* - MCP_FS_ROOT: the
|
|
55
|
+
* - MCP_FS_ROOT: the root of the files: each tool keeps its paths in it, or it is refused (default: no root)
|
|
56
56
|
*/
|
|
57
57
|
/** The default time limit of a tool call: a build or a test run can take minutes. */
|
|
58
58
|
export declare const DEFAULT_TOOL_TIMEOUT_MS = 600000;
|
package/dist/config.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* - MCP_READ_ONLY: "true" or "1" gives only the tools that change nothing (default: false)
|
|
16
16
|
* - MCP_HTTP_PORT, MCP_HTTP_HOST, MCP_HTTP_TOKEN: serve over Streamable HTTP, not stdio
|
|
17
17
|
* - MCP_PROGRAM_CHECK: "false" or "0" starts a program without the check before the run
|
|
18
|
-
* - MCP_FS_ROOT: the
|
|
18
|
+
* - MCP_FS_ROOT: the root of the files: each tool keeps its paths in it, or it is refused (default: no root)
|
|
19
19
|
*/
|
|
20
20
|
/** The default time limit of a tool call: a build or a test run can take minutes. */
|
|
21
21
|
export const DEFAULT_TOOL_TIMEOUT_MS = 600_000;
|
package/dist/host.d.ts
CHANGED
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* `server.ts` (the file in the MCP configuration of Claude Code) and `mark mcp` both start the
|
|
11
11
|
* server with `startDevToolsServer()`.
|
|
12
12
|
*
|
|
13
|
-
* `MCP_FS_ROOT` confines the
|
|
14
|
-
* its
|
|
13
|
+
* `MCP_FS_ROOT` confines the procedures to one folder (`confineToRoot()` of `@procedures/fs`):
|
|
14
|
+
* each tool keeps its paths in it, or the root refuses the tool. The host serves no remote
|
|
15
|
+
* events: its transport carries only MCP, and `events.subscribe` is not a tool.
|
|
15
16
|
*/
|
|
16
17
|
import { ProcedureServer, type HostPolicy, type ProcedureModule, type ProcedureRegistry, type ToolSurface } from "@procedures/client";
|
|
17
18
|
import { type BundleSurfaceModule } from "@procedures/mcp-server";
|
|
@@ -34,8 +35,10 @@ export interface DevToolsHost {
|
|
|
34
35
|
surface: ToolSurface | undefined;
|
|
35
36
|
policy: HostPolicy;
|
|
36
37
|
server: ProcedureServer;
|
|
37
|
-
/** The absolute path of the root of the
|
|
38
|
+
/** The absolute path of the root of the files (`MCP_FS_ROOT`), or undefined. */
|
|
38
39
|
fsRoot?: string | undefined;
|
|
40
|
+
/** With a root: the keys of the procedures that the root refuses. Some of them are tools. */
|
|
41
|
+
refusedUnderRoot?: string[] | undefined;
|
|
39
42
|
}
|
|
40
43
|
/** This function builds the host. It starts no transport. */
|
|
41
44
|
export declare function createDevToolsHost(config?: McpServerConfig): Promise<DevToolsHost>;
|
package/dist/host.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAEL,eAAe,EAQf,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAqC,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAErG,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAQ/D,sDAAsD;AACtD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,kFAAkF;AAClF,wBAAsB,WAAW,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAgBpF;AAaD,kFAAkF;AAClF,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,eAAe,CAAC;IACxB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,6FAA6F;IAC7F,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACzC;AAED,6DAA6D;AAC7D,wBAAsB,kBAAkB,CAAC,MAAM,GAAE,eAA8B,GAAG,OAAO,CAAC,YAAY,CAAC,CAsCtG;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,GAAE,eAA8B,GAAG,OAAO,CAAC,YAAY,CAAC,CAyCvG"}
|
package/dist/host.js
CHANGED
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* `server.ts` (the file in the MCP configuration of Claude Code) and `mark mcp` both start the
|
|
11
11
|
* server with `startDevToolsServer()`.
|
|
12
12
|
*
|
|
13
|
-
* `MCP_FS_ROOT` confines the
|
|
14
|
-
* its
|
|
13
|
+
* `MCP_FS_ROOT` confines the procedures to one folder (`confineToRoot()` of `@procedures/fs`):
|
|
14
|
+
* each tool keeps its paths in it, or the root refuses the tool. The host serves no remote
|
|
15
|
+
* events: its transport carries only MCP, and `events.subscribe` is not a tool.
|
|
15
16
|
*/
|
|
16
17
|
import { PROCEDURE_REGISTRY, ProcedureServer, createRegistry, registerClientProcedures, capabilityRefusal, narrowCapability, surfaceRule, hostPolicy, procedureServerOptions, } from "@procedures/client";
|
|
17
18
|
import { McpServerTransport, mergeSurfaces } from "@procedures/mcp-server";
|
|
@@ -52,12 +53,13 @@ async function loadBundlesGlobally(bundles) {
|
|
|
52
53
|
export async function createDevToolsHost(config = loadConfig()) {
|
|
53
54
|
const loaded = await loadBundles(config.bundles);
|
|
54
55
|
const registry = loaded.global ? PROCEDURE_REGISTRY : createRegistry(...loaded.modules);
|
|
55
|
-
// MCP_FS_ROOT (roadmap R33): each
|
|
56
|
-
// nested
|
|
56
|
+
// MCP_FS_ROOT (roadmap R33): each procedure of the registry keeps its paths in the root, also
|
|
57
|
+
// in the nested calls, or the root refuses it. It adds no procedure: the tools stay the same.
|
|
57
58
|
let fsRoot;
|
|
59
|
+
let refusedUnderRoot;
|
|
58
60
|
if (config.fsRoot !== undefined) {
|
|
59
|
-
const {
|
|
60
|
-
fsRoot =
|
|
61
|
+
const { confineToRoot } = await import("@procedures/fs/module");
|
|
62
|
+
({ root: fsRoot, refused: refusedUnderRoot } = confineToRoot(registry, config.fsRoot));
|
|
61
63
|
}
|
|
62
64
|
// Bundles without mcpNamespaces say nothing about their tools: then every procedure is a tool
|
|
63
65
|
const surface = mergeSurfaces(loaded.surfaces);
|
|
@@ -86,7 +88,7 @@ export async function createDevToolsHost(config = loadConfig()) {
|
|
|
86
88
|
...(programCheck.length > 0 ? { interceptors: programCheck } : {}),
|
|
87
89
|
});
|
|
88
90
|
const server = new ProcedureServer(procedureServerOptions(policy, registry));
|
|
89
|
-
return { registry, surface, policy, server, ...(fsRoot !== undefined ? { fsRoot } : {}) };
|
|
91
|
+
return { registry, surface, policy, server, ...(fsRoot !== undefined ? { fsRoot, refusedUnderRoot } : {}) };
|
|
90
92
|
}
|
|
91
93
|
/**
|
|
92
94
|
* This function starts the dev-tools MCP server over stdio, or over Streamable HTTP with
|
|
@@ -129,7 +131,7 @@ export async function startDevToolsServer(config = loadConfig()) {
|
|
|
129
131
|
console.error(`[mcp-server] Started with ${transport.getState().toolCount} tools`);
|
|
130
132
|
}
|
|
131
133
|
if (host.fsRoot !== undefined)
|
|
132
|
-
console.error(`[mcp-server]
|
|
134
|
+
console.error(`[mcp-server] Each tool refuses a path outside ${host.fsRoot}. Refused under the root: ${String(host.refusedUnderRoot)}`);
|
|
133
135
|
const url = transport.getState().url;
|
|
134
136
|
if (url)
|
|
135
137
|
console.error(`[mcp-server] Streamable HTTP at ${url}${config.http?.token ? " (send Authorization: Bearer <token>)" : ""}`);
|
package/dist/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@procedures/mcp-dev-tools",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0",
|
|
5
5
|
"description": "A ready-to-use MCP server for Claude Code and Claude Desktop: 91 developer tools (docker, mongo, sqlite, cue, vitest, workspace) with a strict call policy.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mcp",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"provenance": true
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@procedures/bundle-mcp": "0.
|
|
57
|
-
"@procedures/client": "0.
|
|
58
|
-
"@procedures/compiler": "0.
|
|
59
|
-
"@procedures/fs": "0.
|
|
60
|
-
"@procedures/mcp-server": "0.
|
|
56
|
+
"@procedures/bundle-mcp": "0.8.0",
|
|
57
|
+
"@procedures/client": "0.8.0",
|
|
58
|
+
"@procedures/compiler": "0.8.0",
|
|
59
|
+
"@procedures/fs": "0.8.0",
|
|
60
|
+
"@procedures/mcp-server": "0.8.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@mark1russell7/cue": "^1.0.0",
|
package/src/config.ts
CHANGED
|
@@ -31,9 +31,9 @@ export interface McpServerConfig {
|
|
|
31
31
|
*/
|
|
32
32
|
programCheck?: boolean | undefined;
|
|
33
33
|
/**
|
|
34
|
-
* The
|
|
35
|
-
* nested
|
|
36
|
-
*
|
|
34
|
+
* The root of the files of the host (roadmap R33). Each procedure keeps its paths in it, also
|
|
35
|
+
* in the nested calls (`lib.scan`, `cue.add`), or the root refuses it. A path outside, and a
|
|
36
|
+
* refused tool, give `FORBIDDEN` with the reason `outside-root`. No value: no root.
|
|
37
37
|
*/
|
|
38
38
|
fsRoot?: string | undefined;
|
|
39
39
|
}
|
|
@@ -50,7 +50,7 @@ export interface McpServerConfig {
|
|
|
50
50
|
* - MCP_READ_ONLY: "true" or "1" gives only the tools that change nothing (default: false)
|
|
51
51
|
* - MCP_HTTP_PORT, MCP_HTTP_HOST, MCP_HTTP_TOKEN: serve over Streamable HTTP, not stdio
|
|
52
52
|
* - MCP_PROGRAM_CHECK: "false" or "0" starts a program without the check before the run
|
|
53
|
-
* - MCP_FS_ROOT: the
|
|
53
|
+
* - MCP_FS_ROOT: the root of the files: each tool keeps its paths in it, or it is refused (default: no root)
|
|
54
54
|
*/
|
|
55
55
|
/** The default time limit of a tool call: a build or a test run can take minutes. */
|
|
56
56
|
export const DEFAULT_TOOL_TIMEOUT_MS = 600_000;
|
package/src/host.ts
CHANGED
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* `server.ts` (the file in the MCP configuration of Claude Code) and `mark mcp` both start the
|
|
11
11
|
* server with `startDevToolsServer()`.
|
|
12
12
|
*
|
|
13
|
-
* `MCP_FS_ROOT` confines the
|
|
14
|
-
* its
|
|
13
|
+
* `MCP_FS_ROOT` confines the procedures to one folder (`confineToRoot()` of `@procedures/fs`):
|
|
14
|
+
* each tool keeps its paths in it, or the root refuses the tool. The host serves no remote
|
|
15
|
+
* events: its transport carries only MCP, and `events.subscribe` is not a tool.
|
|
15
16
|
*/
|
|
16
17
|
|
|
17
18
|
import {
|
|
@@ -86,20 +87,23 @@ export interface DevToolsHost {
|
|
|
86
87
|
surface: ToolSurface | undefined;
|
|
87
88
|
policy: HostPolicy;
|
|
88
89
|
server: ProcedureServer;
|
|
89
|
-
/** The absolute path of the root of the
|
|
90
|
+
/** The absolute path of the root of the files (`MCP_FS_ROOT`), or undefined. */
|
|
90
91
|
fsRoot?: string | undefined;
|
|
92
|
+
/** With a root: the keys of the procedures that the root refuses. Some of them are tools. */
|
|
93
|
+
refusedUnderRoot?: string[] | undefined;
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
/** This function builds the host. It starts no transport. */
|
|
94
97
|
export async function createDevToolsHost(config: McpServerConfig = loadConfig()): Promise<DevToolsHost> {
|
|
95
98
|
const loaded = await loadBundles(config.bundles);
|
|
96
99
|
const registry = loaded.global ? PROCEDURE_REGISTRY : createRegistry(...loaded.modules);
|
|
97
|
-
// MCP_FS_ROOT (roadmap R33): each
|
|
98
|
-
// nested
|
|
100
|
+
// MCP_FS_ROOT (roadmap R33): each procedure of the registry keeps its paths in the root, also
|
|
101
|
+
// in the nested calls, or the root refuses it. It adds no procedure: the tools stay the same.
|
|
99
102
|
let fsRoot: string | undefined;
|
|
103
|
+
let refusedUnderRoot: string[] | undefined;
|
|
100
104
|
if (config.fsRoot !== undefined) {
|
|
101
|
-
const {
|
|
102
|
-
fsRoot =
|
|
105
|
+
const { confineToRoot } = await import("@procedures/fs/module");
|
|
106
|
+
({ root: fsRoot, refused: refusedUnderRoot } = confineToRoot(registry, config.fsRoot));
|
|
103
107
|
}
|
|
104
108
|
// Bundles without mcpNamespaces say nothing about their tools: then every procedure is a tool
|
|
105
109
|
const surface = mergeSurfaces(loaded.surfaces);
|
|
@@ -127,7 +131,7 @@ export async function createDevToolsHost(config: McpServerConfig = loadConfig())
|
|
|
127
131
|
...(programCheck.length > 0 ? { interceptors: programCheck } : {}),
|
|
128
132
|
});
|
|
129
133
|
const server = new ProcedureServer(procedureServerOptions(policy, registry));
|
|
130
|
-
return { registry, surface, policy, server, ...(fsRoot !== undefined ? { fsRoot } : {}) };
|
|
134
|
+
return { registry, surface, policy, server, ...(fsRoot !== undefined ? { fsRoot, refusedUnderRoot } : {}) };
|
|
131
135
|
}
|
|
132
136
|
|
|
133
137
|
/**
|
|
@@ -172,7 +176,7 @@ export async function startDevToolsServer(config: McpServerConfig = loadConfig()
|
|
|
172
176
|
if (config.debug) {
|
|
173
177
|
console.error(`[mcp-server] Started with ${transport.getState().toolCount} tools`);
|
|
174
178
|
}
|
|
175
|
-
if (host.fsRoot !== undefined) console.error(`[mcp-server]
|
|
179
|
+
if (host.fsRoot !== undefined) console.error(`[mcp-server] Each tool refuses a path outside ${host.fsRoot}. Refused under the root: ${String(host.refusedUnderRoot)}`);
|
|
176
180
|
const url = transport.getState().url;
|
|
177
181
|
if (url) console.error(`[mcp-server] Streamable HTTP at ${url}${config.http?.token ? " (send Authorization: Bearer <token>)" : ""}`);
|
|
178
182
|
return host;
|