@agimon-ai/mcp-proxy 0.4.3 → 0.4.5
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/cli.cjs +197 -171
- package/dist/cli.mjs +197 -171
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-0OJqEpGA.mjs → src-BgRM8oW0.mjs} +1 -1
- package/dist/{src-G1hs2GLZ.cjs → src-h-U3G1P0.cjs} +1 -1
- package/package.json +3 -3
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_src = require('./src-
|
|
2
|
+
const require_src = require('./src-h-U3G1P0.cjs');
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
let node_fs_promises = require("node:fs/promises");
|
|
5
5
|
let node_path = require("node:path");
|
|
@@ -113,6 +113,169 @@ const initCommand = new commander.Command("init").description("Initialize MCP co
|
|
|
113
113
|
}
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/commands/prestart-http.ts
|
|
118
|
+
/**
|
|
119
|
+
* Prestart HTTP Command
|
|
120
|
+
*
|
|
121
|
+
* Starts an mcp-proxy HTTP runtime in the background, waits until it is healthy,
|
|
122
|
+
* and then exits so the runtime can be reused by other commands.
|
|
123
|
+
*/
|
|
124
|
+
const WORKSPACE_MARKERS = [
|
|
125
|
+
"pnpm-workspace.yaml",
|
|
126
|
+
"nx.json",
|
|
127
|
+
".git"
|
|
128
|
+
];
|
|
129
|
+
const DEFAULT_HOST$1 = "localhost";
|
|
130
|
+
const DEFAULT_TIMEOUT_MS = 12e4;
|
|
131
|
+
const POLL_INTERVAL_MS = 250;
|
|
132
|
+
function resolveWorkspaceRoot(startPath = process.env.PROJECT_PATH || process.cwd()) {
|
|
133
|
+
let current = node_path.default.resolve(startPath);
|
|
134
|
+
while (true) {
|
|
135
|
+
for (const marker of WORKSPACE_MARKERS) if ((0, node_fs.existsSync)(node_path.default.join(current, marker))) return current;
|
|
136
|
+
const parent = node_path.default.dirname(current);
|
|
137
|
+
if (parent === current) return process.cwd();
|
|
138
|
+
current = parent;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function resolveSiblingRegistryPath(registryPath, fileName) {
|
|
142
|
+
if (!registryPath) return;
|
|
143
|
+
const resolved = node_path.default.resolve(registryPath);
|
|
144
|
+
if (node_path.default.extname(resolved) === ".json") return node_path.default.join(node_path.default.dirname(resolved), fileName);
|
|
145
|
+
return node_path.default.join(resolved, fileName);
|
|
146
|
+
}
|
|
147
|
+
function buildCliCandidates() {
|
|
148
|
+
const __filename$1 = (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href);
|
|
149
|
+
const __dirname$1 = node_path.default.dirname(__filename$1);
|
|
150
|
+
const distCandidates = [
|
|
151
|
+
node_path.default.resolve(__dirname$1, "cli.mjs"),
|
|
152
|
+
node_path.default.resolve(__dirname$1, "..", "dist", "cli.mjs"),
|
|
153
|
+
node_path.default.resolve(__dirname$1, "..", "..", "dist", "cli.mjs")
|
|
154
|
+
];
|
|
155
|
+
const srcCandidates = [node_path.default.resolve(__dirname$1, "..", "cli.ts"), node_path.default.resolve(__dirname$1, "..", "..", "src", "cli.ts")];
|
|
156
|
+
for (const candidate of distCandidates) if ((0, node_fs.existsSync)(candidate)) return {
|
|
157
|
+
command: process.execPath,
|
|
158
|
+
args: [candidate]
|
|
159
|
+
};
|
|
160
|
+
for (const candidate of srcCandidates) if ((0, node_fs.existsSync)(candidate)) return {
|
|
161
|
+
command: process.execPath,
|
|
162
|
+
args: [
|
|
163
|
+
"--import",
|
|
164
|
+
"tsx",
|
|
165
|
+
candidate
|
|
166
|
+
]
|
|
167
|
+
};
|
|
168
|
+
throw new Error("Unable to locate mcp-proxy CLI entrypoint");
|
|
169
|
+
}
|
|
170
|
+
function parseTimeoutMs(value) {
|
|
171
|
+
if (!value) return DEFAULT_TIMEOUT_MS;
|
|
172
|
+
const parsed = Number.parseInt(value, 10);
|
|
173
|
+
if (!Number.isInteger(parsed) || parsed <= 0) throw new Error(`Invalid timeout value: ${value}`);
|
|
174
|
+
return parsed;
|
|
175
|
+
}
|
|
176
|
+
async function waitForFile(filePath, timeoutMs) {
|
|
177
|
+
const deadline = Date.now() + timeoutMs;
|
|
178
|
+
while (Date.now() < deadline) {
|
|
179
|
+
try {
|
|
180
|
+
await (0, node_fs_promises.access)(filePath);
|
|
181
|
+
return;
|
|
182
|
+
} catch {}
|
|
183
|
+
await new Promise((resolve$2) => setTimeout(resolve$2, POLL_INTERVAL_MS));
|
|
184
|
+
}
|
|
185
|
+
throw new Error(`Timed out waiting for runtime state file: ${filePath}`);
|
|
186
|
+
}
|
|
187
|
+
async function waitForHealthyRuntime(serverId, timeoutMs) {
|
|
188
|
+
const runtimeStateService = new require_src.RuntimeStateService();
|
|
189
|
+
const deadline = Date.now() + timeoutMs;
|
|
190
|
+
while (Date.now() < deadline) {
|
|
191
|
+
const record = await runtimeStateService.read(serverId);
|
|
192
|
+
if (record) {
|
|
193
|
+
const healthUrl = `http://${record.host}:${record.port}/health`;
|
|
194
|
+
try {
|
|
195
|
+
const response = await fetch(healthUrl);
|
|
196
|
+
if (response.ok) {
|
|
197
|
+
const payload = await response.json().catch(() => null);
|
|
198
|
+
if (!payload || payload.transport === "http") return {
|
|
199
|
+
host: record.host,
|
|
200
|
+
port: record.port
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
} catch {}
|
|
204
|
+
}
|
|
205
|
+
await new Promise((resolve$2) => setTimeout(resolve$2, POLL_INTERVAL_MS));
|
|
206
|
+
}
|
|
207
|
+
throw new Error(`Timed out waiting for HTTP runtime '${serverId}' to become healthy`);
|
|
208
|
+
}
|
|
209
|
+
function spawnBackgroundRuntime(args, env, cwd) {
|
|
210
|
+
const { command, args: baseArgs } = buildCliCandidates();
|
|
211
|
+
const child = (0, node_child_process.spawn)(command, [...baseArgs, ...args], {
|
|
212
|
+
detached: true,
|
|
213
|
+
cwd,
|
|
214
|
+
stdio: "ignore",
|
|
215
|
+
env
|
|
216
|
+
});
|
|
217
|
+
child.unref();
|
|
218
|
+
return child;
|
|
219
|
+
}
|
|
220
|
+
async function prestartHttpRuntime(options) {
|
|
221
|
+
const serverId = options.id || require_src.generateServerId();
|
|
222
|
+
const timeoutMs = parseTimeoutMs(options.timeoutMs);
|
|
223
|
+
const registryPath = options.registryPath || options.registryDir;
|
|
224
|
+
const workspaceRoot = resolveWorkspaceRoot();
|
|
225
|
+
const childEnv = {
|
|
226
|
+
...process.env,
|
|
227
|
+
...registryPath ? {
|
|
228
|
+
PORT_REGISTRY_PATH: registryPath,
|
|
229
|
+
PROCESS_REGISTRY_PATH: resolveSiblingRegistryPath(registryPath, "processes.json")
|
|
230
|
+
} : {}
|
|
231
|
+
};
|
|
232
|
+
const child = spawnBackgroundRuntime([
|
|
233
|
+
"mcp-serve",
|
|
234
|
+
"--type",
|
|
235
|
+
"http",
|
|
236
|
+
"--id",
|
|
237
|
+
serverId,
|
|
238
|
+
"--host",
|
|
239
|
+
options.host || DEFAULT_HOST$1,
|
|
240
|
+
...options.port !== void 0 ? ["--port", String(options.port)] : [],
|
|
241
|
+
...options.config ? ["--config", options.config] : [],
|
|
242
|
+
...options.cache === false ? ["--no-cache"] : [],
|
|
243
|
+
...options.definitionsCache ? ["--definitions-cache", options.definitionsCache] : [],
|
|
244
|
+
...options.clearDefinitionsCache ? ["--clear-definitions-cache"] : [],
|
|
245
|
+
"--proxy-mode",
|
|
246
|
+
options.proxyMode
|
|
247
|
+
], childEnv, workspaceRoot);
|
|
248
|
+
const childExit = new Promise((_, reject) => {
|
|
249
|
+
child.once("exit", (code, signal) => {
|
|
250
|
+
reject(/* @__PURE__ */ new Error(`Background runtime exited before becoming healthy (code=${code ?? "null"}, signal=${signal ?? "null"})`));
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
const runtimeFile = node_path.default.join(require_src.RuntimeStateService.getDefaultRuntimeDir(), `${serverId}.runtime.json`);
|
|
254
|
+
try {
|
|
255
|
+
await Promise.race([waitForFile(runtimeFile, timeoutMs), childExit]);
|
|
256
|
+
const { host, port } = await Promise.race([waitForHealthyRuntime(serverId, timeoutMs), childExit]);
|
|
257
|
+
return {
|
|
258
|
+
host,
|
|
259
|
+
port,
|
|
260
|
+
serverId,
|
|
261
|
+
workspaceRoot
|
|
262
|
+
};
|
|
263
|
+
} catch (error) {
|
|
264
|
+
throw new Error(`Failed to prestart HTTP runtime '${serverId}': ${error instanceof Error ? error.message : String(error)}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const prestartHttpCommand = new commander.Command("prestart-http").description("Start an mcp-proxy HTTP runtime in the background and wait until it is healthy").option("--id <id>", "Server identifier to assign to the runtime").option("--host <host>", "Host to bind to", DEFAULT_HOST$1).option("-p, --port <port>", "Preferred HTTP port for the runtime", (value) => Number.parseInt(value, 10)).option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Disable configuration caching, always reload from config file").option("--definitions-cache <path>", "Path to prefetched tool/prompt/skill definitions cache file").option("--clear-definitions-cache", "Delete definitions cache before startup", false).option("--proxy-mode <mode>", "How mcp-proxy exposes downstream tools: meta, flat, or search", "meta").option("--registry-path <path>", "Custom registry path or directory for service discovery").option("--registry-dir <path>", "Custom registry directory for service discovery").option("--timeout-ms <ms>", "How long to wait for the runtime to become healthy", String(DEFAULT_TIMEOUT_MS)).action(async (options) => {
|
|
268
|
+
try {
|
|
269
|
+
const { host, port, serverId, workspaceRoot } = await prestartHttpRuntime(options);
|
|
270
|
+
process.stdout.write(`mcp-proxy HTTP runtime ready at http://${host}:${port} (${serverId})\n`);
|
|
271
|
+
process.stdout.write(`runtimeId=${serverId}\n`);
|
|
272
|
+
process.stdout.write(`runtimeUrl=http://${host}:${port}\n`);
|
|
273
|
+
process.stdout.write(`workspaceRoot=${workspaceRoot}\n`);
|
|
274
|
+
} catch (error) {
|
|
275
|
+
throw new Error(`Failed to prestart HTTP runtime '${options.id || "generated-server-id"}': ${error instanceof Error ? error.message : String(error)}`);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
|
|
116
279
|
//#endregion
|
|
117
280
|
//#region src/commands/mcp-serve.ts
|
|
118
281
|
/**
|
|
@@ -141,7 +304,7 @@ const CONFIG_FILE_NAMES = [
|
|
|
141
304
|
"mcp-config.json"
|
|
142
305
|
];
|
|
143
306
|
const MCP_ENDPOINT_PATH = "/mcp";
|
|
144
|
-
const DEFAULT_HOST
|
|
307
|
+
const DEFAULT_HOST = "localhost";
|
|
145
308
|
const TRANSPORT_TYPE_STDIO = "stdio";
|
|
146
309
|
const TRANSPORT_TYPE_HTTP = "http";
|
|
147
310
|
const TRANSPORT_TYPE_SSE = "sse";
|
|
@@ -149,10 +312,14 @@ const TRANSPORT_TYPE_STDIO_HTTP = "stdio-http";
|
|
|
149
312
|
const RUNTIME_TRANSPORT = TRANSPORT_TYPE_HTTP;
|
|
150
313
|
const PORT_REGISTRY_SERVICE_HTTP = "mcp-proxy-http";
|
|
151
314
|
const PORT_REGISTRY_SERVICE_TYPE = "service";
|
|
152
|
-
|
|
315
|
+
function getWorkspaceRoot() {
|
|
316
|
+
return resolveWorkspaceRoot();
|
|
317
|
+
}
|
|
153
318
|
const PROCESS_REGISTRY_SERVICE_HTTP = "mcp-proxy-http";
|
|
154
319
|
const PROCESS_REGISTRY_SERVICE_TYPE = "service";
|
|
155
|
-
|
|
320
|
+
function getRegistryRepositoryPath() {
|
|
321
|
+
return getWorkspaceRoot();
|
|
322
|
+
}
|
|
156
323
|
function toErrorMessage$9(error) {
|
|
157
324
|
return error instanceof Error ? error.message : String(error);
|
|
158
325
|
}
|
|
@@ -213,7 +380,7 @@ function createTransportConfig(options, mode) {
|
|
|
213
380
|
return {
|
|
214
381
|
mode,
|
|
215
382
|
port: options.port ?? (Number.isFinite(envPort) ? envPort : void 0),
|
|
216
|
-
host: options.host || process.env.MCP_HOST || DEFAULT_HOST
|
|
383
|
+
host: options.host || process.env.MCP_HOST || DEFAULT_HOST
|
|
217
384
|
};
|
|
218
385
|
}
|
|
219
386
|
function createServerOptions(options, resolvedConfigPath, serverId) {
|
|
@@ -234,7 +401,7 @@ function formatStartError(type, host, port, error) {
|
|
|
234
401
|
function createRuntimeRecord(serverId, config, port, shutdownToken, configPath) {
|
|
235
402
|
return {
|
|
236
403
|
serverId,
|
|
237
|
-
host: config.host ?? DEFAULT_HOST
|
|
404
|
+
host: config.host ?? DEFAULT_HOST,
|
|
238
405
|
port,
|
|
239
406
|
transport: RUNTIME_TRANSPORT,
|
|
240
407
|
shutdownToken,
|
|
@@ -258,7 +425,7 @@ async function createPortRegistryLease(serviceName, host, preferredPort, serverI
|
|
|
258
425
|
} : __agimon_ai_foundation_port_registry.DEFAULT_PORT_RANGE) {
|
|
259
426
|
const portRegistry = createPortRegistryService();
|
|
260
427
|
const result = await portRegistry.reservePort({
|
|
261
|
-
repositoryPath:
|
|
428
|
+
repositoryPath: getRegistryRepositoryPath(),
|
|
262
429
|
serviceName,
|
|
263
430
|
serviceType: PORT_REGISTRY_SERVICE_TYPE,
|
|
264
431
|
environment: getRegistryEnvironment(),
|
|
@@ -284,7 +451,7 @@ async function createPortRegistryLease(serviceName, host, preferredPort, serverI
|
|
|
284
451
|
if (released) return;
|
|
285
452
|
released = true;
|
|
286
453
|
const releaseResult = await portRegistry.releasePort({
|
|
287
|
-
repositoryPath:
|
|
454
|
+
repositoryPath: getRegistryRepositoryPath(),
|
|
288
455
|
serviceName,
|
|
289
456
|
serviceType: PORT_REGISTRY_SERVICE_TYPE,
|
|
290
457
|
pid: process.pid,
|
|
@@ -298,7 +465,7 @@ async function createPortRegistryLease(serviceName, host, preferredPort, serverI
|
|
|
298
465
|
async function createProcessRegistryLease(serviceName, host, port, serverId, transport, configPath) {
|
|
299
466
|
const processRegistry = createProcessRegistryService();
|
|
300
467
|
const result = await processRegistry.registerProcess({
|
|
301
|
-
repositoryPath:
|
|
468
|
+
repositoryPath: getRegistryRepositoryPath(),
|
|
302
469
|
serviceName,
|
|
303
470
|
serviceType: PROCESS_REGISTRY_SERVICE_TYPE,
|
|
304
471
|
environment: getRegistryEnvironment(),
|
|
@@ -319,7 +486,7 @@ async function createProcessRegistryLease(serviceName, host, port, serverId, tra
|
|
|
319
486
|
if (released) return;
|
|
320
487
|
released = true;
|
|
321
488
|
const releaseResult = await processRegistry.releaseProcess({
|
|
322
|
-
repositoryPath:
|
|
489
|
+
repositoryPath: getRegistryRepositoryPath(),
|
|
323
490
|
serviceName,
|
|
324
491
|
serviceType: PROCESS_REGISTRY_SERVICE_TYPE,
|
|
325
492
|
pid: process.pid,
|
|
@@ -420,13 +587,13 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
420
587
|
min: requestedPort,
|
|
421
588
|
max: requestedPort
|
|
422
589
|
} : __agimon_ai_foundation_port_registry.DEFAULT_PORT_RANGE;
|
|
423
|
-
const portLease = await createPortRegistryLease(PORT_REGISTRY_SERVICE_HTTP, config.host ?? DEFAULT_HOST
|
|
590
|
+
const portLease = await createPortRegistryLease(PORT_REGISTRY_SERVICE_HTTP, config.host ?? DEFAULT_HOST, requestedPort, runtimeServerId, TRANSPORT_TYPE_HTTP, resolvedConfigPath, portRange);
|
|
424
591
|
const runtimePort = portLease.port;
|
|
425
592
|
const runtimeConfig = {
|
|
426
593
|
...config,
|
|
427
594
|
port: runtimePort
|
|
428
595
|
};
|
|
429
|
-
const processLease = await createProcessRegistryLease(PROCESS_REGISTRY_SERVICE_HTTP, runtimeConfig.host ?? DEFAULT_HOST
|
|
596
|
+
const processLease = await createProcessRegistryLease(PROCESS_REGISTRY_SERVICE_HTTP, runtimeConfig.host ?? DEFAULT_HOST, runtimePort, runtimeServerId, TRANSPORT_TYPE_HTTP, resolvedConfigPath);
|
|
430
597
|
let releasePort = async () => {
|
|
431
598
|
await releasePortLease(portLease ?? null);
|
|
432
599
|
releasePort = async () => void 0;
|
|
@@ -494,20 +661,29 @@ async function startSseTransport(serverOptions, config) {
|
|
|
494
661
|
throw new Error(`Failed to start SSE transport: ${toErrorMessage$9(error)}`);
|
|
495
662
|
}
|
|
496
663
|
}
|
|
497
|
-
async function resolveStdioHttpEndpoint(config) {
|
|
498
|
-
|
|
664
|
+
async function resolveStdioHttpEndpoint(config, options, resolvedConfigPath) {
|
|
665
|
+
const repositoryPath = getRegistryRepositoryPath();
|
|
666
|
+
if (config.port !== void 0) return new URL(`http://${config.host ?? DEFAULT_HOST}:${config.port}${MCP_ENDPOINT_PATH}`);
|
|
499
667
|
const result = await createPortRegistryService().getPort({
|
|
500
|
-
repositoryPath
|
|
668
|
+
repositoryPath,
|
|
501
669
|
serviceName: PORT_REGISTRY_SERVICE_HTTP,
|
|
502
670
|
serviceType: PORT_REGISTRY_SERVICE_TYPE,
|
|
503
671
|
environment: getRegistryEnvironment()
|
|
504
672
|
});
|
|
505
|
-
if (
|
|
506
|
-
|
|
673
|
+
if (result.success && result.record) return new URL(`http://${config.host ?? result.record.host}:${result.record.port}${MCP_ENDPOINT_PATH}`);
|
|
674
|
+
const runtime = await prestartHttpRuntime({
|
|
675
|
+
host: config.host ?? DEFAULT_HOST,
|
|
676
|
+
config: options.config || resolvedConfigPath,
|
|
677
|
+
cache: options.cache,
|
|
678
|
+
definitionsCache: options.definitionsCache,
|
|
679
|
+
clearDefinitionsCache: options.clearDefinitionsCache,
|
|
680
|
+
proxyMode: options.proxyMode
|
|
681
|
+
});
|
|
682
|
+
return new URL(`http://${runtime.host}:${runtime.port}${MCP_ENDPOINT_PATH}`);
|
|
507
683
|
}
|
|
508
|
-
async function startStdioHttpTransport(config) {
|
|
684
|
+
async function startStdioHttpTransport(config, options, resolvedConfigPath) {
|
|
509
685
|
try {
|
|
510
|
-
await startServer(new require_src.StdioHttpTransportHandler({ endpoint: await resolveStdioHttpEndpoint(config) }));
|
|
686
|
+
await startServer(new require_src.StdioHttpTransportHandler({ endpoint: await resolveStdioHttpEndpoint(config, options, resolvedConfigPath) }));
|
|
511
687
|
} catch (error) {
|
|
512
688
|
throw new Error(`Failed to start stdio-http transport: ${toErrorMessage$9(error)}`);
|
|
513
689
|
}
|
|
@@ -526,7 +702,7 @@ async function startTransport(transportType, options, resolvedConfigPath, server
|
|
|
526
702
|
await startSseTransport(serverOptions, createTransportConfig(options, require_src.TRANSPORT_MODE.SSE));
|
|
527
703
|
return;
|
|
528
704
|
}
|
|
529
|
-
await startStdioHttpTransport(createTransportConfig(options, require_src.TRANSPORT_MODE.HTTP));
|
|
705
|
+
await startStdioHttpTransport(createTransportConfig(options, require_src.TRANSPORT_MODE.HTTP), options, resolvedConfigPath);
|
|
530
706
|
} catch (error) {
|
|
531
707
|
throw new Error(`Failed to start transport '${transportType}': ${toErrorMessage$9(error)}`);
|
|
532
708
|
}
|
|
@@ -534,7 +710,7 @@ async function startTransport(transportType, options, resolvedConfigPath, server
|
|
|
534
710
|
/**
|
|
535
711
|
* MCP Serve command
|
|
536
712
|
*/
|
|
537
|
-
const mcpServeCommand = new commander.Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", `Transport type: ${TRANSPORT_TYPE_STDIO}, ${TRANSPORT_TYPE_HTTP}, ${TRANSPORT_TYPE_SSE}, or ${TRANSPORT_TYPE_STDIO_HTTP}`, TRANSPORT_TYPE_STDIO).option("-p, --port <port>", "Port to listen on (http/sse) or backend port for stdio-http", (val) => parseInt(val, 10)).option("--host <host>", "Host to bind to (http/sse) or backend host for stdio-http", DEFAULT_HOST
|
|
713
|
+
const mcpServeCommand = new commander.Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", `Transport type: ${TRANSPORT_TYPE_STDIO}, ${TRANSPORT_TYPE_HTTP}, ${TRANSPORT_TYPE_SSE}, or ${TRANSPORT_TYPE_STDIO_HTTP}`, TRANSPORT_TYPE_STDIO).option("-p, --port <port>", "Port to listen on (http/sse) or backend port for stdio-http", (val) => parseInt(val, 10)).option("--host <host>", "Host to bind to (http/sse) or backend host for stdio-http", DEFAULT_HOST).option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Disable configuration caching, always reload from config file").option("--definitions-cache <path>", "Path to prefetched tool/prompt/skill definitions cache file").option("--clear-definitions-cache", "Delete definitions cache before startup", false).option("--proxy-mode <mode>", "How mcp-proxy exposes downstream tools: meta, flat, or search", "meta").option("--id <id>", "Unique server identifier (overrides config file id, auto-generated if not provided)").action(async (options) => {
|
|
538
714
|
try {
|
|
539
715
|
const transportType = validateTransportType(options.type.toLowerCase());
|
|
540
716
|
validateProxyMode(options.proxyMode);
|
|
@@ -550,156 +726,6 @@ const mcpServeCommand = new commander.Command("mcp-serve").description("Start MC
|
|
|
550
726
|
}
|
|
551
727
|
});
|
|
552
728
|
|
|
553
|
-
//#endregion
|
|
554
|
-
//#region src/commands/prestart-http.ts
|
|
555
|
-
/**
|
|
556
|
-
* Prestart HTTP Command
|
|
557
|
-
*
|
|
558
|
-
* Starts an mcp-proxy HTTP runtime in the background, waits until it is healthy,
|
|
559
|
-
* and then exits so the runtime can be reused by other commands.
|
|
560
|
-
*/
|
|
561
|
-
const WORKSPACE_MARKERS = [
|
|
562
|
-
"pnpm-workspace.yaml",
|
|
563
|
-
"nx.json",
|
|
564
|
-
".git"
|
|
565
|
-
];
|
|
566
|
-
const DEFAULT_HOST = "localhost";
|
|
567
|
-
const DEFAULT_TIMEOUT_MS = 12e4;
|
|
568
|
-
const POLL_INTERVAL_MS = 250;
|
|
569
|
-
function resolveWorkspaceRoot(startPath = process.cwd()) {
|
|
570
|
-
let current = node_path.default.resolve(startPath);
|
|
571
|
-
while (true) {
|
|
572
|
-
for (const marker of WORKSPACE_MARKERS) if ((0, node_fs.existsSync)(node_path.default.join(current, marker))) return current;
|
|
573
|
-
const parent = node_path.default.dirname(current);
|
|
574
|
-
if (parent === current) return process.cwd();
|
|
575
|
-
current = parent;
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
function resolveSiblingRegistryPath(registryPath, fileName) {
|
|
579
|
-
if (!registryPath) return;
|
|
580
|
-
const resolved = node_path.default.resolve(registryPath);
|
|
581
|
-
if (node_path.default.extname(resolved) === ".json") return node_path.default.join(node_path.default.dirname(resolved), fileName);
|
|
582
|
-
return node_path.default.join(resolved, fileName);
|
|
583
|
-
}
|
|
584
|
-
function buildCliCandidates() {
|
|
585
|
-
const __filename$1 = (0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href);
|
|
586
|
-
const __dirname$1 = node_path.default.dirname(__filename$1);
|
|
587
|
-
const distCandidates = [
|
|
588
|
-
node_path.default.resolve(__dirname$1, "cli.mjs"),
|
|
589
|
-
node_path.default.resolve(__dirname$1, "..", "dist", "cli.mjs"),
|
|
590
|
-
node_path.default.resolve(__dirname$1, "..", "..", "dist", "cli.mjs")
|
|
591
|
-
];
|
|
592
|
-
const srcCandidates = [node_path.default.resolve(__dirname$1, "..", "cli.ts"), node_path.default.resolve(__dirname$1, "..", "..", "src", "cli.ts")];
|
|
593
|
-
for (const candidate of distCandidates) if ((0, node_fs.existsSync)(candidate)) return {
|
|
594
|
-
command: process.execPath,
|
|
595
|
-
args: [candidate]
|
|
596
|
-
};
|
|
597
|
-
for (const candidate of srcCandidates) if ((0, node_fs.existsSync)(candidate)) return {
|
|
598
|
-
command: process.execPath,
|
|
599
|
-
args: [
|
|
600
|
-
"--import",
|
|
601
|
-
"tsx",
|
|
602
|
-
candidate
|
|
603
|
-
]
|
|
604
|
-
};
|
|
605
|
-
throw new Error("Unable to locate mcp-proxy CLI entrypoint");
|
|
606
|
-
}
|
|
607
|
-
function parseTimeoutMs(value) {
|
|
608
|
-
if (!value) return DEFAULT_TIMEOUT_MS;
|
|
609
|
-
const parsed = Number.parseInt(value, 10);
|
|
610
|
-
if (!Number.isInteger(parsed) || parsed <= 0) throw new Error(`Invalid timeout value: ${value}`);
|
|
611
|
-
return parsed;
|
|
612
|
-
}
|
|
613
|
-
async function waitForFile(filePath, timeoutMs) {
|
|
614
|
-
const deadline = Date.now() + timeoutMs;
|
|
615
|
-
while (Date.now() < deadline) {
|
|
616
|
-
try {
|
|
617
|
-
await (0, node_fs_promises.access)(filePath);
|
|
618
|
-
return;
|
|
619
|
-
} catch {}
|
|
620
|
-
await new Promise((resolve$2) => setTimeout(resolve$2, POLL_INTERVAL_MS));
|
|
621
|
-
}
|
|
622
|
-
throw new Error(`Timed out waiting for runtime state file: ${filePath}`);
|
|
623
|
-
}
|
|
624
|
-
async function waitForHealthyRuntime(serverId, timeoutMs) {
|
|
625
|
-
const runtimeStateService = new require_src.RuntimeStateService();
|
|
626
|
-
const deadline = Date.now() + timeoutMs;
|
|
627
|
-
while (Date.now() < deadline) {
|
|
628
|
-
const record = await runtimeStateService.read(serverId);
|
|
629
|
-
if (record) {
|
|
630
|
-
const healthUrl = `http://${record.host}:${record.port}/health`;
|
|
631
|
-
try {
|
|
632
|
-
const response = await fetch(healthUrl);
|
|
633
|
-
if (response.ok) {
|
|
634
|
-
const payload = await response.json().catch(() => null);
|
|
635
|
-
if (!payload || payload.transport === "http") return {
|
|
636
|
-
host: record.host,
|
|
637
|
-
port: record.port
|
|
638
|
-
};
|
|
639
|
-
}
|
|
640
|
-
} catch {}
|
|
641
|
-
}
|
|
642
|
-
await new Promise((resolve$2) => setTimeout(resolve$2, POLL_INTERVAL_MS));
|
|
643
|
-
}
|
|
644
|
-
throw new Error(`Timed out waiting for HTTP runtime '${serverId}' to become healthy`);
|
|
645
|
-
}
|
|
646
|
-
function spawnBackgroundRuntime(args, env) {
|
|
647
|
-
const { command, args: baseArgs } = buildCliCandidates();
|
|
648
|
-
const child = (0, node_child_process.spawn)(command, [...baseArgs, ...args], {
|
|
649
|
-
detached: true,
|
|
650
|
-
stdio: "ignore",
|
|
651
|
-
env
|
|
652
|
-
});
|
|
653
|
-
child.unref();
|
|
654
|
-
return child;
|
|
655
|
-
}
|
|
656
|
-
const prestartHttpCommand = new commander.Command("prestart-http").description("Start an mcp-proxy HTTP runtime in the background and wait until it is healthy").option("--id <id>", "Server identifier to assign to the runtime").option("--host <host>", "Host to bind to", DEFAULT_HOST).option("-p, --port <port>", "Preferred HTTP port for the runtime", (value) => Number.parseInt(value, 10)).option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Disable configuration caching, always reload from config file").option("--definitions-cache <path>", "Path to prefetched tool/prompt/skill definitions cache file").option("--clear-definitions-cache", "Delete definitions cache before startup", false).option("--proxy-mode <mode>", "How mcp-proxy exposes downstream tools: meta, flat, or search", "meta").option("--registry-path <path>", "Custom registry path or directory for service discovery").option("--registry-dir <path>", "Custom registry directory for service discovery").option("--timeout-ms <ms>", "How long to wait for the runtime to become healthy", String(DEFAULT_TIMEOUT_MS)).action(async (options) => {
|
|
657
|
-
const serverId = options.id || require_src.generateServerId();
|
|
658
|
-
const timeoutMs = parseTimeoutMs(options.timeoutMs);
|
|
659
|
-
const registryPath = options.registryPath || options.registryDir;
|
|
660
|
-
new require_src.RuntimeStateService();
|
|
661
|
-
const workspaceRoot = resolveWorkspaceRoot(process.cwd());
|
|
662
|
-
const childEnv = {
|
|
663
|
-
...process.env,
|
|
664
|
-
...registryPath ? {
|
|
665
|
-
PORT_REGISTRY_PATH: registryPath,
|
|
666
|
-
PROCESS_REGISTRY_PATH: resolveSiblingRegistryPath(registryPath, "processes.json")
|
|
667
|
-
} : {}
|
|
668
|
-
};
|
|
669
|
-
const child = spawnBackgroundRuntime([
|
|
670
|
-
"mcp-serve",
|
|
671
|
-
"--type",
|
|
672
|
-
"http",
|
|
673
|
-
"--id",
|
|
674
|
-
serverId,
|
|
675
|
-
"--host",
|
|
676
|
-
options.host || DEFAULT_HOST,
|
|
677
|
-
...options.port !== void 0 ? ["--port", String(options.port)] : [],
|
|
678
|
-
...options.config ? ["--config", options.config] : [],
|
|
679
|
-
...options.cache === false ? ["--no-cache"] : [],
|
|
680
|
-
...options.definitionsCache ? ["--definitions-cache", options.definitionsCache] : [],
|
|
681
|
-
...options.clearDefinitionsCache ? ["--clear-definitions-cache"] : [],
|
|
682
|
-
"--proxy-mode",
|
|
683
|
-
options.proxyMode
|
|
684
|
-
], childEnv);
|
|
685
|
-
const childExit = new Promise((_, reject) => {
|
|
686
|
-
child.once("exit", (code, signal) => {
|
|
687
|
-
reject(/* @__PURE__ */ new Error(`Background runtime exited before becoming healthy (code=${code ?? "null"}, signal=${signal ?? "null"})`));
|
|
688
|
-
});
|
|
689
|
-
});
|
|
690
|
-
const runtimeFile = node_path.default.join(require_src.RuntimeStateService.getDefaultRuntimeDir(), `${serverId}.runtime.json`);
|
|
691
|
-
try {
|
|
692
|
-
await Promise.race([waitForFile(runtimeFile, timeoutMs), childExit]);
|
|
693
|
-
const { host, port } = await Promise.race([waitForHealthyRuntime(serverId, timeoutMs), childExit]);
|
|
694
|
-
process.stdout.write(`mcp-proxy HTTP runtime ready at http://${host}:${port} (${serverId})\n`);
|
|
695
|
-
process.stdout.write(`runtimeId=${serverId}\n`);
|
|
696
|
-
process.stdout.write(`runtimeUrl=http://${host}:${port}\n`);
|
|
697
|
-
process.stdout.write(`workspaceRoot=${workspaceRoot}\n`);
|
|
698
|
-
} catch (error) {
|
|
699
|
-
throw new Error(`Failed to prestart HTTP runtime '${serverId}': ${error instanceof Error ? error.message : String(error)}`);
|
|
700
|
-
}
|
|
701
|
-
});
|
|
702
|
-
|
|
703
729
|
//#endregion
|
|
704
730
|
//#region src/commands/bootstrap.ts
|
|
705
731
|
function toErrorMessage$8(error) {
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { D as findConfigFile, E as generateServerId, T as DefinitionsCacheService, d as version, f as StdioHttpTransportHandler, h as HttpTransportHandler, m as SseTransportHandler, n as createServer, o as createProxyIoCContainer, p as StdioTransportHandler, r as createSessionServer, t as TRANSPORT_MODE, u as initializeSharedServices, v as RuntimeStateService } from "./src-
|
|
2
|
+
import { D as findConfigFile, E as generateServerId, T as DefinitionsCacheService, d as version, f as StdioHttpTransportHandler, h as HttpTransportHandler, m as SseTransportHandler, n as createServer, o as createProxyIoCContainer, p as StdioTransportHandler, r as createSessionServer, t as TRANSPORT_MODE, u as initializeSharedServices, v as RuntimeStateService } from "./src-BgRM8oW0.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { access, writeFile } from "node:fs/promises";
|
|
5
5
|
import path, { join, resolve } from "node:path";
|
|
@@ -112,6 +112,169 @@ const initCommand = new Command("init").description("Initialize MCP configuratio
|
|
|
112
112
|
}
|
|
113
113
|
});
|
|
114
114
|
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/commands/prestart-http.ts
|
|
117
|
+
/**
|
|
118
|
+
* Prestart HTTP Command
|
|
119
|
+
*
|
|
120
|
+
* Starts an mcp-proxy HTTP runtime in the background, waits until it is healthy,
|
|
121
|
+
* and then exits so the runtime can be reused by other commands.
|
|
122
|
+
*/
|
|
123
|
+
const WORKSPACE_MARKERS = [
|
|
124
|
+
"pnpm-workspace.yaml",
|
|
125
|
+
"nx.json",
|
|
126
|
+
".git"
|
|
127
|
+
];
|
|
128
|
+
const DEFAULT_HOST$1 = "localhost";
|
|
129
|
+
const DEFAULT_TIMEOUT_MS = 12e4;
|
|
130
|
+
const POLL_INTERVAL_MS = 250;
|
|
131
|
+
function resolveWorkspaceRoot(startPath = process.env.PROJECT_PATH || process.cwd()) {
|
|
132
|
+
let current = path.resolve(startPath);
|
|
133
|
+
while (true) {
|
|
134
|
+
for (const marker of WORKSPACE_MARKERS) if (existsSync(path.join(current, marker))) return current;
|
|
135
|
+
const parent = path.dirname(current);
|
|
136
|
+
if (parent === current) return process.cwd();
|
|
137
|
+
current = parent;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function resolveSiblingRegistryPath(registryPath, fileName) {
|
|
141
|
+
if (!registryPath) return;
|
|
142
|
+
const resolved = path.resolve(registryPath);
|
|
143
|
+
if (path.extname(resolved) === ".json") return path.join(path.dirname(resolved), fileName);
|
|
144
|
+
return path.join(resolved, fileName);
|
|
145
|
+
}
|
|
146
|
+
function buildCliCandidates() {
|
|
147
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
148
|
+
const __dirname = path.dirname(__filename);
|
|
149
|
+
const distCandidates = [
|
|
150
|
+
path.resolve(__dirname, "cli.mjs"),
|
|
151
|
+
path.resolve(__dirname, "..", "dist", "cli.mjs"),
|
|
152
|
+
path.resolve(__dirname, "..", "..", "dist", "cli.mjs")
|
|
153
|
+
];
|
|
154
|
+
const srcCandidates = [path.resolve(__dirname, "..", "cli.ts"), path.resolve(__dirname, "..", "..", "src", "cli.ts")];
|
|
155
|
+
for (const candidate of distCandidates) if (existsSync(candidate)) return {
|
|
156
|
+
command: process.execPath,
|
|
157
|
+
args: [candidate]
|
|
158
|
+
};
|
|
159
|
+
for (const candidate of srcCandidates) if (existsSync(candidate)) return {
|
|
160
|
+
command: process.execPath,
|
|
161
|
+
args: [
|
|
162
|
+
"--import",
|
|
163
|
+
"tsx",
|
|
164
|
+
candidate
|
|
165
|
+
]
|
|
166
|
+
};
|
|
167
|
+
throw new Error("Unable to locate mcp-proxy CLI entrypoint");
|
|
168
|
+
}
|
|
169
|
+
function parseTimeoutMs(value) {
|
|
170
|
+
if (!value) return DEFAULT_TIMEOUT_MS;
|
|
171
|
+
const parsed = Number.parseInt(value, 10);
|
|
172
|
+
if (!Number.isInteger(parsed) || parsed <= 0) throw new Error(`Invalid timeout value: ${value}`);
|
|
173
|
+
return parsed;
|
|
174
|
+
}
|
|
175
|
+
async function waitForFile(filePath, timeoutMs) {
|
|
176
|
+
const deadline = Date.now() + timeoutMs;
|
|
177
|
+
while (Date.now() < deadline) {
|
|
178
|
+
try {
|
|
179
|
+
await access(filePath);
|
|
180
|
+
return;
|
|
181
|
+
} catch {}
|
|
182
|
+
await new Promise((resolve$1) => setTimeout(resolve$1, POLL_INTERVAL_MS));
|
|
183
|
+
}
|
|
184
|
+
throw new Error(`Timed out waiting for runtime state file: ${filePath}`);
|
|
185
|
+
}
|
|
186
|
+
async function waitForHealthyRuntime(serverId, timeoutMs) {
|
|
187
|
+
const runtimeStateService = new RuntimeStateService();
|
|
188
|
+
const deadline = Date.now() + timeoutMs;
|
|
189
|
+
while (Date.now() < deadline) {
|
|
190
|
+
const record = await runtimeStateService.read(serverId);
|
|
191
|
+
if (record) {
|
|
192
|
+
const healthUrl = `http://${record.host}:${record.port}/health`;
|
|
193
|
+
try {
|
|
194
|
+
const response = await fetch(healthUrl);
|
|
195
|
+
if (response.ok) {
|
|
196
|
+
const payload = await response.json().catch(() => null);
|
|
197
|
+
if (!payload || payload.transport === "http") return {
|
|
198
|
+
host: record.host,
|
|
199
|
+
port: record.port
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
} catch {}
|
|
203
|
+
}
|
|
204
|
+
await new Promise((resolve$1) => setTimeout(resolve$1, POLL_INTERVAL_MS));
|
|
205
|
+
}
|
|
206
|
+
throw new Error(`Timed out waiting for HTTP runtime '${serverId}' to become healthy`);
|
|
207
|
+
}
|
|
208
|
+
function spawnBackgroundRuntime(args, env, cwd) {
|
|
209
|
+
const { command, args: baseArgs } = buildCliCandidates();
|
|
210
|
+
const child = spawn(command, [...baseArgs, ...args], {
|
|
211
|
+
detached: true,
|
|
212
|
+
cwd,
|
|
213
|
+
stdio: "ignore",
|
|
214
|
+
env
|
|
215
|
+
});
|
|
216
|
+
child.unref();
|
|
217
|
+
return child;
|
|
218
|
+
}
|
|
219
|
+
async function prestartHttpRuntime(options) {
|
|
220
|
+
const serverId = options.id || generateServerId();
|
|
221
|
+
const timeoutMs = parseTimeoutMs(options.timeoutMs);
|
|
222
|
+
const registryPath = options.registryPath || options.registryDir;
|
|
223
|
+
const workspaceRoot = resolveWorkspaceRoot();
|
|
224
|
+
const childEnv = {
|
|
225
|
+
...process.env,
|
|
226
|
+
...registryPath ? {
|
|
227
|
+
PORT_REGISTRY_PATH: registryPath,
|
|
228
|
+
PROCESS_REGISTRY_PATH: resolveSiblingRegistryPath(registryPath, "processes.json")
|
|
229
|
+
} : {}
|
|
230
|
+
};
|
|
231
|
+
const child = spawnBackgroundRuntime([
|
|
232
|
+
"mcp-serve",
|
|
233
|
+
"--type",
|
|
234
|
+
"http",
|
|
235
|
+
"--id",
|
|
236
|
+
serverId,
|
|
237
|
+
"--host",
|
|
238
|
+
options.host || DEFAULT_HOST$1,
|
|
239
|
+
...options.port !== void 0 ? ["--port", String(options.port)] : [],
|
|
240
|
+
...options.config ? ["--config", options.config] : [],
|
|
241
|
+
...options.cache === false ? ["--no-cache"] : [],
|
|
242
|
+
...options.definitionsCache ? ["--definitions-cache", options.definitionsCache] : [],
|
|
243
|
+
...options.clearDefinitionsCache ? ["--clear-definitions-cache"] : [],
|
|
244
|
+
"--proxy-mode",
|
|
245
|
+
options.proxyMode
|
|
246
|
+
], childEnv, workspaceRoot);
|
|
247
|
+
const childExit = new Promise((_, reject) => {
|
|
248
|
+
child.once("exit", (code, signal) => {
|
|
249
|
+
reject(/* @__PURE__ */ new Error(`Background runtime exited before becoming healthy (code=${code ?? "null"}, signal=${signal ?? "null"})`));
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
const runtimeFile = path.join(RuntimeStateService.getDefaultRuntimeDir(), `${serverId}.runtime.json`);
|
|
253
|
+
try {
|
|
254
|
+
await Promise.race([waitForFile(runtimeFile, timeoutMs), childExit]);
|
|
255
|
+
const { host, port } = await Promise.race([waitForHealthyRuntime(serverId, timeoutMs), childExit]);
|
|
256
|
+
return {
|
|
257
|
+
host,
|
|
258
|
+
port,
|
|
259
|
+
serverId,
|
|
260
|
+
workspaceRoot
|
|
261
|
+
};
|
|
262
|
+
} catch (error) {
|
|
263
|
+
throw new Error(`Failed to prestart HTTP runtime '${serverId}': ${error instanceof Error ? error.message : String(error)}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const prestartHttpCommand = new Command("prestart-http").description("Start an mcp-proxy HTTP runtime in the background and wait until it is healthy").option("--id <id>", "Server identifier to assign to the runtime").option("--host <host>", "Host to bind to", DEFAULT_HOST$1).option("-p, --port <port>", "Preferred HTTP port for the runtime", (value) => Number.parseInt(value, 10)).option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Disable configuration caching, always reload from config file").option("--definitions-cache <path>", "Path to prefetched tool/prompt/skill definitions cache file").option("--clear-definitions-cache", "Delete definitions cache before startup", false).option("--proxy-mode <mode>", "How mcp-proxy exposes downstream tools: meta, flat, or search", "meta").option("--registry-path <path>", "Custom registry path or directory for service discovery").option("--registry-dir <path>", "Custom registry directory for service discovery").option("--timeout-ms <ms>", "How long to wait for the runtime to become healthy", String(DEFAULT_TIMEOUT_MS)).action(async (options) => {
|
|
267
|
+
try {
|
|
268
|
+
const { host, port, serverId, workspaceRoot } = await prestartHttpRuntime(options);
|
|
269
|
+
process.stdout.write(`mcp-proxy HTTP runtime ready at http://${host}:${port} (${serverId})\n`);
|
|
270
|
+
process.stdout.write(`runtimeId=${serverId}\n`);
|
|
271
|
+
process.stdout.write(`runtimeUrl=http://${host}:${port}\n`);
|
|
272
|
+
process.stdout.write(`workspaceRoot=${workspaceRoot}\n`);
|
|
273
|
+
} catch (error) {
|
|
274
|
+
throw new Error(`Failed to prestart HTTP runtime '${options.id || "generated-server-id"}': ${error instanceof Error ? error.message : String(error)}`);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
115
278
|
//#endregion
|
|
116
279
|
//#region src/commands/mcp-serve.ts
|
|
117
280
|
/**
|
|
@@ -140,7 +303,7 @@ const CONFIG_FILE_NAMES = [
|
|
|
140
303
|
"mcp-config.json"
|
|
141
304
|
];
|
|
142
305
|
const MCP_ENDPOINT_PATH = "/mcp";
|
|
143
|
-
const DEFAULT_HOST
|
|
306
|
+
const DEFAULT_HOST = "localhost";
|
|
144
307
|
const TRANSPORT_TYPE_STDIO = "stdio";
|
|
145
308
|
const TRANSPORT_TYPE_HTTP = "http";
|
|
146
309
|
const TRANSPORT_TYPE_SSE = "sse";
|
|
@@ -148,10 +311,14 @@ const TRANSPORT_TYPE_STDIO_HTTP = "stdio-http";
|
|
|
148
311
|
const RUNTIME_TRANSPORT = TRANSPORT_TYPE_HTTP;
|
|
149
312
|
const PORT_REGISTRY_SERVICE_HTTP = "mcp-proxy-http";
|
|
150
313
|
const PORT_REGISTRY_SERVICE_TYPE = "service";
|
|
151
|
-
|
|
314
|
+
function getWorkspaceRoot() {
|
|
315
|
+
return resolveWorkspaceRoot();
|
|
316
|
+
}
|
|
152
317
|
const PROCESS_REGISTRY_SERVICE_HTTP = "mcp-proxy-http";
|
|
153
318
|
const PROCESS_REGISTRY_SERVICE_TYPE = "service";
|
|
154
|
-
|
|
319
|
+
function getRegistryRepositoryPath() {
|
|
320
|
+
return getWorkspaceRoot();
|
|
321
|
+
}
|
|
155
322
|
function toErrorMessage$9(error) {
|
|
156
323
|
return error instanceof Error ? error.message : String(error);
|
|
157
324
|
}
|
|
@@ -212,7 +379,7 @@ function createTransportConfig(options, mode) {
|
|
|
212
379
|
return {
|
|
213
380
|
mode,
|
|
214
381
|
port: options.port ?? (Number.isFinite(envPort) ? envPort : void 0),
|
|
215
|
-
host: options.host || process.env.MCP_HOST || DEFAULT_HOST
|
|
382
|
+
host: options.host || process.env.MCP_HOST || DEFAULT_HOST
|
|
216
383
|
};
|
|
217
384
|
}
|
|
218
385
|
function createServerOptions(options, resolvedConfigPath, serverId) {
|
|
@@ -233,7 +400,7 @@ function formatStartError(type, host, port, error) {
|
|
|
233
400
|
function createRuntimeRecord(serverId, config, port, shutdownToken, configPath) {
|
|
234
401
|
return {
|
|
235
402
|
serverId,
|
|
236
|
-
host: config.host ?? DEFAULT_HOST
|
|
403
|
+
host: config.host ?? DEFAULT_HOST,
|
|
237
404
|
port,
|
|
238
405
|
transport: RUNTIME_TRANSPORT,
|
|
239
406
|
shutdownToken,
|
|
@@ -257,7 +424,7 @@ async function createPortRegistryLease(serviceName, host, preferredPort, serverI
|
|
|
257
424
|
} : DEFAULT_PORT_RANGE) {
|
|
258
425
|
const portRegistry = createPortRegistryService();
|
|
259
426
|
const result = await portRegistry.reservePort({
|
|
260
|
-
repositoryPath:
|
|
427
|
+
repositoryPath: getRegistryRepositoryPath(),
|
|
261
428
|
serviceName,
|
|
262
429
|
serviceType: PORT_REGISTRY_SERVICE_TYPE,
|
|
263
430
|
environment: getRegistryEnvironment(),
|
|
@@ -283,7 +450,7 @@ async function createPortRegistryLease(serviceName, host, preferredPort, serverI
|
|
|
283
450
|
if (released) return;
|
|
284
451
|
released = true;
|
|
285
452
|
const releaseResult = await portRegistry.releasePort({
|
|
286
|
-
repositoryPath:
|
|
453
|
+
repositoryPath: getRegistryRepositoryPath(),
|
|
287
454
|
serviceName,
|
|
288
455
|
serviceType: PORT_REGISTRY_SERVICE_TYPE,
|
|
289
456
|
pid: process.pid,
|
|
@@ -297,7 +464,7 @@ async function createPortRegistryLease(serviceName, host, preferredPort, serverI
|
|
|
297
464
|
async function createProcessRegistryLease(serviceName, host, port, serverId, transport, configPath) {
|
|
298
465
|
const processRegistry = createProcessRegistryService();
|
|
299
466
|
const result = await processRegistry.registerProcess({
|
|
300
|
-
repositoryPath:
|
|
467
|
+
repositoryPath: getRegistryRepositoryPath(),
|
|
301
468
|
serviceName,
|
|
302
469
|
serviceType: PROCESS_REGISTRY_SERVICE_TYPE,
|
|
303
470
|
environment: getRegistryEnvironment(),
|
|
@@ -318,7 +485,7 @@ async function createProcessRegistryLease(serviceName, host, port, serverId, tra
|
|
|
318
485
|
if (released) return;
|
|
319
486
|
released = true;
|
|
320
487
|
const releaseResult = await processRegistry.releaseProcess({
|
|
321
|
-
repositoryPath:
|
|
488
|
+
repositoryPath: getRegistryRepositoryPath(),
|
|
322
489
|
serviceName,
|
|
323
490
|
serviceType: PROCESS_REGISTRY_SERVICE_TYPE,
|
|
324
491
|
pid: process.pid,
|
|
@@ -419,13 +586,13 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
419
586
|
min: requestedPort,
|
|
420
587
|
max: requestedPort
|
|
421
588
|
} : DEFAULT_PORT_RANGE;
|
|
422
|
-
const portLease = await createPortRegistryLease(PORT_REGISTRY_SERVICE_HTTP, config.host ?? DEFAULT_HOST
|
|
589
|
+
const portLease = await createPortRegistryLease(PORT_REGISTRY_SERVICE_HTTP, config.host ?? DEFAULT_HOST, requestedPort, runtimeServerId, TRANSPORT_TYPE_HTTP, resolvedConfigPath, portRange);
|
|
423
590
|
const runtimePort = portLease.port;
|
|
424
591
|
const runtimeConfig = {
|
|
425
592
|
...config,
|
|
426
593
|
port: runtimePort
|
|
427
594
|
};
|
|
428
|
-
const processLease = await createProcessRegistryLease(PROCESS_REGISTRY_SERVICE_HTTP, runtimeConfig.host ?? DEFAULT_HOST
|
|
595
|
+
const processLease = await createProcessRegistryLease(PROCESS_REGISTRY_SERVICE_HTTP, runtimeConfig.host ?? DEFAULT_HOST, runtimePort, runtimeServerId, TRANSPORT_TYPE_HTTP, resolvedConfigPath);
|
|
429
596
|
let releasePort = async () => {
|
|
430
597
|
await releasePortLease(portLease ?? null);
|
|
431
598
|
releasePort = async () => void 0;
|
|
@@ -493,20 +660,29 @@ async function startSseTransport(serverOptions, config) {
|
|
|
493
660
|
throw new Error(`Failed to start SSE transport: ${toErrorMessage$9(error)}`);
|
|
494
661
|
}
|
|
495
662
|
}
|
|
496
|
-
async function resolveStdioHttpEndpoint(config) {
|
|
497
|
-
|
|
663
|
+
async function resolveStdioHttpEndpoint(config, options, resolvedConfigPath) {
|
|
664
|
+
const repositoryPath = getRegistryRepositoryPath();
|
|
665
|
+
if (config.port !== void 0) return new URL(`http://${config.host ?? DEFAULT_HOST}:${config.port}${MCP_ENDPOINT_PATH}`);
|
|
498
666
|
const result = await createPortRegistryService().getPort({
|
|
499
|
-
repositoryPath
|
|
667
|
+
repositoryPath,
|
|
500
668
|
serviceName: PORT_REGISTRY_SERVICE_HTTP,
|
|
501
669
|
serviceType: PORT_REGISTRY_SERVICE_TYPE,
|
|
502
670
|
environment: getRegistryEnvironment()
|
|
503
671
|
});
|
|
504
|
-
if (
|
|
505
|
-
|
|
672
|
+
if (result.success && result.record) return new URL(`http://${config.host ?? result.record.host}:${result.record.port}${MCP_ENDPOINT_PATH}`);
|
|
673
|
+
const runtime = await prestartHttpRuntime({
|
|
674
|
+
host: config.host ?? DEFAULT_HOST,
|
|
675
|
+
config: options.config || resolvedConfigPath,
|
|
676
|
+
cache: options.cache,
|
|
677
|
+
definitionsCache: options.definitionsCache,
|
|
678
|
+
clearDefinitionsCache: options.clearDefinitionsCache,
|
|
679
|
+
proxyMode: options.proxyMode
|
|
680
|
+
});
|
|
681
|
+
return new URL(`http://${runtime.host}:${runtime.port}${MCP_ENDPOINT_PATH}`);
|
|
506
682
|
}
|
|
507
|
-
async function startStdioHttpTransport(config) {
|
|
683
|
+
async function startStdioHttpTransport(config, options, resolvedConfigPath) {
|
|
508
684
|
try {
|
|
509
|
-
await startServer(new StdioHttpTransportHandler({ endpoint: await resolveStdioHttpEndpoint(config) }));
|
|
685
|
+
await startServer(new StdioHttpTransportHandler({ endpoint: await resolveStdioHttpEndpoint(config, options, resolvedConfigPath) }));
|
|
510
686
|
} catch (error) {
|
|
511
687
|
throw new Error(`Failed to start stdio-http transport: ${toErrorMessage$9(error)}`);
|
|
512
688
|
}
|
|
@@ -525,7 +701,7 @@ async function startTransport(transportType, options, resolvedConfigPath, server
|
|
|
525
701
|
await startSseTransport(serverOptions, createTransportConfig(options, TRANSPORT_MODE.SSE));
|
|
526
702
|
return;
|
|
527
703
|
}
|
|
528
|
-
await startStdioHttpTransport(createTransportConfig(options, TRANSPORT_MODE.HTTP));
|
|
704
|
+
await startStdioHttpTransport(createTransportConfig(options, TRANSPORT_MODE.HTTP), options, resolvedConfigPath);
|
|
529
705
|
} catch (error) {
|
|
530
706
|
throw new Error(`Failed to start transport '${transportType}': ${toErrorMessage$9(error)}`);
|
|
531
707
|
}
|
|
@@ -533,7 +709,7 @@ async function startTransport(transportType, options, resolvedConfigPath, server
|
|
|
533
709
|
/**
|
|
534
710
|
* MCP Serve command
|
|
535
711
|
*/
|
|
536
|
-
const mcpServeCommand = new Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", `Transport type: ${TRANSPORT_TYPE_STDIO}, ${TRANSPORT_TYPE_HTTP}, ${TRANSPORT_TYPE_SSE}, or ${TRANSPORT_TYPE_STDIO_HTTP}`, TRANSPORT_TYPE_STDIO).option("-p, --port <port>", "Port to listen on (http/sse) or backend port for stdio-http", (val) => parseInt(val, 10)).option("--host <host>", "Host to bind to (http/sse) or backend host for stdio-http", DEFAULT_HOST
|
|
712
|
+
const mcpServeCommand = new Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", `Transport type: ${TRANSPORT_TYPE_STDIO}, ${TRANSPORT_TYPE_HTTP}, ${TRANSPORT_TYPE_SSE}, or ${TRANSPORT_TYPE_STDIO_HTTP}`, TRANSPORT_TYPE_STDIO).option("-p, --port <port>", "Port to listen on (http/sse) or backend port for stdio-http", (val) => parseInt(val, 10)).option("--host <host>", "Host to bind to (http/sse) or backend host for stdio-http", DEFAULT_HOST).option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Disable configuration caching, always reload from config file").option("--definitions-cache <path>", "Path to prefetched tool/prompt/skill definitions cache file").option("--clear-definitions-cache", "Delete definitions cache before startup", false).option("--proxy-mode <mode>", "How mcp-proxy exposes downstream tools: meta, flat, or search", "meta").option("--id <id>", "Unique server identifier (overrides config file id, auto-generated if not provided)").action(async (options) => {
|
|
537
713
|
try {
|
|
538
714
|
const transportType = validateTransportType(options.type.toLowerCase());
|
|
539
715
|
validateProxyMode(options.proxyMode);
|
|
@@ -549,156 +725,6 @@ const mcpServeCommand = new Command("mcp-serve").description("Start MCP server w
|
|
|
549
725
|
}
|
|
550
726
|
});
|
|
551
727
|
|
|
552
|
-
//#endregion
|
|
553
|
-
//#region src/commands/prestart-http.ts
|
|
554
|
-
/**
|
|
555
|
-
* Prestart HTTP Command
|
|
556
|
-
*
|
|
557
|
-
* Starts an mcp-proxy HTTP runtime in the background, waits until it is healthy,
|
|
558
|
-
* and then exits so the runtime can be reused by other commands.
|
|
559
|
-
*/
|
|
560
|
-
const WORKSPACE_MARKERS = [
|
|
561
|
-
"pnpm-workspace.yaml",
|
|
562
|
-
"nx.json",
|
|
563
|
-
".git"
|
|
564
|
-
];
|
|
565
|
-
const DEFAULT_HOST = "localhost";
|
|
566
|
-
const DEFAULT_TIMEOUT_MS = 12e4;
|
|
567
|
-
const POLL_INTERVAL_MS = 250;
|
|
568
|
-
function resolveWorkspaceRoot(startPath = process.cwd()) {
|
|
569
|
-
let current = path.resolve(startPath);
|
|
570
|
-
while (true) {
|
|
571
|
-
for (const marker of WORKSPACE_MARKERS) if (existsSync(path.join(current, marker))) return current;
|
|
572
|
-
const parent = path.dirname(current);
|
|
573
|
-
if (parent === current) return process.cwd();
|
|
574
|
-
current = parent;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
function resolveSiblingRegistryPath(registryPath, fileName) {
|
|
578
|
-
if (!registryPath) return;
|
|
579
|
-
const resolved = path.resolve(registryPath);
|
|
580
|
-
if (path.extname(resolved) === ".json") return path.join(path.dirname(resolved), fileName);
|
|
581
|
-
return path.join(resolved, fileName);
|
|
582
|
-
}
|
|
583
|
-
function buildCliCandidates() {
|
|
584
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
585
|
-
const __dirname = path.dirname(__filename);
|
|
586
|
-
const distCandidates = [
|
|
587
|
-
path.resolve(__dirname, "cli.mjs"),
|
|
588
|
-
path.resolve(__dirname, "..", "dist", "cli.mjs"),
|
|
589
|
-
path.resolve(__dirname, "..", "..", "dist", "cli.mjs")
|
|
590
|
-
];
|
|
591
|
-
const srcCandidates = [path.resolve(__dirname, "..", "cli.ts"), path.resolve(__dirname, "..", "..", "src", "cli.ts")];
|
|
592
|
-
for (const candidate of distCandidates) if (existsSync(candidate)) return {
|
|
593
|
-
command: process.execPath,
|
|
594
|
-
args: [candidate]
|
|
595
|
-
};
|
|
596
|
-
for (const candidate of srcCandidates) if (existsSync(candidate)) return {
|
|
597
|
-
command: process.execPath,
|
|
598
|
-
args: [
|
|
599
|
-
"--import",
|
|
600
|
-
"tsx",
|
|
601
|
-
candidate
|
|
602
|
-
]
|
|
603
|
-
};
|
|
604
|
-
throw new Error("Unable to locate mcp-proxy CLI entrypoint");
|
|
605
|
-
}
|
|
606
|
-
function parseTimeoutMs(value) {
|
|
607
|
-
if (!value) return DEFAULT_TIMEOUT_MS;
|
|
608
|
-
const parsed = Number.parseInt(value, 10);
|
|
609
|
-
if (!Number.isInteger(parsed) || parsed <= 0) throw new Error(`Invalid timeout value: ${value}`);
|
|
610
|
-
return parsed;
|
|
611
|
-
}
|
|
612
|
-
async function waitForFile(filePath, timeoutMs) {
|
|
613
|
-
const deadline = Date.now() + timeoutMs;
|
|
614
|
-
while (Date.now() < deadline) {
|
|
615
|
-
try {
|
|
616
|
-
await access(filePath);
|
|
617
|
-
return;
|
|
618
|
-
} catch {}
|
|
619
|
-
await new Promise((resolve$1) => setTimeout(resolve$1, POLL_INTERVAL_MS));
|
|
620
|
-
}
|
|
621
|
-
throw new Error(`Timed out waiting for runtime state file: ${filePath}`);
|
|
622
|
-
}
|
|
623
|
-
async function waitForHealthyRuntime(serverId, timeoutMs) {
|
|
624
|
-
const runtimeStateService = new RuntimeStateService();
|
|
625
|
-
const deadline = Date.now() + timeoutMs;
|
|
626
|
-
while (Date.now() < deadline) {
|
|
627
|
-
const record = await runtimeStateService.read(serverId);
|
|
628
|
-
if (record) {
|
|
629
|
-
const healthUrl = `http://${record.host}:${record.port}/health`;
|
|
630
|
-
try {
|
|
631
|
-
const response = await fetch(healthUrl);
|
|
632
|
-
if (response.ok) {
|
|
633
|
-
const payload = await response.json().catch(() => null);
|
|
634
|
-
if (!payload || payload.transport === "http") return {
|
|
635
|
-
host: record.host,
|
|
636
|
-
port: record.port
|
|
637
|
-
};
|
|
638
|
-
}
|
|
639
|
-
} catch {}
|
|
640
|
-
}
|
|
641
|
-
await new Promise((resolve$1) => setTimeout(resolve$1, POLL_INTERVAL_MS));
|
|
642
|
-
}
|
|
643
|
-
throw new Error(`Timed out waiting for HTTP runtime '${serverId}' to become healthy`);
|
|
644
|
-
}
|
|
645
|
-
function spawnBackgroundRuntime(args, env) {
|
|
646
|
-
const { command, args: baseArgs } = buildCliCandidates();
|
|
647
|
-
const child = spawn(command, [...baseArgs, ...args], {
|
|
648
|
-
detached: true,
|
|
649
|
-
stdio: "ignore",
|
|
650
|
-
env
|
|
651
|
-
});
|
|
652
|
-
child.unref();
|
|
653
|
-
return child;
|
|
654
|
-
}
|
|
655
|
-
const prestartHttpCommand = new Command("prestart-http").description("Start an mcp-proxy HTTP runtime in the background and wait until it is healthy").option("--id <id>", "Server identifier to assign to the runtime").option("--host <host>", "Host to bind to", DEFAULT_HOST).option("-p, --port <port>", "Preferred HTTP port for the runtime", (value) => Number.parseInt(value, 10)).option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Disable configuration caching, always reload from config file").option("--definitions-cache <path>", "Path to prefetched tool/prompt/skill definitions cache file").option("--clear-definitions-cache", "Delete definitions cache before startup", false).option("--proxy-mode <mode>", "How mcp-proxy exposes downstream tools: meta, flat, or search", "meta").option("--registry-path <path>", "Custom registry path or directory for service discovery").option("--registry-dir <path>", "Custom registry directory for service discovery").option("--timeout-ms <ms>", "How long to wait for the runtime to become healthy", String(DEFAULT_TIMEOUT_MS)).action(async (options) => {
|
|
656
|
-
const serverId = options.id || generateServerId();
|
|
657
|
-
const timeoutMs = parseTimeoutMs(options.timeoutMs);
|
|
658
|
-
const registryPath = options.registryPath || options.registryDir;
|
|
659
|
-
new RuntimeStateService();
|
|
660
|
-
const workspaceRoot = resolveWorkspaceRoot(process.cwd());
|
|
661
|
-
const childEnv = {
|
|
662
|
-
...process.env,
|
|
663
|
-
...registryPath ? {
|
|
664
|
-
PORT_REGISTRY_PATH: registryPath,
|
|
665
|
-
PROCESS_REGISTRY_PATH: resolveSiblingRegistryPath(registryPath, "processes.json")
|
|
666
|
-
} : {}
|
|
667
|
-
};
|
|
668
|
-
const child = spawnBackgroundRuntime([
|
|
669
|
-
"mcp-serve",
|
|
670
|
-
"--type",
|
|
671
|
-
"http",
|
|
672
|
-
"--id",
|
|
673
|
-
serverId,
|
|
674
|
-
"--host",
|
|
675
|
-
options.host || DEFAULT_HOST,
|
|
676
|
-
...options.port !== void 0 ? ["--port", String(options.port)] : [],
|
|
677
|
-
...options.config ? ["--config", options.config] : [],
|
|
678
|
-
...options.cache === false ? ["--no-cache"] : [],
|
|
679
|
-
...options.definitionsCache ? ["--definitions-cache", options.definitionsCache] : [],
|
|
680
|
-
...options.clearDefinitionsCache ? ["--clear-definitions-cache"] : [],
|
|
681
|
-
"--proxy-mode",
|
|
682
|
-
options.proxyMode
|
|
683
|
-
], childEnv);
|
|
684
|
-
const childExit = new Promise((_, reject) => {
|
|
685
|
-
child.once("exit", (code, signal) => {
|
|
686
|
-
reject(/* @__PURE__ */ new Error(`Background runtime exited before becoming healthy (code=${code ?? "null"}, signal=${signal ?? "null"})`));
|
|
687
|
-
});
|
|
688
|
-
});
|
|
689
|
-
const runtimeFile = path.join(RuntimeStateService.getDefaultRuntimeDir(), `${serverId}.runtime.json`);
|
|
690
|
-
try {
|
|
691
|
-
await Promise.race([waitForFile(runtimeFile, timeoutMs), childExit]);
|
|
692
|
-
const { host, port } = await Promise.race([waitForHealthyRuntime(serverId, timeoutMs), childExit]);
|
|
693
|
-
process.stdout.write(`mcp-proxy HTTP runtime ready at http://${host}:${port} (${serverId})\n`);
|
|
694
|
-
process.stdout.write(`runtimeId=${serverId}\n`);
|
|
695
|
-
process.stdout.write(`runtimeUrl=http://${host}:${port}\n`);
|
|
696
|
-
process.stdout.write(`workspaceRoot=${workspaceRoot}\n`);
|
|
697
|
-
} catch (error) {
|
|
698
|
-
throw new Error(`Failed to prestart HTTP runtime '${serverId}': ${error instanceof Error ? error.message : String(error)}`);
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
|
|
702
728
|
//#endregion
|
|
703
729
|
//#region src/commands/bootstrap.ts
|
|
704
730
|
function toErrorMessage$8(error) {
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as SearchListToolsTool, D as findConfigFile, E as generateServerId, S as UseToolTool, T as DefinitionsCacheService, _ as StopServerService, a as createProxyContainer, b as createProxyLogger, c as createStdioHttpTransportHandler, f as StdioHttpTransportHandler, g as SkillService, h as HttpTransportHandler, i as createHttpTransportHandler, l as createStdioTransportHandler, m as SseTransportHandler, n as createServer, p as StdioTransportHandler, r as createSessionServer, s as createSseTransportHandler, t as TRANSPORT_MODE, u as initializeSharedServices, v as RuntimeStateService, w as DescribeToolsTool, x as ConfigFetcherService, y as McpClientManagerService } from "./src-
|
|
1
|
+
import { C as SearchListToolsTool, D as findConfigFile, E as generateServerId, S as UseToolTool, T as DefinitionsCacheService, _ as StopServerService, a as createProxyContainer, b as createProxyLogger, c as createStdioHttpTransportHandler, f as StdioHttpTransportHandler, g as SkillService, h as HttpTransportHandler, i as createHttpTransportHandler, l as createStdioTransportHandler, m as SseTransportHandler, n as createServer, p as StdioTransportHandler, r as createSessionServer, s as createSseTransportHandler, t as TRANSPORT_MODE, u as initializeSharedServices, v as RuntimeStateService, w as DescribeToolsTool, x as ConfigFetcherService, y as McpClientManagerService } from "./src-BgRM8oW0.mjs";
|
|
2
2
|
|
|
3
3
|
export { ConfigFetcherService, DefinitionsCacheService, DescribeToolsTool, HttpTransportHandler, McpClientManagerService, RuntimeStateService, SearchListToolsTool, SkillService, SseTransportHandler, StdioHttpTransportHandler, StdioTransportHandler, StopServerService, TRANSPORT_MODE, UseToolTool, createHttpTransportHandler, createProxyContainer, createProxyLogger, createServer, createSessionServer, createSseTransportHandler, createStdioHttpTransportHandler, createStdioTransportHandler, findConfigFile, generateServerId, initializeSharedServices };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/mcp-proxy",
|
|
3
3
|
"description": "MCP proxy server package",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.5",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mcp",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"liquidjs": "^10.21.0",
|
|
29
29
|
"zod": "^3.24.1",
|
|
30
30
|
"@agimon-ai/foundation-process-registry": "0.2.3",
|
|
31
|
-
"@agimon-ai/
|
|
32
|
-
"@agimon-ai/
|
|
31
|
+
"@agimon-ai/log-sink-mcp": "0.2.7",
|
|
32
|
+
"@agimon-ai/foundation-port-registry": "0.2.7"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/express": "^5.0.0",
|