@wrongstack/mcp 0.250.0 → 0.256.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/dist/index.d.ts +28 -0
- package/dist/index.js +86 -15
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -120,14 +120,41 @@ interface MCPRegistryOptions {
|
|
|
120
120
|
toolRegistry: ToolRegistry;
|
|
121
121
|
events: EventBus;
|
|
122
122
|
log: Logger;
|
|
123
|
+
/**
|
|
124
|
+
* Lazy mode: when true, MCP server tools are NOT registered into the
|
|
125
|
+
* tool registry on connect. They are cached internally and can be
|
|
126
|
+
* activated on demand via `activateServer(name)`. This is used in
|
|
127
|
+
* token-saving mode to avoid bloating the system prompt with 50-100+
|
|
128
|
+
* MCP tool descriptions. The model uses `mcp_control({ action: "activate", server: "..." })`
|
|
129
|
+
* to temporarily enable tools when needed.
|
|
130
|
+
* Default: false.
|
|
131
|
+
*/
|
|
132
|
+
lazyMode?: boolean | undefined;
|
|
123
133
|
}
|
|
124
134
|
declare class MCPRegistry {
|
|
125
135
|
private readonly servers;
|
|
126
136
|
private readonly toolRegistry;
|
|
127
137
|
private readonly events;
|
|
128
138
|
private readonly log;
|
|
139
|
+
private readonly lazyMode;
|
|
129
140
|
constructor(opts: MCPRegistryOptions);
|
|
130
141
|
start(cfg: MCPServerConfig): Promise<void>;
|
|
142
|
+
/**
|
|
143
|
+
* Register all cached tools for a given server into the tool registry.
|
|
144
|
+
* No-op if tools are already registered or the server is not connected.
|
|
145
|
+
* The server connection stays alive — this only toggles tool visibility.
|
|
146
|
+
*/
|
|
147
|
+
activateServer(name: string): void;
|
|
148
|
+
/**
|
|
149
|
+
* Unregister all tools for a given server from the tool registry.
|
|
150
|
+
* The server connection stays alive — this only toggles tool visibility.
|
|
151
|
+
* Returns the number of tools that were deactivated.
|
|
152
|
+
*/
|
|
153
|
+
deactivateServer(name: string): number;
|
|
154
|
+
/**
|
|
155
|
+
* Check whether a server's tools are currently registered.
|
|
156
|
+
*/
|
|
157
|
+
isActivated(name: string): boolean;
|
|
131
158
|
stop(name: string): Promise<void>;
|
|
132
159
|
restart(name: string): Promise<void>;
|
|
133
160
|
list(): {
|
|
@@ -162,6 +189,7 @@ declare class MCPRegistry {
|
|
|
162
189
|
* Unregister the previous wrapper set, then re-register the fresh
|
|
163
190
|
* tool list. The client has already refreshed its cache before
|
|
164
191
|
* dispatching — we just need to re-wrap and re-register.
|
|
192
|
+
* In lazy mode, only update the internal cache without registering.
|
|
165
193
|
*/
|
|
166
194
|
private readonly onToolsChanged;
|
|
167
195
|
private readonly onChildExit;
|
package/dist/index.js
CHANGED
|
@@ -1257,10 +1257,12 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1257
1257
|
toolRegistry;
|
|
1258
1258
|
events;
|
|
1259
1259
|
log;
|
|
1260
|
+
lazyMode;
|
|
1260
1261
|
constructor(opts) {
|
|
1261
1262
|
this.toolRegistry = opts.toolRegistry;
|
|
1262
1263
|
this.events = opts.events;
|
|
1263
1264
|
this.log = opts.log;
|
|
1265
|
+
this.lazyMode = opts.lazyMode ?? false;
|
|
1264
1266
|
}
|
|
1265
1267
|
async start(cfg) {
|
|
1266
1268
|
if (cfg.enabled === false) return;
|
|
@@ -1268,6 +1270,7 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1268
1270
|
cfg,
|
|
1269
1271
|
state: "idle",
|
|
1270
1272
|
toolNames: [],
|
|
1273
|
+
lazyTools: [],
|
|
1271
1274
|
attempts: 0,
|
|
1272
1275
|
reconnectPending: false,
|
|
1273
1276
|
reconnectCycles: 0
|
|
@@ -1275,6 +1278,56 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1275
1278
|
this.servers.set(cfg.name, slot);
|
|
1276
1279
|
await this.attemptConnect(slot);
|
|
1277
1280
|
}
|
|
1281
|
+
/**
|
|
1282
|
+
* Register all cached tools for a given server into the tool registry.
|
|
1283
|
+
* No-op if tools are already registered or the server is not connected.
|
|
1284
|
+
* The server connection stays alive — this only toggles tool visibility.
|
|
1285
|
+
*/
|
|
1286
|
+
activateServer(name) {
|
|
1287
|
+
const slot = this.servers.get(name);
|
|
1288
|
+
if (!slot || !slot.client) return;
|
|
1289
|
+
if (slot.toolNames.length > 0) return;
|
|
1290
|
+
const cached = slot.lazyTools;
|
|
1291
|
+
if (cached.length === 0) return;
|
|
1292
|
+
for (const tool of cached) {
|
|
1293
|
+
try {
|
|
1294
|
+
this.toolRegistry.register(tool, `mcp:${name}`);
|
|
1295
|
+
slot.toolNames.push(tool.name);
|
|
1296
|
+
} catch (err) {
|
|
1297
|
+
this.log.warn(`MCP tool "${tool.name}" activate failed`, err);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
this.log.info(`MCP server "${name}" activated (${slot.toolNames.length} tools)`);
|
|
1301
|
+
this.events.emit("mcp.server.connected", { name, toolCount: slot.toolNames.length });
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1304
|
+
* Unregister all tools for a given server from the tool registry.
|
|
1305
|
+
* The server connection stays alive — this only toggles tool visibility.
|
|
1306
|
+
* Returns the number of tools that were deactivated.
|
|
1307
|
+
*/
|
|
1308
|
+
deactivateServer(name) {
|
|
1309
|
+
const slot = this.servers.get(name);
|
|
1310
|
+
if (!slot) return 0;
|
|
1311
|
+
const count = slot.toolNames.length;
|
|
1312
|
+
if (count === 0) return 0;
|
|
1313
|
+
for (const t of slot.toolNames) {
|
|
1314
|
+
try {
|
|
1315
|
+
this.toolRegistry.unregister(t);
|
|
1316
|
+
} catch {
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
slot.toolNames = [];
|
|
1320
|
+
this.log.info(`MCP server "${name}" deactivated (${count} tools removed)`);
|
|
1321
|
+
this.events.emit("mcp.server.disconnected", { name, reason: "deactivate" });
|
|
1322
|
+
return count;
|
|
1323
|
+
}
|
|
1324
|
+
/**
|
|
1325
|
+
* Check whether a server's tools are currently registered.
|
|
1326
|
+
*/
|
|
1327
|
+
isActivated(name) {
|
|
1328
|
+
const slot = this.servers.get(name);
|
|
1329
|
+
return slot ? slot.toolNames.length > 0 : false;
|
|
1330
|
+
}
|
|
1278
1331
|
async stop(name) {
|
|
1279
1332
|
const slot = this.servers.get(name);
|
|
1280
1333
|
if (!slot) return;
|
|
@@ -1289,6 +1342,7 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1289
1342
|
slot.onDisconnect = void 0;
|
|
1290
1343
|
for (const t of slot.toolNames) this.toolRegistry.unregister(t);
|
|
1291
1344
|
slot.toolNames = [];
|
|
1345
|
+
slot.lazyTools = [];
|
|
1292
1346
|
slot.state = "disconnected";
|
|
1293
1347
|
this.events.emit("mcp.server.disconnected", { name, reason: "stop" });
|
|
1294
1348
|
}
|
|
@@ -1304,7 +1358,7 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1304
1358
|
return Array.from(this.servers.values()).map((s) => ({
|
|
1305
1359
|
name: s.cfg.name,
|
|
1306
1360
|
state: s.state,
|
|
1307
|
-
toolCount: s.toolNames.length
|
|
1361
|
+
toolCount: Math.max(s.toolNames.length, s.lazyTools.length)
|
|
1308
1362
|
}));
|
|
1309
1363
|
}
|
|
1310
1364
|
/**
|
|
@@ -1317,7 +1371,7 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1317
1371
|
return Array.from(this.servers.values()).map((s) => ({
|
|
1318
1372
|
name: s.cfg.name,
|
|
1319
1373
|
state: s.state,
|
|
1320
|
-
toolCount: s.toolNames.length,
|
|
1374
|
+
toolCount: Math.max(s.toolNames.length, s.lazyTools.length),
|
|
1321
1375
|
enabled: s.cfg.enabled !== false
|
|
1322
1376
|
}));
|
|
1323
1377
|
}
|
|
@@ -1341,6 +1395,7 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1341
1395
|
* Unregister the previous wrapper set, then re-register the fresh
|
|
1342
1396
|
* tool list. The client has already refreshed its cache before
|
|
1343
1397
|
* dispatching — we just need to re-wrap and re-register.
|
|
1398
|
+
* In lazy mode, only update the internal cache without registering.
|
|
1344
1399
|
*/
|
|
1345
1400
|
onToolsChanged = (name, _tools) => {
|
|
1346
1401
|
const slot = this.servers.get(name);
|
|
@@ -1354,12 +1409,19 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1354
1409
|
slot.toolNames = [];
|
|
1355
1410
|
const allowed = slot.cfg.allowedTools;
|
|
1356
1411
|
const wrapped = slot.client.listTools().filter((t) => !allowed || allowed.includes(t.name)).map((t) => wrapMCPTool(slot.cfg.name, t, expectDefined(slot.client), slot.cfg.permission ?? "confirm"));
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
slot.
|
|
1361
|
-
|
|
1362
|
-
|
|
1412
|
+
if (this.lazyMode) {
|
|
1413
|
+
slot.lazyTools = wrapped;
|
|
1414
|
+
this.log.info(
|
|
1415
|
+
`MCP server "${slot.cfg.name}" tools refreshed in lazy mode (${wrapped.length} cached)`
|
|
1416
|
+
);
|
|
1417
|
+
} else {
|
|
1418
|
+
for (const tool of wrapped) {
|
|
1419
|
+
try {
|
|
1420
|
+
this.toolRegistry.register(tool, `mcp:${slot.cfg.name}`);
|
|
1421
|
+
slot.toolNames.push(tool.name);
|
|
1422
|
+
} catch (err) {
|
|
1423
|
+
this.log.warn(`MCP tool "${tool.name}" not re-registered after list_changed`, err);
|
|
1424
|
+
}
|
|
1363
1425
|
}
|
|
1364
1426
|
}
|
|
1365
1427
|
this.events.emit("mcp.server.connected", {
|
|
@@ -1367,7 +1429,7 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1367
1429
|
toolCount: slot.toolNames.length
|
|
1368
1430
|
});
|
|
1369
1431
|
this.log.info(
|
|
1370
|
-
`MCP server "${slot.cfg.name}" tools refreshed (${slot.toolNames.length} active)`
|
|
1432
|
+
`MCP server "${slot.cfg.name}" tools refreshed (${slot.toolNames.length} active, ${wrapped.length} total)`
|
|
1371
1433
|
);
|
|
1372
1434
|
};
|
|
1373
1435
|
onChildExit = (name, code, _signal) => {
|
|
@@ -1380,6 +1442,7 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1380
1442
|
}
|
|
1381
1443
|
}
|
|
1382
1444
|
slot.toolNames = [];
|
|
1445
|
+
slot.lazyTools = [];
|
|
1383
1446
|
slot.state = "disconnected";
|
|
1384
1447
|
this.events.emit("mcp.server.disconnected", { name, reason: `exit:${code ?? "unknown"}` });
|
|
1385
1448
|
this.scheduleReconnect(slot);
|
|
@@ -1395,6 +1458,7 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1395
1458
|
}
|
|
1396
1459
|
}
|
|
1397
1460
|
slot.toolNames = [];
|
|
1461
|
+
slot.lazyTools = [];
|
|
1398
1462
|
slot.state = "disconnected";
|
|
1399
1463
|
this.events.emit("mcp.server.disconnected", { name, reason: "http-disconnect" });
|
|
1400
1464
|
this.scheduleReconnect(slot);
|
|
@@ -1485,12 +1549,19 @@ var MCPRegistry = class _MCPRegistry {
|
|
|
1485
1549
|
const candidateTools = mc.listTools();
|
|
1486
1550
|
const toWrap = candidateTools.length > 0 ? candidateTools : mc.listTools();
|
|
1487
1551
|
const wrapped = toWrap.filter((t) => !allowed || allowed.includes(t.name)).map((t) => wrapMCPTool(slot.cfg.name, t, mc, slot.cfg.permission ?? "confirm"));
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
slot.
|
|
1492
|
-
|
|
1493
|
-
|
|
1552
|
+
if (this.lazyMode) {
|
|
1553
|
+
slot.lazyTools = wrapped;
|
|
1554
|
+
this.log.info(
|
|
1555
|
+
`MCP server "${slot.cfg.name}" connected in lazy mode (${wrapped.length} tools cached, not registered)`
|
|
1556
|
+
);
|
|
1557
|
+
} else {
|
|
1558
|
+
for (const tool of wrapped) {
|
|
1559
|
+
try {
|
|
1560
|
+
this.toolRegistry.register(tool, `mcp:${slot.cfg.name}`);
|
|
1561
|
+
slot.toolNames.push(tool.name);
|
|
1562
|
+
} catch (err) {
|
|
1563
|
+
this.log.warn(`MCP tool "${tool.name}" not registered`, err);
|
|
1564
|
+
}
|
|
1494
1565
|
}
|
|
1495
1566
|
}
|
|
1496
1567
|
this.events.emit(isReconnect ? "mcp.server.reconnected" : "mcp.server.connected", {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/tool-schema.ts","../src/transport.ts","../src/client.ts","../src/wrap-tool.ts","../src/registry.ts","../src/server.ts"],"names":["body","expectDefined"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Shared constants for the MCP package.\n *\n * Centralizing these values means:\n * - Protocol version and client identity are updated in one place\n * - Reconnect parameters can be overridden via config in the future\n * - No scattered magic values across multiple files\n */\nexport const MCP_CONSTANTS = Object.freeze({\n /** MCP protocol version advertised during handshake. */\n PROTOCOL_VERSION: '2024-11-05',\n\n /** Identity announced to MCP servers during `initialize`. */\n CLIENT_INFO: Object.freeze({\n name: 'wrongstack',\n version: '0.1.10',\n }),\n\n /** Reconnection behaviour when a transport disconnects. */\n RECONNECT: Object.freeze({\n /** Max full reconnect cycles before the slot is marked `failed`. */\n MAX_CYCLES: 5,\n /** Base delay between cycles (exponential backoff applied on top). */\n BASE_DELAY_MS: 1000,\n /** Jitter factor applied to the backoff (0 = no jitter, 1 = full). */\n JITTER_FACTOR: 0.2,\n /** Max connection attempts within a single cycle. */\n MAX_ATTEMPTS: 3,\n /** Base multiplier for the exponential backoff formula (`delay = BASE * multiplier^attempt`). */\n BACKOFF_MULTIPLIER: 2,\n }),\n\n /** Timing for graceful / forced disconnect. */\n DISCONNECT: Object.freeze({\n /** Ms to wait for in-flight requests to complete before force-closing. */\n GRACEFUL_MS: 800,\n /** Ms after which the force disconnect is triggered. */\n FORCE_TIMEOUT_MS: 1200,\n }),\n\n /** JSON-RPC response timeout for outstanding requests. */\n RESPONSE_TIMEOUT_MS: 500,\n\n /** Max buffer size for the SSE reader. */\n SSE_READER_MAX_BUFFER: 256 * 1024,\n\n /** Max characters logged from a request body. */\n REQUEST_LOG_CAP: 1024,\n} as const);","import type { MCPTool } from './client.js';\n\nexport function normalizeMCPTools(value: unknown): MCPTool[] {\n if (!Array.isArray(value)) return [];\n const tools: MCPTool[] = [];\n for (const raw of value) {\n if (!raw || typeof raw !== 'object') continue;\n const t = raw as { name?: unknown | undefined; description?: unknown | undefined; inputSchema?: unknown | undefined };\n if (typeof t.name !== 'string' || t.name.trim().length === 0) continue;\n const inputSchema =\n t.inputSchema && typeof t.inputSchema === 'object' && !Array.isArray(t.inputSchema)\n ? (t.inputSchema as Record<string, unknown>)\n : { type: 'object', properties: {} };\n // Log when a tool's schema is absent or invalid — this could indicate a\n // broken, misbehaving, or (if the server is untrusted) adversarial MCP\n // server trying to confuse the LLM with misleading type info.\n if (!t.inputSchema || typeof t.inputSchema !== 'object' || Array.isArray(t.inputSchema)) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'mcp.tool_schema_invalid',\n tool: t.name,\n message: 'no/invalid inputSchema — defaulting to empty object',\n timestamp: new Date().toISOString(),\n }));\n }\n tools.push({\n name: t.name,\n ...(typeof t.description === 'string' ? { description: t.description } : {}),\n inputSchema,\n });\n }\n return tools;\n}\n","import { randomBytes } from 'node:crypto';\nimport * as https from 'node:https';\nimport * as net from 'node:net';\nimport type { Dispatcher } from 'undici';\nimport type { ConnectionState, JsonRpcResponse, MCPTool, ToolCallResult } from './client.js';\nimport { MCP_CONSTANTS } from './constants.js';\nimport { normalizeMCPTools } from './tool-schema.js';\n\nexport type JsonRpcResult = {\n jsonrpc: string;\n id?: number | undefined;\n result?: unknown | undefined;\n error?: { code: number | undefined; message: string; data?: unknown | undefined } | undefined;\n};\n\nexport interface HttpTransportOptions {\n name: string;\n url: string;\n headers?: Record<string, string> | undefined;\n startupTimeoutMs?: number | undefined;\n requestTimeoutMs?: number | undefined;\n /**\n * Per-request TLS configuration. When set, an https.Agent is created\n * and passed to fetch via the `dispatch` option. This avoids globally\n * disabling certificate validation (NODE_TLS_REJECT_UNAUTHORIZED) which\n * would affect all provider API calls in the same process.\n *\n * ⚠️ Security gate: `rejectUnauthorized: false` REQUIRES either:\n * - `WRONGSTACK_UNSAFE_MCP_TLS=1` env var, OR\n * - `CI` env var is set (for automated testing)\n *\n * Without this gate, an active network attacker between the client and the\n * MCP server can read and modify tool calls and responses. Only use this\n * for local development with self-signed certificates; production MCP\n * servers must present a valid certificate.\n */\n tls?: { ca?: string | undefined; rejectUnauthorized?: boolean | undefined };\n}\n\nfunction isTlsUnsafeAllowed(): boolean {\n return process.env['WRONGSTACK_UNSAFE_MCP_TLS'] === '1' || process.env['CI'] === 'true';\n}\n\n/**\n * Validate that an MCP transport URL is not targeting private/internal\n * addresses. This is a defense-in-depth SSRF check — MCP servers are\n * typically local or LAN, but config manipulation could point to metadata\n * endpoints (169.254.169.254) or internal services.\n *\n * The check is intentionally lighter than fetch.ts's assertNotPrivate:\n * MCP URLs are admin-configured, not LLM-supplied, so we only block\n * the most obvious attack vectors.\n */\nfunction validateTransportUrl(rawUrl: string): void {\n let url: URL;\n try {\n url = new URL(rawUrl);\n } catch {\n throw new Error(`MCP transport: invalid URL \"${rawUrl}\"`);\n }\n\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error(\n `MCP transport: unsupported protocol \"${url.protocol}\" — only http/https allowed`,\n );\n }\n\n const hostname = url.hostname;\n // URL.hostname keeps the brackets on IPv6 literals; strip them so net.isIP\n // and prefix checks see the bare address.\n const host =\n hostname.startsWith('[') && hostname.endsWith(']') ? hostname.slice(1, -1) : hostname;\n\n // Block cloud metadata endpoints (IMDS) — these are never valid MCP servers\n const ipVersion = net.isIP(host);\n if (ipVersion === 4) {\n const parts = host.split('.').map(Number);\n // 169.254.x.x (link-local / IMDS)\n if (parts[0] === 169 && parts[1] === 254) {\n throw new Error(\n `MCP transport: blocked link-local/IMDS address \"${hostname}\" — likely not a valid MCP server`,\n );\n }\n } else if (ipVersion === 6) {\n const lower = host.toLowerCase();\n // fe80::/10 link-local (first hextet fe80–febf) and the AWS IPv6 IMDS\n // address fd00:ec2::254 — the IPv6 counterparts of the IPv4 block above.\n const linkLocal = /^fe[89ab]/.test(lower);\n if (linkLocal || lower === 'fd00:ec2::254') {\n throw new Error(\n `MCP transport: blocked link-local/IMDS address \"${hostname}\" — likely not a valid MCP server`,\n );\n }\n }\n\n // Plaintext http: is only permitted for loopback addresses where the\n // attacker would already need machine-level access. Remote HTTP MCP servers\n // must use TLS so an active network attacker cannot read or modify tool\n // calls and responses.\n if (url.protocol === 'http:') {\n const isLoopback =\n hostname === 'localhost' ||\n hostname === '127.0.0.1' ||\n hostname === '::1' ||\n hostname === '[::1]';\n if (!isLoopback) {\n throw new Error(\n `MCP transport: http:// is only allowed for loopback addresses; use https:// for \"${hostname}\"`,\n );\n }\n }\n}\n\n/**\n * SSE-based MCP transport using native fetch.\n *\n * Communication pattern:\n * - Client connects to SSE endpoint to receive server messages (JSON-RPC events)\n * - Client sends JSON-RPC requests via HTTP POST to the same or separate endpoint\n * - Server sends results/errors via the SSE stream\n *\n * The SSE reader parses the SSE protocol (event:, data:, blank line to dispatch).\n */\n/**\n * Cap on the pending-line buffer. The upstream SSE parser\n * (packages/providers/src/sse.ts) already enforces 256 KB; this\n * reader is used only inside MCP HTTP transports, but defense-in-depth\n * says we should never let a malicious stream pin memory.\n */\nconst SSE_READER_MAX_BUFFER = 256 * 1024;\n/** Max data lines buffered per event before flush. Prevents a malicious\n * server from accumulating unbounded data: lines without a blank-line\n * delimiter would grow this array indefinitely. */\nconst SSE_READER_MAX_DATA_LINES = 1024;\n\nexport class SSEReader {\n private buffer = '';\n private dataLines: string[] = [];\n private listeners: Array<\n (event: { jsonrpc?: string | undefined; method?: string | undefined; params?: unknown | undefined; id?: number | undefined }) => void\n > = [];\n\n onMessage(\n cb: (data: { jsonrpc?: string | undefined; method?: string | undefined; params?: unknown | undefined; id?: number | undefined }) => void,\n ): () => void {\n this.listeners.push(cb);\n return () => {\n const idx = this.listeners.indexOf(cb);\n if (idx >= 0) this.listeners.splice(idx, 1);\n };\n }\n\n feed(chunk: string): void {\n // Guard against a single chunk that exceeds the buffer cap.\n if (chunk.length > SSE_READER_MAX_BUFFER) {\n throw new Error(\n `SSE: chunk size ${chunk.length} exceeds max buffer ${SSE_READER_MAX_BUFFER} — refusing to accumulate`,\n );\n }\n this.buffer += chunk;\n if (this.buffer.length > SSE_READER_MAX_BUFFER) {\n throw new Error(\n `SSE: pending line exceeds ${SSE_READER_MAX_BUFFER} bytes — upstream is not framing events`,\n );\n }\n let idx = this.buffer.indexOf('\\n');\n while (idx !== -1) {\n const line = this.buffer.slice(0, idx).replace(/\\r$/, '');\n this.buffer = this.buffer.slice(idx + 1);\n idx = this.buffer.indexOf('\\n');\n\n this.processLine(line);\n }\n }\n\n private processLine(line: string): void {\n if (line === '') {\n this.flush();\n return;\n }\n if (line.startsWith(':')) return;\n\n const colonIdx = line.indexOf(':');\n const field = colonIdx === -1 ? line : line.slice(0, colonIdx);\n let value = colonIdx === -1 ? '' : line.slice(colonIdx + 1);\n if (value.startsWith(' ')) value = value.slice(1);\n\n if (field === 'event') {\n // The current transport only cares about JSON-RPC payloads in data\n // fields. Event names are accepted for spec compatibility.\n } else if (field === 'data') {\n if (this.dataLines.length >= SSE_READER_MAX_DATA_LINES) {\n throw new Error(\n `SSE: exceeded ${SSE_READER_MAX_DATA_LINES} data lines per event — upstream is not sending blank-line delimiters`,\n );\n }\n this.dataLines.push(value);\n }\n }\n\n private flush(): void {\n if (this.dataLines.length === 0) {\n return;\n }\n const data = this.dataLines.join('\\n').trim();\n this.dataLines = [];\n if (!data) return;\n try {\n const parsed = JSON.parse(data) as {\n jsonrpc?: string | undefined;\n method?: string | undefined;\n params?: unknown | undefined;\n id?: number | undefined;\n };\n this.dispatch(parsed);\n } catch {\n // ignore parse errors\n }\n }\n\n private dispatch(msg: {\n jsonrpc?: string | undefined;\n method?: string | undefined;\n params?: unknown | undefined;\n id?: number | undefined;\n }): void {\n for (const cb of this.listeners) {\n try {\n cb(msg);\n } catch {\n /* ignore */\n }\n }\n }\n\n reset(): void {\n this.buffer = '';\n this.dataLines = [];\n this.listeners = [];\n }\n}\n\nfunction isJsonRpcResult(v: unknown): v is JsonRpcResult {\n if (typeof v !== 'object' || v === null) return false;\n const r = v as JsonRpcResult;\n if (r.jsonrpc !== '2.0') return false;\n if (r.error !== undefined) {\n return (\n typeof r.error === 'object' &&\n r.error !== null &&\n typeof r.error.code === 'number' &&\n typeof r.error.message === 'string'\n );\n }\n return 'result' in r || r.id === undefined;\n}\n\n/**\n * Extract JSON-RPC envelopes from a streamable-http response body. Handles BOTH\n * plain NDJSON (one JSON object per line) AND SSE framing\n * (`event: message\\ndata: {...}` blocks) — modern MCP servers (e.g. Context7)\n * reply with `text/event-stream` even on a single POST, so the data must be\n * un-prefixed before parsing. Multi-line `data:` values within one event are\n * joined per the SSE spec.\n */\nexport function extractJsonRpcResults(text: string): JsonRpcResult[] {\n const out: JsonRpcResult[] = [];\n let dataBuf: string[] = [];\n const flush = () => {\n if (dataBuf.length === 0) return;\n const joined = dataBuf.join('\\n').trim();\n dataBuf = [];\n if (!joined) return;\n try {\n const parsed = JSON.parse(joined);\n if (isJsonRpcResult(parsed)) out.push(parsed);\n } catch {\n /* ignore non-JSON event data */\n }\n };\n for (const raw of text.split('\\n')) {\n const line = raw.replace(/\\r$/, '');\n if (line === '') {\n flush(); // blank line ends an SSE event\n continue;\n }\n if (line.startsWith(':')) continue; // SSE comment\n if (line.startsWith('data:')) {\n let v = line.slice(5);\n if (v.startsWith(' ')) v = v.slice(1);\n dataBuf.push(v);\n continue;\n }\n if (line.startsWith('event:') || line.startsWith('id:') || line.startsWith('retry:')) {\n continue; // other SSE fields\n }\n // Plain NDJSON line (no SSE framing).\n const trimmed = line.trim();\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n const parsed = JSON.parse(trimmed);\n if (isJsonRpcResult(parsed)) out.push(parsed);\n } catch {\n /* ignore */\n }\n }\n }\n flush();\n return out;\n}\n\n/** Pick the JSON-RPC envelope matching `id`, or the first one if none matches. */\nfunction pickJsonRpcResult(text: string, id: number): JsonRpcResult | undefined {\n const results = extractJsonRpcResults(text);\n return results.find((r) => r.id === id) ?? results[0];\n}\n\nfunction assertMatchingJsonRpcResult(\n data: unknown,\n expectedId: number,\n method: string,\n): JsonRpcResult {\n if (!isJsonRpcResult(data)) {\n throw new Error('Invalid JSON-RPC response: not a JSON-RPC 2.0 envelope');\n }\n if (data.id !== undefined && data.id !== expectedId) {\n throw new Error(\n `Invalid JSON-RPC response: id mismatch for ${method} (expected ${expectedId}, got ${data.id})`,\n );\n }\n if (data.id === undefined && !method.startsWith('notifications/')) {\n throw new Error(`Invalid JSON-RPC response: missing id for ${method}`);\n }\n return data;\n}\n\n/**\n * SSE transport for MCP over HTTP.\n *\n * Uses native fetch API with ReadableStream to consume SSE events.\n * HTTP POST is used to send JSON-RPC requests.\n */\nexport class SSETransport {\n private state: ConnectionState = 'idle';\n private url: string;\n private headers: Record<string, string>;\n private timeout: number;\n private requestTimeout: number;\n /** Per-request TLS agent — created once from HttpTransportOptions.tls */\n private tlsAgent?: https.Agent | undefined;\n private nextId = 1;\n private tools: MCPTool[] = [];\n private abortController?: AbortController | undefined;\n private reader?: globalThis.ReadableStreamDefaultReader<string> | undefined;\n private readerDone = false;\n private disconnectHandlers: Array<() => void> = [];\n private readLoopAbort?: AbortController | undefined;\n private readonly toolsChangedListeners = new Set<(tools: MCPTool[]) => void>();\n\n constructor(opts: HttpTransportOptions) {\n validateTransportUrl(opts.url);\n this.url = opts.url;\n this.headers = { ...opts.headers };\n this.timeout = opts.startupTimeoutMs ?? 10_000;\n this.requestTimeout = opts.requestTimeoutMs ?? 60_000;\n if (opts.tls) {\n if (opts.tls.rejectUnauthorized === false) {\n if (!isTlsUnsafeAllowed()) {\n throw new Error(\n `[mcp:SSETransport] TLS verification disabled — set WRONGSTACK_UNSAFE_MCP_TLS=1 ` +\n `or CI=true to allow. Rejecting insecure configuration for ${this.url}.`,\n );\n }\n console.error(\n `[mcp:SSETransport] ⚠️ TLS verification DISABLED for ${this.url}. ` +\n `Network attacks are possible — only use on localhost.`,\n );\n }\n this.tlsAgent = new https.Agent({\n ca: opts.tls.ca,\n rejectUnauthorized: opts.tls.rejectUnauthorized,\n });\n }\n }\n\n getState(): ConnectionState {\n return this.state;\n }\n\n listTools(): MCPTool[] {\n return [...this.tools];\n }\n\n onDisconnect(cb: () => void): () => void {\n this.disconnectHandlers.push(cb);\n return () => {\n const idx = this.disconnectHandlers.indexOf(cb);\n if (idx >= 0) this.disconnectHandlers.splice(idx, 1);\n };\n }\n\n onToolsChanged(cb: (tools: MCPTool[]) => void): () => void {\n this.toolsChangedListeners.add(cb);\n return () => {\n this.toolsChangedListeners.delete(cb);\n };\n }\n\n /** Refresh tool list when server sends notifications/tools/list_changed. */\n private async handleToolsListChanged(): Promise<void> {\n try {\n const res = await this.httpPost('tools/list', {});\n if (!res.error) {\n this.tools = normalizeMCPTools((res.result as { tools?: unknown | undefined } | undefined)?.tools);\n for (const cb of this.toolsChangedListeners) {\n try {\n cb([...this.tools]);\n } catch {\n /* ignore */\n }\n }\n }\n } catch {\n /* ignore transient failures */\n }\n }\n\n async connect(): Promise<void> {\n this.state = 'connecting';\n this.abortController = new AbortController();\n const signal = this.abortController.signal;\n const startupTimer = setTimeout(() => this.abortController?.abort(), this.timeout);\n\n try {\n const sseUrl = this.buildSSEUrl();\n const fetchOpts: RequestInit = {\n headers: this.headers,\n signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) fetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const response = await fetch(sseUrl, fetchOpts);\n\n if (!response.ok) {\n throw new Error(`SSE connect HTTP ${response.status}: ${response.statusText}`);\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body');\n }\n\n const textDecoder = new TextDecoder();\n const sseReader = new SSEReader();\n this.readLoopAbort = new AbortController();\n\n sseReader.onMessage((msg) => {\n // Future: if the spec evolves to send JSON-RPC responses over SSE\n // (rather than as HTTP POST replies), wire id-correlation here via\n // `_reservedPending`. Today httpPost owns response routing.\n // Server-initiated notifications (no id). Handle list_changed for L2-C.\n if (msg.method && !msg.id) {\n if (msg.method === 'notifications/tools/list_changed') {\n void this.handleToolsListChanged();\n }\n }\n });\n\n const reader = response.body.getReader();\n this.reader = {\n cancel: () => reader.cancel(),\n releaseLock: () => reader.releaseLock(),\n } as globalThis.ReadableStreamDefaultReader<string>;\n\n this.readSSEBody(reader, textDecoder, sseReader);\n\n const initRes = await this.httpPost('initialize', {\n protocolVersion: MCP_CONSTANTS.PROTOCOL_VERSION,\n capabilities: { tools: {} },\n clientInfo: MCP_CONSTANTS.CLIENT_INFO,\n });\n\n if (initRes.error) {\n throw new Error(`initialize failed: ${initRes.error.message}`);\n }\n\n try {\n await this.httpPost('notifications/initialized', {});\n } catch {\n // servers may not require it\n }\n\n const toolsRes = await this.httpPost('tools/list', {});\n if (toolsRes.error) {\n this.tools = [];\n } else {\n const result = toolsRes.result as { tools?: unknown | undefined } | undefined;\n this.tools = normalizeMCPTools(result?.tools);\n }\n\n this.state = 'connected';\n clearTimeout(startupTimer);\n } catch (err) {\n clearTimeout(startupTimer);\n this.state = 'failed';\n this.abortController.abort();\n throw err;\n }\n }\n\n private async readSSEBody(\n reader: globalThis.ReadableStreamDefaultReader<Uint8Array>,\n decoder: InstanceType<typeof TextDecoder>,\n sseReader: SSEReader,\n ): Promise<void> {\n try {\n while (!this.readerDone) {\n const { done, value } = await reader.read();\n if (done) break;\n const chunk = decoder.decode(value, { stream: true });\n sseReader.feed(chunk);\n }\n } catch {\n // SSE read error — connection lost. Transition to disconnected so\n // callTool and health checks see the correct state, then notify\n // disconnect handlers so the registry can schedule a reconnect.\n if (this.state !== 'disconnected' && this.state !== 'failed') {\n this.state = 'disconnected';\n for (const cb of this.disconnectHandlers) {\n try {\n cb();\n } catch {\n /* ignore */\n }\n }\n }\n }\n }\n\n private buildSSEUrl(): string {\n try {\n const url = new URL(this.url);\n // Cryptographically random session ID instead of timestamp —\n // prevents an attacker on the same LAN from guessing the session\n // param and reconnecting to the SSE stream.\n url.searchParams.set('session', randomBytes(16).toString('hex'));\n return url.toString();\n } catch {\n return this.url;\n }\n }\n\n private async httpPost(method: string, params: unknown): Promise<JsonRpcResult> {\n const id = this.nextId++;\n const body = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n\n const timeoutSignal = createTimeoutSignal(this.abortController?.signal, this.requestTimeout);\n const fetchOpts: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...this.headers,\n },\n body,\n signal: timeoutSignal.signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) fetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const res = await fetch(this.url, fetchOpts);\n\n try {\n if (!res.ok) {\n // Cap the body — a misbehaving server could return megabytes of\n // HTML and that's not useful in an error message anyway.\n const body = await res.text();\n const cap = MCP_CONSTANTS.REQUEST_LOG_CAP;\n const snippet =\n body.length > cap ? `${body.slice(0, cap)}… [${body.length} bytes total]` : body;\n throw new Error(`HTTP ${res.status}: ${snippet}`);\n }\n\n let data: unknown;\n try {\n data = await res.json();\n } catch (err) {\n throw new Error(\n `Invalid JSON-RPC response: ${err instanceof Error ? err.message : 'parse failed'}`,\n { cause: err },\n );\n }\n return assertMatchingJsonRpcResult(data, id, method);\n } finally {\n timeoutSignal.dispose();\n }\n }\n\n async callTool(name: string, input: unknown): Promise<ToolCallResult> {\n if (this.state !== 'connected') {\n throw new Error(`SSE transport not connected (state=${this.state})`);\n }\n const res = await this.httpPost('tools/call', { name, arguments: input });\n if (res.error) {\n return { content: res.error.message, isError: true };\n }\n const result = res.result as { content?: unknown | undefined; isError?: boolean | undefined } | undefined;\n return {\n content: result?.content ?? '',\n isError: Boolean(result?.isError),\n };\n }\n\n /** Generic JSON-RPC request — used by MCPClient.request() for SSE transports. */\n async request(method: string, params: unknown, timeoutMs?: number): Promise<JsonRpcResponse> {\n const id = this.nextId++;\n const body = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n\n const timeoutSignal = createTimeoutSignal(\n this.abortController?.signal,\n timeoutMs ?? this.requestTimeout,\n );\n const fetchOpts: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...this.headers,\n },\n body,\n signal: timeoutSignal.signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) fetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const res = await fetch(this.url, fetchOpts);\n\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n }\n\n let data: unknown;\n try {\n data = await res.json();\n } catch (err) {\n throw new Error(\n `Invalid JSON-RPC response: ${err instanceof Error ? err.message : 'parse failed'}`,\n { cause: err },\n );\n }\n const result = assertMatchingJsonRpcResult(data, id, method);\n timeoutSignal.dispose();\n return { jsonrpc: '2.0', id, result: result.result, error: result.error };\n }\n\n async close(): Promise<void> {\n // Idempotent — safe to call multiple times.\n if (this.state === 'disconnected') return;\n this.readerDone = true;\n this.readLoopAbort?.abort();\n try {\n this.reader?.cancel();\n } catch {\n /* ignore */\n }\n try {\n this.reader?.releaseLock();\n } catch {\n /* ignore */\n }\n this.abortController?.abort();\n this.disconnectHandlers = [];\n this.state = 'disconnected';\n }\n}\n\n/**\n * Streamable HTTP transport for MCP.\n *\n * Uses session-based HTTP with NDJSON responses.\n */\nexport class StreamableHTTPTransport {\n private state: ConnectionState = 'idle';\n private url: string;\n private headers: Record<string, string>;\n private timeout: number;\n private requestTimeout: number;\n /** Per-request TLS agent — created once from HttpTransportOptions.tls */\n private tlsAgent?: https.Agent | undefined;\n private nextId = 1;\n private tools: MCPTool[] = [];\n private abortController?: AbortController | undefined;\n private sessionId?: string | undefined;\n private disconnectHandlers: Array<() => void> = [];\n private readonly toolsChangedListeners = new Set<(tools: MCPTool[]) => void>();\n\n constructor(opts: HttpTransportOptions) {\n validateTransportUrl(opts.url);\n this.url = opts.url;\n this.headers = { ...opts.headers };\n this.timeout = opts.startupTimeoutMs ?? 10_000;\n this.requestTimeout = opts.requestTimeoutMs ?? 60_000;\n if (opts.tls) {\n if (opts.tls.rejectUnauthorized === false) {\n if (!isTlsUnsafeAllowed()) {\n throw new Error(\n `[mcp:StreamableHTTP] TLS verification disabled — set WRONGSTACK_UNSAFE_MCP_TLS=1 ` +\n `or CI=true to allow. Rejecting insecure configuration for ${this.url}.`,\n );\n }\n console.error(\n `[mcp:StreamableHTTP] ⚠️ TLS verification DISABLED for ${this.url}. ` +\n `Network attacks are possible — only use on localhost.`,\n );\n }\n this.tlsAgent = new https.Agent({\n ca: opts.tls.ca,\n rejectUnauthorized: opts.tls.rejectUnauthorized,\n });\n }\n }\n\n getState(): ConnectionState {\n return this.state;\n }\n\n listTools(): MCPTool[] {\n return [...this.tools];\n }\n\n onDisconnect(cb: () => void): () => void {\n this.disconnectHandlers.push(cb);\n return () => {\n const idx = this.disconnectHandlers.indexOf(cb);\n if (idx >= 0) this.disconnectHandlers.splice(idx, 1);\n };\n }\n\n onToolsChanged(cb: (tools: MCPTool[]) => void): () => void {\n this.toolsChangedListeners.add(cb);\n return () => {\n this.toolsChangedListeners.delete(cb);\n };\n }\n\n async connect(): Promise<void> {\n this.state = 'connecting';\n this.abortController = new AbortController();\n const signal = this.abortController.signal;\n const startupTimer = setTimeout(() => this.abortController?.abort(), this.timeout);\n\n try {\n const initFetchOpts: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n ...this.headers,\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: this.nextId++,\n method: 'initialize',\n params: {\n protocolVersion: MCP_CONSTANTS.PROTOCOL_VERSION,\n capabilities: { tools: {} },\n clientInfo: MCP_CONSTANTS.CLIENT_INFO,\n },\n }),\n signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) initFetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const initRes = await fetch(this.url, initFetchOpts);\n\n if (!initRes.ok) {\n throw new Error(`initialize HTTP ${initRes.status}: ${initRes.statusText}`);\n }\n\n const contentType = initRes.headers.get('content-type') ?? '';\n let data: JsonRpcResult | undefined;\n\n if (contentType.includes('application/json')) {\n const parsed = await initRes.json();\n if (isJsonRpcResult(parsed)) data = parsed;\n } else {\n // text/event-stream or NDJSON — handle SSE `data:` framing.\n data = extractJsonRpcResults(await initRes.text())[0];\n }\n\n if (!data) {\n throw new Error('Could not parse initialize response');\n }\n data = assertMatchingJsonRpcResult(data, this.nextId - 1, 'initialize');\n\n if (data.error) {\n throw new Error(`initialize failed: ${data.error.message}`);\n }\n\n // MCP Streamable HTTP spec: the server assigns a session via the\n // `Mcp-Session-Id` response header, which the client must echo on every\n // subsequent request. (Header lookups are case-insensitive.)\n this.sessionId = initRes.headers.get('mcp-session-id') ?? undefined;\n await this.postRaw('notifications/initialized', {});\n\n const toolsRes = await this.postRaw('tools/list', {});\n if (toolsRes.error) {\n this.tools = [];\n } else {\n const result = toolsRes.result as { tools?: unknown | undefined } | undefined;\n this.tools = normalizeMCPTools(result?.tools);\n }\n\n this.state = 'connected';\n clearTimeout(startupTimer);\n } catch (err) {\n clearTimeout(startupTimer);\n this.state = 'failed';\n this.abortController.abort();\n throw err;\n }\n }\n\n private async postRaw(method: string, params: unknown): Promise<JsonRpcResult> {\n const id = this.nextId++;\n const body = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n\n const timeoutSignal = createTimeoutSignal(this.abortController?.signal, this.requestTimeout);\n const fetchOpts: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n ...(this.sessionId ? { 'Mcp-Session-Id': this.sessionId } : {}),\n ...this.headers,\n },\n body,\n signal: timeoutSignal.signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) fetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const res = await fetch(this.url, fetchOpts);\n\n try {\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n }\n\n // Notifications get no JSON-RPC reply (the server returns 202 / empty body).\n if (method.startsWith('notifications/')) {\n await res.text().catch(() => undefined);\n return { jsonrpc: '2.0' };\n }\n\n const match = pickJsonRpcResult(await res.text(), id);\n if (match) {\n return assertMatchingJsonRpcResult(match, id, method);\n }\n throw new Error('Could not parse response as JSON-RPC');\n } finally {\n timeoutSignal.dispose();\n }\n }\n\n /** Generic JSON-RPC request — used by MCPClient.request() for SSE/streamable-http transports. */\n async request(method: string, params: unknown, timeoutMs?: number): Promise<JsonRpcResponse> {\n const id = this.nextId++;\n const body = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n\n const timeoutSignal = createTimeoutSignal(\n this.abortController?.signal,\n timeoutMs ?? this.requestTimeout,\n );\n const fetchOpts: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n ...(this.sessionId ? { 'Mcp-Session-Id': this.sessionId } : {}),\n ...this.headers,\n },\n body,\n signal: timeoutSignal.signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) fetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const res = await fetch(this.url, fetchOpts);\n\n try {\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n }\n\n if (method.startsWith('notifications/')) {\n await res.text().catch(() => undefined);\n return { jsonrpc: '2.0', id };\n }\n\n const parsed = pickJsonRpcResult(await res.text(), id);\n if (parsed) {\n // Convert JsonRpcResult to JsonRpcResponse\n return {\n jsonrpc: '2.0',\n id,\n result: parsed.result,\n error: parsed.error,\n };\n }\n throw new Error('Could not parse response as JSON-RPC');\n } finally {\n timeoutSignal.dispose();\n }\n }\n\n async callTool(name: string, input: unknown): Promise<ToolCallResult> {\n if (this.state !== 'connected') {\n throw new Error(`streamable-http transport not connected (state=${this.state})`);\n }\n const res = await this.postRaw('tools/call', { name, arguments: input });\n if (res.error) {\n return { content: res.error.message, isError: true };\n }\n const result = res.result as { content?: unknown | undefined; isError?: boolean | undefined } | undefined;\n return {\n content: result?.content ?? '',\n isError: Boolean(result?.isError),\n };\n }\n\n async close(): Promise<void> {\n if (this.state === 'disconnected') return;\n this.state = 'disconnected';\n this.abortController?.abort();\n // Intentionally do NOT fire disconnect handlers — those trigger\n // reconnection in the registry, which would fight an explicit close().\n this.disconnectHandlers = [];\n }\n}\n\nfunction createTimeoutSignal(\n parent: AbortSignal | undefined,\n timeoutMs: number,\n): { signal: AbortSignal; dispose: () => void } {\n const ctrl = new AbortController();\n const onAbort = () => ctrl.abort(parent?.reason);\n if (parent?.aborted) {\n ctrl.abort(parent.reason);\n } else {\n parent?.addEventListener('abort', onAbort, { once: true });\n }\n const timer = setTimeout(\n () => ctrl.abort(new Error(`MCP HTTP request timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n return {\n signal: ctrl.signal,\n dispose: () => {\n clearTimeout(timer);\n parent?.removeEventListener('abort', onAbort);\n },\n };\n}\n","import { type ChildProcess, spawn } from 'node:child_process';\nimport { buildChildEnv } from '@wrongstack/core';\nimport { MCP_CONSTANTS } from './constants.js';\nimport { normalizeMCPTools } from './tool-schema.js';\nimport { type HttpTransportOptions, SSETransport, StreamableHTTPTransport } from './transport.js';\n\nexport type Transport = 'stdio' | 'sse' | 'streamable-http';\n\nexport interface MCPClientOptions {\n name: string;\n transport: Transport;\n command?: string | undefined;\n args?: string[] | undefined;\n env?: Record<string, string> | undefined;\n url?: string | undefined;\n headers?: Record<string, string> | undefined;\n startupTimeoutMs?: number | undefined;\n requestTimeoutMs?: number | undefined;\n}\n\nexport type ConnectionState =\n | 'idle'\n | 'connecting'\n | 'connected'\n | 'disconnected'\n | 'reconnecting'\n | 'failed';\n\nexport interface MCPTool {\n name: string;\n description?: string | undefined;\n inputSchema: Record<string, unknown>;\n}\n\nexport interface ToolCallResult {\n content: unknown;\n isError: boolean;\n}\n\ninterface JsonRpcRequest {\n jsonrpc: '2.0';\n id: number;\n method: string;\n params?: unknown | undefined;\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: '2.0';\n id: number;\n result?: unknown | undefined;\n error?: { code: number | undefined; message: string; data?: unknown | undefined } | undefined;\n}\n\ntype ExitListener = (name: string, code: number | null, signal: string | null) => void;\n/**\n * Fired when the server sends `notifications/tools/list_changed`. The\n * client refreshes its cached tool list before invoking listeners, so\n * subscribers can call `listTools()` for the fresh set.\n */\ntype ToolsChangedListener = (name: string, tools: MCPTool[]) => void;\n\n/**\n * Lightweight MCP client supporting three transport types:\n * - stdio: spawns a child process and communicates over pipes\n * - sse: connects to an HTTP SSE endpoint for server events, POST for requests\n * - streamable-http: session-based HTTP transport with NDJSON responses\n */\nexport class MCPClient {\n private state: ConnectionState = 'idle';\n private child?: ChildProcess | undefined;\n private nextId = 1;\n /**\n * In-flight JSON-RPC calls keyed by id. `resolve` settles the call; `reject`\n * is invoked from {@link failPending} when the underlying transport dies\n * (stdio child exit, `close()`) so callers don't hang forever.\n */\n private readonly pending = new Map<\n number,\n { resolve: (res: JsonRpcResponse) => void; reject: (err: Error) => void; timer: NodeJS.Timeout }\n >();\n private rxBuffer = '';\n private _tools: MCPTool[] = [];\n /** Cached tool list — survives reconnects so the registry can re-register without re-discovering. */\n private _toolsCache?: MCPTool[] | undefined;\n private _drainPending = false;\n private _lastNotifySkipped = false;\n // HTTP transports\n private sseTransport?: SSETransport | undefined;\n private httpTransport?: StreamableHTTPTransport | undefined;\n /** Notified when the stdio child process exits so the registry can attempt reconnect. */\n private readonly exitListeners = new Set<ExitListener>();\n /** Notified when the server announces a tools/list_changed notification. */\n private readonly toolsChangedListeners = new Set<ToolsChangedListener>();\n /** Notified when an HTTP transport (SSE or streamable-http) disconnects. */\n private readonly disconnectListeners = new Set<() => void>();\n\n constructor(public readonly opts: MCPClientOptions) {}\n\n getState(): ConnectionState {\n return this.state;\n }\n\n listTools(): MCPTool[] {\n return this._tools.length > 0\n ? [...this._tools]\n : this._toolsCache\n ? [...this._toolsCache]\n : [];\n }\n\n /** Returns true if a prior notify() call was skipped due to backpressure. */\n hadNotifySkipped(): boolean {\n return this._lastNotifySkipped;\n }\n\n /**\n * Register a listener for child-process exit events.\n * The registry uses this to trigger reconnection.\n */\n addExitListener(listener: ExitListener): void {\n this.exitListeners.add(listener);\n }\n\n removeExitListener(listener: ExitListener): void {\n this.exitListeners.delete(listener);\n }\n\n /**\n * Register a listener for transport disconnect events (SSE / streamable-http).\n * Used by the registry to trigger reconnection for HTTP-based servers.\n */\n addDisconnectListener(listener: () => void): void {\n this.disconnectListeners.add(listener);\n }\n\n removeDisconnectListener(listener: () => void): void {\n this.disconnectListeners.delete(listener);\n }\n\n async connect(): Promise<void> {\n this.state = 'connecting';\n\n if (this.opts.transport === 'stdio') {\n await this.connectStdio();\n } else if (this.opts.transport === 'sse') {\n await this.connectSSE();\n } else if (this.opts.transport === 'streamable-http') {\n await this.connectStreamableHTTP();\n } else {\n this.state = 'failed';\n throw new Error(`Unknown transport \"${this.opts.transport}\"`);\n }\n }\n\n private async connectStdio(): Promise<void> {\n if (!this.opts.command) {\n this.state = 'failed';\n throw new Error('MCP stdio transport requires \"command\"');\n }\n\n // Defense-in-depth: clear any rx state from a previous connect attempt\n // on this instance. The registry normally creates a fresh client per\n // (re)connect cycle, but a leftover rxBuffer from a half-initialized\n // attempt would corrupt JSON-RPC parsing on the new stream.\n this.rxBuffer = '';\n\n // On Windows, MCP servers are usually launched via `npx`/`npm`/`uvx`,\n // which resolve to `.cmd` shims. Since the CVE-2024-27980 fix Node refuses\n // to spawn `.cmd`/`.bat` without a shell (raw spawn throws ENOENT), so the\n // whole npx-based preset catalog is unusable without a shell. We pass the\n // full command line as a single string (with each token cmd.exe-quoted) and\n // `shell: true` — an empty args array avoids the DEP0190 warning that\n // `shell:true` + an args array triggers. Server command+args come from\n // config (admin-controlled), not the model, so shell use is not an\n // injection vector here.\n const isWin = process.platform === 'win32';\n const rawArgs = this.opts.args ?? [];\n const spawnEnv = buildChildEnv({ extra: this.opts.env });\n const stdio: ['pipe', 'pipe', 'pipe'] = ['pipe', 'pipe', 'pipe'];\n const child = isWin\n ? spawn([this.opts.command, ...rawArgs].map(quoteWindowsArg).join(' '), {\n env: spawnEnv,\n stdio,\n shell: true,\n // Without this every MCP server spawned from a console-less host\n // (WebUI server, scheduled runs) opens a visible console window.\n windowsHide: true,\n })\n : spawn(this.opts.command, rawArgs, { env: spawnEnv, stdio, windowsHide: true });\n this.child = child;\n\n child.stdout?.on('data', (chunk: Buffer) => this.onData(chunk.toString()));\n child.stderr?.on('data', () => {\n // intentionally discard stderr noise from server\n });\n child.on('exit', (code, signal) => {\n this.state = 'disconnected';\n // Reject any in-flight JSON-RPC requests — without this, callers\n // (e.g. callTool during a tool invocation) await forever on a child\n // that has already gone away.\n this.failPending(\n `MCP \"${this.opts.name}\" child exited (code=${code ?? 'null'} signal=${signal ?? 'null'})`,\n );\n for (const listener of this.exitListeners) {\n try {\n listener(this.opts.name, code, signal);\n } catch {\n /* ignore */\n }\n }\n });\n child.on('error', () => {\n this.state = 'failed';\n });\n\n const initialize = await this.request(\n 'initialize',\n {\n protocolVersion: MCP_CONSTANTS.PROTOCOL_VERSION,\n capabilities: { tools: {} },\n clientInfo: MCP_CONSTANTS.CLIENT_INFO,\n },\n this.opts.startupTimeoutMs ?? 10_000,\n );\n if (initialize.error) {\n this.state = 'failed';\n throw new Error(`MCP initialize failed: ${initialize.error.message}`);\n }\n try {\n await this.notify('notifications/initialized', {});\n } catch (err) {\n console.warn(\n '[MCP] notify(\"notifications/initialized\") failed for \"' +\n this.opts.name +\n '\": ' +\n (err instanceof Error ? err.message : String(err)),\n );\n }\n const toolsRes = await this.request('tools/list', {});\n if (toolsRes.error) {\n this._tools = [];\n } else {\n const result = toolsRes.result as { tools?: MCPTool[] | undefined } | undefined;\n this._tools = normalizeMCPTools(result?.tools);\n }\n // Cache tools so reconnect can re-register without re-discovering\n this._toolsCache = this._tools;\n this.state = 'connected';\n }\n\n private async connectSSE(): Promise<void> {\n if (!this.opts.url) {\n this.state = 'failed';\n throw new Error('MCP SSE transport requires \"url\"');\n }\n const httpOpts: HttpTransportOptions = {\n name: this.opts.name,\n url: this.opts.url,\n headers: this.opts.headers,\n startupTimeoutMs: this.opts.startupTimeoutMs,\n requestTimeoutMs: this.opts.requestTimeoutMs,\n };\n this.sseTransport = new SSETransport(httpOpts);\n this.sseTransport.onDisconnect(() => {\n this.state = 'disconnected';\n for (const cb of this.disconnectListeners) {\n try {\n cb();\n } catch {\n /* ignore */\n }\n }\n });\n this.sseTransport.onToolsChanged((tools) => {\n this._tools = tools;\n // Keep the reconnect-recovery cache in sync. Without this, an empty\n // tools update would leave `_toolsCache` pointing at the previous\n // non-empty list, and `listTools()` would serve the stale cache\n // (since it falls back to the cache when `_tools` is empty).\n this._toolsCache = tools;\n for (const cb of this.toolsChangedListeners) {\n try {\n cb(this.opts.name, tools);\n } catch {\n /* ignore */\n }\n }\n });\n try {\n await this.sseTransport.connect();\n } catch (err) {\n this.state = 'failed';\n throw err;\n }\n this._tools = this.sseTransport.listTools();\n this._toolsCache = this._tools;\n this.state = 'connected';\n }\n\n private async connectStreamableHTTP(): Promise<void> {\n if (!this.opts.url) {\n this.state = 'failed';\n throw new Error('MCP streamable-http transport requires \"url\"');\n }\n const httpOpts: HttpTransportOptions = {\n name: this.opts.name,\n url: this.opts.url,\n headers: this.opts.headers,\n startupTimeoutMs: this.opts.startupTimeoutMs,\n requestTimeoutMs: this.opts.requestTimeoutMs,\n };\n this.httpTransport = new StreamableHTTPTransport(httpOpts);\n this.httpTransport.onDisconnect(() => {\n this.state = 'disconnected';\n for (const cb of this.disconnectListeners) {\n try {\n cb();\n } catch {\n /* ignore */\n }\n }\n });\n this.httpTransport.onToolsChanged((tools) => {\n this._tools = tools;\n // Same cache-sync reasoning as the SSE branch above — keep\n // `_toolsCache` in lockstep with `_tools` on every transport\n // update so the empty-list fallback in `listTools()` never serves\n // stale data.\n this._toolsCache = tools;\n for (const cb of this.toolsChangedListeners) {\n try {\n cb(this.opts.name, tools);\n } catch {\n /* ignore */\n }\n }\n });\n try {\n await this.httpTransport.connect();\n } catch (err) {\n this.state = 'failed';\n throw err;\n }\n this._tools = this.httpTransport.listTools();\n this._toolsCache = this._tools;\n this.state = 'connected';\n }\n\n async callTool(name: string, input: unknown): Promise<ToolCallResult> {\n if (this.state !== 'connected') {\n throw new Error(`MCP client \"${this.opts.name}\" not connected (state=${this.state})`);\n }\n // Delegate to the active transport\n if (this.sseTransport) {\n return this.sseTransport.callTool(name, input);\n }\n if (this.httpTransport) {\n return this.httpTransport.callTool(name, input);\n }\n // stdio\n const res = await this.request('tools/call', { name, arguments: input });\n if (res.error) {\n return { content: res.error.message, isError: true };\n }\n const result = res.result as { content?: unknown | undefined; isError?: boolean | undefined } | undefined;\n return {\n content: result?.content ?? '',\n isError: Boolean(result?.isError),\n };\n }\n\n async close(): Promise<void> {\n if (this.child) {\n const child = this.child;\n // Always register the listener first. Checking exitCode/signalCode\n // before registering creates a TOCTOU race: the child can exit between\n // the check and child.once('exit', ...), so the listener never fires\n // and exitPromise hangs forever. The double-check below handles the\n // case where the child already exited before we registered.\n const exitPromise = new Promise<void>((resolve) => {\n child.once('exit', () => resolve());\n if (child.exitCode !== null || child.signalCode !== null) resolve();\n });\n try {\n // Initial SIGTERM lets the server flush logs / clean up sockets.\n child.kill();\n } catch {\n // ignore\n }\n // Wait briefly for graceful exit, then escalate to SIGKILL. A stuck\n // server that ignores SIGTERM would otherwise stay alive after\n // close() returns — orphan child processes accumulate over restarts.\n const GRACEFUL_MS = 800;\n const FORCE_TIMEOUT_MS = 1200;\n const gracefulRace = await Promise.race([\n exitPromise.then(() => 'exited' as const),\n new Promise<'timeout'>((resolve) => setTimeout(() => resolve('timeout'), GRACEFUL_MS)),\n ]);\n if (gracefulRace === 'timeout') {\n try {\n // SIGKILL is ignored by `kill('SIGKILL')` on Windows in older\n // Node, but `child.kill('SIGKILL')` maps to TerminateProcess\n // under the hood for spawned children since Node 18 — safe to\n // call cross-platform.\n child.kill('SIGKILL');\n } catch {\n // ignore\n }\n await Promise.race([\n exitPromise,\n new Promise<void>((resolve) => setTimeout(resolve, FORCE_TIMEOUT_MS)),\n ]);\n }\n }\n // Reject pending requests BEFORE closing transports. This matters for\n // in-flight HTTP requests: they are not yet in `this.pending` (waiting\n // for a response from the network), so failPending() must run while the\n // transport is still alive. After this, the transport close is safe to\n // call even on a never-started or HTTP-only client — the exit handler\n // may have already run failPending, but calling it again with the same\n // pending set is a no-op (failPending guards on `this.pending.size`).\n this.failPending(`MCP \"${this.opts.name}\" closed`);\n this.sseTransport?.close();\n this.httpTransport?.close();\n this.state = 'disconnected';\n }\n\n private request(\n method: string,\n params: unknown,\n timeoutMs = this.opts.requestTimeoutMs ?? 60_000,\n ): Promise<JsonRpcResponse> {\n // For HTTP transports, delegate to the transport's request method.\n // SSE and streamable-http both use postRaw which handles the full\n // round-trip including timeout signal.\n if (this.sseTransport) return this.sseTransport.request(method, params, timeoutMs);\n if (this.httpTransport) return this.httpTransport.request(method, params, timeoutMs);\n\n // stdio path\n const id = this.nextId++;\n const req: JsonRpcRequest = { jsonrpc: '2.0', id, method, params };\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(\n new Error(`MCP \"${this.opts.name}\" request \"${method}\" timed out after ${timeoutMs}ms`),\n );\n }, timeoutMs);\n this.pending.set(id, {\n resolve: (res) => {\n clearTimeout(timer);\n resolve(res);\n },\n reject: (err) => {\n clearTimeout(timer);\n reject(err);\n },\n timer,\n });\n try {\n this.child?.stdin?.write(JSON.stringify(req) + '\\n');\n } catch (err) {\n const pending = this.pending.get(id);\n this.pending.delete(id);\n if (pending) clearTimeout(pending.timer);\n reject(err);\n }\n });\n }\n\n /**\n * Reject every in-flight {@link request} call. Used when the underlying\n * transport dies — without this, callers awaiting `tools/call` over a\n * killed stdio child or a closed transport would hang indefinitely.\n */\n private failPending(reason: string): void {\n if (this.pending.size === 0) return;\n const err = new Error(reason);\n for (const [, entry] of this.pending) {\n try {\n clearTimeout(entry.timer);\n entry.reject(err);\n } catch {\n /* ignore */\n }\n }\n this.pending.clear();\n }\n\n private async notify(method: string, params: unknown): Promise<void> {\n const req = { jsonrpc: '2.0', method, params };\n const encoded = JSON.stringify(req) + '\\n';\n try {\n const ok = this.child?.stdin?.write(encoded);\n if (!ok) {\n // Only the first caller waits for drain; others just warn and return.\n // This avoids a race where two concurrent notify() calls each start\n // their own drain-wait, then both resolve and the buffer is still full.\n if (this._drainPending) {\n this._lastNotifySkipped = true;\n console.warn(\n `[MCP] notify(\"${method}\") skipped: stdin buffer backpressure (already waiting for drain)`,\n );\n return;\n }\n this._drainPending = true;\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.child?.stdin?.removeListener?.('drain', onDrain);\n this.child?.stdin?.removeListener?.('error', onError);\n this._drainPending = false;\n reject(new Error(`MCP notify(\"${method}\") drain timeout`));\n }, 500);\n const onDrain = () => {\n clearTimeout(timeout);\n this.child?.stdin?.removeListener?.('drain', onDrain);\n this.child?.stdin?.removeListener?.('error', onError);\n this._drainPending = false;\n resolve();\n };\n const onError = (err: Error) => {\n clearTimeout(timeout);\n this.child?.stdin?.removeListener?.('drain', onDrain);\n this.child?.stdin?.removeListener?.('error', onError);\n this._drainPending = false;\n reject(err);\n };\n this.child?.stdin?.once('drain', onDrain);\n this.child?.stdin?.once('error', onError);\n });\n }\n } catch (err) {\n throw new Error(\n `[MCP] notify(\"${method}\") failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n private onData(s: string): void {\n this.rxBuffer += s;\n let idx = this.rxBuffer.indexOf('\\n');\n while (idx !== -1) {\n const line = this.rxBuffer.slice(0, idx).trim();\n this.rxBuffer = this.rxBuffer.slice(idx + 1);\n if (line) this.onLine(line);\n idx = this.rxBuffer.indexOf('\\n');\n }\n }\n\n private onLine(line: string): void {\n let msg: JsonRpcResponse & { method?: string | undefined; params?: unknown | undefined };\n try {\n msg = JSON.parse(line) as JsonRpcResponse & { method?: string | undefined; params?: unknown | undefined };\n } catch {\n return;\n }\n if (msg.id !== undefined && this.pending.has(msg.id)) {\n const entry = this.pending.get(msg.id);\n this.pending.delete(msg.id);\n entry?.resolve(msg);\n return;\n }\n // Notifications have a `method` but no `id`. The MCP spec defines\n // `notifications/tools/list_changed` for tool-set invalidation —\n // refresh the cache asynchronously and fire listeners so the\n // registry can re-register the wrapped tools.\n if (typeof msg.method === 'string' && msg.method === 'notifications/tools/list_changed') {\n void this.handleToolsListChanged();\n }\n }\n\n /**\n * L2-C: refresh the cached tool list when the server announces a\n * `tools/list_changed`. Listeners (the registry) re-wrap and\n * re-register. Failures are swallowed — a stale cache is preferable\n * to a hard crash on a transient notification glitch.\n */\n private async handleToolsListChanged(): Promise<void> {\n try {\n const toolsRes = await this.request('tools/list', {});\n const tools = normalizeMCPTools((toolsRes.result as { tools?: unknown | undefined } | undefined)?.tools);\n this._tools = tools;\n this._toolsCache = tools;\n for (const listener of this.toolsChangedListeners) {\n try {\n listener(this.opts.name, [...tools]);\n } catch {\n // listeners must be best-effort\n }\n }\n } catch {\n // ignore — keep the existing cache\n }\n }\n\n addToolsChangedListener(listener: ToolsChangedListener): void {\n this.toolsChangedListeners.add(listener);\n }\n\n removeToolsChangedListener(listener: ToolsChangedListener): void {\n this.toolsChangedListeners.delete(listener);\n }\n}\n\n/**\n * Quote a single argument for `cmd.exe` when spawning with `shell: true` on\n * Windows. Only args containing whitespace or quotes need wrapping; inside\n * double quotes cmd.exe escapes a literal `\"` as `\"\"`. Backslashes are literal\n * inside cmd quotes, so paths like `C:\\Program Files\\x` pass through unharmed.\n */\nexport function quoteWindowsArg(arg: string): string {\n if (!/[\\s\"]/.test(arg)) return arg;\n return `\"${arg.replace(/\"/g, '\"\"')}\"`;\n}\n","import type { Permission, Tool } from '@wrongstack/core';\nimport type { MCPClient, MCPTool } from './client.js';\n\n/**\n * Keywords that indicate a mutating operation.\n * Applied to both the tool name and its inputSchema property names.\n */\nconst MUTATING_RE = /create|update|delete|write|send|set|put|post|patch|remove|rename|move/i;\n\nfunction isMutatingTool(mcpTool: MCPTool): boolean {\n if (MUTATING_RE.test(mcpTool.name)) return true;\n // Check property names in the input schema for mutating intent.\n // e.g. { properties: { createTable: {...}, dropIndex: {...} } }\n const schema = mcpTool.inputSchema;\n if (schema && typeof schema === 'object') {\n const props = (schema as { properties?: Record<string, unknown> }).properties;\n if (props) {\n for (const key of Object.keys(props)) {\n if (MUTATING_RE.test(key)) return true;\n }\n }\n }\n return false;\n}\n\nexport function wrapMCPTool(\n serverName: string,\n mcpTool: MCPTool,\n client: MCPClient,\n permission: Permission = 'confirm',\n): Tool {\n const qualifiedName = `mcp__${serverName}__${mcpTool.name}`;\n return {\n name: qualifiedName,\n description: mcpTool.description ?? `${qualifiedName} (MCP tool)`,\n usageHint: `Tool provided by MCP server \"${serverName}\". ${mcpTool.description ?? ''}`,\n permission,\n mutating: isMutatingTool(mcpTool),\n inputSchema: mcpTool.inputSchema ?? { type: 'object', properties: {} },\n async execute(input, _ctx, _opts) {\n const res = await client.callTool(mcpTool.name, input);\n if (res.isError) {\n throw new Error(stringify(res.content));\n }\n return stringify(res.content);\n },\n };\n}\n\nfunction stringify(c: unknown): string {\n if (typeof c === 'string') return c;\n if (Array.isArray(c)) {\n return c\n .map((item) => {\n if (item && typeof item === 'object') {\n const t = (item as { type?: string | undefined; text?: string | undefined }).type;\n if (t === 'text') return (item as { text?: string | undefined }).text ?? '';\n return JSON.stringify(item);\n }\n return String(item);\n })\n .join('\\n');\n }\n if (c && typeof c === 'object') {\n if ('text' in (c as Record<string, unknown>)) {\n return String((c as Record<string, unknown>).text);\n }\n return JSON.stringify(c);\n }\n return String(c ?? '');\n}\n","import { expectDefined } from '@wrongstack/core';\nimport type { EventBus, Logger, MCPServerConfig, ToolRegistry } from '@wrongstack/core';\nimport { MCP_CONSTANTS } from './constants.js';\nimport { type ConnectionState, MCPClient } from './client.js';\nimport { wrapMCPTool } from './wrap-tool.js';\ninterface ServerSlot {\n cfg: MCPServerConfig;\n client?: MCPClient | undefined;\n state: ConnectionState;\n toolNames: string[];\n attempts: number;\n /** Set when a reconnect cycle is already running for this slot. */\n reconnectPending: boolean;\n /**\n * L2-B: number of full reconnect *cycles* (where one cycle = one\n * `attemptConnect` invocation, which itself can try multiple times\n * before giving up). After `MAX_RECONNECT_CYCLES`, the slot stays\n * `failed` until a manual `restart()` resets it.\n */\n reconnectCycles: number;\n /**\n * Slot-scoped, bound disconnect callback. Stored so the matching\n * `removeDisconnectListener` call can hand back the *same* reference —\n * a fresh arrow `() => onTransportDisconnect(slot.cfg.name)` would\n * not match the one we added and the set-based listener registry\n * would silently keep the old handler, causing duplicate reconnect\n * cycles after a few transport flaps.\n */\n onDisconnect?: (() => void) | undefined;\n}\n\nexport interface MCPRegistryOptions {\n toolRegistry: ToolRegistry;\n events: EventBus;\n log: Logger;\n}\n\nexport class MCPRegistry {\n private readonly servers = new Map<string, ServerSlot>();\n private readonly toolRegistry: ToolRegistry;\n private readonly events: EventBus;\n private readonly log: Logger;\n\n constructor(opts: MCPRegistryOptions) {\n this.toolRegistry = opts.toolRegistry;\n this.events = opts.events;\n this.log = opts.log;\n }\n\n async start(cfg: MCPServerConfig): Promise<void> {\n if (cfg.enabled === false) return;\n const slot: ServerSlot = {\n cfg,\n state: 'idle',\n toolNames: [],\n attempts: 0,\n reconnectPending: false,\n reconnectCycles: 0,\n };\n this.servers.set(cfg.name, slot);\n await this.attemptConnect(slot);\n }\n\n async stop(name: string): Promise<void> {\n const slot = this.servers.get(name);\n if (!slot) return;\n slot.reconnectPending = false;\n if (slot.client) {\n slot.client.removeExitListener(this.onChildExit);\n if (slot.onDisconnect) slot.client.removeDisconnectListener(slot.onDisconnect);\n slot.client.removeToolsChangedListener(this.onToolsChanged);\n await slot.client.close();\n slot.client = undefined;\n }\n slot.onDisconnect = undefined;\n for (const t of slot.toolNames) this.toolRegistry.unregister(t);\n slot.toolNames = [];\n slot.state = 'disconnected';\n this.events.emit('mcp.server.disconnected', { name, reason: 'stop' });\n }\n\n async restart(name: string): Promise<void> {\n const slot = this.servers.get(name);\n if (!slot) throw new Error(`MCP server \"${name}\" not registered`);\n await this.stop(name);\n slot.attempts = 0;\n slot.reconnectCycles = 0; // user intent: start fresh\n await this.attemptConnect(slot);\n }\n\n list(): { name: string; state: ConnectionState; toolCount: number }[] {\n return Array.from(this.servers.values()).map((s) => ({\n name: s.cfg.name,\n state: s.state,\n toolCount: s.toolNames.length,\n }));\n }\n\n /**\n * Catalog of every server ever registered with this registry — includes\n * servers that are stopped, failed, or not yet started.\n * Useful for the `mcp_control` tool to show all known servers without\n * triggering connections.\n */\n describe(): { name: string; state: ConnectionState; toolCount: number; enabled: boolean }[] {\n return Array.from(this.servers.values()).map((s) => ({\n name: s.cfg.name,\n state: s.state,\n toolCount: s.toolNames.length,\n enabled: s.cfg.enabled !== false,\n }));\n }\n\n async stopAll(): Promise<void> {\n for (const name of Array.from(this.servers.keys())) {\n await this.stop(name);\n }\n }\n\n /**\n * Health check — returns 'ok' for connected servers, the current state otherwise.\n * For HTTP-based transports this could also ping the server.\n */\n health(): { name: string; alive: boolean; latencyMs?: number | undefined }[] {\n return Array.from(this.servers.values()).map((s) => ({\n name: s.cfg.name,\n alive: s.state === 'connected',\n }));\n }\n\n /**\n * L2-C: handle `notifications/tools/list_changed` from the server.\n * Unregister the previous wrapper set, then re-register the fresh\n * tool list. The client has already refreshed its cache before\n * dispatching — we just need to re-wrap and re-register.\n */\n private readonly onToolsChanged = (name: string, _tools: { name: string }[]): void => {\n const slot = this.servers.get(name);\n if (!slot || !slot.client) return;\n for (const t of slot.toolNames) {\n try {\n this.toolRegistry.unregister(t);\n } catch {\n /* ignore */\n }\n }\n slot.toolNames = [];\n const allowed = slot.cfg.allowedTools;\n const wrapped = slot.client\n .listTools()\n .filter((t) => !allowed || allowed.includes(t.name))\n .map((t) => wrapMCPTool(slot.cfg.name, t, expectDefined(slot.client), slot.cfg.permission ?? 'confirm'));\n for (const tool of wrapped) {\n try {\n this.toolRegistry.register(tool, `mcp:${slot.cfg.name}`);\n slot.toolNames.push(tool.name);\n } catch (err) {\n this.log.warn(`MCP tool \"${tool.name}\" not re-registered after list_changed`, err);\n }\n }\n this.events.emit('mcp.server.connected', {\n name: slot.cfg.name,\n toolCount: slot.toolNames.length,\n });\n this.log.info(\n `MCP server \"${slot.cfg.name}\" tools refreshed (${slot.toolNames.length} active)`,\n );\n };\n\n private readonly onChildExit = (\n name: string,\n code: number | null,\n _signal: string | null,\n ): void => {\n const slot = this.servers.get(name);\n if (!slot) return;\n for (const t of slot.toolNames) {\n try {\n this.toolRegistry.unregister(t);\n } catch {\n /* ignore */\n }\n }\n slot.toolNames = [];\n slot.state = 'disconnected';\n this.events.emit('mcp.server.disconnected', { name, reason: `exit:${code ?? 'unknown'}` });\n this.scheduleReconnect(slot);\n };\n\n /** Handles SSE / streamable-http disconnect — same recovery as stdio child exit. */\n private readonly onTransportDisconnect = (name: string): void => {\n const slot = this.servers.get(name);\n if (!slot) return;\n for (const t of slot.toolNames) {\n try {\n this.toolRegistry.unregister(t);\n } catch {\n /* ignore */\n }\n }\n slot.toolNames = [];\n slot.state = 'disconnected';\n this.events.emit('mcp.server.disconnected', { name, reason: 'http-disconnect' });\n this.scheduleReconnect(slot);\n };\n\n /**\n * L2-B: maximum number of reconnect cycles before staying `failed`.\n * One cycle = one full `attemptConnect` (which itself may try up to 3\n * times). Caps total reconnect storm at ~5 cycles, then the slot\n * needs an explicit `restart()` to re-engage.\n */\n private static readonly MAX_RECONNECT_CYCLES = MCP_CONSTANTS.RECONNECT.MAX_CYCLES;\n /** Base delay between cycles, in ms. Real delay adds jitter. */\n private static readonly BASE_RECONNECT_DELAY_MS = MCP_CONSTANTS.RECONNECT.BASE_DELAY_MS;\n /** Hard ceiling on the inter-cycle delay so the user doesn't wait minutes. */\n private static readonly MAX_RECONNECT_DELAY_MS = 30_000;\n\n private scheduleReconnect(slot: ServerSlot): void {\n if (slot.reconnectPending) return;\n if (slot.reconnectCycles >= MCPRegistry.MAX_RECONNECT_CYCLES) {\n slot.state = 'failed';\n this.log.error(\n `MCP server \"${slot.cfg.name}\" giving up after ${slot.reconnectCycles} reconnect cycles. Use \\`/mcp restart ${slot.cfg.name}\\` to retry.`,\n );\n this.events.emit('mcp.server.disconnected', {\n name: slot.cfg.name,\n reason: `reconnect-exhausted:${slot.reconnectCycles}`,\n });\n return;\n }\n slot.reconnectPending = true;\n // Exponential backoff with light jitter: 1s, 2s, 4s, 8s, 16s, capped\n // at 30s. The ±20% jitter avoids reconnect stampedes when many\n // servers crash together.\n const base = Math.min(\n MCPRegistry.BASE_RECONNECT_DELAY_MS * 2 ** slot.reconnectCycles,\n MCPRegistry.MAX_RECONNECT_DELAY_MS,\n );\n const jitter = base * MCP_CONSTANTS.RECONNECT.JITTER_FACTOR * (Math.random() * 2 - 1);\n const delay = Math.max(100, Math.round(base + jitter));\n setTimeout(() => this.attemptReconnect(slot), delay);\n }\n\n private async attemptReconnect(slot: ServerSlot): Promise<void> {\n slot.reconnectPending = false;\n slot.reconnectCycles++;\n await this.attemptConnect(slot);\n }\n\n private async attemptConnect(slot: ServerSlot): Promise<void> {\n const MAX_ATTEMPTS = MCP_CONSTANTS.RECONNECT.MAX_ATTEMPTS;\n let attempt = 0;\n while (attempt < MAX_ATTEMPTS) {\n attempt++;\n slot.state = attempt === 1 ? 'connecting' : 'reconnecting';\n slot.attempts = attempt;\n let client: MCPClient | undefined;\n let boundDisconnect: (() => void) | undefined;\n try {\n client = new MCPClient({\n name: slot.cfg.name,\n transport: slot.cfg.transport,\n command: slot.cfg.command,\n args: slot.cfg.args,\n env: slot.cfg.env,\n url: slot.cfg.url,\n headers: slot.cfg.headers,\n startupTimeoutMs: slot.cfg.startupTimeoutMs,\n requestTimeoutMs: slot.cfg.requestTimeoutMs,\n });\n if (slot.cfg.transport === 'stdio') {\n client.addExitListener(this.onChildExit);\n } else {\n // SSE / streamable-http — wire transport disconnect to registry reconnect.\n // Capture the bound function so we can hand the same reference to\n // removeDisconnectListener on cleanup paths.\n boundDisconnect = () => this.onTransportDisconnect(slot.cfg.name);\n client.addDisconnectListener(boundDisconnect);\n }\n // L2-C: react to server-side tool changes by re-registering wrappers.\n client.addToolsChangedListener(this.onToolsChanged);\n await client.connect();\n // Close any prior client before swapping refs so the old transport\n // can release its abort controller, child process, and listeners\n // instead of being held until GC.\n if (slot.client && slot.client !== client) {\n const prior = slot.client;\n const priorDisconnect = slot.onDisconnect;\n slot.client.removeExitListener(this.onChildExit);\n if (priorDisconnect) prior.removeDisconnectListener(priorDisconnect);\n prior.removeToolsChangedListener(this.onToolsChanged);\n prior.close().catch(() => {\n /* best-effort */\n });\n }\n slot.client = client;\n slot.onDisconnect = boundDisconnect;\n const isReconnect = attempt > 1;\n slot.state = 'connected';\n // L2-B: a healthy connect resets the cycle counter so future\n // crashes get the full reconnect budget again.\n slot.reconnectCycles = 0;\n const allowed = slot.cfg.allowedTools;\n // Prefer cached tools to avoid a round-trip to the server on reconnect.\n // The cache is populated by client.listTools() on first connect.\n const mc = client as MCPClient;\n const candidateTools = mc.listTools();\n const toWrap = candidateTools.length > 0 ? candidateTools : mc.listTools(); // fallback — in practice both return the same list\n const wrapped = toWrap\n .filter((t) => !allowed || allowed.includes(t.name))\n .map((t) => wrapMCPTool(slot.cfg.name, t, mc, slot.cfg.permission ?? 'confirm'));\n for (const tool of wrapped) {\n try {\n this.toolRegistry.register(tool, `mcp:${slot.cfg.name}`);\n slot.toolNames.push(tool.name);\n } catch (err) {\n this.log.warn(`MCP tool \"${tool.name}\" not registered`, err);\n }\n }\n this.events.emit(isReconnect ? 'mcp.server.reconnected' : 'mcp.server.connected', {\n name: slot.cfg.name,\n toolCount: slot.toolNames.length,\n });\n return; // success\n } catch (err) {\n this.log.warn(`MCP server \"${slot.cfg.name}\" connect attempt ${attempt} failed`, err);\n if (client) {\n client.removeExitListener(this.onChildExit);\n if (boundDisconnect) client.removeDisconnectListener(boundDisconnect);\n client.removeToolsChangedListener(this.onToolsChanged);\n await client.close().catch(() => {\n /* ignore */\n });\n }\n if (attempt >= MAX_ATTEMPTS) {\n this.log.error(\n `MCP server \"${slot.cfg.name}\" connect exhausted after ${MAX_ATTEMPTS} attempts`,\n err,\n );\n slot.state = 'failed';\n slot.client = undefined;\n this.events.emit('mcp.server.disconnected', {\n name: slot.cfg.name,\n reason: err instanceof Error ? err.message : 'unknown',\n });\n return;\n }\n const delay = 500 * 2 ** attempt;\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n }\n}\n","import { expectDefined } from '@wrongstack/core';\nimport { type IncomingMessage, type ServerResponse, createServer } from 'node:http';\nimport { MCP_CONSTANTS } from './constants.js';\n/**\n * Server-side MCP. The mirror image of `MCPClient`: instead of consuming a\n * remote MCP server, this lets WrongStack *be* an MCP server — exposing its\n * tools to any MCP client (Claude Desktop, another agent, an IDE) over a\n * JSON-RPC 2.0 stream.\n *\n * The protocol core (`MCPServer`) is transport-agnostic: feed it a raw JSON\n * line via `handleMessage`, get back a response string (or `null` for\n * notifications). `serveStdio` wires it to stdin/stdout for the canonical\n * stdio transport.\n */\n\n/** A tool descriptor advertised over `tools/list`. */\nexport interface MCPServerTool {\n name: string;\n description?: string | undefined;\n inputSchema: Record<string, unknown>;\n}\n\n/** The result of a `tools/call`, as the host produces it. */\nexport interface MCPServerCallResult {\n /** Text or pre-built MCP content blocks. Strings are wrapped as a text block. */\n content: unknown;\n isError: boolean;\n}\n\n/**\n * Bridges the MCP server to a tool backend (in the CLI, the `ToolRegistry`).\n * Kept narrow so the protocol core has no dependency on `@wrongstack/core`.\n */\nexport interface MCPServerToolHost {\n listTools(): MCPServerTool[] | Promise<MCPServerTool[]>;\n callTool(name: string, args: Record<string, unknown>): Promise<MCPServerCallResult>;\n}\n\nexport interface MCPServerLogger {\n warn?(msg: string): void;\n info?(msg: string): void;\n}\n\nexport interface MCPServerOptions {\n host: MCPServerToolHost;\n /** Advertised in the `initialize` handshake. Defaults to the wrongstack identity. */\n serverInfo?: { name: string; version: string };\n logger?: MCPServerLogger | undefined;\n}\n\ninterface JsonRpcRequest {\n jsonrpc?: string | undefined;\n id?: number | string | null | undefined;\n method?: string | undefined;\n params?: unknown | undefined;\n}\n\n// JSON-RPC 2.0 reserved error codes.\nconst PARSE_ERROR = -32700;\nconst INVALID_REQUEST = -32600;\nconst METHOD_NOT_FOUND = -32601;\nconst INTERNAL_ERROR = -32603;\n\nexport class MCPServer {\n private readonly host: MCPServerToolHost;\n private readonly serverInfo: { name: string; version: string };\n private readonly logger?: MCPServerLogger | undefined;\n\n constructor(opts: MCPServerOptions) {\n this.host = opts.host;\n this.serverInfo = opts.serverInfo ?? {\n name: MCP_CONSTANTS.CLIENT_INFO.name,\n version: MCP_CONSTANTS.CLIENT_INFO.version,\n };\n this.logger = opts.logger;\n }\n\n /**\n * Handle one raw JSON-RPC line. Returns the response JSON string for\n * requests, or `null` for notifications (no `id`) and for blank input —\n * the caller should write the string to its output stream when non-null.\n */\n async handleMessage(raw: string): Promise<string | null> {\n const line = raw.trim();\n if (!line) return null;\n\n let msg: JsonRpcRequest;\n try {\n msg = JSON.parse(line) as JsonRpcRequest;\n } catch {\n return this.encodeError(null, PARSE_ERROR, 'Parse error');\n }\n\n if (typeof msg !== 'object' || msg === null || typeof msg.method !== 'string') {\n const id = msg && typeof msg === 'object' ? (msg.id ?? null) : null;\n return this.encodeError(id ?? null, INVALID_REQUEST, 'Invalid Request');\n }\n\n const isNotification = msg.id === undefined || msg.id === null;\n\n // Notifications never get a response. We still dispatch known ones for\n // side effects, but `notifications/initialized` is purely a handshake ack.\n if (isNotification) {\n return null;\n }\n\n try {\n const result = await this.dispatch(msg.method, msg.params);\n if (result === METHOD_NOT_FOUND_SENTINEL) {\n return this.encodeError(expectDefined(msg.id), METHOD_NOT_FOUND, `Method not found: ${msg.method}`);\n }\n return JSON.stringify({ jsonrpc: '2.0', id: msg.id, result });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n this.logger?.warn?.(`MCP server: method \"${msg.method}\" threw: ${message}`);\n return this.encodeError(expectDefined(msg.id), INTERNAL_ERROR, message);\n }\n }\n\n private async dispatch(method: string, params: unknown): Promise<unknown> {\n switch (method) {\n case 'initialize':\n return {\n protocolVersion: MCP_CONSTANTS.PROTOCOL_VERSION,\n capabilities: { tools: { listChanged: false } },\n serverInfo: this.serverInfo,\n };\n case 'ping':\n return {};\n case 'tools/list': {\n const tools = await this.host.listTools();\n return { tools };\n }\n case 'tools/call': {\n const p = (params ?? {}) as { name?: unknown | undefined; arguments?: unknown | undefined };\n if (typeof p.name !== 'string') {\n throw new Error('tools/call requires a string \"name\"');\n }\n const args =\n p.arguments && typeof p.arguments === 'object' && !Array.isArray(p.arguments)\n ? (p.arguments as Record<string, unknown>)\n : {};\n const res = await this.host.callTool(p.name, args);\n return { content: toContentBlocks(res.content), isError: res.isError };\n }\n default:\n return METHOD_NOT_FOUND_SENTINEL;\n }\n }\n\n private encodeError(id: number | string | null, code: number, message: string): string {\n return JSON.stringify({ jsonrpc: '2.0', id, error: { code, message } });\n }\n}\n\nconst METHOD_NOT_FOUND_SENTINEL = Symbol('method-not-found');\n\n/** Normalize a host result's content into MCP content blocks. */\nexport function toContentBlocks(content: unknown): Array<{ type: 'text'; text: string }> {\n if (typeof content === 'string') return [{ type: 'text', text: content }];\n if (Array.isArray(content)) {\n // Already-shaped content blocks pass through; otherwise stringify each item.\n const allBlocks = content.every(\n (c) => c && typeof c === 'object' && (c as { type?: unknown | undefined }).type === 'text',\n );\n if (allBlocks) return content as Array<{ type: 'text'; text: string }>;\n return [{ type: 'text', text: content.map((c) => stringifyItem(c)).join('\\n') }];\n }\n if (content === undefined || content === null) return [{ type: 'text', text: '' }];\n return [{ type: 'text', text: stringifyItem(content) }];\n}\n\nfunction stringifyItem(c: unknown): string {\n if (typeof c === 'string') return c;\n try {\n return JSON.stringify(c);\n } catch {\n return String(c);\n }\n}\n\nexport interface ServeStdioHandle {\n /** Stop reading and detach listeners. Does not exit the process. */\n close(): void;\n /** Resolves when the input stream ends (EOF). */\n done: Promise<void>;\n}\n\nexport interface ServeStdioOptions {\n stdin?: NodeJS.ReadableStream | undefined;\n stdout?: NodeJS.WritableStream | undefined;\n}\n\n/**\n * Run an `MCPServer` over stdio: newline-delimited JSON-RPC in on stdin,\n * responses out on stdout. CRITICAL: nothing else may write to stdout while\n * this runs — it is the JSON-RPC channel. Route all logging to stderr.\n */\nexport function serveStdio(server: MCPServer, opts: ServeStdioOptions = {}): ServeStdioHandle {\n const stdin: NodeJS.ReadableStream = opts.stdin ?? process.stdin;\n const stdout = opts.stdout ?? process.stdout;\n let buffer = '';\n let closed = false;\n // Serialize writes so concurrent async handlers don't interleave lines.\n let writeChain: Promise<void> = Promise.resolve();\n\n const writeLine = (s: string) => {\n writeChain = writeChain\n .then(\n () =>\n new Promise<void>((resolve) => {\n stdout.write(`${s}\\n`, () => resolve());\n }),\n )\n .catch((err) => {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(JSON.stringify({\n level: 'error',\n event: 'mcp_server.stdout_write_failed',\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n });\n };\n\n const onData = (chunk: Buffer | string) => {\n buffer += typeof chunk === 'string' ? chunk : chunk.toString('utf8');\n let idx = buffer.indexOf('\\n');\n while (idx !== -1) {\n const line = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 1);\n idx = buffer.indexOf('\\n');\n if (!line.trim()) continue;\n void server\n .handleMessage(line)\n .then((res) => {\n if (res !== null && !closed) writeLine(res);\n })\n .catch((err) => {\n // Malformed JSON from a peer — log and continue so one bad line\n // doesn't kill the entire session.\n console.error(JSON.stringify({\n level: 'error',\n event: 'mcp_server.handle_message_failed',\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n });\n }\n };\n\n let resolveDone!: () => void;\n const done = new Promise<void>((resolve) => {\n resolveDone = resolve;\n });\n\n const onEnd = () => {\n if (closed) return;\n closed = true;\n stdin.off('data', onData);\n resolveDone();\n };\n\n stdin.on('data', onData);\n stdin.once('end', onEnd);\n stdin.once('close', onEnd);\n if (typeof (stdin as { resume?: () => void }).resume === 'function') {\n (stdin as { resume: () => void }).resume();\n }\n\n return {\n close: () => {\n onEnd();\n },\n done,\n };\n}\n\n// ── HTTP transport ──────────────────────────────────────────────────────────\n\nconst HTTP_BODY_CAP = 4 * 1024 * 1024; // 4 MiB\n\nexport interface ServeHttpOptions {\n /** TCP port. 0 picks an ephemeral port (resolved in the handle). Default 0. */\n port?: number | undefined;\n /** Bind address. Default '127.0.0.1' (loopback only). */\n host?: string | undefined;\n /**\n * Bearer token required on every request (`Authorization: Bearer <token>`).\n * REQUIRED when binding to a non-loopback host — `serveHttp` refuses to\n * expose tools to the network without one.\n */\n token?: string | undefined;\n logger?: MCPServerLogger | undefined;\n}\n\nexport interface ServeHttpHandle {\n port: number;\n host: string;\n url: string;\n close(): Promise<void>;\n}\n\nfunction isLoopbackHost(host: string): boolean {\n return host === '127.0.0.1' || host === '::1' || host === 'localhost';\n}\n\n/**\n * Run an `MCPServer` over HTTP: POST a single JSON-RPC request, get the JSON\n * response (notifications → 202 with no body). Reuses `handleMessage`, so the\n * protocol is identical to the stdio transport.\n *\n * Security: binds to loopback by default. Binding to any other host (e.g.\n * `0.0.0.0`) REQUIRES a `token` — otherwise this rejects, because it would\n * otherwise expose tool execution to the whole network unauthenticated.\n */\nexport function serveHttp(\n server: MCPServer,\n opts: ServeHttpOptions = {},\n): Promise<ServeHttpHandle> {\n const host = opts.host ?? '127.0.0.1';\n const port = opts.port ?? 0;\n const token = opts.token;\n const log = opts.logger;\n\n if (!isLoopbackHost(host) && !token) {\n return Promise.reject(\n new Error(\n `serveHttp: refusing to bind to non-loopback host \"${host}\" without a token — ` +\n 'pass a token to expose tools to the network, or bind to 127.0.0.1.',\n ),\n );\n }\n\n const httpServer = createServer((req: IncomingMessage, res: ServerResponse) => {\n void handleHttpRequest(server, req, res, token, log);\n });\n\n return new Promise<ServeHttpHandle>((resolve, reject) => {\n httpServer.once('error', reject);\n httpServer.listen(port, host, () => {\n httpServer.removeListener('error', reject);\n const addr = httpServer.address();\n const boundPort = typeof addr === 'object' && addr ? addr.port : port;\n const displayHost = host === '::1' ? '[::1]' : host;\n resolve({\n port: boundPort,\n host,\n url: `http://${displayHost}:${boundPort}/`,\n close: () =>\n new Promise<void>((res2) => {\n httpServer.close(() => res2());\n }),\n });\n });\n });\n}\n\nasync function handleHttpRequest(\n server: MCPServer,\n req: IncomingMessage,\n res: ServerResponse,\n token: string | undefined,\n log: MCPServerLogger | undefined,\n): Promise<void> {\n const send = (status: number, body: string, type = 'application/json') => {\n res.writeHead(status, { 'content-type': type });\n res.end(body);\n };\n\n // Health probe.\n if (req.method === 'GET') {\n return send(200, JSON.stringify({ status: 'ok', server: 'wrongstack-mcp' }));\n }\n if (req.method !== 'POST') {\n return send(405, JSON.stringify({ error: 'method not allowed' }));\n }\n if (token) {\n const auth = req.headers.authorization ?? '';\n const expected = `Bearer ${token}`;\n if (auth !== expected) {\n return send(401, JSON.stringify({ error: 'unauthorized' }));\n }\n }\n\n let body = '';\n let tooLarge = false;\n req.on('data', (chunk: Buffer) => {\n if (tooLarge) return;\n body += chunk.toString('utf8');\n if (body.length > HTTP_BODY_CAP) {\n tooLarge = true;\n send(413, JSON.stringify({ error: 'payload too large' }));\n req.destroy();\n }\n });\n req.on('end', () => {\n if (tooLarge) return;\n void server\n .handleMessage(body)\n .then((out) => {\n // Notifications produce no response body.\n if (out === null) return send(202, '');\n return send(200, out);\n })\n .catch((err) => {\n log?.warn?.(`MCP http handler error: ${err instanceof Error ? err.message : String(err)}`);\n send(500, JSON.stringify({ error: 'internal error' }));\n });\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/tool-schema.ts","../src/transport.ts","../src/client.ts","../src/wrap-tool.ts","../src/registry.ts","../src/server.ts"],"names":["body","expectDefined"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Shared constants for the MCP package.\n *\n * Centralizing these values means:\n * - Protocol version and client identity are updated in one place\n * - Reconnect parameters can be overridden via config in the future\n * - No scattered magic values across multiple files\n */\nexport const MCP_CONSTANTS = Object.freeze({\n /** MCP protocol version advertised during handshake. */\n PROTOCOL_VERSION: '2024-11-05',\n\n /** Identity announced to MCP servers during `initialize`. */\n CLIENT_INFO: Object.freeze({\n name: 'wrongstack',\n version: '0.1.10',\n }),\n\n /** Reconnection behaviour when a transport disconnects. */\n RECONNECT: Object.freeze({\n /** Max full reconnect cycles before the slot is marked `failed`. */\n MAX_CYCLES: 5,\n /** Base delay between cycles (exponential backoff applied on top). */\n BASE_DELAY_MS: 1000,\n /** Jitter factor applied to the backoff (0 = no jitter, 1 = full). */\n JITTER_FACTOR: 0.2,\n /** Max connection attempts within a single cycle. */\n MAX_ATTEMPTS: 3,\n /** Base multiplier for the exponential backoff formula (`delay = BASE * multiplier^attempt`). */\n BACKOFF_MULTIPLIER: 2,\n }),\n\n /** Timing for graceful / forced disconnect. */\n DISCONNECT: Object.freeze({\n /** Ms to wait for in-flight requests to complete before force-closing. */\n GRACEFUL_MS: 800,\n /** Ms after which the force disconnect is triggered. */\n FORCE_TIMEOUT_MS: 1200,\n }),\n\n /** JSON-RPC response timeout for outstanding requests. */\n RESPONSE_TIMEOUT_MS: 500,\n\n /** Max buffer size for the SSE reader. */\n SSE_READER_MAX_BUFFER: 256 * 1024,\n\n /** Max characters logged from a request body. */\n REQUEST_LOG_CAP: 1024,\n} as const);","import type { MCPTool } from './client.js';\n\nexport function normalizeMCPTools(value: unknown): MCPTool[] {\n if (!Array.isArray(value)) return [];\n const tools: MCPTool[] = [];\n for (const raw of value) {\n if (!raw || typeof raw !== 'object') continue;\n const t = raw as { name?: unknown | undefined; description?: unknown | undefined; inputSchema?: unknown | undefined };\n if (typeof t.name !== 'string' || t.name.trim().length === 0) continue;\n const inputSchema =\n t.inputSchema && typeof t.inputSchema === 'object' && !Array.isArray(t.inputSchema)\n ? (t.inputSchema as Record<string, unknown>)\n : { type: 'object', properties: {} };\n // Log when a tool's schema is absent or invalid — this could indicate a\n // broken, misbehaving, or (if the server is untrusted) adversarial MCP\n // server trying to confuse the LLM with misleading type info.\n if (!t.inputSchema || typeof t.inputSchema !== 'object' || Array.isArray(t.inputSchema)) {\n console.warn(JSON.stringify({\n level: 'warn',\n event: 'mcp.tool_schema_invalid',\n tool: t.name,\n message: 'no/invalid inputSchema — defaulting to empty object',\n timestamp: new Date().toISOString(),\n }));\n }\n tools.push({\n name: t.name,\n ...(typeof t.description === 'string' ? { description: t.description } : {}),\n inputSchema,\n });\n }\n return tools;\n}\n","import { randomBytes } from 'node:crypto';\nimport * as https from 'node:https';\nimport * as net from 'node:net';\nimport type { Dispatcher } from 'undici';\nimport type { ConnectionState, JsonRpcResponse, MCPTool, ToolCallResult } from './client.js';\nimport { MCP_CONSTANTS } from './constants.js';\nimport { normalizeMCPTools } from './tool-schema.js';\n\nexport type JsonRpcResult = {\n jsonrpc: string;\n id?: number | undefined;\n result?: unknown | undefined;\n error?: { code: number | undefined; message: string; data?: unknown | undefined } | undefined;\n};\n\nexport interface HttpTransportOptions {\n name: string;\n url: string;\n headers?: Record<string, string> | undefined;\n startupTimeoutMs?: number | undefined;\n requestTimeoutMs?: number | undefined;\n /**\n * Per-request TLS configuration. When set, an https.Agent is created\n * and passed to fetch via the `dispatch` option. This avoids globally\n * disabling certificate validation (NODE_TLS_REJECT_UNAUTHORIZED) which\n * would affect all provider API calls in the same process.\n *\n * ⚠️ Security gate: `rejectUnauthorized: false` REQUIRES either:\n * - `WRONGSTACK_UNSAFE_MCP_TLS=1` env var, OR\n * - `CI` env var is set (for automated testing)\n *\n * Without this gate, an active network attacker between the client and the\n * MCP server can read and modify tool calls and responses. Only use this\n * for local development with self-signed certificates; production MCP\n * servers must present a valid certificate.\n */\n tls?: { ca?: string | undefined; rejectUnauthorized?: boolean | undefined };\n}\n\nfunction isTlsUnsafeAllowed(): boolean {\n return process.env['WRONGSTACK_UNSAFE_MCP_TLS'] === '1' || process.env['CI'] === 'true';\n}\n\n/**\n * Validate that an MCP transport URL is not targeting private/internal\n * addresses. This is a defense-in-depth SSRF check — MCP servers are\n * typically local or LAN, but config manipulation could point to metadata\n * endpoints (169.254.169.254) or internal services.\n *\n * The check is intentionally lighter than fetch.ts's assertNotPrivate:\n * MCP URLs are admin-configured, not LLM-supplied, so we only block\n * the most obvious attack vectors.\n */\nfunction validateTransportUrl(rawUrl: string): void {\n let url: URL;\n try {\n url = new URL(rawUrl);\n } catch {\n throw new Error(`MCP transport: invalid URL \"${rawUrl}\"`);\n }\n\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error(\n `MCP transport: unsupported protocol \"${url.protocol}\" — only http/https allowed`,\n );\n }\n\n const hostname = url.hostname;\n // URL.hostname keeps the brackets on IPv6 literals; strip them so net.isIP\n // and prefix checks see the bare address.\n const host =\n hostname.startsWith('[') && hostname.endsWith(']') ? hostname.slice(1, -1) : hostname;\n\n // Block cloud metadata endpoints (IMDS) — these are never valid MCP servers\n const ipVersion = net.isIP(host);\n if (ipVersion === 4) {\n const parts = host.split('.').map(Number);\n // 169.254.x.x (link-local / IMDS)\n if (parts[0] === 169 && parts[1] === 254) {\n throw new Error(\n `MCP transport: blocked link-local/IMDS address \"${hostname}\" — likely not a valid MCP server`,\n );\n }\n } else if (ipVersion === 6) {\n const lower = host.toLowerCase();\n // fe80::/10 link-local (first hextet fe80–febf) and the AWS IPv6 IMDS\n // address fd00:ec2::254 — the IPv6 counterparts of the IPv4 block above.\n const linkLocal = /^fe[89ab]/.test(lower);\n if (linkLocal || lower === 'fd00:ec2::254') {\n throw new Error(\n `MCP transport: blocked link-local/IMDS address \"${hostname}\" — likely not a valid MCP server`,\n );\n }\n }\n\n // Plaintext http: is only permitted for loopback addresses where the\n // attacker would already need machine-level access. Remote HTTP MCP servers\n // must use TLS so an active network attacker cannot read or modify tool\n // calls and responses.\n if (url.protocol === 'http:') {\n const isLoopback =\n hostname === 'localhost' ||\n hostname === '127.0.0.1' ||\n hostname === '::1' ||\n hostname === '[::1]';\n if (!isLoopback) {\n throw new Error(\n `MCP transport: http:// is only allowed for loopback addresses; use https:// for \"${hostname}\"`,\n );\n }\n }\n}\n\n/**\n * SSE-based MCP transport using native fetch.\n *\n * Communication pattern:\n * - Client connects to SSE endpoint to receive server messages (JSON-RPC events)\n * - Client sends JSON-RPC requests via HTTP POST to the same or separate endpoint\n * - Server sends results/errors via the SSE stream\n *\n * The SSE reader parses the SSE protocol (event:, data:, blank line to dispatch).\n */\n/**\n * Cap on the pending-line buffer. The upstream SSE parser\n * (packages/providers/src/sse.ts) already enforces 256 KB; this\n * reader is used only inside MCP HTTP transports, but defense-in-depth\n * says we should never let a malicious stream pin memory.\n */\nconst SSE_READER_MAX_BUFFER = 256 * 1024;\n/** Max data lines buffered per event before flush. Prevents a malicious\n * server from accumulating unbounded data: lines without a blank-line\n * delimiter would grow this array indefinitely. */\nconst SSE_READER_MAX_DATA_LINES = 1024;\n\nexport class SSEReader {\n private buffer = '';\n private dataLines: string[] = [];\n private listeners: Array<\n (event: { jsonrpc?: string | undefined; method?: string | undefined; params?: unknown | undefined; id?: number | undefined }) => void\n > = [];\n\n onMessage(\n cb: (data: { jsonrpc?: string | undefined; method?: string | undefined; params?: unknown | undefined; id?: number | undefined }) => void,\n ): () => void {\n this.listeners.push(cb);\n return () => {\n const idx = this.listeners.indexOf(cb);\n if (idx >= 0) this.listeners.splice(idx, 1);\n };\n }\n\n feed(chunk: string): void {\n // Guard against a single chunk that exceeds the buffer cap.\n if (chunk.length > SSE_READER_MAX_BUFFER) {\n throw new Error(\n `SSE: chunk size ${chunk.length} exceeds max buffer ${SSE_READER_MAX_BUFFER} — refusing to accumulate`,\n );\n }\n this.buffer += chunk;\n if (this.buffer.length > SSE_READER_MAX_BUFFER) {\n throw new Error(\n `SSE: pending line exceeds ${SSE_READER_MAX_BUFFER} bytes — upstream is not framing events`,\n );\n }\n let idx = this.buffer.indexOf('\\n');\n while (idx !== -1) {\n const line = this.buffer.slice(0, idx).replace(/\\r$/, '');\n this.buffer = this.buffer.slice(idx + 1);\n idx = this.buffer.indexOf('\\n');\n\n this.processLine(line);\n }\n }\n\n private processLine(line: string): void {\n if (line === '') {\n this.flush();\n return;\n }\n if (line.startsWith(':')) return;\n\n const colonIdx = line.indexOf(':');\n const field = colonIdx === -1 ? line : line.slice(0, colonIdx);\n let value = colonIdx === -1 ? '' : line.slice(colonIdx + 1);\n if (value.startsWith(' ')) value = value.slice(1);\n\n if (field === 'event') {\n // The current transport only cares about JSON-RPC payloads in data\n // fields. Event names are accepted for spec compatibility.\n } else if (field === 'data') {\n if (this.dataLines.length >= SSE_READER_MAX_DATA_LINES) {\n throw new Error(\n `SSE: exceeded ${SSE_READER_MAX_DATA_LINES} data lines per event — upstream is not sending blank-line delimiters`,\n );\n }\n this.dataLines.push(value);\n }\n }\n\n private flush(): void {\n if (this.dataLines.length === 0) {\n return;\n }\n const data = this.dataLines.join('\\n').trim();\n this.dataLines = [];\n if (!data) return;\n try {\n const parsed = JSON.parse(data) as {\n jsonrpc?: string | undefined;\n method?: string | undefined;\n params?: unknown | undefined;\n id?: number | undefined;\n };\n this.dispatch(parsed);\n } catch {\n // ignore parse errors\n }\n }\n\n private dispatch(msg: {\n jsonrpc?: string | undefined;\n method?: string | undefined;\n params?: unknown | undefined;\n id?: number | undefined;\n }): void {\n for (const cb of this.listeners) {\n try {\n cb(msg);\n } catch {\n /* ignore */\n }\n }\n }\n\n reset(): void {\n this.buffer = '';\n this.dataLines = [];\n this.listeners = [];\n }\n}\n\nfunction isJsonRpcResult(v: unknown): v is JsonRpcResult {\n if (typeof v !== 'object' || v === null) return false;\n const r = v as JsonRpcResult;\n if (r.jsonrpc !== '2.0') return false;\n if (r.error !== undefined) {\n return (\n typeof r.error === 'object' &&\n r.error !== null &&\n typeof r.error.code === 'number' &&\n typeof r.error.message === 'string'\n );\n }\n return 'result' in r || r.id === undefined;\n}\n\n/**\n * Extract JSON-RPC envelopes from a streamable-http response body. Handles BOTH\n * plain NDJSON (one JSON object per line) AND SSE framing\n * (`event: message\\ndata: {...}` blocks) — modern MCP servers (e.g. Context7)\n * reply with `text/event-stream` even on a single POST, so the data must be\n * un-prefixed before parsing. Multi-line `data:` values within one event are\n * joined per the SSE spec.\n */\nexport function extractJsonRpcResults(text: string): JsonRpcResult[] {\n const out: JsonRpcResult[] = [];\n let dataBuf: string[] = [];\n const flush = () => {\n if (dataBuf.length === 0) return;\n const joined = dataBuf.join('\\n').trim();\n dataBuf = [];\n if (!joined) return;\n try {\n const parsed = JSON.parse(joined);\n if (isJsonRpcResult(parsed)) out.push(parsed);\n } catch {\n /* ignore non-JSON event data */\n }\n };\n for (const raw of text.split('\\n')) {\n const line = raw.replace(/\\r$/, '');\n if (line === '') {\n flush(); // blank line ends an SSE event\n continue;\n }\n if (line.startsWith(':')) continue; // SSE comment\n if (line.startsWith('data:')) {\n let v = line.slice(5);\n if (v.startsWith(' ')) v = v.slice(1);\n dataBuf.push(v);\n continue;\n }\n if (line.startsWith('event:') || line.startsWith('id:') || line.startsWith('retry:')) {\n continue; // other SSE fields\n }\n // Plain NDJSON line (no SSE framing).\n const trimmed = line.trim();\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n const parsed = JSON.parse(trimmed);\n if (isJsonRpcResult(parsed)) out.push(parsed);\n } catch {\n /* ignore */\n }\n }\n }\n flush();\n return out;\n}\n\n/** Pick the JSON-RPC envelope matching `id`, or the first one if none matches. */\nfunction pickJsonRpcResult(text: string, id: number): JsonRpcResult | undefined {\n const results = extractJsonRpcResults(text);\n return results.find((r) => r.id === id) ?? results[0];\n}\n\nfunction assertMatchingJsonRpcResult(\n data: unknown,\n expectedId: number,\n method: string,\n): JsonRpcResult {\n if (!isJsonRpcResult(data)) {\n throw new Error('Invalid JSON-RPC response: not a JSON-RPC 2.0 envelope');\n }\n if (data.id !== undefined && data.id !== expectedId) {\n throw new Error(\n `Invalid JSON-RPC response: id mismatch for ${method} (expected ${expectedId}, got ${data.id})`,\n );\n }\n if (data.id === undefined && !method.startsWith('notifications/')) {\n throw new Error(`Invalid JSON-RPC response: missing id for ${method}`);\n }\n return data;\n}\n\n/**\n * SSE transport for MCP over HTTP.\n *\n * Uses native fetch API with ReadableStream to consume SSE events.\n * HTTP POST is used to send JSON-RPC requests.\n */\nexport class SSETransport {\n private state: ConnectionState = 'idle';\n private url: string;\n private headers: Record<string, string>;\n private timeout: number;\n private requestTimeout: number;\n /** Per-request TLS agent — created once from HttpTransportOptions.tls */\n private tlsAgent?: https.Agent | undefined;\n private nextId = 1;\n private tools: MCPTool[] = [];\n private abortController?: AbortController | undefined;\n private reader?: globalThis.ReadableStreamDefaultReader<string> | undefined;\n private readerDone = false;\n private disconnectHandlers: Array<() => void> = [];\n private readLoopAbort?: AbortController | undefined;\n private readonly toolsChangedListeners = new Set<(tools: MCPTool[]) => void>();\n\n constructor(opts: HttpTransportOptions) {\n validateTransportUrl(opts.url);\n this.url = opts.url;\n this.headers = { ...opts.headers };\n this.timeout = opts.startupTimeoutMs ?? 10_000;\n this.requestTimeout = opts.requestTimeoutMs ?? 60_000;\n if (opts.tls) {\n if (opts.tls.rejectUnauthorized === false) {\n if (!isTlsUnsafeAllowed()) {\n throw new Error(\n `[mcp:SSETransport] TLS verification disabled — set WRONGSTACK_UNSAFE_MCP_TLS=1 ` +\n `or CI=true to allow. Rejecting insecure configuration for ${this.url}.`,\n );\n }\n console.error(\n `[mcp:SSETransport] ⚠️ TLS verification DISABLED for ${this.url}. ` +\n `Network attacks are possible — only use on localhost.`,\n );\n }\n this.tlsAgent = new https.Agent({\n ca: opts.tls.ca,\n rejectUnauthorized: opts.tls.rejectUnauthorized,\n });\n }\n }\n\n getState(): ConnectionState {\n return this.state;\n }\n\n listTools(): MCPTool[] {\n return [...this.tools];\n }\n\n onDisconnect(cb: () => void): () => void {\n this.disconnectHandlers.push(cb);\n return () => {\n const idx = this.disconnectHandlers.indexOf(cb);\n if (idx >= 0) this.disconnectHandlers.splice(idx, 1);\n };\n }\n\n onToolsChanged(cb: (tools: MCPTool[]) => void): () => void {\n this.toolsChangedListeners.add(cb);\n return () => {\n this.toolsChangedListeners.delete(cb);\n };\n }\n\n /** Refresh tool list when server sends notifications/tools/list_changed. */\n private async handleToolsListChanged(): Promise<void> {\n try {\n const res = await this.httpPost('tools/list', {});\n if (!res.error) {\n this.tools = normalizeMCPTools((res.result as { tools?: unknown | undefined } | undefined)?.tools);\n for (const cb of this.toolsChangedListeners) {\n try {\n cb([...this.tools]);\n } catch {\n /* ignore */\n }\n }\n }\n } catch {\n /* ignore transient failures */\n }\n }\n\n async connect(): Promise<void> {\n this.state = 'connecting';\n this.abortController = new AbortController();\n const signal = this.abortController.signal;\n const startupTimer = setTimeout(() => this.abortController?.abort(), this.timeout);\n\n try {\n const sseUrl = this.buildSSEUrl();\n const fetchOpts: RequestInit = {\n headers: this.headers,\n signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) fetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const response = await fetch(sseUrl, fetchOpts);\n\n if (!response.ok) {\n throw new Error(`SSE connect HTTP ${response.status}: ${response.statusText}`);\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body');\n }\n\n const textDecoder = new TextDecoder();\n const sseReader = new SSEReader();\n this.readLoopAbort = new AbortController();\n\n sseReader.onMessage((msg) => {\n // Future: if the spec evolves to send JSON-RPC responses over SSE\n // (rather than as HTTP POST replies), wire id-correlation here via\n // `_reservedPending`. Today httpPost owns response routing.\n // Server-initiated notifications (no id). Handle list_changed for L2-C.\n if (msg.method && !msg.id) {\n if (msg.method === 'notifications/tools/list_changed') {\n void this.handleToolsListChanged();\n }\n }\n });\n\n const reader = response.body.getReader();\n this.reader = {\n cancel: () => reader.cancel(),\n releaseLock: () => reader.releaseLock(),\n } as globalThis.ReadableStreamDefaultReader<string>;\n\n this.readSSEBody(reader, textDecoder, sseReader);\n\n const initRes = await this.httpPost('initialize', {\n protocolVersion: MCP_CONSTANTS.PROTOCOL_VERSION,\n capabilities: { tools: {} },\n clientInfo: MCP_CONSTANTS.CLIENT_INFO,\n });\n\n if (initRes.error) {\n throw new Error(`initialize failed: ${initRes.error.message}`);\n }\n\n try {\n await this.httpPost('notifications/initialized', {});\n } catch {\n // servers may not require it\n }\n\n const toolsRes = await this.httpPost('tools/list', {});\n if (toolsRes.error) {\n this.tools = [];\n } else {\n const result = toolsRes.result as { tools?: unknown | undefined } | undefined;\n this.tools = normalizeMCPTools(result?.tools);\n }\n\n this.state = 'connected';\n clearTimeout(startupTimer);\n } catch (err) {\n clearTimeout(startupTimer);\n this.state = 'failed';\n this.abortController.abort();\n throw err;\n }\n }\n\n private async readSSEBody(\n reader: globalThis.ReadableStreamDefaultReader<Uint8Array>,\n decoder: InstanceType<typeof TextDecoder>,\n sseReader: SSEReader,\n ): Promise<void> {\n try {\n while (!this.readerDone) {\n const { done, value } = await reader.read();\n if (done) break;\n const chunk = decoder.decode(value, { stream: true });\n sseReader.feed(chunk);\n }\n } catch {\n // SSE read error — connection lost. Transition to disconnected so\n // callTool and health checks see the correct state, then notify\n // disconnect handlers so the registry can schedule a reconnect.\n if (this.state !== 'disconnected' && this.state !== 'failed') {\n this.state = 'disconnected';\n for (const cb of this.disconnectHandlers) {\n try {\n cb();\n } catch {\n /* ignore */\n }\n }\n }\n }\n }\n\n private buildSSEUrl(): string {\n try {\n const url = new URL(this.url);\n // Cryptographically random session ID instead of timestamp —\n // prevents an attacker on the same LAN from guessing the session\n // param and reconnecting to the SSE stream.\n url.searchParams.set('session', randomBytes(16).toString('hex'));\n return url.toString();\n } catch {\n return this.url;\n }\n }\n\n private async httpPost(method: string, params: unknown): Promise<JsonRpcResult> {\n const id = this.nextId++;\n const body = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n\n const timeoutSignal = createTimeoutSignal(this.abortController?.signal, this.requestTimeout);\n const fetchOpts: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...this.headers,\n },\n body,\n signal: timeoutSignal.signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) fetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const res = await fetch(this.url, fetchOpts);\n\n try {\n if (!res.ok) {\n // Cap the body — a misbehaving server could return megabytes of\n // HTML and that's not useful in an error message anyway.\n const body = await res.text();\n const cap = MCP_CONSTANTS.REQUEST_LOG_CAP;\n const snippet =\n body.length > cap ? `${body.slice(0, cap)}… [${body.length} bytes total]` : body;\n throw new Error(`HTTP ${res.status}: ${snippet}`);\n }\n\n let data: unknown;\n try {\n data = await res.json();\n } catch (err) {\n throw new Error(\n `Invalid JSON-RPC response: ${err instanceof Error ? err.message : 'parse failed'}`,\n { cause: err },\n );\n }\n return assertMatchingJsonRpcResult(data, id, method);\n } finally {\n timeoutSignal.dispose();\n }\n }\n\n async callTool(name: string, input: unknown): Promise<ToolCallResult> {\n if (this.state !== 'connected') {\n throw new Error(`SSE transport not connected (state=${this.state})`);\n }\n const res = await this.httpPost('tools/call', { name, arguments: input });\n if (res.error) {\n return { content: res.error.message, isError: true };\n }\n const result = res.result as { content?: unknown | undefined; isError?: boolean | undefined } | undefined;\n return {\n content: result?.content ?? '',\n isError: Boolean(result?.isError),\n };\n }\n\n /** Generic JSON-RPC request — used by MCPClient.request() for SSE transports. */\n async request(method: string, params: unknown, timeoutMs?: number): Promise<JsonRpcResponse> {\n const id = this.nextId++;\n const body = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n\n const timeoutSignal = createTimeoutSignal(\n this.abortController?.signal,\n timeoutMs ?? this.requestTimeout,\n );\n const fetchOpts: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...this.headers,\n },\n body,\n signal: timeoutSignal.signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) fetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const res = await fetch(this.url, fetchOpts);\n\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n }\n\n let data: unknown;\n try {\n data = await res.json();\n } catch (err) {\n throw new Error(\n `Invalid JSON-RPC response: ${err instanceof Error ? err.message : 'parse failed'}`,\n { cause: err },\n );\n }\n const result = assertMatchingJsonRpcResult(data, id, method);\n timeoutSignal.dispose();\n return { jsonrpc: '2.0', id, result: result.result, error: result.error };\n }\n\n async close(): Promise<void> {\n // Idempotent — safe to call multiple times.\n if (this.state === 'disconnected') return;\n this.readerDone = true;\n this.readLoopAbort?.abort();\n try {\n this.reader?.cancel();\n } catch {\n /* ignore */\n }\n try {\n this.reader?.releaseLock();\n } catch {\n /* ignore */\n }\n this.abortController?.abort();\n this.disconnectHandlers = [];\n this.state = 'disconnected';\n }\n}\n\n/**\n * Streamable HTTP transport for MCP.\n *\n * Uses session-based HTTP with NDJSON responses.\n */\nexport class StreamableHTTPTransport {\n private state: ConnectionState = 'idle';\n private url: string;\n private headers: Record<string, string>;\n private timeout: number;\n private requestTimeout: number;\n /** Per-request TLS agent — created once from HttpTransportOptions.tls */\n private tlsAgent?: https.Agent | undefined;\n private nextId = 1;\n private tools: MCPTool[] = [];\n private abortController?: AbortController | undefined;\n private sessionId?: string | undefined;\n private disconnectHandlers: Array<() => void> = [];\n private readonly toolsChangedListeners = new Set<(tools: MCPTool[]) => void>();\n\n constructor(opts: HttpTransportOptions) {\n validateTransportUrl(opts.url);\n this.url = opts.url;\n this.headers = { ...opts.headers };\n this.timeout = opts.startupTimeoutMs ?? 10_000;\n this.requestTimeout = opts.requestTimeoutMs ?? 60_000;\n if (opts.tls) {\n if (opts.tls.rejectUnauthorized === false) {\n if (!isTlsUnsafeAllowed()) {\n throw new Error(\n `[mcp:StreamableHTTP] TLS verification disabled — set WRONGSTACK_UNSAFE_MCP_TLS=1 ` +\n `or CI=true to allow. Rejecting insecure configuration for ${this.url}.`,\n );\n }\n console.error(\n `[mcp:StreamableHTTP] ⚠️ TLS verification DISABLED for ${this.url}. ` +\n `Network attacks are possible — only use on localhost.`,\n );\n }\n this.tlsAgent = new https.Agent({\n ca: opts.tls.ca,\n rejectUnauthorized: opts.tls.rejectUnauthorized,\n });\n }\n }\n\n getState(): ConnectionState {\n return this.state;\n }\n\n listTools(): MCPTool[] {\n return [...this.tools];\n }\n\n onDisconnect(cb: () => void): () => void {\n this.disconnectHandlers.push(cb);\n return () => {\n const idx = this.disconnectHandlers.indexOf(cb);\n if (idx >= 0) this.disconnectHandlers.splice(idx, 1);\n };\n }\n\n onToolsChanged(cb: (tools: MCPTool[]) => void): () => void {\n this.toolsChangedListeners.add(cb);\n return () => {\n this.toolsChangedListeners.delete(cb);\n };\n }\n\n async connect(): Promise<void> {\n this.state = 'connecting';\n this.abortController = new AbortController();\n const signal = this.abortController.signal;\n const startupTimer = setTimeout(() => this.abortController?.abort(), this.timeout);\n\n try {\n const initFetchOpts: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n ...this.headers,\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: this.nextId++,\n method: 'initialize',\n params: {\n protocolVersion: MCP_CONSTANTS.PROTOCOL_VERSION,\n capabilities: { tools: {} },\n clientInfo: MCP_CONSTANTS.CLIENT_INFO,\n },\n }),\n signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) initFetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const initRes = await fetch(this.url, initFetchOpts);\n\n if (!initRes.ok) {\n throw new Error(`initialize HTTP ${initRes.status}: ${initRes.statusText}`);\n }\n\n const contentType = initRes.headers.get('content-type') ?? '';\n let data: JsonRpcResult | undefined;\n\n if (contentType.includes('application/json')) {\n const parsed = await initRes.json();\n if (isJsonRpcResult(parsed)) data = parsed;\n } else {\n // text/event-stream or NDJSON — handle SSE `data:` framing.\n data = extractJsonRpcResults(await initRes.text())[0];\n }\n\n if (!data) {\n throw new Error('Could not parse initialize response');\n }\n data = assertMatchingJsonRpcResult(data, this.nextId - 1, 'initialize');\n\n if (data.error) {\n throw new Error(`initialize failed: ${data.error.message}`);\n }\n\n // MCP Streamable HTTP spec: the server assigns a session via the\n // `Mcp-Session-Id` response header, which the client must echo on every\n // subsequent request. (Header lookups are case-insensitive.)\n this.sessionId = initRes.headers.get('mcp-session-id') ?? undefined;\n await this.postRaw('notifications/initialized', {});\n\n const toolsRes = await this.postRaw('tools/list', {});\n if (toolsRes.error) {\n this.tools = [];\n } else {\n const result = toolsRes.result as { tools?: unknown | undefined } | undefined;\n this.tools = normalizeMCPTools(result?.tools);\n }\n\n this.state = 'connected';\n clearTimeout(startupTimer);\n } catch (err) {\n clearTimeout(startupTimer);\n this.state = 'failed';\n this.abortController.abort();\n throw err;\n }\n }\n\n private async postRaw(method: string, params: unknown): Promise<JsonRpcResult> {\n const id = this.nextId++;\n const body = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n\n const timeoutSignal = createTimeoutSignal(this.abortController?.signal, this.requestTimeout);\n const fetchOpts: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n ...(this.sessionId ? { 'Mcp-Session-Id': this.sessionId } : {}),\n ...this.headers,\n },\n body,\n signal: timeoutSignal.signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) fetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const res = await fetch(this.url, fetchOpts);\n\n try {\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n }\n\n // Notifications get no JSON-RPC reply (the server returns 202 / empty body).\n if (method.startsWith('notifications/')) {\n await res.text().catch(() => undefined);\n return { jsonrpc: '2.0' };\n }\n\n const match = pickJsonRpcResult(await res.text(), id);\n if (match) {\n return assertMatchingJsonRpcResult(match, id, method);\n }\n throw new Error('Could not parse response as JSON-RPC');\n } finally {\n timeoutSignal.dispose();\n }\n }\n\n /** Generic JSON-RPC request — used by MCPClient.request() for SSE/streamable-http transports. */\n async request(method: string, params: unknown, timeoutMs?: number): Promise<JsonRpcResponse> {\n const id = this.nextId++;\n const body = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n\n const timeoutSignal = createTimeoutSignal(\n this.abortController?.signal,\n timeoutMs ?? this.requestTimeout,\n );\n const fetchOpts: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n ...(this.sessionId ? { 'Mcp-Session-Id': this.sessionId } : {}),\n ...this.headers,\n },\n body,\n signal: timeoutSignal.signal,\n };\n // @ts-expect-error — https.Agent is compatible at runtime; type mismatch is from undici@7 bundling types vs @types/node transitively pulling undici-types@6\n if (this.tlsAgent) fetchOpts.dispatcher = this.tlsAgent as unknown as Dispatcher;\n const res = await fetch(this.url, fetchOpts);\n\n try {\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n }\n\n if (method.startsWith('notifications/')) {\n await res.text().catch(() => undefined);\n return { jsonrpc: '2.0', id };\n }\n\n const parsed = pickJsonRpcResult(await res.text(), id);\n if (parsed) {\n // Convert JsonRpcResult to JsonRpcResponse\n return {\n jsonrpc: '2.0',\n id,\n result: parsed.result,\n error: parsed.error,\n };\n }\n throw new Error('Could not parse response as JSON-RPC');\n } finally {\n timeoutSignal.dispose();\n }\n }\n\n async callTool(name: string, input: unknown): Promise<ToolCallResult> {\n if (this.state !== 'connected') {\n throw new Error(`streamable-http transport not connected (state=${this.state})`);\n }\n const res = await this.postRaw('tools/call', { name, arguments: input });\n if (res.error) {\n return { content: res.error.message, isError: true };\n }\n const result = res.result as { content?: unknown | undefined; isError?: boolean | undefined } | undefined;\n return {\n content: result?.content ?? '',\n isError: Boolean(result?.isError),\n };\n }\n\n async close(): Promise<void> {\n if (this.state === 'disconnected') return;\n this.state = 'disconnected';\n this.abortController?.abort();\n // Intentionally do NOT fire disconnect handlers — those trigger\n // reconnection in the registry, which would fight an explicit close().\n this.disconnectHandlers = [];\n }\n}\n\nfunction createTimeoutSignal(\n parent: AbortSignal | undefined,\n timeoutMs: number,\n): { signal: AbortSignal; dispose: () => void } {\n const ctrl = new AbortController();\n const onAbort = () => ctrl.abort(parent?.reason);\n if (parent?.aborted) {\n ctrl.abort(parent.reason);\n } else {\n parent?.addEventListener('abort', onAbort, { once: true });\n }\n const timer = setTimeout(\n () => ctrl.abort(new Error(`MCP HTTP request timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n return {\n signal: ctrl.signal,\n dispose: () => {\n clearTimeout(timer);\n parent?.removeEventListener('abort', onAbort);\n },\n };\n}\n","import { type ChildProcess, spawn } from 'node:child_process';\nimport { buildChildEnv } from '@wrongstack/core';\nimport { MCP_CONSTANTS } from './constants.js';\nimport { normalizeMCPTools } from './tool-schema.js';\nimport { type HttpTransportOptions, SSETransport, StreamableHTTPTransport } from './transport.js';\n\nexport type Transport = 'stdio' | 'sse' | 'streamable-http';\n\nexport interface MCPClientOptions {\n name: string;\n transport: Transport;\n command?: string | undefined;\n args?: string[] | undefined;\n env?: Record<string, string> | undefined;\n url?: string | undefined;\n headers?: Record<string, string> | undefined;\n startupTimeoutMs?: number | undefined;\n requestTimeoutMs?: number | undefined;\n}\n\nexport type ConnectionState =\n | 'idle'\n | 'connecting'\n | 'connected'\n | 'disconnected'\n | 'reconnecting'\n | 'failed';\n\nexport interface MCPTool {\n name: string;\n description?: string | undefined;\n inputSchema: Record<string, unknown>;\n}\n\nexport interface ToolCallResult {\n content: unknown;\n isError: boolean;\n}\n\ninterface JsonRpcRequest {\n jsonrpc: '2.0';\n id: number;\n method: string;\n params?: unknown | undefined;\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: '2.0';\n id: number;\n result?: unknown | undefined;\n error?: { code: number | undefined; message: string; data?: unknown | undefined } | undefined;\n}\n\ntype ExitListener = (name: string, code: number | null, signal: string | null) => void;\n/**\n * Fired when the server sends `notifications/tools/list_changed`. The\n * client refreshes its cached tool list before invoking listeners, so\n * subscribers can call `listTools()` for the fresh set.\n */\ntype ToolsChangedListener = (name: string, tools: MCPTool[]) => void;\n\n/**\n * Lightweight MCP client supporting three transport types:\n * - stdio: spawns a child process and communicates over pipes\n * - sse: connects to an HTTP SSE endpoint for server events, POST for requests\n * - streamable-http: session-based HTTP transport with NDJSON responses\n */\nexport class MCPClient {\n private state: ConnectionState = 'idle';\n private child?: ChildProcess | undefined;\n private nextId = 1;\n /**\n * In-flight JSON-RPC calls keyed by id. `resolve` settles the call; `reject`\n * is invoked from {@link failPending} when the underlying transport dies\n * (stdio child exit, `close()`) so callers don't hang forever.\n */\n private readonly pending = new Map<\n number,\n { resolve: (res: JsonRpcResponse) => void; reject: (err: Error) => void; timer: NodeJS.Timeout }\n >();\n private rxBuffer = '';\n private _tools: MCPTool[] = [];\n /** Cached tool list — survives reconnects so the registry can re-register without re-discovering. */\n private _toolsCache?: MCPTool[] | undefined;\n private _drainPending = false;\n private _lastNotifySkipped = false;\n // HTTP transports\n private sseTransport?: SSETransport | undefined;\n private httpTransport?: StreamableHTTPTransport | undefined;\n /** Notified when the stdio child process exits so the registry can attempt reconnect. */\n private readonly exitListeners = new Set<ExitListener>();\n /** Notified when the server announces a tools/list_changed notification. */\n private readonly toolsChangedListeners = new Set<ToolsChangedListener>();\n /** Notified when an HTTP transport (SSE or streamable-http) disconnects. */\n private readonly disconnectListeners = new Set<() => void>();\n\n constructor(public readonly opts: MCPClientOptions) {}\n\n getState(): ConnectionState {\n return this.state;\n }\n\n listTools(): MCPTool[] {\n return this._tools.length > 0\n ? [...this._tools]\n : this._toolsCache\n ? [...this._toolsCache]\n : [];\n }\n\n /** Returns true if a prior notify() call was skipped due to backpressure. */\n hadNotifySkipped(): boolean {\n return this._lastNotifySkipped;\n }\n\n /**\n * Register a listener for child-process exit events.\n * The registry uses this to trigger reconnection.\n */\n addExitListener(listener: ExitListener): void {\n this.exitListeners.add(listener);\n }\n\n removeExitListener(listener: ExitListener): void {\n this.exitListeners.delete(listener);\n }\n\n /**\n * Register a listener for transport disconnect events (SSE / streamable-http).\n * Used by the registry to trigger reconnection for HTTP-based servers.\n */\n addDisconnectListener(listener: () => void): void {\n this.disconnectListeners.add(listener);\n }\n\n removeDisconnectListener(listener: () => void): void {\n this.disconnectListeners.delete(listener);\n }\n\n async connect(): Promise<void> {\n this.state = 'connecting';\n\n if (this.opts.transport === 'stdio') {\n await this.connectStdio();\n } else if (this.opts.transport === 'sse') {\n await this.connectSSE();\n } else if (this.opts.transport === 'streamable-http') {\n await this.connectStreamableHTTP();\n } else {\n this.state = 'failed';\n throw new Error(`Unknown transport \"${this.opts.transport}\"`);\n }\n }\n\n private async connectStdio(): Promise<void> {\n if (!this.opts.command) {\n this.state = 'failed';\n throw new Error('MCP stdio transport requires \"command\"');\n }\n\n // Defense-in-depth: clear any rx state from a previous connect attempt\n // on this instance. The registry normally creates a fresh client per\n // (re)connect cycle, but a leftover rxBuffer from a half-initialized\n // attempt would corrupt JSON-RPC parsing on the new stream.\n this.rxBuffer = '';\n\n // On Windows, MCP servers are usually launched via `npx`/`npm`/`uvx`,\n // which resolve to `.cmd` shims. Since the CVE-2024-27980 fix Node refuses\n // to spawn `.cmd`/`.bat` without a shell (raw spawn throws ENOENT), so the\n // whole npx-based preset catalog is unusable without a shell. We pass the\n // full command line as a single string (with each token cmd.exe-quoted) and\n // `shell: true` — an empty args array avoids the DEP0190 warning that\n // `shell:true` + an args array triggers. Server command+args come from\n // config (admin-controlled), not the model, so shell use is not an\n // injection vector here.\n const isWin = process.platform === 'win32';\n const rawArgs = this.opts.args ?? [];\n const spawnEnv = buildChildEnv({ extra: this.opts.env });\n const stdio: ['pipe', 'pipe', 'pipe'] = ['pipe', 'pipe', 'pipe'];\n const child = isWin\n ? spawn([this.opts.command, ...rawArgs].map(quoteWindowsArg).join(' '), {\n env: spawnEnv,\n stdio,\n shell: true,\n // Without this every MCP server spawned from a console-less host\n // (WebUI server, scheduled runs) opens a visible console window.\n windowsHide: true,\n })\n : spawn(this.opts.command, rawArgs, { env: spawnEnv, stdio, windowsHide: true });\n this.child = child;\n\n child.stdout?.on('data', (chunk: Buffer) => this.onData(chunk.toString()));\n child.stderr?.on('data', () => {\n // intentionally discard stderr noise from server\n });\n child.on('exit', (code, signal) => {\n this.state = 'disconnected';\n // Reject any in-flight JSON-RPC requests — without this, callers\n // (e.g. callTool during a tool invocation) await forever on a child\n // that has already gone away.\n this.failPending(\n `MCP \"${this.opts.name}\" child exited (code=${code ?? 'null'} signal=${signal ?? 'null'})`,\n );\n for (const listener of this.exitListeners) {\n try {\n listener(this.opts.name, code, signal);\n } catch {\n /* ignore */\n }\n }\n });\n child.on('error', () => {\n this.state = 'failed';\n });\n\n const initialize = await this.request(\n 'initialize',\n {\n protocolVersion: MCP_CONSTANTS.PROTOCOL_VERSION,\n capabilities: { tools: {} },\n clientInfo: MCP_CONSTANTS.CLIENT_INFO,\n },\n this.opts.startupTimeoutMs ?? 10_000,\n );\n if (initialize.error) {\n this.state = 'failed';\n throw new Error(`MCP initialize failed: ${initialize.error.message}`);\n }\n try {\n await this.notify('notifications/initialized', {});\n } catch (err) {\n console.warn(\n '[MCP] notify(\"notifications/initialized\") failed for \"' +\n this.opts.name +\n '\": ' +\n (err instanceof Error ? err.message : String(err)),\n );\n }\n const toolsRes = await this.request('tools/list', {});\n if (toolsRes.error) {\n this._tools = [];\n } else {\n const result = toolsRes.result as { tools?: MCPTool[] | undefined } | undefined;\n this._tools = normalizeMCPTools(result?.tools);\n }\n // Cache tools so reconnect can re-register without re-discovering\n this._toolsCache = this._tools;\n this.state = 'connected';\n }\n\n private async connectSSE(): Promise<void> {\n if (!this.opts.url) {\n this.state = 'failed';\n throw new Error('MCP SSE transport requires \"url\"');\n }\n const httpOpts: HttpTransportOptions = {\n name: this.opts.name,\n url: this.opts.url,\n headers: this.opts.headers,\n startupTimeoutMs: this.opts.startupTimeoutMs,\n requestTimeoutMs: this.opts.requestTimeoutMs,\n };\n this.sseTransport = new SSETransport(httpOpts);\n this.sseTransport.onDisconnect(() => {\n this.state = 'disconnected';\n for (const cb of this.disconnectListeners) {\n try {\n cb();\n } catch {\n /* ignore */\n }\n }\n });\n this.sseTransport.onToolsChanged((tools) => {\n this._tools = tools;\n // Keep the reconnect-recovery cache in sync. Without this, an empty\n // tools update would leave `_toolsCache` pointing at the previous\n // non-empty list, and `listTools()` would serve the stale cache\n // (since it falls back to the cache when `_tools` is empty).\n this._toolsCache = tools;\n for (const cb of this.toolsChangedListeners) {\n try {\n cb(this.opts.name, tools);\n } catch {\n /* ignore */\n }\n }\n });\n try {\n await this.sseTransport.connect();\n } catch (err) {\n this.state = 'failed';\n throw err;\n }\n this._tools = this.sseTransport.listTools();\n this._toolsCache = this._tools;\n this.state = 'connected';\n }\n\n private async connectStreamableHTTP(): Promise<void> {\n if (!this.opts.url) {\n this.state = 'failed';\n throw new Error('MCP streamable-http transport requires \"url\"');\n }\n const httpOpts: HttpTransportOptions = {\n name: this.opts.name,\n url: this.opts.url,\n headers: this.opts.headers,\n startupTimeoutMs: this.opts.startupTimeoutMs,\n requestTimeoutMs: this.opts.requestTimeoutMs,\n };\n this.httpTransport = new StreamableHTTPTransport(httpOpts);\n this.httpTransport.onDisconnect(() => {\n this.state = 'disconnected';\n for (const cb of this.disconnectListeners) {\n try {\n cb();\n } catch {\n /* ignore */\n }\n }\n });\n this.httpTransport.onToolsChanged((tools) => {\n this._tools = tools;\n // Same cache-sync reasoning as the SSE branch above — keep\n // `_toolsCache` in lockstep with `_tools` on every transport\n // update so the empty-list fallback in `listTools()` never serves\n // stale data.\n this._toolsCache = tools;\n for (const cb of this.toolsChangedListeners) {\n try {\n cb(this.opts.name, tools);\n } catch {\n /* ignore */\n }\n }\n });\n try {\n await this.httpTransport.connect();\n } catch (err) {\n this.state = 'failed';\n throw err;\n }\n this._tools = this.httpTransport.listTools();\n this._toolsCache = this._tools;\n this.state = 'connected';\n }\n\n async callTool(name: string, input: unknown): Promise<ToolCallResult> {\n if (this.state !== 'connected') {\n throw new Error(`MCP client \"${this.opts.name}\" not connected (state=${this.state})`);\n }\n // Delegate to the active transport\n if (this.sseTransport) {\n return this.sseTransport.callTool(name, input);\n }\n if (this.httpTransport) {\n return this.httpTransport.callTool(name, input);\n }\n // stdio\n const res = await this.request('tools/call', { name, arguments: input });\n if (res.error) {\n return { content: res.error.message, isError: true };\n }\n const result = res.result as { content?: unknown | undefined; isError?: boolean | undefined } | undefined;\n return {\n content: result?.content ?? '',\n isError: Boolean(result?.isError),\n };\n }\n\n async close(): Promise<void> {\n if (this.child) {\n const child = this.child;\n // Always register the listener first. Checking exitCode/signalCode\n // before registering creates a TOCTOU race: the child can exit between\n // the check and child.once('exit', ...), so the listener never fires\n // and exitPromise hangs forever. The double-check below handles the\n // case where the child already exited before we registered.\n const exitPromise = new Promise<void>((resolve) => {\n child.once('exit', () => resolve());\n if (child.exitCode !== null || child.signalCode !== null) resolve();\n });\n try {\n // Initial SIGTERM lets the server flush logs / clean up sockets.\n child.kill();\n } catch {\n // ignore\n }\n // Wait briefly for graceful exit, then escalate to SIGKILL. A stuck\n // server that ignores SIGTERM would otherwise stay alive after\n // close() returns — orphan child processes accumulate over restarts.\n const GRACEFUL_MS = 800;\n const FORCE_TIMEOUT_MS = 1200;\n const gracefulRace = await Promise.race([\n exitPromise.then(() => 'exited' as const),\n new Promise<'timeout'>((resolve) => setTimeout(() => resolve('timeout'), GRACEFUL_MS)),\n ]);\n if (gracefulRace === 'timeout') {\n try {\n // SIGKILL is ignored by `kill('SIGKILL')` on Windows in older\n // Node, but `child.kill('SIGKILL')` maps to TerminateProcess\n // under the hood for spawned children since Node 18 — safe to\n // call cross-platform.\n child.kill('SIGKILL');\n } catch {\n // ignore\n }\n await Promise.race([\n exitPromise,\n new Promise<void>((resolve) => setTimeout(resolve, FORCE_TIMEOUT_MS)),\n ]);\n }\n }\n // Reject pending requests BEFORE closing transports. This matters for\n // in-flight HTTP requests: they are not yet in `this.pending` (waiting\n // for a response from the network), so failPending() must run while the\n // transport is still alive. After this, the transport close is safe to\n // call even on a never-started or HTTP-only client — the exit handler\n // may have already run failPending, but calling it again with the same\n // pending set is a no-op (failPending guards on `this.pending.size`).\n this.failPending(`MCP \"${this.opts.name}\" closed`);\n this.sseTransport?.close();\n this.httpTransport?.close();\n this.state = 'disconnected';\n }\n\n private request(\n method: string,\n params: unknown,\n timeoutMs = this.opts.requestTimeoutMs ?? 60_000,\n ): Promise<JsonRpcResponse> {\n // For HTTP transports, delegate to the transport's request method.\n // SSE and streamable-http both use postRaw which handles the full\n // round-trip including timeout signal.\n if (this.sseTransport) return this.sseTransport.request(method, params, timeoutMs);\n if (this.httpTransport) return this.httpTransport.request(method, params, timeoutMs);\n\n // stdio path\n const id = this.nextId++;\n const req: JsonRpcRequest = { jsonrpc: '2.0', id, method, params };\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(\n new Error(`MCP \"${this.opts.name}\" request \"${method}\" timed out after ${timeoutMs}ms`),\n );\n }, timeoutMs);\n this.pending.set(id, {\n resolve: (res) => {\n clearTimeout(timer);\n resolve(res);\n },\n reject: (err) => {\n clearTimeout(timer);\n reject(err);\n },\n timer,\n });\n try {\n this.child?.stdin?.write(JSON.stringify(req) + '\\n');\n } catch (err) {\n const pending = this.pending.get(id);\n this.pending.delete(id);\n if (pending) clearTimeout(pending.timer);\n reject(err);\n }\n });\n }\n\n /**\n * Reject every in-flight {@link request} call. Used when the underlying\n * transport dies — without this, callers awaiting `tools/call` over a\n * killed stdio child or a closed transport would hang indefinitely.\n */\n private failPending(reason: string): void {\n if (this.pending.size === 0) return;\n const err = new Error(reason);\n for (const [, entry] of this.pending) {\n try {\n clearTimeout(entry.timer);\n entry.reject(err);\n } catch {\n /* ignore */\n }\n }\n this.pending.clear();\n }\n\n private async notify(method: string, params: unknown): Promise<void> {\n const req = { jsonrpc: '2.0', method, params };\n const encoded = JSON.stringify(req) + '\\n';\n try {\n const ok = this.child?.stdin?.write(encoded);\n if (!ok) {\n // Only the first caller waits for drain; others just warn and return.\n // This avoids a race where two concurrent notify() calls each start\n // their own drain-wait, then both resolve and the buffer is still full.\n if (this._drainPending) {\n this._lastNotifySkipped = true;\n console.warn(\n `[MCP] notify(\"${method}\") skipped: stdin buffer backpressure (already waiting for drain)`,\n );\n return;\n }\n this._drainPending = true;\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.child?.stdin?.removeListener?.('drain', onDrain);\n this.child?.stdin?.removeListener?.('error', onError);\n this._drainPending = false;\n reject(new Error(`MCP notify(\"${method}\") drain timeout`));\n }, 500);\n const onDrain = () => {\n clearTimeout(timeout);\n this.child?.stdin?.removeListener?.('drain', onDrain);\n this.child?.stdin?.removeListener?.('error', onError);\n this._drainPending = false;\n resolve();\n };\n const onError = (err: Error) => {\n clearTimeout(timeout);\n this.child?.stdin?.removeListener?.('drain', onDrain);\n this.child?.stdin?.removeListener?.('error', onError);\n this._drainPending = false;\n reject(err);\n };\n this.child?.stdin?.once('drain', onDrain);\n this.child?.stdin?.once('error', onError);\n });\n }\n } catch (err) {\n throw new Error(\n `[MCP] notify(\"${method}\") failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n private onData(s: string): void {\n this.rxBuffer += s;\n let idx = this.rxBuffer.indexOf('\\n');\n while (idx !== -1) {\n const line = this.rxBuffer.slice(0, idx).trim();\n this.rxBuffer = this.rxBuffer.slice(idx + 1);\n if (line) this.onLine(line);\n idx = this.rxBuffer.indexOf('\\n');\n }\n }\n\n private onLine(line: string): void {\n let msg: JsonRpcResponse & { method?: string | undefined; params?: unknown | undefined };\n try {\n msg = JSON.parse(line) as JsonRpcResponse & { method?: string | undefined; params?: unknown | undefined };\n } catch {\n return;\n }\n if (msg.id !== undefined && this.pending.has(msg.id)) {\n const entry = this.pending.get(msg.id);\n this.pending.delete(msg.id);\n entry?.resolve(msg);\n return;\n }\n // Notifications have a `method` but no `id`. The MCP spec defines\n // `notifications/tools/list_changed` for tool-set invalidation —\n // refresh the cache asynchronously and fire listeners so the\n // registry can re-register the wrapped tools.\n if (typeof msg.method === 'string' && msg.method === 'notifications/tools/list_changed') {\n void this.handleToolsListChanged();\n }\n }\n\n /**\n * L2-C: refresh the cached tool list when the server announces a\n * `tools/list_changed`. Listeners (the registry) re-wrap and\n * re-register. Failures are swallowed — a stale cache is preferable\n * to a hard crash on a transient notification glitch.\n */\n private async handleToolsListChanged(): Promise<void> {\n try {\n const toolsRes = await this.request('tools/list', {});\n const tools = normalizeMCPTools((toolsRes.result as { tools?: unknown | undefined } | undefined)?.tools);\n this._tools = tools;\n this._toolsCache = tools;\n for (const listener of this.toolsChangedListeners) {\n try {\n listener(this.opts.name, [...tools]);\n } catch {\n // listeners must be best-effort\n }\n }\n } catch {\n // ignore — keep the existing cache\n }\n }\n\n addToolsChangedListener(listener: ToolsChangedListener): void {\n this.toolsChangedListeners.add(listener);\n }\n\n removeToolsChangedListener(listener: ToolsChangedListener): void {\n this.toolsChangedListeners.delete(listener);\n }\n}\n\n/**\n * Quote a single argument for `cmd.exe` when spawning with `shell: true` on\n * Windows. Only args containing whitespace or quotes need wrapping; inside\n * double quotes cmd.exe escapes a literal `\"` as `\"\"`. Backslashes are literal\n * inside cmd quotes, so paths like `C:\\Program Files\\x` pass through unharmed.\n */\nexport function quoteWindowsArg(arg: string): string {\n if (!/[\\s\"]/.test(arg)) return arg;\n return `\"${arg.replace(/\"/g, '\"\"')}\"`;\n}\n","import type { Permission, Tool } from '@wrongstack/core';\nimport type { MCPClient, MCPTool } from './client.js';\n\n/**\n * Keywords that indicate a mutating operation.\n * Applied to both the tool name and its inputSchema property names.\n */\nconst MUTATING_RE = /create|update|delete|write|send|set|put|post|patch|remove|rename|move/i;\n\nfunction isMutatingTool(mcpTool: MCPTool): boolean {\n if (MUTATING_RE.test(mcpTool.name)) return true;\n // Check property names in the input schema for mutating intent.\n // e.g. { properties: { createTable: {...}, dropIndex: {...} } }\n const schema = mcpTool.inputSchema;\n if (schema && typeof schema === 'object') {\n const props = (schema as { properties?: Record<string, unknown> }).properties;\n if (props) {\n for (const key of Object.keys(props)) {\n if (MUTATING_RE.test(key)) return true;\n }\n }\n }\n return false;\n}\n\nexport function wrapMCPTool(\n serverName: string,\n mcpTool: MCPTool,\n client: MCPClient,\n permission: Permission = 'confirm',\n): Tool {\n const qualifiedName = `mcp__${serverName}__${mcpTool.name}`;\n return {\n name: qualifiedName,\n description: mcpTool.description ?? `${qualifiedName} (MCP tool)`,\n usageHint: `Tool provided by MCP server \"${serverName}\". ${mcpTool.description ?? ''}`,\n permission,\n mutating: isMutatingTool(mcpTool),\n inputSchema: mcpTool.inputSchema ?? { type: 'object', properties: {} },\n async execute(input, _ctx, _opts) {\n const res = await client.callTool(mcpTool.name, input);\n if (res.isError) {\n throw new Error(stringify(res.content));\n }\n return stringify(res.content);\n },\n };\n}\n\nfunction stringify(c: unknown): string {\n if (typeof c === 'string') return c;\n if (Array.isArray(c)) {\n return c\n .map((item) => {\n if (item && typeof item === 'object') {\n const t = (item as { type?: string | undefined; text?: string | undefined }).type;\n if (t === 'text') return (item as { text?: string | undefined }).text ?? '';\n return JSON.stringify(item);\n }\n return String(item);\n })\n .join('\\n');\n }\n if (c && typeof c === 'object') {\n if ('text' in (c as Record<string, unknown>)) {\n return String((c as Record<string, unknown>).text);\n }\n return JSON.stringify(c);\n }\n return String(c ?? '');\n}\n","import { expectDefined } from '@wrongstack/core';\nimport type { EventBus, Logger, MCPServerConfig, Tool, ToolRegistry } from '@wrongstack/core';\nimport { MCP_CONSTANTS } from './constants.js';\nimport { type ConnectionState, MCPClient } from './client.js';\nimport { wrapMCPTool } from './wrap-tool.js';\ninterface ServerSlot {\n cfg: MCPServerConfig;\n client?: MCPClient | undefined;\n state: ConnectionState;\n /** Tools currently registered in toolRegistry (empty in lazy mode). */\n toolNames: string[];\n /** Cached tools when lazyMode is active (not registered in toolRegistry). */\n lazyTools: Tool[];\n attempts: number;\n /** Set when a reconnect cycle is already running for this slot. */\n reconnectPending: boolean;\n /**\n * L2-B: number of full reconnect *cycles* (where one cycle = one\n * `attemptConnect` invocation, which itself can try multiple times\n * before giving up). After `MAX_RECONNECT_CYCLES`, the slot stays\n * `failed` until a manual `restart()` resets it.\n */\n reconnectCycles: number;\n /**\n * Slot-scoped, bound disconnect callback. Stored so the matching\n * `removeDisconnectListener` call can hand back the *same* reference —\n * a fresh arrow `() => onTransportDisconnect(slot.cfg.name)` would\n * not match the one we added and the set-based listener registry\n * would silently keep the old handler, causing duplicate reconnect\n * cycles after a few transport flaps.\n */\n onDisconnect?: (() => void) | undefined;\n}\n\nexport interface MCPRegistryOptions {\n toolRegistry: ToolRegistry;\n events: EventBus;\n log: Logger;\n /**\n * Lazy mode: when true, MCP server tools are NOT registered into the\n * tool registry on connect. They are cached internally and can be\n * activated on demand via `activateServer(name)`. This is used in\n * token-saving mode to avoid bloating the system prompt with 50-100+\n * MCP tool descriptions. The model uses `mcp_control({ action: \"activate\", server: \"...\" })`\n * to temporarily enable tools when needed.\n * Default: false.\n */\n lazyMode?: boolean | undefined;\n}\n\nexport class MCPRegistry {\n private readonly servers = new Map<string, ServerSlot>();\n private readonly toolRegistry: ToolRegistry;\n private readonly events: EventBus;\n private readonly log: Logger;\n private readonly lazyMode: boolean;\n\n constructor(opts: MCPRegistryOptions) {\n this.toolRegistry = opts.toolRegistry;\n this.events = opts.events;\n this.log = opts.log;\n this.lazyMode = opts.lazyMode ?? false;\n }\n\n async start(cfg: MCPServerConfig): Promise<void> {\n if (cfg.enabled === false) return;\n const slot: ServerSlot = {\n cfg,\n state: 'idle',\n toolNames: [],\n lazyTools: [],\n attempts: 0,\n reconnectPending: false,\n reconnectCycles: 0,\n };\n this.servers.set(cfg.name, slot);\n await this.attemptConnect(slot);\n }\n\n /**\n * Register all cached tools for a given server into the tool registry.\n * No-op if tools are already registered or the server is not connected.\n * The server connection stays alive — this only toggles tool visibility.\n */\n activateServer(name: string): void {\n const slot = this.servers.get(name);\n if (!slot || !slot.client) return;\n if (slot.toolNames.length > 0) return; // already active\n const cached = slot.lazyTools;\n if (cached.length === 0) return;\n for (const tool of cached) {\n try {\n this.toolRegistry.register(tool, `mcp:${name}`);\n slot.toolNames.push(tool.name);\n } catch (err) {\n this.log.warn(`MCP tool \"${tool.name}\" activate failed`, err);\n }\n }\n this.log.info(`MCP server \"${name}\" activated (${slot.toolNames.length} tools)`);\n this.events.emit('mcp.server.connected', { name, toolCount: slot.toolNames.length });\n }\n\n /**\n * Unregister all tools for a given server from the tool registry.\n * The server connection stays alive — this only toggles tool visibility.\n * Returns the number of tools that were deactivated.\n */\n deactivateServer(name: string): number {\n const slot = this.servers.get(name);\n if (!slot) return 0;\n const count = slot.toolNames.length;\n if (count === 0) return 0;\n for (const t of slot.toolNames) {\n try {\n this.toolRegistry.unregister(t);\n } catch {\n /* ignore */\n }\n }\n slot.toolNames = [];\n this.log.info(`MCP server \"${name}\" deactivated (${count} tools removed)`);\n this.events.emit('mcp.server.disconnected', { name, reason: 'deactivate' });\n return count;\n }\n\n /**\n * Check whether a server's tools are currently registered.\n */\n isActivated(name: string): boolean {\n const slot = this.servers.get(name);\n return slot ? slot.toolNames.length > 0 : false;\n }\n\n async stop(name: string): Promise<void> {\n const slot = this.servers.get(name);\n if (!slot) return;\n slot.reconnectPending = false;\n if (slot.client) {\n slot.client.removeExitListener(this.onChildExit);\n if (slot.onDisconnect) slot.client.removeDisconnectListener(slot.onDisconnect);\n slot.client.removeToolsChangedListener(this.onToolsChanged);\n await slot.client.close();\n slot.client = undefined;\n }\n slot.onDisconnect = undefined;\n for (const t of slot.toolNames) this.toolRegistry.unregister(t);\n slot.toolNames = [];\n slot.lazyTools = [];\n slot.state = 'disconnected';\n this.events.emit('mcp.server.disconnected', { name, reason: 'stop' });\n }\n\n async restart(name: string): Promise<void> {\n const slot = this.servers.get(name);\n if (!slot) throw new Error(`MCP server \"${name}\" not registered`);\n await this.stop(name);\n slot.attempts = 0;\n slot.reconnectCycles = 0; // user intent: start fresh\n await this.attemptConnect(slot);\n }\n\n list(): { name: string; state: ConnectionState; toolCount: number }[] {\n return Array.from(this.servers.values()).map((s) => ({\n name: s.cfg.name,\n state: s.state,\n toolCount: Math.max(s.toolNames.length, s.lazyTools.length),\n }));\n }\n\n /**\n * Catalog of every server ever registered with this registry — includes\n * servers that are stopped, failed, or not yet started.\n * Useful for the `mcp_control` tool to show all known servers without\n * triggering connections.\n */\n describe(): { name: string; state: ConnectionState; toolCount: number; enabled: boolean }[] {\n return Array.from(this.servers.values()).map((s) => ({\n name: s.cfg.name,\n state: s.state,\n toolCount: Math.max(s.toolNames.length, s.lazyTools.length),\n enabled: s.cfg.enabled !== false,\n }));\n }\n\n async stopAll(): Promise<void> {\n for (const name of Array.from(this.servers.keys())) {\n await this.stop(name);\n }\n }\n\n /**\n * Health check — returns 'ok' for connected servers, the current state otherwise.\n * For HTTP-based transports this could also ping the server.\n */\n health(): { name: string; alive: boolean; latencyMs?: number | undefined }[] {\n return Array.from(this.servers.values()).map((s) => ({\n name: s.cfg.name,\n alive: s.state === 'connected',\n }));\n }\n\n /**\n * L2-C: handle `notifications/tools/list_changed` from the server.\n * Unregister the previous wrapper set, then re-register the fresh\n * tool list. The client has already refreshed its cache before\n * dispatching — we just need to re-wrap and re-register.\n * In lazy mode, only update the internal cache without registering.\n */\n private readonly onToolsChanged = (name: string, _tools: { name: string }[]): void => {\n const slot = this.servers.get(name);\n if (!slot || !slot.client) return;\n // Unregister any previously registered tools\n for (const t of slot.toolNames) {\n try {\n this.toolRegistry.unregister(t);\n } catch {\n /* ignore */\n }\n }\n slot.toolNames = [];\n const allowed = slot.cfg.allowedTools;\n const wrapped = slot.client\n .listTools()\n .filter((t) => !allowed || allowed.includes(t.name))\n .map((t) => wrapMCPTool(slot.cfg.name, t, expectDefined(slot.client), slot.cfg.permission ?? 'confirm'));\n if (this.lazyMode) {\n // Lazy mode: cache tools without registering\n slot.lazyTools = wrapped;\n this.log.info(\n `MCP server \"${slot.cfg.name}\" tools refreshed in lazy mode (${wrapped.length} cached)`,\n );\n } else {\n // Normal mode: register tools\n for (const tool of wrapped) {\n try {\n this.toolRegistry.register(tool, `mcp:${slot.cfg.name}`);\n slot.toolNames.push(tool.name);\n } catch (err) {\n this.log.warn(`MCP tool \"${tool.name}\" not re-registered after list_changed`, err);\n }\n }\n }\n this.events.emit('mcp.server.connected', {\n name: slot.cfg.name,\n toolCount: slot.toolNames.length,\n });\n this.log.info(\n `MCP server \"${slot.cfg.name}\" tools refreshed (${slot.toolNames.length} active, ${wrapped.length} total)`,\n );\n };\n\n private readonly onChildExit = (\n name: string,\n code: number | null,\n _signal: string | null,\n ): void => {\n const slot = this.servers.get(name);\n if (!slot) return;\n for (const t of slot.toolNames) {\n try {\n this.toolRegistry.unregister(t);\n } catch {\n /* ignore */\n }\n }\n slot.toolNames = [];\n slot.lazyTools = [];\n slot.state = 'disconnected';\n this.events.emit('mcp.server.disconnected', { name, reason: `exit:${code ?? 'unknown'}` });\n this.scheduleReconnect(slot);\n };\n\n /** Handles SSE / streamable-http disconnect — same recovery as stdio child exit. */\n private readonly onTransportDisconnect = (name: string): void => {\n const slot = this.servers.get(name);\n if (!slot) return;\n for (const t of slot.toolNames) {\n try {\n this.toolRegistry.unregister(t);\n } catch {\n /* ignore */\n }\n }\n slot.toolNames = [];\n slot.lazyTools = [];\n slot.state = 'disconnected';\n this.events.emit('mcp.server.disconnected', { name, reason: 'http-disconnect' });\n this.scheduleReconnect(slot);\n };\n\n /**\n * L2-B: maximum number of reconnect cycles before staying `failed`.\n * One cycle = one full `attemptConnect` (which itself may try up to 3\n * times). Caps total reconnect storm at ~5 cycles, then the slot\n * needs an explicit `restart()` to re-engage.\n */\n private static readonly MAX_RECONNECT_CYCLES = MCP_CONSTANTS.RECONNECT.MAX_CYCLES;\n /** Base delay between cycles, in ms. Real delay adds jitter. */\n private static readonly BASE_RECONNECT_DELAY_MS = MCP_CONSTANTS.RECONNECT.BASE_DELAY_MS;\n /** Hard ceiling on the inter-cycle delay so the user doesn't wait minutes. */\n private static readonly MAX_RECONNECT_DELAY_MS = 30_000;\n\n private scheduleReconnect(slot: ServerSlot): void {\n if (slot.reconnectPending) return;\n if (slot.reconnectCycles >= MCPRegistry.MAX_RECONNECT_CYCLES) {\n slot.state = 'failed';\n this.log.error(\n `MCP server \"${slot.cfg.name}\" giving up after ${slot.reconnectCycles} reconnect cycles. Use \\`/mcp restart ${slot.cfg.name}\\` to retry.`,\n );\n this.events.emit('mcp.server.disconnected', {\n name: slot.cfg.name,\n reason: `reconnect-exhausted:${slot.reconnectCycles}`,\n });\n return;\n }\n slot.reconnectPending = true;\n // Exponential backoff with light jitter: 1s, 2s, 4s, 8s, 16s, capped\n // at 30s. The ±20% jitter avoids reconnect stampedes when many\n // servers crash together.\n const base = Math.min(\n MCPRegistry.BASE_RECONNECT_DELAY_MS * 2 ** slot.reconnectCycles,\n MCPRegistry.MAX_RECONNECT_DELAY_MS,\n );\n const jitter = base * MCP_CONSTANTS.RECONNECT.JITTER_FACTOR * (Math.random() * 2 - 1);\n const delay = Math.max(100, Math.round(base + jitter));\n setTimeout(() => this.attemptReconnect(slot), delay);\n }\n\n private async attemptReconnect(slot: ServerSlot): Promise<void> {\n slot.reconnectPending = false;\n slot.reconnectCycles++;\n await this.attemptConnect(slot);\n }\n\n private async attemptConnect(slot: ServerSlot): Promise<void> {\n const MAX_ATTEMPTS = MCP_CONSTANTS.RECONNECT.MAX_ATTEMPTS;\n let attempt = 0;\n while (attempt < MAX_ATTEMPTS) {\n attempt++;\n slot.state = attempt === 1 ? 'connecting' : 'reconnecting';\n slot.attempts = attempt;\n let client: MCPClient | undefined;\n let boundDisconnect: (() => void) | undefined;\n try {\n client = new MCPClient({\n name: slot.cfg.name,\n transport: slot.cfg.transport,\n command: slot.cfg.command,\n args: slot.cfg.args,\n env: slot.cfg.env,\n url: slot.cfg.url,\n headers: slot.cfg.headers,\n startupTimeoutMs: slot.cfg.startupTimeoutMs,\n requestTimeoutMs: slot.cfg.requestTimeoutMs,\n });\n if (slot.cfg.transport === 'stdio') {\n client.addExitListener(this.onChildExit);\n } else {\n // SSE / streamable-http — wire transport disconnect to registry reconnect.\n // Capture the bound function so we can hand the same reference to\n // removeDisconnectListener on cleanup paths.\n boundDisconnect = () => this.onTransportDisconnect(slot.cfg.name);\n client.addDisconnectListener(boundDisconnect);\n }\n // L2-C: react to server-side tool changes by re-registering wrappers.\n client.addToolsChangedListener(this.onToolsChanged);\n await client.connect();\n // Close any prior client before swapping refs so the old transport\n // can release its abort controller, child process, and listeners\n // instead of being held until GC.\n if (slot.client && slot.client !== client) {\n const prior = slot.client;\n const priorDisconnect = slot.onDisconnect;\n slot.client.removeExitListener(this.onChildExit);\n if (priorDisconnect) prior.removeDisconnectListener(priorDisconnect);\n prior.removeToolsChangedListener(this.onToolsChanged);\n prior.close().catch(() => {\n /* best-effort */\n });\n }\n slot.client = client;\n slot.onDisconnect = boundDisconnect;\n const isReconnect = attempt > 1;\n slot.state = 'connected';\n // L2-B: a healthy connect resets the cycle counter so future\n // crashes get the full reconnect budget again.\n slot.reconnectCycles = 0;\n const allowed = slot.cfg.allowedTools;\n // Prefer cached tools to avoid a round-trip to the server on reconnect.\n // The cache is populated by client.listTools() on first connect.\n const mc = client as MCPClient;\n const candidateTools = mc.listTools();\n const toWrap = candidateTools.length > 0 ? candidateTools : mc.listTools(); // fallback — in practice both return the same list\n const wrapped = toWrap\n .filter((t) => !allowed || allowed.includes(t.name))\n .map((t) => wrapMCPTool(slot.cfg.name, t, mc, slot.cfg.permission ?? 'confirm'));\n if (this.lazyMode) {\n // Lazy mode: cache tools without registering them\n slot.lazyTools = wrapped;\n this.log.info(\n `MCP server \"${slot.cfg.name}\" connected in lazy mode (${wrapped.length} tools cached, not registered)`,\n );\n } else {\n // Normal mode: register all tools\n for (const tool of wrapped) {\n try {\n this.toolRegistry.register(tool, `mcp:${slot.cfg.name}`);\n slot.toolNames.push(tool.name);\n } catch (err) {\n this.log.warn(`MCP tool \"${tool.name}\" not registered`, err);\n }\n }\n }\n this.events.emit(isReconnect ? 'mcp.server.reconnected' : 'mcp.server.connected', {\n name: slot.cfg.name,\n toolCount: slot.toolNames.length,\n });\n return; // success\n } catch (err) {\n this.log.warn(`MCP server \"${slot.cfg.name}\" connect attempt ${attempt} failed`, err);\n if (client) {\n client.removeExitListener(this.onChildExit);\n if (boundDisconnect) client.removeDisconnectListener(boundDisconnect);\n client.removeToolsChangedListener(this.onToolsChanged);\n await client.close().catch(() => {\n /* ignore */\n });\n }\n if (attempt >= MAX_ATTEMPTS) {\n this.log.error(\n `MCP server \"${slot.cfg.name}\" connect exhausted after ${MAX_ATTEMPTS} attempts`,\n err,\n );\n slot.state = 'failed';\n slot.client = undefined;\n this.events.emit('mcp.server.disconnected', {\n name: slot.cfg.name,\n reason: err instanceof Error ? err.message : 'unknown',\n });\n return;\n }\n const delay = 500 * 2 ** attempt;\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n }\n}\n","import { expectDefined } from '@wrongstack/core';\nimport { type IncomingMessage, type ServerResponse, createServer } from 'node:http';\nimport { MCP_CONSTANTS } from './constants.js';\n/**\n * Server-side MCP. The mirror image of `MCPClient`: instead of consuming a\n * remote MCP server, this lets WrongStack *be* an MCP server — exposing its\n * tools to any MCP client (Claude Desktop, another agent, an IDE) over a\n * JSON-RPC 2.0 stream.\n *\n * The protocol core (`MCPServer`) is transport-agnostic: feed it a raw JSON\n * line via `handleMessage`, get back a response string (or `null` for\n * notifications). `serveStdio` wires it to stdin/stdout for the canonical\n * stdio transport.\n */\n\n/** A tool descriptor advertised over `tools/list`. */\nexport interface MCPServerTool {\n name: string;\n description?: string | undefined;\n inputSchema: Record<string, unknown>;\n}\n\n/** The result of a `tools/call`, as the host produces it. */\nexport interface MCPServerCallResult {\n /** Text or pre-built MCP content blocks. Strings are wrapped as a text block. */\n content: unknown;\n isError: boolean;\n}\n\n/**\n * Bridges the MCP server to a tool backend (in the CLI, the `ToolRegistry`).\n * Kept narrow so the protocol core has no dependency on `@wrongstack/core`.\n */\nexport interface MCPServerToolHost {\n listTools(): MCPServerTool[] | Promise<MCPServerTool[]>;\n callTool(name: string, args: Record<string, unknown>): Promise<MCPServerCallResult>;\n}\n\nexport interface MCPServerLogger {\n warn?(msg: string): void;\n info?(msg: string): void;\n}\n\nexport interface MCPServerOptions {\n host: MCPServerToolHost;\n /** Advertised in the `initialize` handshake. Defaults to the wrongstack identity. */\n serverInfo?: { name: string; version: string };\n logger?: MCPServerLogger | undefined;\n}\n\ninterface JsonRpcRequest {\n jsonrpc?: string | undefined;\n id?: number | string | null | undefined;\n method?: string | undefined;\n params?: unknown | undefined;\n}\n\n// JSON-RPC 2.0 reserved error codes.\nconst PARSE_ERROR = -32700;\nconst INVALID_REQUEST = -32600;\nconst METHOD_NOT_FOUND = -32601;\nconst INTERNAL_ERROR = -32603;\n\nexport class MCPServer {\n private readonly host: MCPServerToolHost;\n private readonly serverInfo: { name: string; version: string };\n private readonly logger?: MCPServerLogger | undefined;\n\n constructor(opts: MCPServerOptions) {\n this.host = opts.host;\n this.serverInfo = opts.serverInfo ?? {\n name: MCP_CONSTANTS.CLIENT_INFO.name,\n version: MCP_CONSTANTS.CLIENT_INFO.version,\n };\n this.logger = opts.logger;\n }\n\n /**\n * Handle one raw JSON-RPC line. Returns the response JSON string for\n * requests, or `null` for notifications (no `id`) and for blank input —\n * the caller should write the string to its output stream when non-null.\n */\n async handleMessage(raw: string): Promise<string | null> {\n const line = raw.trim();\n if (!line) return null;\n\n let msg: JsonRpcRequest;\n try {\n msg = JSON.parse(line) as JsonRpcRequest;\n } catch {\n return this.encodeError(null, PARSE_ERROR, 'Parse error');\n }\n\n if (typeof msg !== 'object' || msg === null || typeof msg.method !== 'string') {\n const id = msg && typeof msg === 'object' ? (msg.id ?? null) : null;\n return this.encodeError(id ?? null, INVALID_REQUEST, 'Invalid Request');\n }\n\n const isNotification = msg.id === undefined || msg.id === null;\n\n // Notifications never get a response. We still dispatch known ones for\n // side effects, but `notifications/initialized` is purely a handshake ack.\n if (isNotification) {\n return null;\n }\n\n try {\n const result = await this.dispatch(msg.method, msg.params);\n if (result === METHOD_NOT_FOUND_SENTINEL) {\n return this.encodeError(expectDefined(msg.id), METHOD_NOT_FOUND, `Method not found: ${msg.method}`);\n }\n return JSON.stringify({ jsonrpc: '2.0', id: msg.id, result });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n this.logger?.warn?.(`MCP server: method \"${msg.method}\" threw: ${message}`);\n return this.encodeError(expectDefined(msg.id), INTERNAL_ERROR, message);\n }\n }\n\n private async dispatch(method: string, params: unknown): Promise<unknown> {\n switch (method) {\n case 'initialize':\n return {\n protocolVersion: MCP_CONSTANTS.PROTOCOL_VERSION,\n capabilities: { tools: { listChanged: false } },\n serverInfo: this.serverInfo,\n };\n case 'ping':\n return {};\n case 'tools/list': {\n const tools = await this.host.listTools();\n return { tools };\n }\n case 'tools/call': {\n const p = (params ?? {}) as { name?: unknown | undefined; arguments?: unknown | undefined };\n if (typeof p.name !== 'string') {\n throw new Error('tools/call requires a string \"name\"');\n }\n const args =\n p.arguments && typeof p.arguments === 'object' && !Array.isArray(p.arguments)\n ? (p.arguments as Record<string, unknown>)\n : {};\n const res = await this.host.callTool(p.name, args);\n return { content: toContentBlocks(res.content), isError: res.isError };\n }\n default:\n return METHOD_NOT_FOUND_SENTINEL;\n }\n }\n\n private encodeError(id: number | string | null, code: number, message: string): string {\n return JSON.stringify({ jsonrpc: '2.0', id, error: { code, message } });\n }\n}\n\nconst METHOD_NOT_FOUND_SENTINEL = Symbol('method-not-found');\n\n/** Normalize a host result's content into MCP content blocks. */\nexport function toContentBlocks(content: unknown): Array<{ type: 'text'; text: string }> {\n if (typeof content === 'string') return [{ type: 'text', text: content }];\n if (Array.isArray(content)) {\n // Already-shaped content blocks pass through; otherwise stringify each item.\n const allBlocks = content.every(\n (c) => c && typeof c === 'object' && (c as { type?: unknown | undefined }).type === 'text',\n );\n if (allBlocks) return content as Array<{ type: 'text'; text: string }>;\n return [{ type: 'text', text: content.map((c) => stringifyItem(c)).join('\\n') }];\n }\n if (content === undefined || content === null) return [{ type: 'text', text: '' }];\n return [{ type: 'text', text: stringifyItem(content) }];\n}\n\nfunction stringifyItem(c: unknown): string {\n if (typeof c === 'string') return c;\n try {\n return JSON.stringify(c);\n } catch {\n return String(c);\n }\n}\n\nexport interface ServeStdioHandle {\n /** Stop reading and detach listeners. Does not exit the process. */\n close(): void;\n /** Resolves when the input stream ends (EOF). */\n done: Promise<void>;\n}\n\nexport interface ServeStdioOptions {\n stdin?: NodeJS.ReadableStream | undefined;\n stdout?: NodeJS.WritableStream | undefined;\n}\n\n/**\n * Run an `MCPServer` over stdio: newline-delimited JSON-RPC in on stdin,\n * responses out on stdout. CRITICAL: nothing else may write to stdout while\n * this runs — it is the JSON-RPC channel. Route all logging to stderr.\n */\nexport function serveStdio(server: MCPServer, opts: ServeStdioOptions = {}): ServeStdioHandle {\n const stdin: NodeJS.ReadableStream = opts.stdin ?? process.stdin;\n const stdout = opts.stdout ?? process.stdout;\n let buffer = '';\n let closed = false;\n // Serialize writes so concurrent async handlers don't interleave lines.\n let writeChain: Promise<void> = Promise.resolve();\n\n const writeLine = (s: string) => {\n writeChain = writeChain\n .then(\n () =>\n new Promise<void>((resolve) => {\n stdout.write(`${s}\\n`, () => resolve());\n }),\n )\n .catch((err) => {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(JSON.stringify({\n level: 'error',\n event: 'mcp_server.stdout_write_failed',\n message: msg,\n timestamp: new Date().toISOString(),\n }));\n });\n };\n\n const onData = (chunk: Buffer | string) => {\n buffer += typeof chunk === 'string' ? chunk : chunk.toString('utf8');\n let idx = buffer.indexOf('\\n');\n while (idx !== -1) {\n const line = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 1);\n idx = buffer.indexOf('\\n');\n if (!line.trim()) continue;\n void server\n .handleMessage(line)\n .then((res) => {\n if (res !== null && !closed) writeLine(res);\n })\n .catch((err) => {\n // Malformed JSON from a peer — log and continue so one bad line\n // doesn't kill the entire session.\n console.error(JSON.stringify({\n level: 'error',\n event: 'mcp_server.handle_message_failed',\n message: err instanceof Error ? err.message : String(err),\n timestamp: new Date().toISOString(),\n }));\n });\n }\n };\n\n let resolveDone!: () => void;\n const done = new Promise<void>((resolve) => {\n resolveDone = resolve;\n });\n\n const onEnd = () => {\n if (closed) return;\n closed = true;\n stdin.off('data', onData);\n resolveDone();\n };\n\n stdin.on('data', onData);\n stdin.once('end', onEnd);\n stdin.once('close', onEnd);\n if (typeof (stdin as { resume?: () => void }).resume === 'function') {\n (stdin as { resume: () => void }).resume();\n }\n\n return {\n close: () => {\n onEnd();\n },\n done,\n };\n}\n\n// ── HTTP transport ──────────────────────────────────────────────────────────\n\nconst HTTP_BODY_CAP = 4 * 1024 * 1024; // 4 MiB\n\nexport interface ServeHttpOptions {\n /** TCP port. 0 picks an ephemeral port (resolved in the handle). Default 0. */\n port?: number | undefined;\n /** Bind address. Default '127.0.0.1' (loopback only). */\n host?: string | undefined;\n /**\n * Bearer token required on every request (`Authorization: Bearer <token>`).\n * REQUIRED when binding to a non-loopback host — `serveHttp` refuses to\n * expose tools to the network without one.\n */\n token?: string | undefined;\n logger?: MCPServerLogger | undefined;\n}\n\nexport interface ServeHttpHandle {\n port: number;\n host: string;\n url: string;\n close(): Promise<void>;\n}\n\nfunction isLoopbackHost(host: string): boolean {\n return host === '127.0.0.1' || host === '::1' || host === 'localhost';\n}\n\n/**\n * Run an `MCPServer` over HTTP: POST a single JSON-RPC request, get the JSON\n * response (notifications → 202 with no body). Reuses `handleMessage`, so the\n * protocol is identical to the stdio transport.\n *\n * Security: binds to loopback by default. Binding to any other host (e.g.\n * `0.0.0.0`) REQUIRES a `token` — otherwise this rejects, because it would\n * otherwise expose tool execution to the whole network unauthenticated.\n */\nexport function serveHttp(\n server: MCPServer,\n opts: ServeHttpOptions = {},\n): Promise<ServeHttpHandle> {\n const host = opts.host ?? '127.0.0.1';\n const port = opts.port ?? 0;\n const token = opts.token;\n const log = opts.logger;\n\n if (!isLoopbackHost(host) && !token) {\n return Promise.reject(\n new Error(\n `serveHttp: refusing to bind to non-loopback host \"${host}\" without a token — ` +\n 'pass a token to expose tools to the network, or bind to 127.0.0.1.',\n ),\n );\n }\n\n const httpServer = createServer((req: IncomingMessage, res: ServerResponse) => {\n void handleHttpRequest(server, req, res, token, log);\n });\n\n return new Promise<ServeHttpHandle>((resolve, reject) => {\n httpServer.once('error', reject);\n httpServer.listen(port, host, () => {\n httpServer.removeListener('error', reject);\n const addr = httpServer.address();\n const boundPort = typeof addr === 'object' && addr ? addr.port : port;\n const displayHost = host === '::1' ? '[::1]' : host;\n resolve({\n port: boundPort,\n host,\n url: `http://${displayHost}:${boundPort}/`,\n close: () =>\n new Promise<void>((res2) => {\n httpServer.close(() => res2());\n }),\n });\n });\n });\n}\n\nasync function handleHttpRequest(\n server: MCPServer,\n req: IncomingMessage,\n res: ServerResponse,\n token: string | undefined,\n log: MCPServerLogger | undefined,\n): Promise<void> {\n const send = (status: number, body: string, type = 'application/json') => {\n res.writeHead(status, { 'content-type': type });\n res.end(body);\n };\n\n // Health probe.\n if (req.method === 'GET') {\n return send(200, JSON.stringify({ status: 'ok', server: 'wrongstack-mcp' }));\n }\n if (req.method !== 'POST') {\n return send(405, JSON.stringify({ error: 'method not allowed' }));\n }\n if (token) {\n const auth = req.headers.authorization ?? '';\n const expected = `Bearer ${token}`;\n if (auth !== expected) {\n return send(401, JSON.stringify({ error: 'unauthorized' }));\n }\n }\n\n let body = '';\n let tooLarge = false;\n req.on('data', (chunk: Buffer) => {\n if (tooLarge) return;\n body += chunk.toString('utf8');\n if (body.length > HTTP_BODY_CAP) {\n tooLarge = true;\n send(413, JSON.stringify({ error: 'payload too large' }));\n req.destroy();\n }\n });\n req.on('end', () => {\n if (tooLarge) return;\n void server\n .handleMessage(body)\n .then((out) => {\n // Notifications produce no response body.\n if (out === null) return send(202, '');\n return send(200, out);\n })\n .catch((err) => {\n log?.warn?.(`MCP http handler error: ${err instanceof Error ? err.message : String(err)}`);\n send(500, JSON.stringify({ error: 'internal error' }));\n });\n });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.256.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack Model Context Protocol client and registry: stdio, SSE, and streamable HTTP transports.",
|
|
6
6
|
"repository": {
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@wrongstack/core": "0.
|
|
28
|
+
"@wrongstack/core": "0.256.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@types/node": "^25.9.
|
|
31
|
+
"@types/node": "^25.9.3",
|
|
32
32
|
"tsup": "^8.5.1",
|
|
33
33
|
"typescript": "^6.0.3",
|
|
34
34
|
"undici": "^8.4.1",
|