@agimon-ai/mcp-proxy 0.4.2 → 0.4.3
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 +42 -164
- package/dist/cli.mjs +42 -164
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-CNXwWpA2.mjs → src-0OJqEpGA.mjs} +1 -1
- package/dist/{src-Cm2AVRBA.cjs → src-G1hs2GLZ.cjs} +1 -1
- package/package.json +4 -4
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-G1hs2GLZ.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");
|
|
@@ -141,21 +141,16 @@ const CONFIG_FILE_NAMES = [
|
|
|
141
141
|
"mcp-config.json"
|
|
142
142
|
];
|
|
143
143
|
const MCP_ENDPOINT_PATH = "/mcp";
|
|
144
|
-
const DEFAULT_PORT = 3e3;
|
|
145
144
|
const DEFAULT_HOST$1 = "localhost";
|
|
146
145
|
const TRANSPORT_TYPE_STDIO = "stdio";
|
|
147
146
|
const TRANSPORT_TYPE_HTTP = "http";
|
|
148
147
|
const TRANSPORT_TYPE_SSE = "sse";
|
|
149
148
|
const TRANSPORT_TYPE_STDIO_HTTP = "stdio-http";
|
|
150
149
|
const RUNTIME_TRANSPORT = TRANSPORT_TYPE_HTTP;
|
|
151
|
-
const STDIO_HTTP_PROXY_STOP_LABEL = "Failed stopping stdio-http proxy";
|
|
152
|
-
const INTERNAL_HTTP_STOP_LABEL = "Failed stopping internal HTTP transport";
|
|
153
150
|
const PORT_REGISTRY_SERVICE_HTTP = "mcp-proxy-http";
|
|
154
|
-
const PORT_REGISTRY_SERVICE_STDIO_HTTP = "mcp-proxy-stdio-http";
|
|
155
151
|
const PORT_REGISTRY_SERVICE_TYPE = "service";
|
|
156
152
|
const PORT_REGISTRY_REPOSITORY_PATH = process.cwd();
|
|
157
153
|
const PROCESS_REGISTRY_SERVICE_HTTP = "mcp-proxy-http";
|
|
158
|
-
const PROCESS_REGISTRY_SERVICE_STDIO_HTTP = "mcp-proxy-stdio-http";
|
|
159
154
|
const PROCESS_REGISTRY_SERVICE_TYPE = "service";
|
|
160
155
|
const PROCESS_REGISTRY_REPOSITORY_PATH = process.cwd();
|
|
161
156
|
function toErrorMessage$9(error) {
|
|
@@ -167,13 +162,6 @@ function isValidTransportType(type) {
|
|
|
167
162
|
function isValidProxyMode(mode) {
|
|
168
163
|
return mode === "meta" || mode === "flat" || mode === "search";
|
|
169
164
|
}
|
|
170
|
-
function isAddressInUseError(error) {
|
|
171
|
-
if (error instanceof Error && error.message.includes("EADDRINUSE")) return true;
|
|
172
|
-
if (typeof error !== "object" || error === null) return false;
|
|
173
|
-
if ("code" in error && error.code === "EADDRINUSE") return true;
|
|
174
|
-
if ("message" in error && typeof error.message === "string" && error.message.includes("EADDRINUSE")) return true;
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
165
|
async function pathExists(filePath) {
|
|
178
166
|
try {
|
|
179
167
|
await (0, node_fs_promises.access)(filePath, node_fs.constants.F_OK);
|
|
@@ -224,7 +212,7 @@ function createTransportConfig(options, mode) {
|
|
|
224
212
|
const envPort = process.env.MCP_PORT ? Number(process.env.MCP_PORT) : void 0;
|
|
225
213
|
return {
|
|
226
214
|
mode,
|
|
227
|
-
port: options.port ?? (Number.isFinite(envPort) ? envPort : void 0)
|
|
215
|
+
port: options.port ?? (Number.isFinite(envPort) ? envPort : void 0),
|
|
228
216
|
host: options.host || process.env.MCP_HOST || DEFAULT_HOST$1
|
|
229
217
|
};
|
|
230
218
|
}
|
|
@@ -241,7 +229,7 @@ function createServerOptions(options, resolvedConfigPath, serverId) {
|
|
|
241
229
|
function formatStartError(type, host, port, error) {
|
|
242
230
|
const startErrorMessage = toErrorMessage$9(error);
|
|
243
231
|
if (type === TRANSPORT_TYPE_STDIO) return `Failed to start MCP server with transport '${type}': ${startErrorMessage}`;
|
|
244
|
-
return `Failed to start MCP server with transport '${type}' on ${host}:${port}: ${startErrorMessage}`;
|
|
232
|
+
return `Failed to start MCP server with transport '${type}' on ${port === void 0 ? `${host} (dynamic port)` : `${host}:${port}`}: ${startErrorMessage}`;
|
|
245
233
|
}
|
|
246
234
|
function createRuntimeRecord(serverId, config, port, shutdownToken, configPath) {
|
|
247
235
|
return {
|
|
@@ -264,10 +252,10 @@ function createProcessRegistryService() {
|
|
|
264
252
|
function getRegistryEnvironment() {
|
|
265
253
|
return process.env.NODE_ENV ?? "development";
|
|
266
254
|
}
|
|
267
|
-
async function createPortRegistryLease(serviceName, host, preferredPort, serverId, transport, configPath, portRange = {
|
|
255
|
+
async function createPortRegistryLease(serviceName, host, preferredPort, serverId, transport, configPath, portRange = preferredPort !== void 0 ? {
|
|
268
256
|
min: preferredPort,
|
|
269
257
|
max: preferredPort
|
|
270
|
-
}) {
|
|
258
|
+
} : __agimon_ai_foundation_port_registry.DEFAULT_PORT_RANGE) {
|
|
271
259
|
const portRegistry = createPortRegistryService();
|
|
272
260
|
const result = await portRegistry.reservePort({
|
|
273
261
|
repositoryPath: PORT_REGISTRY_REPOSITORY_PATH,
|
|
@@ -285,7 +273,10 @@ async function createPortRegistryLease(serviceName, host, preferredPort, serverI
|
|
|
285
273
|
...configPath ? { configPath } : {}
|
|
286
274
|
}
|
|
287
275
|
});
|
|
288
|
-
if (!result.success || !result.record)
|
|
276
|
+
if (!result.success || !result.record) {
|
|
277
|
+
const requestedPortLabel = preferredPort === void 0 ? "dynamic port" : `port ${preferredPort}`;
|
|
278
|
+
throw new Error(result.error || `Failed to reserve ${requestedPortLabel} in port registry`);
|
|
279
|
+
}
|
|
289
280
|
let released = false;
|
|
290
281
|
return {
|
|
291
282
|
port: result.record.port,
|
|
@@ -394,27 +385,6 @@ async function cleanupFailedRuntimeStartup(handler, runtimeStateService, serverI
|
|
|
394
385
|
await removeRuntimeRecord(runtimeStateService, serverId);
|
|
395
386
|
}
|
|
396
387
|
}
|
|
397
|
-
async function stopTransportWithContext(label, stopOperation) {
|
|
398
|
-
try {
|
|
399
|
-
await stopOperation();
|
|
400
|
-
} catch (error) {
|
|
401
|
-
throw new Error(`${label}: ${toErrorMessage$9(error)}`);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
async function removeRuntimeRecordDuringStop(runtimeStateService, serverId) {
|
|
405
|
-
try {
|
|
406
|
-
await removeRuntimeRecord(runtimeStateService, serverId);
|
|
407
|
-
} catch (error) {
|
|
408
|
-
throw new Error(`Failed to remove runtime state during HTTP stop callback for '${serverId}': ${toErrorMessage$9(error)}`);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
function createStdioHttpInternalTransport(sharedServices, config, adminOptions) {
|
|
412
|
-
try {
|
|
413
|
-
return new require_src.HttpTransportHandler(() => require_src.createSessionServer(sharedServices), config, adminOptions);
|
|
414
|
-
} catch (error) {
|
|
415
|
-
throw new Error(`Failed to create internal HTTP transport for stdio-http proxy: ${toErrorMessage$9(error)}`);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
388
|
/**
|
|
419
389
|
* Start MCP server with given transport handler
|
|
420
390
|
* @param handler - The transport handler to start
|
|
@@ -445,14 +415,23 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
445
415
|
const runtimeStateService = new require_src.RuntimeStateService();
|
|
446
416
|
const shutdownToken = (0, node_crypto.randomUUID)();
|
|
447
417
|
const runtimeServerId = serverOptions.serverId ?? require_src.generateServerId();
|
|
448
|
-
const
|
|
449
|
-
const
|
|
450
|
-
|
|
418
|
+
const requestedPort = config.port;
|
|
419
|
+
const portRange = requestedPort !== void 0 ? {
|
|
420
|
+
min: requestedPort,
|
|
421
|
+
max: requestedPort
|
|
422
|
+
} : __agimon_ai_foundation_port_registry.DEFAULT_PORT_RANGE;
|
|
423
|
+
const portLease = await createPortRegistryLease(PORT_REGISTRY_SERVICE_HTTP, config.host ?? DEFAULT_HOST$1, requestedPort, runtimeServerId, TRANSPORT_TYPE_HTTP, resolvedConfigPath, portRange);
|
|
424
|
+
const runtimePort = portLease.port;
|
|
425
|
+
const runtimeConfig = {
|
|
426
|
+
...config,
|
|
427
|
+
port: runtimePort
|
|
428
|
+
};
|
|
429
|
+
const processLease = await createProcessRegistryLease(PROCESS_REGISTRY_SERVICE_HTTP, runtimeConfig.host ?? DEFAULT_HOST$1, runtimePort, runtimeServerId, TRANSPORT_TYPE_HTTP, resolvedConfigPath);
|
|
451
430
|
let releasePort = async () => {
|
|
452
431
|
await releasePortLease(portLease ?? null);
|
|
453
432
|
releasePort = async () => void 0;
|
|
454
433
|
};
|
|
455
|
-
const runtimeRecord = createRuntimeRecord(runtimeServerId,
|
|
434
|
+
const runtimeRecord = createRuntimeRecord(runtimeServerId, runtimeConfig, runtimePort, shutdownToken, resolvedConfigPath);
|
|
456
435
|
let handler;
|
|
457
436
|
let isStopping = false;
|
|
458
437
|
const stopHandler = async () => {
|
|
@@ -468,7 +447,7 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
468
447
|
}
|
|
469
448
|
};
|
|
470
449
|
try {
|
|
471
|
-
handler = new require_src.HttpTransportHandler(() => require_src.createSessionServer(sharedServices),
|
|
450
|
+
handler = new require_src.HttpTransportHandler(() => require_src.createSessionServer(sharedServices), runtimeConfig, createHttpAdminOptions(runtimeRecord.serverId, shutdownToken, stopHandler));
|
|
472
451
|
} catch (error) {
|
|
473
452
|
await releasePort();
|
|
474
453
|
await processLease.release({
|
|
@@ -486,7 +465,7 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
486
465
|
kill: false,
|
|
487
466
|
releasePort: false
|
|
488
467
|
});
|
|
489
|
-
await
|
|
468
|
+
await removeRuntimeRecord(runtimeStateService, runtimeRecord.serverId);
|
|
490
469
|
});
|
|
491
470
|
await writeRuntimeRecord(runtimeStateService, runtimeRecord);
|
|
492
471
|
} catch (error) {
|
|
@@ -501,19 +480,6 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
501
480
|
}
|
|
502
481
|
console.error(`Runtime state: http://${runtimeRecord.host}:${runtimeRecord.port} (${runtimeRecord.serverId})`);
|
|
503
482
|
}
|
|
504
|
-
async function stopInternalHttpTransport(stdioHttpHandler, httpHandler, ownsInternalHttpTransport) {
|
|
505
|
-
try {
|
|
506
|
-
const stopOperations = [stopTransportWithContext(STDIO_HTTP_PROXY_STOP_LABEL, async () => {
|
|
507
|
-
await stdioHttpHandler.stop();
|
|
508
|
-
})];
|
|
509
|
-
if (ownsInternalHttpTransport && httpHandler) stopOperations.push(stopTransportWithContext(INTERNAL_HTTP_STOP_LABEL, async () => {
|
|
510
|
-
await httpHandler.stop();
|
|
511
|
-
}));
|
|
512
|
-
await Promise.all(stopOperations);
|
|
513
|
-
} catch (error) {
|
|
514
|
-
throw new Error(`Failed to stop stdio-http transport: ${toErrorMessage$9(error)}`);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
483
|
async function startStdioTransport(serverOptions) {
|
|
518
484
|
try {
|
|
519
485
|
await startServer(new require_src.StdioTransportHandler(await require_src.createServer(serverOptions)));
|
|
@@ -528,111 +494,21 @@ async function startSseTransport(serverOptions, config) {
|
|
|
528
494
|
throw new Error(`Failed to start SSE transport: ${toErrorMessage$9(error)}`);
|
|
529
495
|
}
|
|
530
496
|
}
|
|
531
|
-
async function
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
497
|
+
async function resolveStdioHttpEndpoint(config) {
|
|
498
|
+
if (config.port !== void 0) return new URL(`http://${config.host ?? DEFAULT_HOST$1}:${config.port}${MCP_ENDPOINT_PATH}`);
|
|
499
|
+
const result = await createPortRegistryService().getPort({
|
|
500
|
+
repositoryPath: PORT_REGISTRY_REPOSITORY_PATH,
|
|
501
|
+
serviceName: PORT_REGISTRY_SERVICE_HTTP,
|
|
502
|
+
serviceType: PORT_REGISTRY_SERVICE_TYPE,
|
|
503
|
+
environment: getRegistryEnvironment()
|
|
504
|
+
});
|
|
505
|
+
if (!result.success || !result.record) throw new Error(result.error || "No prestarted HTTP backend found for stdio-http transport");
|
|
506
|
+
return new URL(`http://${config.host ?? result.record.host}:${result.record.port}${MCP_ENDPOINT_PATH}`);
|
|
507
|
+
}
|
|
508
|
+
async function startStdioHttpTransport(config) {
|
|
535
509
|
try {
|
|
536
|
-
|
|
537
|
-
const envPort = process.env.MCP_PORT ? Number(process.env.MCP_PORT) : void 0;
|
|
538
|
-
const requestedPort = options.port ?? (Number.isFinite(envPort) ? envPort : void 0) ?? DEFAULT_PORT;
|
|
539
|
-
const portRange = options.port !== void 0 || Number.isFinite(envPort) ? {
|
|
540
|
-
min: requestedPort,
|
|
541
|
-
max: requestedPort
|
|
542
|
-
} : __agimon_ai_foundation_port_registry.DEFAULT_PORT_RANGE;
|
|
543
|
-
portLease = await createPortRegistryLease(PORT_REGISTRY_SERVICE_STDIO_HTTP, config.host ?? DEFAULT_HOST$1, requestedPort, serverId, TRANSPORT_TYPE_STDIO_HTTP, resolvedConfigPath, portRange);
|
|
544
|
-
const internalPort = portLease.port;
|
|
545
|
-
const transportConfig = {
|
|
546
|
-
...config,
|
|
547
|
-
port: internalPort
|
|
548
|
-
};
|
|
549
|
-
const stdioHttpHandler = new require_src.StdioHttpTransportHandler({ endpoint: new URL(`http://${transportConfig.host}:${transportConfig.port}${MCP_ENDPOINT_PATH}`) });
|
|
550
|
-
const runtimeStateService = new require_src.RuntimeStateService();
|
|
551
|
-
const shutdownToken = (0, node_crypto.randomUUID)();
|
|
552
|
-
processLease = await createProcessRegistryLease(PROCESS_REGISTRY_SERVICE_STDIO_HTTP, transportConfig.host ?? DEFAULT_HOST$1, internalPort, serverId, TRANSPORT_TYPE_STDIO_HTTP, resolvedConfigPath);
|
|
553
|
-
let httpHandler = null;
|
|
554
|
-
let ownsInternalHttpTransport = false;
|
|
555
|
-
let isStopping = false;
|
|
556
|
-
const stopOwnedRuntime = async () => {
|
|
557
|
-
if (isStopping) return;
|
|
558
|
-
isStopping = true;
|
|
559
|
-
try {
|
|
560
|
-
await Promise.all([stopInternalHttpTransport(stdioHttpHandler, httpHandler, ownsInternalHttpTransport), removeRuntimeRecord(runtimeStateService, serverId)]);
|
|
561
|
-
await releasePortLease(portLease ?? null);
|
|
562
|
-
if (shared.services) await shared.services.dispose();
|
|
563
|
-
ownsInternalHttpTransport = false;
|
|
564
|
-
process.exit(0);
|
|
565
|
-
} catch (error) {
|
|
566
|
-
console.error(`Unexpected error during admin shutdown: ${toErrorMessage$9(error)}`);
|
|
567
|
-
process.exit(1);
|
|
568
|
-
}
|
|
569
|
-
};
|
|
570
|
-
const adminOptions = createHttpAdminOptions(serverId, shutdownToken, stopOwnedRuntime);
|
|
571
|
-
await startServer({
|
|
572
|
-
async start() {
|
|
573
|
-
let initialProxyConnectError;
|
|
574
|
-
try {
|
|
575
|
-
await stdioHttpHandler.start();
|
|
576
|
-
return;
|
|
577
|
-
} catch (error) {
|
|
578
|
-
initialProxyConnectError = error;
|
|
579
|
-
}
|
|
580
|
-
if (!shared.services) shared.services = await require_src.initializeSharedServices(serverOptions);
|
|
581
|
-
try {
|
|
582
|
-
httpHandler = createStdioHttpInternalTransport(shared.services, transportConfig, adminOptions);
|
|
583
|
-
await httpHandler.start();
|
|
584
|
-
ownsInternalHttpTransport = true;
|
|
585
|
-
} catch (error) {
|
|
586
|
-
if (!isAddressInUseError(error)) throw new Error(`Failed to start internal HTTP transport for stdio-http proxy: ${toErrorMessage$9(error)}`);
|
|
587
|
-
}
|
|
588
|
-
try {
|
|
589
|
-
await stdioHttpHandler.start();
|
|
590
|
-
} catch (error) {
|
|
591
|
-
let rollbackStopErrorMessage = "";
|
|
592
|
-
if (ownsInternalHttpTransport && httpHandler) {
|
|
593
|
-
try {
|
|
594
|
-
await httpHandler.stop();
|
|
595
|
-
} catch (stopError) {
|
|
596
|
-
rollbackStopErrorMessage = toErrorMessage$9(stopError);
|
|
597
|
-
}
|
|
598
|
-
ownsInternalHttpTransport = false;
|
|
599
|
-
}
|
|
600
|
-
const retryErrorMessage = toErrorMessage$9(error);
|
|
601
|
-
const initialErrorMessage = toErrorMessage$9(initialProxyConnectError);
|
|
602
|
-
const rollbackMessage = rollbackStopErrorMessage ? `; rollback stop failed: ${rollbackStopErrorMessage}` : "";
|
|
603
|
-
throw new Error(`Failed to start stdio-http proxy bridge: initial connect failed (${initialErrorMessage}); retry failed (${retryErrorMessage})${rollbackMessage}`);
|
|
604
|
-
}
|
|
605
|
-
if (ownsInternalHttpTransport) try {
|
|
606
|
-
await writeRuntimeRecord(runtimeStateService, createRuntimeRecord(serverId, transportConfig, internalPort, shutdownToken, resolvedConfigPath));
|
|
607
|
-
} catch (error) {
|
|
608
|
-
throw new Error(`Failed to persist runtime state for stdio-http server '${serverId}': ${toErrorMessage$9(error)}`);
|
|
609
|
-
}
|
|
610
|
-
},
|
|
611
|
-
async stop() {
|
|
612
|
-
try {
|
|
613
|
-
await Promise.all([stopInternalHttpTransport(stdioHttpHandler, httpHandler, ownsInternalHttpTransport), removeRuntimeRecord(runtimeStateService, serverId)]);
|
|
614
|
-
await releasePortLease(portLease ?? null);
|
|
615
|
-
await processLease?.release({
|
|
616
|
-
kill: false,
|
|
617
|
-
releasePort: false
|
|
618
|
-
});
|
|
619
|
-
ownsInternalHttpTransport = false;
|
|
620
|
-
if (shared.services) await shared.services.dispose();
|
|
621
|
-
} catch (error) {
|
|
622
|
-
ownsInternalHttpTransport = false;
|
|
623
|
-
throw new Error(`Failed during stdio-http shutdown for '${serverId}': ${toErrorMessage$9(error)}`);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
});
|
|
510
|
+
await startServer(new require_src.StdioHttpTransportHandler({ endpoint: await resolveStdioHttpEndpoint(config) }));
|
|
627
511
|
} catch (error) {
|
|
628
|
-
try {
|
|
629
|
-
await portLease?.release();
|
|
630
|
-
await processLease?.release({
|
|
631
|
-
kill: false,
|
|
632
|
-
releasePort: false
|
|
633
|
-
});
|
|
634
|
-
} catch {}
|
|
635
|
-
if (shared.services) await shared.services.dispose();
|
|
636
512
|
throw new Error(`Failed to start stdio-http transport: ${toErrorMessage$9(error)}`);
|
|
637
513
|
}
|
|
638
514
|
}
|
|
@@ -650,7 +526,7 @@ async function startTransport(transportType, options, resolvedConfigPath, server
|
|
|
650
526
|
await startSseTransport(serverOptions, createTransportConfig(options, require_src.TRANSPORT_MODE.SSE));
|
|
651
527
|
return;
|
|
652
528
|
}
|
|
653
|
-
await startStdioHttpTransport(
|
|
529
|
+
await startStdioHttpTransport(createTransportConfig(options, require_src.TRANSPORT_MODE.HTTP));
|
|
654
530
|
} catch (error) {
|
|
655
531
|
throw new Error(`Failed to start transport '${transportType}': ${toErrorMessage$9(error)}`);
|
|
656
532
|
}
|
|
@@ -658,7 +534,7 @@ async function startTransport(transportType, options, resolvedConfigPath, server
|
|
|
658
534
|
/**
|
|
659
535
|
* MCP Serve command
|
|
660
536
|
*/
|
|
661
|
-
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
|
|
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$1).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) => {
|
|
662
538
|
try {
|
|
663
539
|
const transportType = validateTransportType(options.type.toLowerCase());
|
|
664
540
|
validateProxyMode(options.proxyMode);
|
|
@@ -667,7 +543,9 @@ const mcpServeCommand = new commander.Command("mcp-serve").description("Start MC
|
|
|
667
543
|
} catch (error) {
|
|
668
544
|
const rawTransportType = options.type.toLowerCase();
|
|
669
545
|
const transportType = isValidTransportType(rawTransportType) ? rawTransportType : TRANSPORT_TYPE_STDIO;
|
|
670
|
-
|
|
546
|
+
const envPort = process.env.MCP_PORT ? Number(process.env.MCP_PORT) : void 0;
|
|
547
|
+
const requestedPort = options.port ?? (Number.isFinite(envPort) ? envPort : void 0);
|
|
548
|
+
console.error(formatStartError(transportType, options.host, requestedPort, error));
|
|
671
549
|
process.exit(1);
|
|
672
550
|
}
|
|
673
551
|
});
|
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-0OJqEpGA.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";
|
|
@@ -140,21 +140,16 @@ const CONFIG_FILE_NAMES = [
|
|
|
140
140
|
"mcp-config.json"
|
|
141
141
|
];
|
|
142
142
|
const MCP_ENDPOINT_PATH = "/mcp";
|
|
143
|
-
const DEFAULT_PORT = 3e3;
|
|
144
143
|
const DEFAULT_HOST$1 = "localhost";
|
|
145
144
|
const TRANSPORT_TYPE_STDIO = "stdio";
|
|
146
145
|
const TRANSPORT_TYPE_HTTP = "http";
|
|
147
146
|
const TRANSPORT_TYPE_SSE = "sse";
|
|
148
147
|
const TRANSPORT_TYPE_STDIO_HTTP = "stdio-http";
|
|
149
148
|
const RUNTIME_TRANSPORT = TRANSPORT_TYPE_HTTP;
|
|
150
|
-
const STDIO_HTTP_PROXY_STOP_LABEL = "Failed stopping stdio-http proxy";
|
|
151
|
-
const INTERNAL_HTTP_STOP_LABEL = "Failed stopping internal HTTP transport";
|
|
152
149
|
const PORT_REGISTRY_SERVICE_HTTP = "mcp-proxy-http";
|
|
153
|
-
const PORT_REGISTRY_SERVICE_STDIO_HTTP = "mcp-proxy-stdio-http";
|
|
154
150
|
const PORT_REGISTRY_SERVICE_TYPE = "service";
|
|
155
151
|
const PORT_REGISTRY_REPOSITORY_PATH = process.cwd();
|
|
156
152
|
const PROCESS_REGISTRY_SERVICE_HTTP = "mcp-proxy-http";
|
|
157
|
-
const PROCESS_REGISTRY_SERVICE_STDIO_HTTP = "mcp-proxy-stdio-http";
|
|
158
153
|
const PROCESS_REGISTRY_SERVICE_TYPE = "service";
|
|
159
154
|
const PROCESS_REGISTRY_REPOSITORY_PATH = process.cwd();
|
|
160
155
|
function toErrorMessage$9(error) {
|
|
@@ -166,13 +161,6 @@ function isValidTransportType(type) {
|
|
|
166
161
|
function isValidProxyMode(mode) {
|
|
167
162
|
return mode === "meta" || mode === "flat" || mode === "search";
|
|
168
163
|
}
|
|
169
|
-
function isAddressInUseError(error) {
|
|
170
|
-
if (error instanceof Error && error.message.includes("EADDRINUSE")) return true;
|
|
171
|
-
if (typeof error !== "object" || error === null) return false;
|
|
172
|
-
if ("code" in error && error.code === "EADDRINUSE") return true;
|
|
173
|
-
if ("message" in error && typeof error.message === "string" && error.message.includes("EADDRINUSE")) return true;
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
164
|
async function pathExists(filePath) {
|
|
177
165
|
try {
|
|
178
166
|
await access(filePath, constants.F_OK);
|
|
@@ -223,7 +211,7 @@ function createTransportConfig(options, mode) {
|
|
|
223
211
|
const envPort = process.env.MCP_PORT ? Number(process.env.MCP_PORT) : void 0;
|
|
224
212
|
return {
|
|
225
213
|
mode,
|
|
226
|
-
port: options.port ?? (Number.isFinite(envPort) ? envPort : void 0)
|
|
214
|
+
port: options.port ?? (Number.isFinite(envPort) ? envPort : void 0),
|
|
227
215
|
host: options.host || process.env.MCP_HOST || DEFAULT_HOST$1
|
|
228
216
|
};
|
|
229
217
|
}
|
|
@@ -240,7 +228,7 @@ function createServerOptions(options, resolvedConfigPath, serverId) {
|
|
|
240
228
|
function formatStartError(type, host, port, error) {
|
|
241
229
|
const startErrorMessage = toErrorMessage$9(error);
|
|
242
230
|
if (type === TRANSPORT_TYPE_STDIO) return `Failed to start MCP server with transport '${type}': ${startErrorMessage}`;
|
|
243
|
-
return `Failed to start MCP server with transport '${type}' on ${host}:${port}: ${startErrorMessage}`;
|
|
231
|
+
return `Failed to start MCP server with transport '${type}' on ${port === void 0 ? `${host} (dynamic port)` : `${host}:${port}`}: ${startErrorMessage}`;
|
|
244
232
|
}
|
|
245
233
|
function createRuntimeRecord(serverId, config, port, shutdownToken, configPath) {
|
|
246
234
|
return {
|
|
@@ -263,10 +251,10 @@ function createProcessRegistryService() {
|
|
|
263
251
|
function getRegistryEnvironment() {
|
|
264
252
|
return process.env.NODE_ENV ?? "development";
|
|
265
253
|
}
|
|
266
|
-
async function createPortRegistryLease(serviceName, host, preferredPort, serverId, transport, configPath, portRange = {
|
|
254
|
+
async function createPortRegistryLease(serviceName, host, preferredPort, serverId, transport, configPath, portRange = preferredPort !== void 0 ? {
|
|
267
255
|
min: preferredPort,
|
|
268
256
|
max: preferredPort
|
|
269
|
-
}) {
|
|
257
|
+
} : DEFAULT_PORT_RANGE) {
|
|
270
258
|
const portRegistry = createPortRegistryService();
|
|
271
259
|
const result = await portRegistry.reservePort({
|
|
272
260
|
repositoryPath: PORT_REGISTRY_REPOSITORY_PATH,
|
|
@@ -284,7 +272,10 @@ async function createPortRegistryLease(serviceName, host, preferredPort, serverI
|
|
|
284
272
|
...configPath ? { configPath } : {}
|
|
285
273
|
}
|
|
286
274
|
});
|
|
287
|
-
if (!result.success || !result.record)
|
|
275
|
+
if (!result.success || !result.record) {
|
|
276
|
+
const requestedPortLabel = preferredPort === void 0 ? "dynamic port" : `port ${preferredPort}`;
|
|
277
|
+
throw new Error(result.error || `Failed to reserve ${requestedPortLabel} in port registry`);
|
|
278
|
+
}
|
|
288
279
|
let released = false;
|
|
289
280
|
return {
|
|
290
281
|
port: result.record.port,
|
|
@@ -393,27 +384,6 @@ async function cleanupFailedRuntimeStartup(handler, runtimeStateService, serverI
|
|
|
393
384
|
await removeRuntimeRecord(runtimeStateService, serverId);
|
|
394
385
|
}
|
|
395
386
|
}
|
|
396
|
-
async function stopTransportWithContext(label, stopOperation) {
|
|
397
|
-
try {
|
|
398
|
-
await stopOperation();
|
|
399
|
-
} catch (error) {
|
|
400
|
-
throw new Error(`${label}: ${toErrorMessage$9(error)}`);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
async function removeRuntimeRecordDuringStop(runtimeStateService, serverId) {
|
|
404
|
-
try {
|
|
405
|
-
await removeRuntimeRecord(runtimeStateService, serverId);
|
|
406
|
-
} catch (error) {
|
|
407
|
-
throw new Error(`Failed to remove runtime state during HTTP stop callback for '${serverId}': ${toErrorMessage$9(error)}`);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
function createStdioHttpInternalTransport(sharedServices, config, adminOptions) {
|
|
411
|
-
try {
|
|
412
|
-
return new HttpTransportHandler(() => createSessionServer(sharedServices), config, adminOptions);
|
|
413
|
-
} catch (error) {
|
|
414
|
-
throw new Error(`Failed to create internal HTTP transport for stdio-http proxy: ${toErrorMessage$9(error)}`);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
387
|
/**
|
|
418
388
|
* Start MCP server with given transport handler
|
|
419
389
|
* @param handler - The transport handler to start
|
|
@@ -444,14 +414,23 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
444
414
|
const runtimeStateService = new RuntimeStateService();
|
|
445
415
|
const shutdownToken = randomUUID();
|
|
446
416
|
const runtimeServerId = serverOptions.serverId ?? generateServerId();
|
|
447
|
-
const
|
|
448
|
-
const
|
|
449
|
-
|
|
417
|
+
const requestedPort = config.port;
|
|
418
|
+
const portRange = requestedPort !== void 0 ? {
|
|
419
|
+
min: requestedPort,
|
|
420
|
+
max: requestedPort
|
|
421
|
+
} : DEFAULT_PORT_RANGE;
|
|
422
|
+
const portLease = await createPortRegistryLease(PORT_REGISTRY_SERVICE_HTTP, config.host ?? DEFAULT_HOST$1, requestedPort, runtimeServerId, TRANSPORT_TYPE_HTTP, resolvedConfigPath, portRange);
|
|
423
|
+
const runtimePort = portLease.port;
|
|
424
|
+
const runtimeConfig = {
|
|
425
|
+
...config,
|
|
426
|
+
port: runtimePort
|
|
427
|
+
};
|
|
428
|
+
const processLease = await createProcessRegistryLease(PROCESS_REGISTRY_SERVICE_HTTP, runtimeConfig.host ?? DEFAULT_HOST$1, runtimePort, runtimeServerId, TRANSPORT_TYPE_HTTP, resolvedConfigPath);
|
|
450
429
|
let releasePort = async () => {
|
|
451
430
|
await releasePortLease(portLease ?? null);
|
|
452
431
|
releasePort = async () => void 0;
|
|
453
432
|
};
|
|
454
|
-
const runtimeRecord = createRuntimeRecord(runtimeServerId,
|
|
433
|
+
const runtimeRecord = createRuntimeRecord(runtimeServerId, runtimeConfig, runtimePort, shutdownToken, resolvedConfigPath);
|
|
455
434
|
let handler;
|
|
456
435
|
let isStopping = false;
|
|
457
436
|
const stopHandler = async () => {
|
|
@@ -467,7 +446,7 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
467
446
|
}
|
|
468
447
|
};
|
|
469
448
|
try {
|
|
470
|
-
handler = new HttpTransportHandler(() => createSessionServer(sharedServices),
|
|
449
|
+
handler = new HttpTransportHandler(() => createSessionServer(sharedServices), runtimeConfig, createHttpAdminOptions(runtimeRecord.serverId, shutdownToken, stopHandler));
|
|
471
450
|
} catch (error) {
|
|
472
451
|
await releasePort();
|
|
473
452
|
await processLease.release({
|
|
@@ -485,7 +464,7 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
485
464
|
kill: false,
|
|
486
465
|
releasePort: false
|
|
487
466
|
});
|
|
488
|
-
await
|
|
467
|
+
await removeRuntimeRecord(runtimeStateService, runtimeRecord.serverId);
|
|
489
468
|
});
|
|
490
469
|
await writeRuntimeRecord(runtimeStateService, runtimeRecord);
|
|
491
470
|
} catch (error) {
|
|
@@ -500,19 +479,6 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
500
479
|
}
|
|
501
480
|
console.error(`Runtime state: http://${runtimeRecord.host}:${runtimeRecord.port} (${runtimeRecord.serverId})`);
|
|
502
481
|
}
|
|
503
|
-
async function stopInternalHttpTransport(stdioHttpHandler, httpHandler, ownsInternalHttpTransport) {
|
|
504
|
-
try {
|
|
505
|
-
const stopOperations = [stopTransportWithContext(STDIO_HTTP_PROXY_STOP_LABEL, async () => {
|
|
506
|
-
await stdioHttpHandler.stop();
|
|
507
|
-
})];
|
|
508
|
-
if (ownsInternalHttpTransport && httpHandler) stopOperations.push(stopTransportWithContext(INTERNAL_HTTP_STOP_LABEL, async () => {
|
|
509
|
-
await httpHandler.stop();
|
|
510
|
-
}));
|
|
511
|
-
await Promise.all(stopOperations);
|
|
512
|
-
} catch (error) {
|
|
513
|
-
throw new Error(`Failed to stop stdio-http transport: ${toErrorMessage$9(error)}`);
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
482
|
async function startStdioTransport(serverOptions) {
|
|
517
483
|
try {
|
|
518
484
|
await startServer(new StdioTransportHandler(await createServer(serverOptions)));
|
|
@@ -527,111 +493,21 @@ async function startSseTransport(serverOptions, config) {
|
|
|
527
493
|
throw new Error(`Failed to start SSE transport: ${toErrorMessage$9(error)}`);
|
|
528
494
|
}
|
|
529
495
|
}
|
|
530
|
-
async function
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
496
|
+
async function resolveStdioHttpEndpoint(config) {
|
|
497
|
+
if (config.port !== void 0) return new URL(`http://${config.host ?? DEFAULT_HOST$1}:${config.port}${MCP_ENDPOINT_PATH}`);
|
|
498
|
+
const result = await createPortRegistryService().getPort({
|
|
499
|
+
repositoryPath: PORT_REGISTRY_REPOSITORY_PATH,
|
|
500
|
+
serviceName: PORT_REGISTRY_SERVICE_HTTP,
|
|
501
|
+
serviceType: PORT_REGISTRY_SERVICE_TYPE,
|
|
502
|
+
environment: getRegistryEnvironment()
|
|
503
|
+
});
|
|
504
|
+
if (!result.success || !result.record) throw new Error(result.error || "No prestarted HTTP backend found for stdio-http transport");
|
|
505
|
+
return new URL(`http://${config.host ?? result.record.host}:${result.record.port}${MCP_ENDPOINT_PATH}`);
|
|
506
|
+
}
|
|
507
|
+
async function startStdioHttpTransport(config) {
|
|
534
508
|
try {
|
|
535
|
-
|
|
536
|
-
const envPort = process.env.MCP_PORT ? Number(process.env.MCP_PORT) : void 0;
|
|
537
|
-
const requestedPort = options.port ?? (Number.isFinite(envPort) ? envPort : void 0) ?? DEFAULT_PORT;
|
|
538
|
-
const portRange = options.port !== void 0 || Number.isFinite(envPort) ? {
|
|
539
|
-
min: requestedPort,
|
|
540
|
-
max: requestedPort
|
|
541
|
-
} : DEFAULT_PORT_RANGE;
|
|
542
|
-
portLease = await createPortRegistryLease(PORT_REGISTRY_SERVICE_STDIO_HTTP, config.host ?? DEFAULT_HOST$1, requestedPort, serverId, TRANSPORT_TYPE_STDIO_HTTP, resolvedConfigPath, portRange);
|
|
543
|
-
const internalPort = portLease.port;
|
|
544
|
-
const transportConfig = {
|
|
545
|
-
...config,
|
|
546
|
-
port: internalPort
|
|
547
|
-
};
|
|
548
|
-
const stdioHttpHandler = new StdioHttpTransportHandler({ endpoint: new URL(`http://${transportConfig.host}:${transportConfig.port}${MCP_ENDPOINT_PATH}`) });
|
|
549
|
-
const runtimeStateService = new RuntimeStateService();
|
|
550
|
-
const shutdownToken = randomUUID();
|
|
551
|
-
processLease = await createProcessRegistryLease(PROCESS_REGISTRY_SERVICE_STDIO_HTTP, transportConfig.host ?? DEFAULT_HOST$1, internalPort, serverId, TRANSPORT_TYPE_STDIO_HTTP, resolvedConfigPath);
|
|
552
|
-
let httpHandler = null;
|
|
553
|
-
let ownsInternalHttpTransport = false;
|
|
554
|
-
let isStopping = false;
|
|
555
|
-
const stopOwnedRuntime = async () => {
|
|
556
|
-
if (isStopping) return;
|
|
557
|
-
isStopping = true;
|
|
558
|
-
try {
|
|
559
|
-
await Promise.all([stopInternalHttpTransport(stdioHttpHandler, httpHandler, ownsInternalHttpTransport), removeRuntimeRecord(runtimeStateService, serverId)]);
|
|
560
|
-
await releasePortLease(portLease ?? null);
|
|
561
|
-
if (shared.services) await shared.services.dispose();
|
|
562
|
-
ownsInternalHttpTransport = false;
|
|
563
|
-
process.exit(0);
|
|
564
|
-
} catch (error) {
|
|
565
|
-
console.error(`Unexpected error during admin shutdown: ${toErrorMessage$9(error)}`);
|
|
566
|
-
process.exit(1);
|
|
567
|
-
}
|
|
568
|
-
};
|
|
569
|
-
const adminOptions = createHttpAdminOptions(serverId, shutdownToken, stopOwnedRuntime);
|
|
570
|
-
await startServer({
|
|
571
|
-
async start() {
|
|
572
|
-
let initialProxyConnectError;
|
|
573
|
-
try {
|
|
574
|
-
await stdioHttpHandler.start();
|
|
575
|
-
return;
|
|
576
|
-
} catch (error) {
|
|
577
|
-
initialProxyConnectError = error;
|
|
578
|
-
}
|
|
579
|
-
if (!shared.services) shared.services = await initializeSharedServices(serverOptions);
|
|
580
|
-
try {
|
|
581
|
-
httpHandler = createStdioHttpInternalTransport(shared.services, transportConfig, adminOptions);
|
|
582
|
-
await httpHandler.start();
|
|
583
|
-
ownsInternalHttpTransport = true;
|
|
584
|
-
} catch (error) {
|
|
585
|
-
if (!isAddressInUseError(error)) throw new Error(`Failed to start internal HTTP transport for stdio-http proxy: ${toErrorMessage$9(error)}`);
|
|
586
|
-
}
|
|
587
|
-
try {
|
|
588
|
-
await stdioHttpHandler.start();
|
|
589
|
-
} catch (error) {
|
|
590
|
-
let rollbackStopErrorMessage = "";
|
|
591
|
-
if (ownsInternalHttpTransport && httpHandler) {
|
|
592
|
-
try {
|
|
593
|
-
await httpHandler.stop();
|
|
594
|
-
} catch (stopError) {
|
|
595
|
-
rollbackStopErrorMessage = toErrorMessage$9(stopError);
|
|
596
|
-
}
|
|
597
|
-
ownsInternalHttpTransport = false;
|
|
598
|
-
}
|
|
599
|
-
const retryErrorMessage = toErrorMessage$9(error);
|
|
600
|
-
const initialErrorMessage = toErrorMessage$9(initialProxyConnectError);
|
|
601
|
-
const rollbackMessage = rollbackStopErrorMessage ? `; rollback stop failed: ${rollbackStopErrorMessage}` : "";
|
|
602
|
-
throw new Error(`Failed to start stdio-http proxy bridge: initial connect failed (${initialErrorMessage}); retry failed (${retryErrorMessage})${rollbackMessage}`);
|
|
603
|
-
}
|
|
604
|
-
if (ownsInternalHttpTransport) try {
|
|
605
|
-
await writeRuntimeRecord(runtimeStateService, createRuntimeRecord(serverId, transportConfig, internalPort, shutdownToken, resolvedConfigPath));
|
|
606
|
-
} catch (error) {
|
|
607
|
-
throw new Error(`Failed to persist runtime state for stdio-http server '${serverId}': ${toErrorMessage$9(error)}`);
|
|
608
|
-
}
|
|
609
|
-
},
|
|
610
|
-
async stop() {
|
|
611
|
-
try {
|
|
612
|
-
await Promise.all([stopInternalHttpTransport(stdioHttpHandler, httpHandler, ownsInternalHttpTransport), removeRuntimeRecord(runtimeStateService, serverId)]);
|
|
613
|
-
await releasePortLease(portLease ?? null);
|
|
614
|
-
await processLease?.release({
|
|
615
|
-
kill: false,
|
|
616
|
-
releasePort: false
|
|
617
|
-
});
|
|
618
|
-
ownsInternalHttpTransport = false;
|
|
619
|
-
if (shared.services) await shared.services.dispose();
|
|
620
|
-
} catch (error) {
|
|
621
|
-
ownsInternalHttpTransport = false;
|
|
622
|
-
throw new Error(`Failed during stdio-http shutdown for '${serverId}': ${toErrorMessage$9(error)}`);
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
});
|
|
509
|
+
await startServer(new StdioHttpTransportHandler({ endpoint: await resolveStdioHttpEndpoint(config) }));
|
|
626
510
|
} catch (error) {
|
|
627
|
-
try {
|
|
628
|
-
await portLease?.release();
|
|
629
|
-
await processLease?.release({
|
|
630
|
-
kill: false,
|
|
631
|
-
releasePort: false
|
|
632
|
-
});
|
|
633
|
-
} catch {}
|
|
634
|
-
if (shared.services) await shared.services.dispose();
|
|
635
511
|
throw new Error(`Failed to start stdio-http transport: ${toErrorMessage$9(error)}`);
|
|
636
512
|
}
|
|
637
513
|
}
|
|
@@ -649,7 +525,7 @@ async function startTransport(transportType, options, resolvedConfigPath, server
|
|
|
649
525
|
await startSseTransport(serverOptions, createTransportConfig(options, TRANSPORT_MODE.SSE));
|
|
650
526
|
return;
|
|
651
527
|
}
|
|
652
|
-
await startStdioHttpTransport(
|
|
528
|
+
await startStdioHttpTransport(createTransportConfig(options, TRANSPORT_MODE.HTTP));
|
|
653
529
|
} catch (error) {
|
|
654
530
|
throw new Error(`Failed to start transport '${transportType}': ${toErrorMessage$9(error)}`);
|
|
655
531
|
}
|
|
@@ -657,7 +533,7 @@ async function startTransport(transportType, options, resolvedConfigPath, server
|
|
|
657
533
|
/**
|
|
658
534
|
* MCP Serve command
|
|
659
535
|
*/
|
|
660
|
-
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
|
|
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$1).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) => {
|
|
661
537
|
try {
|
|
662
538
|
const transportType = validateTransportType(options.type.toLowerCase());
|
|
663
539
|
validateProxyMode(options.proxyMode);
|
|
@@ -666,7 +542,9 @@ const mcpServeCommand = new Command("mcp-serve").description("Start MCP server w
|
|
|
666
542
|
} catch (error) {
|
|
667
543
|
const rawTransportType = options.type.toLowerCase();
|
|
668
544
|
const transportType = isValidTransportType(rawTransportType) ? rawTransportType : TRANSPORT_TYPE_STDIO;
|
|
669
|
-
|
|
545
|
+
const envPort = process.env.MCP_PORT ? Number(process.env.MCP_PORT) : void 0;
|
|
546
|
+
const requestedPort = options.port ?? (Number.isFinite(envPort) ? envPort : void 0);
|
|
547
|
+
console.error(formatStartError(transportType, options.host, requestedPort, error));
|
|
670
548
|
process.exit(1);
|
|
671
549
|
}
|
|
672
550
|
});
|
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-0OJqEpGA.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.3",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mcp",
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"js-yaml": "^4.1.0",
|
|
28
28
|
"liquidjs": "^10.21.0",
|
|
29
29
|
"zod": "^3.24.1",
|
|
30
|
-
"@agimon-ai/foundation-
|
|
31
|
-
"@agimon-ai/
|
|
32
|
-
"@agimon-ai/
|
|
30
|
+
"@agimon-ai/foundation-process-registry": "0.2.3",
|
|
31
|
+
"@agimon-ai/foundation-port-registry": "0.2.7",
|
|
32
|
+
"@agimon-ai/log-sink-mcp": "0.2.7"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/express": "^5.0.0",
|