@procedures/mcp-dev-tools 0.2.3 → 0.3.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 +60 -0
- package/README.md +8 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -1
- package/dist/host.d.ts +3 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +24 -4
- package/dist/host.js.map +1 -1
- package/package.json +8 -7
- package/src/config.ts +22 -0
- package/src/host.ts +23 -4
package/dist/config.d.ts
CHANGED
|
@@ -19,6 +19,20 @@ export interface McpServerConfig {
|
|
|
19
19
|
* each call operates with that capability (CAPABILITIES-2026-10).
|
|
20
20
|
*/
|
|
21
21
|
readOnly?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* The Streamable HTTP endpoint of the server (roadmap R26), in place of stdio. The server
|
|
24
|
+
* listens on loopback by default. A token makes each request send `Authorization: Bearer`.
|
|
25
|
+
*/
|
|
26
|
+
http?: {
|
|
27
|
+
port: number;
|
|
28
|
+
host?: string | undefined;
|
|
29
|
+
token?: string | undefined;
|
|
30
|
+
} | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* False: the host does not check a program before it runs it (roadmap R22). The default is
|
|
33
|
+
* true: a program with an error does not start, so no step of it writes.
|
|
34
|
+
*/
|
|
35
|
+
programCheck?: boolean | undefined;
|
|
22
36
|
}
|
|
23
37
|
/**
|
|
24
38
|
* Load configuration from environment variables.
|
|
@@ -30,6 +44,8 @@ export interface McpServerConfig {
|
|
|
30
44
|
* - MCP_DEBUG: Enable debug logging (default: "false")
|
|
31
45
|
* - MCP_TOOL_TIMEOUT_MS: The time limit of each tool call (default: 600000, 10 minutes; 0: no limit)
|
|
32
46
|
* - MCP_READ_ONLY: "true" or "1" gives only the tools that change nothing (default: false)
|
|
47
|
+
* - MCP_HTTP_PORT, MCP_HTTP_HOST, MCP_HTTP_TOKEN: serve over Streamable HTTP, not stdio
|
|
48
|
+
* - MCP_PROGRAM_CHECK: "false" or "0" starts a program without the check before the run
|
|
33
49
|
*/
|
|
34
50
|
/** The default time limit of a tool call: a build or a test run can take minutes. */
|
|
35
51
|
export declare const DEFAULT_TOOL_TIMEOUT_MS = 600000;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,2BAA2B;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,2BAA2B;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IAC3F;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACpC;AAED;;;;;;;;;;;;GAYG;AACH,qFAAqF;AACrF,eAAO,MAAM,uBAAuB,SAAU,CAAC;AAE/C,oGAAoG;AACpG,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI9D;AAED,wBAAgB,UAAU,IAAI,eAAe,CAsB5C"}
|
package/dist/config.js
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* - MCP_DEBUG: Enable debug logging (default: "false")
|
|
14
14
|
* - MCP_TOOL_TIMEOUT_MS: The time limit of each tool call (default: 600000, 10 minutes; 0: no limit)
|
|
15
15
|
* - MCP_READ_ONLY: "true" or "1" gives only the tools that change nothing (default: false)
|
|
16
|
+
* - MCP_HTTP_PORT, MCP_HTTP_HOST, MCP_HTTP_TOKEN: serve over Streamable HTTP, not stdio
|
|
17
|
+
* - MCP_PROGRAM_CHECK: "false" or "0" starts a program without the check before the run
|
|
16
18
|
*/
|
|
17
19
|
/** The default time limit of a tool call: a build or a test run can take minutes. */
|
|
18
20
|
export const DEFAULT_TOOL_TIMEOUT_MS = 600_000;
|
|
@@ -33,6 +35,16 @@ export function loadConfig() {
|
|
|
33
35
|
debug: process.env["MCP_DEBUG"] === "true",
|
|
34
36
|
toolTimeoutMs: parseTimeout(process.env["MCP_TOOL_TIMEOUT_MS"]),
|
|
35
37
|
readOnly: process.env["MCP_READ_ONLY"] === "true" || process.env["MCP_READ_ONLY"] === "1",
|
|
38
|
+
programCheck: !(process.env["MCP_PROGRAM_CHECK"] === "false" || process.env["MCP_PROGRAM_CHECK"] === "0"),
|
|
39
|
+
...(process.env["MCP_HTTP_PORT"]
|
|
40
|
+
? {
|
|
41
|
+
http: {
|
|
42
|
+
port: Number(process.env["MCP_HTTP_PORT"]),
|
|
43
|
+
...(process.env["MCP_HTTP_HOST"] ? { host: process.env["MCP_HTTP_HOST"] } : {}),
|
|
44
|
+
...(process.env["MCP_HTTP_TOKEN"] ? { token: process.env["MCP_HTTP_TOKEN"] } : {}),
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
: {}),
|
|
36
48
|
};
|
|
37
49
|
}
|
|
38
50
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8BH;;;;;;;;;;;;GAYG;AACH,qFAAqF;AACrF,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAO,CAAC;AAE/C,oGAAoG;AACpG,MAAM,UAAU,YAAY,CAAC,KAAyB;IACpD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,uBAAuB,CAAC;IAC/E,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACzB,OAAO,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,uBAAuB,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,wBAAwB,CAAC;IAC1E,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE3E,OAAO;QACL,OAAO;QACP,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,cAAc;QAC5D,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,OAAO;QAC3D,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,MAAM;QAC1C,aAAa,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QAC/D,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,GAAG;QACzF,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,GAAG,CAAC;QACzG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;YAC9B,CAAC,CAAC;gBACE,IAAI,EAAE;oBACJ,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;oBAC1C,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC/E,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACnF;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC"}
|
package/dist/host.d.ts
CHANGED
|
@@ -35,8 +35,9 @@ export interface DevToolsHost {
|
|
|
35
35
|
/** This function builds the host. It starts no transport. */
|
|
36
36
|
export declare function createDevToolsHost(config?: McpServerConfig): Promise<DevToolsHost>;
|
|
37
37
|
/**
|
|
38
|
-
* This function starts the dev-tools MCP server over stdio
|
|
39
|
-
* `
|
|
38
|
+
* This function starts the dev-tools MCP server over stdio, or over Streamable HTTP with
|
|
39
|
+
* `config.http` (roadmap R26). Over stdio, stdout carries the protocol, so `console.log` goes to
|
|
40
|
+
* stderr from here on (BUGS-2026-07 Bug5).
|
|
40
41
|
*/
|
|
41
42
|
export declare function startDevToolsServer(config?: McpServerConfig): Promise<DevToolsHost>;
|
|
42
43
|
//# sourceMappingURL=host.d.ts.map
|
package/dist/host.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;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;
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;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;CACzB;AAED,6DAA6D;AAC7D,wBAAsB,kBAAkB,CAAC,MAAM,GAAE,eAA8B,GAAG,OAAO,CAAC,YAAY,CAAC,CA8BtG;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,GAAE,eAA8B,GAAG,OAAO,CAAC,YAAY,CAAC,CAwCvG"}
|
package/dist/host.js
CHANGED
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { PROCEDURE_REGISTRY, ProcedureServer, createRegistry, registerClientProcedures, capabilityRefusal, narrowCapability, surfaceRule, hostPolicy, procedureServerOptions, } from "@procedures/client";
|
|
14
14
|
import { McpServerTransport, mergeSurfaces } from "@procedures/mcp-server";
|
|
15
|
+
import { programCheckInterceptor } from "@procedures/compiler";
|
|
15
16
|
import { loadConfig } from "./config.js";
|
|
17
|
+
import { ms } from "@procedures/client";
|
|
16
18
|
/** This function loads the module entry of each bundle (it registers nothing). */
|
|
17
19
|
export async function loadBundles(bundles) {
|
|
18
20
|
const modules = [];
|
|
@@ -62,18 +64,24 @@ export async function createDevToolsHost(config = loadConfig()) {
|
|
|
62
64
|
return procedure !== undefined && capabilityRefusal(procedure, capability) === undefined;
|
|
63
65
|
}
|
|
64
66
|
: surface;
|
|
67
|
+
// The check before the run (roadmap R22): a program with an error does not start, so a refusal
|
|
68
|
+
// in step 3 comes before the write of step 1
|
|
69
|
+
const exposeRule = typeof expose === "function" ? expose : expose ? surfaceRule(expose) : undefined;
|
|
70
|
+
const programCheck = config.programCheck === false ? [] : [programCheckInterceptor({ registry, expose: exposeRule })];
|
|
65
71
|
const policy = hostPolicy({
|
|
66
72
|
...(expose ? { expose } : {}),
|
|
67
73
|
strictCalls: true,
|
|
68
|
-
|
|
74
|
+
timeout: ms(config.toolTimeoutMs),
|
|
69
75
|
...(readOnly ? { readOnly: true } : {}),
|
|
76
|
+
...(programCheck.length > 0 ? { interceptors: programCheck } : {}),
|
|
70
77
|
});
|
|
71
78
|
const server = new ProcedureServer(procedureServerOptions(policy, registry));
|
|
72
79
|
return { registry, surface, policy, server };
|
|
73
80
|
}
|
|
74
81
|
/**
|
|
75
|
-
* This function starts the dev-tools MCP server over stdio
|
|
76
|
-
* `
|
|
82
|
+
* This function starts the dev-tools MCP server over stdio, or over Streamable HTTP with
|
|
83
|
+
* `config.http` (roadmap R26). Over stdio, stdout carries the protocol, so `console.log` goes to
|
|
84
|
+
* stderr from here on (BUGS-2026-07 Bug5).
|
|
77
85
|
*/
|
|
78
86
|
export async function startDevToolsServer(config = loadConfig()) {
|
|
79
87
|
// Defense-in-depth for the stdio transport: a stray console.log (from a procedure handler or a
|
|
@@ -88,7 +96,16 @@ export async function startDevToolsServer(config = loadConfig()) {
|
|
|
88
96
|
const host = await createDevToolsHost(config);
|
|
89
97
|
const expose = host.policy.expose;
|
|
90
98
|
const transport = new McpServerTransport(host.server, {
|
|
91
|
-
|
|
99
|
+
...(config.http
|
|
100
|
+
? {
|
|
101
|
+
transport: "http",
|
|
102
|
+
httpOptions: {
|
|
103
|
+
port: config.http.port,
|
|
104
|
+
...(config.http.host ? { host: config.http.host } : {}),
|
|
105
|
+
...(config.http.token ? { token: config.http.token } : {}),
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
: { transport: "stdio" }),
|
|
92
109
|
serverInfo: {
|
|
93
110
|
name: config.serverName,
|
|
94
111
|
version: config.serverVersion,
|
|
@@ -101,6 +118,9 @@ export async function startDevToolsServer(config = loadConfig()) {
|
|
|
101
118
|
if (config.debug) {
|
|
102
119
|
console.error(`[mcp-server] Started with ${transport.getState().toolCount} tools`);
|
|
103
120
|
}
|
|
121
|
+
const url = transport.getState().url;
|
|
122
|
+
if (url)
|
|
123
|
+
console.error(`[mcp-server] Streamable HTTP at ${url}${config.http?.token ? " (send Authorization: Bearer <token>)" : ""}`);
|
|
104
124
|
return host;
|
|
105
125
|
}
|
|
106
126
|
//# sourceMappingURL=host.js.map
|
package/dist/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,sBAAsB,GAKvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAA4B,MAAM,wBAAwB,CAAC;AACrG,OAAO,EAAE,UAAU,EAAwB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@procedures/mcp-dev-tools",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"description": "A ready-to-use MCP server for Claude Code and Claude Desktop:
|
|
4
|
+
"version": "0.3.0",
|
|
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",
|
|
8
8
|
"model-context-protocol",
|
|
@@ -53,14 +53,15 @@
|
|
|
53
53
|
"provenance": true
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@procedures/bundle-mcp": "0.
|
|
57
|
-
"@procedures/client": "0.
|
|
58
|
-
"@procedures/
|
|
56
|
+
"@procedures/bundle-mcp": "0.3.0",
|
|
57
|
+
"@procedures/client": "0.3.0",
|
|
58
|
+
"@procedures/compiler": "0.3.0",
|
|
59
|
+
"@procedures/mcp-server": "0.3.0"
|
|
59
60
|
},
|
|
60
61
|
"devDependencies": {
|
|
61
|
-
"typescript": "^7.0.2",
|
|
62
|
-
"@types/node": "^22.0.0",
|
|
63
62
|
"@mark1russell7/cue": "^1.0.0",
|
|
63
|
+
"@types/node": "^22.0.0",
|
|
64
|
+
"typescript": "^7.0.2",
|
|
64
65
|
"vitest": "^5.0.3"
|
|
65
66
|
},
|
|
66
67
|
"scripts": {
|
package/src/config.ts
CHANGED
|
@@ -20,6 +20,16 @@ export interface McpServerConfig {
|
|
|
20
20
|
* each call operates with that capability (CAPABILITIES-2026-10).
|
|
21
21
|
*/
|
|
22
22
|
readOnly?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* The Streamable HTTP endpoint of the server (roadmap R26), in place of stdio. The server
|
|
25
|
+
* listens on loopback by default. A token makes each request send `Authorization: Bearer`.
|
|
26
|
+
*/
|
|
27
|
+
http?: { port: number; host?: string | undefined; token?: string | undefined } | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* False: the host does not check a program before it runs it (roadmap R22). The default is
|
|
30
|
+
* true: a program with an error does not start, so no step of it writes.
|
|
31
|
+
*/
|
|
32
|
+
programCheck?: boolean | undefined;
|
|
23
33
|
}
|
|
24
34
|
|
|
25
35
|
/**
|
|
@@ -32,6 +42,8 @@ export interface McpServerConfig {
|
|
|
32
42
|
* - MCP_DEBUG: Enable debug logging (default: "false")
|
|
33
43
|
* - MCP_TOOL_TIMEOUT_MS: The time limit of each tool call (default: 600000, 10 minutes; 0: no limit)
|
|
34
44
|
* - MCP_READ_ONLY: "true" or "1" gives only the tools that change nothing (default: false)
|
|
45
|
+
* - MCP_HTTP_PORT, MCP_HTTP_HOST, MCP_HTTP_TOKEN: serve over Streamable HTTP, not stdio
|
|
46
|
+
* - MCP_PROGRAM_CHECK: "false" or "0" starts a program without the check before the run
|
|
35
47
|
*/
|
|
36
48
|
/** The default time limit of a tool call: a build or a test run can take minutes. */
|
|
37
49
|
export const DEFAULT_TOOL_TIMEOUT_MS = 600_000;
|
|
@@ -54,5 +66,15 @@ export function loadConfig(): McpServerConfig {
|
|
|
54
66
|
debug: process.env["MCP_DEBUG"] === "true",
|
|
55
67
|
toolTimeoutMs: parseTimeout(process.env["MCP_TOOL_TIMEOUT_MS"]),
|
|
56
68
|
readOnly: process.env["MCP_READ_ONLY"] === "true" || process.env["MCP_READ_ONLY"] === "1",
|
|
69
|
+
programCheck: !(process.env["MCP_PROGRAM_CHECK"] === "false" || process.env["MCP_PROGRAM_CHECK"] === "0"),
|
|
70
|
+
...(process.env["MCP_HTTP_PORT"]
|
|
71
|
+
? {
|
|
72
|
+
http: {
|
|
73
|
+
port: Number(process.env["MCP_HTTP_PORT"]),
|
|
74
|
+
...(process.env["MCP_HTTP_HOST"] ? { host: process.env["MCP_HTTP_HOST"] } : {}),
|
|
75
|
+
...(process.env["MCP_HTTP_TOKEN"] ? { token: process.env["MCP_HTTP_TOKEN"] } : {}),
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
: {}),
|
|
57
79
|
};
|
|
58
80
|
}
|
package/src/host.ts
CHANGED
|
@@ -27,7 +27,9 @@ import {
|
|
|
27
27
|
type ToolSurface,
|
|
28
28
|
} from "@procedures/client";
|
|
29
29
|
import { McpServerTransport, mergeSurfaces, type BundleSurfaceModule } from "@procedures/mcp-server";
|
|
30
|
+
import { programCheckInterceptor } from "@procedures/compiler";
|
|
30
31
|
import { loadConfig, type McpServerConfig } from "./config.js";
|
|
32
|
+
import { ms } from "@procedures/client";
|
|
31
33
|
|
|
32
34
|
/** The exports of a bundle's `module` entry: its module and the lists of its tools. */
|
|
33
35
|
interface BundleModuleExports extends BundleSurfaceModule {
|
|
@@ -101,19 +103,25 @@ export async function createDevToolsHost(config: McpServerConfig = loadConfig())
|
|
|
101
103
|
return procedure !== undefined && capabilityRefusal(procedure, capability) === undefined;
|
|
102
104
|
}
|
|
103
105
|
: surface;
|
|
106
|
+
// The check before the run (roadmap R22): a program with an error does not start, so a refusal
|
|
107
|
+
// in step 3 comes before the write of step 1
|
|
108
|
+
const exposeRule = typeof expose === "function" ? expose : expose ? surfaceRule(expose) : undefined;
|
|
109
|
+
const programCheck = config.programCheck === false ? [] : [programCheckInterceptor({ registry, expose: exposeRule })];
|
|
104
110
|
const policy = hostPolicy({
|
|
105
111
|
...(expose ? { expose } : {}),
|
|
106
112
|
strictCalls: true,
|
|
107
|
-
|
|
113
|
+
timeout: ms(config.toolTimeoutMs),
|
|
108
114
|
...(readOnly ? { readOnly: true } : {}),
|
|
115
|
+
...(programCheck.length > 0 ? { interceptors: programCheck } : {}),
|
|
109
116
|
});
|
|
110
117
|
const server = new ProcedureServer(procedureServerOptions(policy, registry));
|
|
111
118
|
return { registry, surface, policy, server };
|
|
112
119
|
}
|
|
113
120
|
|
|
114
121
|
/**
|
|
115
|
-
* This function starts the dev-tools MCP server over stdio
|
|
116
|
-
* `
|
|
122
|
+
* This function starts the dev-tools MCP server over stdio, or over Streamable HTTP with
|
|
123
|
+
* `config.http` (roadmap R26). Over stdio, stdout carries the protocol, so `console.log` goes to
|
|
124
|
+
* stderr from here on (BUGS-2026-07 Bug5).
|
|
117
125
|
*/
|
|
118
126
|
export async function startDevToolsServer(config: McpServerConfig = loadConfig()): Promise<DevToolsHost> {
|
|
119
127
|
// Defense-in-depth for the stdio transport: a stray console.log (from a procedure handler or a
|
|
@@ -129,7 +137,16 @@ export async function startDevToolsServer(config: McpServerConfig = loadConfig()
|
|
|
129
137
|
const host = await createDevToolsHost(config);
|
|
130
138
|
const expose = host.policy.expose;
|
|
131
139
|
const transport = new McpServerTransport(host.server, {
|
|
132
|
-
|
|
140
|
+
...(config.http
|
|
141
|
+
? {
|
|
142
|
+
transport: "http" as const,
|
|
143
|
+
httpOptions: {
|
|
144
|
+
port: config.http.port,
|
|
145
|
+
...(config.http.host ? { host: config.http.host } : {}),
|
|
146
|
+
...(config.http.token ? { token: config.http.token } : {}),
|
|
147
|
+
},
|
|
148
|
+
}
|
|
149
|
+
: { transport: "stdio" as const }),
|
|
133
150
|
serverInfo: {
|
|
134
151
|
name: config.serverName,
|
|
135
152
|
version: config.serverVersion,
|
|
@@ -143,5 +160,7 @@ export async function startDevToolsServer(config: McpServerConfig = loadConfig()
|
|
|
143
160
|
if (config.debug) {
|
|
144
161
|
console.error(`[mcp-server] Started with ${transport.getState().toolCount} tools`);
|
|
145
162
|
}
|
|
163
|
+
const url = transport.getState().url;
|
|
164
|
+
if (url) console.error(`[mcp-server] Streamable HTTP at ${url}${config.http?.token ? " (send Authorization: Bearer <token>)" : ""}`);
|
|
146
165
|
return host;
|
|
147
166
|
}
|