@agiflowai/one-mcp 0.3.12 → 0.3.14

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 CHANGED
@@ -1,192 +1,14 @@
1
1
  #!/usr/bin/env node
2
- const require_http = require('./http-B4_JfY6t.cjs');
2
+ const require_src = require('./src-iTE9Cero.cjs');
3
3
  let node_fs_promises = require("node:fs/promises");
4
+ let node_fs = require("node:fs");
5
+ let node_crypto = require("node:crypto");
4
6
  let node_path = require("node:path");
5
7
  let liquidjs = require("liquidjs");
8
+ let node_child_process = require("node:child_process");
6
9
  let commander = require("commander");
7
10
  let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
8
- let node_child_process = require("node:child_process");
9
-
10
- //#region src/templates/mcp-config.yaml.liquid?raw
11
- var mcp_config_yaml_default = "# MCP Server Configuration\n# This file configures the MCP servers that one-mcp will connect to\n#\n# Environment Variable Interpolation:\n# Use ${VAR_NAME} syntax to reference environment variables\n# Example: ${HOME}, ${API_KEY}, ${DATABASE_URL}\n#\n# Instructions:\n# - config.instruction: Server's default instruction (from server documentation)\n# - instruction: User override (optional, takes precedence over config.instruction)\n# - config.toolBlacklist: Array of tool names to hide/block from this server\n# - config.omitToolDescription: Boolean to show only tool names without descriptions (saves tokens)\n\n# Remote Configuration Sources (OPTIONAL)\n# Fetch and merge configurations from remote URLs\n# Remote configs are merged with local configs based on merge strategy\n#\n# SECURITY: SSRF Protection is ENABLED by default\n# - Only HTTPS URLs are allowed (set security.enforceHttps: false to allow HTTP)\n# - Private IPs and localhost are blocked (set security.allowPrivateIPs: true for internal networks)\n# - Blocked ranges: 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16\nremoteConfigs:\n # Example 1: Basic remote config with default security\n # - url: ${AGIFLOW_URL}/api/v1/mcp-configs\n # headers:\n # Authorization: Bearer ${AGIFLOW_API_KEY}\n # mergeStrategy: local-priority # Options: local-priority (default), remote-priority, merge-deep\n #\n # Example 2: Remote config with custom security settings (for internal networks)\n # - url: ${INTERNAL_URL}/mcp-configs\n # headers:\n # Authorization: Bearer ${INTERNAL_TOKEN}\n # security:\n # allowPrivateIPs: true # Allow internal IPs (default: false)\n # enforceHttps: false # Allow HTTP (default: true, HTTPS only)\n # mergeStrategy: local-priority\n #\n # Example 3: Remote config with additional validation (OPTIONAL)\n # - url: ${AGIFLOW_URL}/api/v1/mcp-configs\n # headers:\n # Authorization: Bearer ${AGIFLOW_API_KEY}\n # X-API-Key: ${AGIFLOW_API_KEY}\n # security:\n # enforceHttps: true # Require HTTPS (default: true)\n # allowPrivateIPs: false # Block private IPs (default: false)\n # validation: # OPTIONAL: Additional regex validation on top of security checks\n # url: ^https://.*\\.agiflow\\.io/.* # OPTIONAL: Regex pattern to validate URL format\n # headers: # OPTIONAL: Regex patterns to validate header values\n # Authorization: ^Bearer [A-Za-z0-9_-]+$\n # X-API-Key: ^[A-Za-z0-9_-]{32,}$\n # mergeStrategy: local-priority\n\nmcpServers:\n{%- if mcpServers %}{% for server in mcpServers %}\n {{ server.name }}:\n command: {{ server.command }}\n args:{% for arg in server.args %}\n - '{{ arg }}'{% endfor %}\n # env:\n # LOG_LEVEL: info\n # # API_KEY: ${MY_API_KEY}\n # config:\n # instruction: Use this server for...\n # # toolBlacklist:\n # # - tool_to_block\n # # omitToolDescription: true\n{% endfor %}\n # Example MCP server using SSE transport\n # remote-server:\n # url: https://example.com/mcp\n # type: sse\n # headers:\n # Authorization: Bearer ${API_KEY}\n # config:\n # instruction: This server provides tools for...\n{% else %}\n # Example MCP server using stdio transport\n example-server:\n command: node\n args:\n - /path/to/mcp-server/build/index.js\n env:\n # Environment variables for the MCP server\n LOG_LEVEL: info\n # You can use environment variable interpolation:\n # DATABASE_URL: ${DATABASE_URL}\n # API_KEY: ${MY_API_KEY}\n config:\n # Server's default instruction (from server documentation)\n instruction: Use this server for...\n # Optional: Block specific tools from being listed or executed\n # toolBlacklist:\n # - dangerous_tool_name\n # - another_blocked_tool\n # Optional: Omit tool descriptions to save tokens (default: false)\n # omitToolDescription: true\n # instruction: Optional user override - takes precedence over config.instruction\n\n # Example MCP server using SSE transport with environment variables\n # remote-server:\n # url: https://example.com/mcp\n # type: sse\n # headers:\n # # Use ${VAR_NAME} to interpolate environment variables\n # Authorization: Bearer ${API_KEY}\n # config:\n # instruction: This server provides tools for...\n # # Optional: Block specific tools from being listed or executed\n # # toolBlacklist:\n # # - tool_to_block\n # # Optional: Omit tool descriptions to save tokens (default: false)\n # # omitToolDescription: true\n # # instruction: Optional user override\n{% endif %}\n";
12
-
13
- //#endregion
14
- //#region src/templates/mcp-config.json?raw
15
- var mcp_config_default = "{\n \"_comment\": \"MCP Server Configuration - Use ${VAR_NAME} syntax for environment variable interpolation\",\n \"_instructions\": \"config.instruction: Server's default instruction | instruction: User override (takes precedence)\",\n \"mcpServers\": {\n \"example-server\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/mcp-server/build/index.js\"],\n \"env\": {\n \"LOG_LEVEL\": \"info\",\n \"_comment\": \"You can use environment variable interpolation:\",\n \"_example_DATABASE_URL\": \"${DATABASE_URL}\",\n \"_example_API_KEY\": \"${MY_API_KEY}\"\n },\n \"config\": {\n \"instruction\": \"Use this server for...\"\n },\n \"_instruction_override\": \"Optional user override - takes precedence over config.instruction\"\n }\n }\n}\n";
16
-
17
- //#endregion
18
- //#region src/commands/init.ts
19
- /**
20
- * Init Command
21
- *
22
- * DESIGN PATTERNS:
23
- * - Command pattern with Commander for CLI argument parsing
24
- * - Async/await pattern for asynchronous operations
25
- * - Error handling pattern with try-catch and proper exit codes
26
- *
27
- * CODING STANDARDS:
28
- * - Use async action handlers for asynchronous operations
29
- * - Provide clear option descriptions and default values
30
- * - Handle errors gracefully with process.exit()
31
- * - Log progress and errors to console
32
- * - Use Commander's .option() and .argument() for inputs
33
- *
34
- * AVOID:
35
- * - Synchronous blocking operations in action handlers
36
- * - Missing error handling (always use try-catch)
37
- * - Hardcoded values (use options or environment variables)
38
- * - Not exiting with appropriate exit codes on errors
39
- */
40
- /**
41
- * Initialize MCP configuration file
42
- */
43
- const initCommand = new commander.Command("init").description("Initialize MCP configuration file").option("-o, --output <path>", "Output file path", "mcp-config.yaml").option("--json", "Generate JSON config instead of YAML", false).option("-f, --force", "Overwrite existing config file", false).option("--mcp-servers <json>", "JSON string of MCP servers to add to config (optional)").action(async (options) => {
44
- try {
45
- const outputPath = (0, node_path.resolve)(options.output);
46
- const isYaml = !options.json && (outputPath.endsWith(".yaml") || outputPath.endsWith(".yml"));
47
- let content;
48
- if (isYaml) {
49
- const liquid = new liquidjs.Liquid();
50
- let mcpServersData = null;
51
- if (options.mcpServers) try {
52
- const serversObj = JSON.parse(options.mcpServers);
53
- mcpServersData = Object.entries(serversObj).map(([name, config]) => ({
54
- name,
55
- command: config.command,
56
- args: config.args
57
- }));
58
- } catch (parseError) {
59
- __agiflowai_aicode_utils.log.error("Failed to parse --mcp-servers JSON:", parseError instanceof Error ? parseError.message : String(parseError));
60
- process.exit(1);
61
- }
62
- content = await liquid.parseAndRender(mcp_config_yaml_default, { mcpServers: mcpServersData });
63
- } else content = mcp_config_default;
64
- try {
65
- await (0, node_fs_promises.writeFile)(outputPath, content, {
66
- encoding: "utf-8",
67
- flag: options.force ? "w" : "wx"
68
- });
69
- } catch (error) {
70
- if (error && typeof error === "object" && "code" in error && error.code === "EEXIST") {
71
- __agiflowai_aicode_utils.log.error(`Config file already exists: ${outputPath}`);
72
- __agiflowai_aicode_utils.log.info("Use --force to overwrite");
73
- process.exit(1);
74
- }
75
- throw error;
76
- }
77
- __agiflowai_aicode_utils.log.info(`MCP configuration file created: ${outputPath}`);
78
- __agiflowai_aicode_utils.log.info("Next steps:");
79
- __agiflowai_aicode_utils.log.info("1. Edit the configuration file to add your MCP servers");
80
- __agiflowai_aicode_utils.log.info(`2. Run: one-mcp mcp-serve --config ${outputPath}`);
81
- } catch (error) {
82
- __agiflowai_aicode_utils.log.error("Error executing init:", error instanceof Error ? error.message : String(error));
83
- process.exit(1);
84
- }
85
- });
86
-
87
- //#endregion
88
- //#region src/types/index.ts
89
- /**
90
- * Transport mode constants
91
- */
92
- const TRANSPORT_MODE = {
93
- STDIO: "stdio",
94
- HTTP: "http",
95
- SSE: "sse"
96
- };
97
-
98
- //#endregion
99
- //#region src/commands/mcp-serve.ts
100
- /**
101
- * MCP Serve Command
102
- *
103
- * DESIGN PATTERNS:
104
- * - Command pattern with Commander for CLI argument parsing
105
- * - Transport abstraction pattern for flexible deployment (stdio, HTTP, SSE)
106
- * - Factory pattern for creating transport handlers
107
- * - Graceful shutdown pattern with signal handling
108
- *
109
- * CODING STANDARDS:
110
- * - Use async/await for asynchronous operations
111
- * - Implement proper error handling with try-catch blocks
112
- * - Handle process signals for graceful shutdown
113
- * - Provide clear CLI options and help messages
114
- *
115
- * AVOID:
116
- * - Hardcoded configuration values (use CLI options or environment variables)
117
- * - Missing error handling for transport startup
118
- * - Not cleaning up resources on shutdown
119
- */
120
- /**
121
- * Type guard to validate transport type
122
- * @param type - The transport type string to validate
123
- * @returns True if the type is a valid transport type
124
- */
125
- function isValidTransportType(type) {
126
- return type === "stdio" || type === "http" || type === "sse";
127
- }
128
- function isValidProxyMode(mode) {
129
- return mode === "meta" || mode === "flat" || mode === "search";
130
- }
131
- /**
132
- * Start MCP server with given transport handler
133
- * @param handler - The transport handler to start
134
- */
135
- async function startServer(handler) {
136
- await handler.start();
137
- const shutdown = async (signal) => {
138
- console.error(`\nReceived ${signal}, shutting down gracefully...`);
139
- try {
140
- await handler.stop();
141
- process.exit(0);
142
- } catch (error) {
143
- console.error("Error during shutdown:", error);
144
- process.exit(1);
145
- }
146
- };
147
- process.on("SIGINT", () => shutdown("SIGINT"));
148
- process.on("SIGTERM", () => shutdown("SIGTERM"));
149
- }
150
- /**
151
- * MCP Serve command
152
- */
153
- const mcpServeCommand = new commander.Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", "Transport type: stdio, http, or sse", "stdio").option("-p, --port <port>", "Port to listen on (http/sse only)", (val) => parseInt(val, 10), 3e3).option("--host <host>", "Host to bind to (http/sse only)", "localhost").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 one-mcp 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) => {
154
- const transportType = options.type.toLowerCase();
155
- if (!isValidTransportType(transportType)) {
156
- console.error(`Unknown transport type: '${transportType}'. Valid options: stdio, http, sse`);
157
- process.exit(1);
158
- }
159
- if (!isValidProxyMode(options.proxyMode)) {
160
- console.error(`Unknown proxy mode: '${options.proxyMode}'. Valid options: meta, flat, search`);
161
- process.exit(1);
162
- }
163
- try {
164
- const serverOptions = {
165
- configFilePath: options.config || require_http.findConfigFile() || void 0,
166
- noCache: options.cache === false,
167
- serverId: options.id,
168
- definitionsCachePath: options.definitionsCache,
169
- clearDefinitionsCache: options.clearDefinitionsCache,
170
- proxyMode: options.proxyMode
171
- };
172
- if (transportType === "stdio") await startServer(new require_http.StdioTransportHandler(await require_http.createServer(serverOptions)));
173
- else if (transportType === "http") await startServer(new require_http.HttpTransportHandler(await require_http.createServer(serverOptions), {
174
- mode: TRANSPORT_MODE.HTTP,
175
- port: options.port || Number(process.env.MCP_PORT) || 3e3,
176
- host: options.host || process.env.MCP_HOST || "localhost"
177
- }));
178
- else if (transportType === "sse") await startServer(new require_http.SseTransportHandler(await require_http.createServer(serverOptions), {
179
- mode: TRANSPORT_MODE.SSE,
180
- port: options.port || Number(process.env.MCP_PORT) || 3e3,
181
- host: options.host || process.env.MCP_HOST || "localhost"
182
- }));
183
- } catch (error) {
184
- console.error(`Failed to start MCP server with transport '${transportType}' on ${options.host}:${options.port}:`, error);
185
- process.exit(1);
186
- }
187
- });
188
11
 
189
- //#endregion
190
12
  //#region src/services/PrefetchService/constants.ts
191
13
  /**
192
14
  * PrefetchService Constants
@@ -531,7 +353,7 @@ var PrefetchService = class {
531
353
  * @returns Promise with success status and output
532
354
  */
533
355
  runCommand(command, args) {
534
- return new Promise((resolve$1) => {
356
+ return new Promise((resolve$2) => {
535
357
  const proc = (0, node_child_process.spawn)(command, args, {
536
358
  stdio: [
537
359
  STDIO_IGNORE,
@@ -549,13 +371,13 @@ var PrefetchService = class {
549
371
  stderr += data.toString();
550
372
  });
551
373
  proc.on("close", (code) => {
552
- resolve$1({
374
+ resolve$2({
553
375
  success: code === EXIT_CODE_SUCCESS,
554
376
  output: stdout || stderr
555
377
  });
556
378
  });
557
379
  proc.on("error", (error) => {
558
- resolve$1({
380
+ resolve$2({
559
381
  success: false,
560
382
  output: error.message
561
383
  });
@@ -564,6 +386,475 @@ var PrefetchService = class {
564
386
  }
565
387
  };
566
388
 
389
+ //#endregion
390
+ //#region src/templates/mcp-config.yaml.liquid?raw
391
+ var mcp_config_yaml_default = "# MCP Server Configuration\n# This file configures the MCP servers that one-mcp will connect to\n#\n# Environment Variable Interpolation:\n# Use ${VAR_NAME} syntax to reference environment variables\n# Example: ${HOME}, ${API_KEY}, ${DATABASE_URL}\n#\n# Instructions:\n# - config.instruction: Server's default instruction (from server documentation)\n# - instruction: User override (optional, takes precedence over config.instruction)\n# - config.toolBlacklist: Array of tool names to hide/block from this server\n# - config.omitToolDescription: Boolean to show only tool names without descriptions (saves tokens)\n\n# Remote Configuration Sources (OPTIONAL)\n# Fetch and merge configurations from remote URLs\n# Remote configs are merged with local configs based on merge strategy\n#\n# SECURITY: SSRF Protection is ENABLED by default\n# - Only HTTPS URLs are allowed (set security.enforceHttps: false to allow HTTP)\n# - Private IPs and localhost are blocked (set security.allowPrivateIPs: true for internal networks)\n# - Blocked ranges: 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16\nremoteConfigs:\n # Example 1: Basic remote config with default security\n # - url: ${AGIFLOW_URL}/api/v1/mcp-configs\n # headers:\n # Authorization: Bearer ${AGIFLOW_API_KEY}\n # mergeStrategy: local-priority # Options: local-priority (default), remote-priority, merge-deep\n #\n # Example 2: Remote config with custom security settings (for internal networks)\n # - url: ${INTERNAL_URL}/mcp-configs\n # headers:\n # Authorization: Bearer ${INTERNAL_TOKEN}\n # security:\n # allowPrivateIPs: true # Allow internal IPs (default: false)\n # enforceHttps: false # Allow HTTP (default: true, HTTPS only)\n # mergeStrategy: local-priority\n #\n # Example 3: Remote config with additional validation (OPTIONAL)\n # - url: ${AGIFLOW_URL}/api/v1/mcp-configs\n # headers:\n # Authorization: Bearer ${AGIFLOW_API_KEY}\n # X-API-Key: ${AGIFLOW_API_KEY}\n # security:\n # enforceHttps: true # Require HTTPS (default: true)\n # allowPrivateIPs: false # Block private IPs (default: false)\n # validation: # OPTIONAL: Additional regex validation on top of security checks\n # url: ^https://.*\\.agiflow\\.io/.* # OPTIONAL: Regex pattern to validate URL format\n # headers: # OPTIONAL: Regex patterns to validate header values\n # Authorization: ^Bearer [A-Za-z0-9_-]+$\n # X-API-Key: ^[A-Za-z0-9_-]{32,}$\n # mergeStrategy: local-priority\n\nmcpServers:\n{%- if mcpServers %}{% for server in mcpServers %}\n {{ server.name }}:\n command: {{ server.command }}\n args:{% for arg in server.args %}\n - '{{ arg }}'{% endfor %}\n # env:\n # LOG_LEVEL: info\n # # API_KEY: ${MY_API_KEY}\n # config:\n # instruction: Use this server for...\n # # toolBlacklist:\n # # - tool_to_block\n # # omitToolDescription: true\n{% endfor %}\n # Example MCP server using SSE transport\n # remote-server:\n # url: https://example.com/mcp\n # type: sse\n # headers:\n # Authorization: Bearer ${API_KEY}\n # config:\n # instruction: This server provides tools for...\n{% else %}\n # Example MCP server using stdio transport\n example-server:\n command: node\n args:\n - /path/to/mcp-server/build/index.js\n env:\n # Environment variables for the MCP server\n LOG_LEVEL: info\n # You can use environment variable interpolation:\n # DATABASE_URL: ${DATABASE_URL}\n # API_KEY: ${MY_API_KEY}\n config:\n # Server's default instruction (from server documentation)\n instruction: Use this server for...\n # Optional: Block specific tools from being listed or executed\n # toolBlacklist:\n # - dangerous_tool_name\n # - another_blocked_tool\n # Optional: Omit tool descriptions to save tokens (default: false)\n # omitToolDescription: true\n # instruction: Optional user override - takes precedence over config.instruction\n\n # Example MCP server using SSE transport with environment variables\n # remote-server:\n # url: https://example.com/mcp\n # type: sse\n # headers:\n # # Use ${VAR_NAME} to interpolate environment variables\n # Authorization: Bearer ${API_KEY}\n # config:\n # instruction: This server provides tools for...\n # # Optional: Block specific tools from being listed or executed\n # # toolBlacklist:\n # # - tool_to_block\n # # Optional: Omit tool descriptions to save tokens (default: false)\n # # omitToolDescription: true\n # # instruction: Optional user override\n{% endif %}\n";
392
+
393
+ //#endregion
394
+ //#region src/templates/mcp-config.json?raw
395
+ var mcp_config_default = "{\n \"_comment\": \"MCP Server Configuration - Use ${VAR_NAME} syntax for environment variable interpolation\",\n \"_instructions\": \"config.instruction: Server's default instruction | instruction: User override (takes precedence)\",\n \"mcpServers\": {\n \"example-server\": {\n \"command\": \"node\",\n \"args\": [\"/path/to/mcp-server/build/index.js\"],\n \"env\": {\n \"LOG_LEVEL\": \"info\",\n \"_comment\": \"You can use environment variable interpolation:\",\n \"_example_DATABASE_URL\": \"${DATABASE_URL}\",\n \"_example_API_KEY\": \"${MY_API_KEY}\"\n },\n \"config\": {\n \"instruction\": \"Use this server for...\"\n },\n \"_instruction_override\": \"Optional user override - takes precedence over config.instruction\"\n }\n }\n}\n";
396
+
397
+ //#endregion
398
+ //#region src/commands/init.ts
399
+ /**
400
+ * Init Command
401
+ *
402
+ * DESIGN PATTERNS:
403
+ * - Command pattern with Commander for CLI argument parsing
404
+ * - Async/await pattern for asynchronous operations
405
+ * - Error handling pattern with try-catch and proper exit codes
406
+ *
407
+ * CODING STANDARDS:
408
+ * - Use async action handlers for asynchronous operations
409
+ * - Provide clear option descriptions and default values
410
+ * - Handle errors gracefully with process.exit()
411
+ * - Log progress and errors to console
412
+ * - Use Commander's .option() and .argument() for inputs
413
+ *
414
+ * AVOID:
415
+ * - Synchronous blocking operations in action handlers
416
+ * - Missing error handling (always use try-catch)
417
+ * - Hardcoded values (use options or environment variables)
418
+ * - Not exiting with appropriate exit codes on errors
419
+ */
420
+ /**
421
+ * Initialize MCP configuration file
422
+ */
423
+ const initCommand = new commander.Command("init").description("Initialize MCP configuration file").option("-o, --output <path>", "Output file path", "mcp-config.yaml").option("--json", "Generate JSON config instead of YAML", false).option("-f, --force", "Overwrite existing config file", false).option("--mcp-servers <json>", "JSON string of MCP servers to add to config (optional)").action(async (options) => {
424
+ try {
425
+ const outputPath = (0, node_path.resolve)(options.output);
426
+ const isYaml = !options.json && (outputPath.endsWith(".yaml") || outputPath.endsWith(".yml"));
427
+ let content;
428
+ if (isYaml) {
429
+ const liquid = new liquidjs.Liquid();
430
+ let mcpServersData = null;
431
+ if (options.mcpServers) try {
432
+ const serversObj = JSON.parse(options.mcpServers);
433
+ mcpServersData = Object.entries(serversObj).map(([name, config]) => ({
434
+ name,
435
+ command: config.command,
436
+ args: config.args
437
+ }));
438
+ } catch (parseError) {
439
+ __agiflowai_aicode_utils.log.error("Failed to parse --mcp-servers JSON:", parseError instanceof Error ? parseError.message : String(parseError));
440
+ process.exit(1);
441
+ }
442
+ content = await liquid.parseAndRender(mcp_config_yaml_default, { mcpServers: mcpServersData });
443
+ } else content = mcp_config_default;
444
+ try {
445
+ await (0, node_fs_promises.writeFile)(outputPath, content, {
446
+ encoding: "utf-8",
447
+ flag: options.force ? "w" : "wx"
448
+ });
449
+ } catch (error) {
450
+ if (error && typeof error === "object" && "code" in error && error.code === "EEXIST") {
451
+ __agiflowai_aicode_utils.log.error(`Config file already exists: ${outputPath}`);
452
+ __agiflowai_aicode_utils.log.info("Use --force to overwrite");
453
+ process.exit(1);
454
+ }
455
+ throw error;
456
+ }
457
+ __agiflowai_aicode_utils.log.info(`MCP configuration file created: ${outputPath}`);
458
+ __agiflowai_aicode_utils.log.info("Next steps:");
459
+ __agiflowai_aicode_utils.log.info("1. Edit the configuration file to add your MCP servers");
460
+ __agiflowai_aicode_utils.log.info(`2. Run: one-mcp mcp-serve --config ${outputPath}`);
461
+ } catch (error) {
462
+ __agiflowai_aicode_utils.log.error("Error executing init:", error instanceof Error ? error.message : String(error));
463
+ process.exit(1);
464
+ }
465
+ });
466
+
467
+ //#endregion
468
+ //#region src/commands/mcp-serve.ts
469
+ /**
470
+ * MCP Serve Command
471
+ *
472
+ * DESIGN PATTERNS:
473
+ * - Command pattern with Commander for CLI argument parsing
474
+ * - Transport abstraction pattern for flexible deployment (stdio, HTTP, SSE)
475
+ * - Factory pattern for creating transport handlers
476
+ * - Graceful shutdown pattern with signal handling
477
+ *
478
+ * CODING STANDARDS:
479
+ * - Use async/await for asynchronous operations
480
+ * - Implement proper error handling with try-catch blocks
481
+ * - Handle process signals for graceful shutdown
482
+ * - Provide clear CLI options and help messages
483
+ *
484
+ * AVOID:
485
+ * - Hardcoded configuration values (use CLI options or environment variables)
486
+ * - Missing error handling for transport startup
487
+ * - Not cleaning up resources on shutdown
488
+ */
489
+ const CONFIG_FILE_NAMES = [
490
+ "mcp-config.yaml",
491
+ "mcp-config.yml",
492
+ "mcp-config.json"
493
+ ];
494
+ const MCP_ENDPOINT_PATH = "/mcp";
495
+ const DEFAULT_PORT = 3e3;
496
+ const DEFAULT_HOST = "localhost";
497
+ const TRANSPORT_TYPE_STDIO = "stdio";
498
+ const TRANSPORT_TYPE_HTTP = "http";
499
+ const TRANSPORT_TYPE_SSE = "sse";
500
+ const TRANSPORT_TYPE_STDIO_HTTP = "stdio-http";
501
+ const RUNTIME_TRANSPORT = TRANSPORT_TYPE_HTTP;
502
+ const STDIO_HTTP_PROXY_STOP_LABEL = "Failed stopping stdio-http proxy";
503
+ const INTERNAL_HTTP_STOP_LABEL = "Failed stopping internal HTTP transport";
504
+ function toErrorMessage$6(error) {
505
+ return error instanceof Error ? error.message : String(error);
506
+ }
507
+ function isValidTransportType(type) {
508
+ return type === TRANSPORT_TYPE_STDIO || type === TRANSPORT_TYPE_HTTP || type === TRANSPORT_TYPE_SSE || type === TRANSPORT_TYPE_STDIO_HTTP;
509
+ }
510
+ function isValidProxyMode(mode) {
511
+ return mode === "meta" || mode === "flat" || mode === "search";
512
+ }
513
+ function isAddressInUseError(error) {
514
+ if (error instanceof Error && error.message.includes("EADDRINUSE")) return true;
515
+ if (typeof error !== "object" || error === null) return false;
516
+ if ("code" in error && error.code === "EADDRINUSE") return true;
517
+ if ("message" in error && typeof error.message === "string" && error.message.includes("EADDRINUSE")) return true;
518
+ return false;
519
+ }
520
+ async function pathExists(filePath) {
521
+ try {
522
+ await (0, node_fs_promises.access)(filePath, node_fs.constants.F_OK);
523
+ return true;
524
+ } catch {
525
+ return false;
526
+ }
527
+ }
528
+ async function findConfigFileAsync() {
529
+ try {
530
+ const projectPath = process.env.PROJECT_PATH;
531
+ if (projectPath) for (const fileName of CONFIG_FILE_NAMES) {
532
+ const configPath = (0, node_path.resolve)(projectPath, fileName);
533
+ if (await pathExists(configPath)) return configPath;
534
+ }
535
+ const cwd = process.cwd();
536
+ for (const fileName of CONFIG_FILE_NAMES) {
537
+ const configPath = (0, node_path.join)(cwd, fileName);
538
+ if (await pathExists(configPath)) return configPath;
539
+ }
540
+ return null;
541
+ } catch (error) {
542
+ throw new Error(`Failed to discover MCP config file: ${toErrorMessage$6(error)}`);
543
+ }
544
+ }
545
+ async function resolveServerId(options, resolvedConfigPath) {
546
+ if (options.id) return options.id;
547
+ if (resolvedConfigPath) try {
548
+ const config = await new require_src.ConfigFetcherService({
549
+ configFilePath: resolvedConfigPath,
550
+ useCache: options.cache !== false
551
+ }).fetchConfiguration(options.cache === false);
552
+ if (config.id) return config.id;
553
+ } catch (error) {
554
+ throw new Error(`Failed to resolve server ID from config '${resolvedConfigPath}': ${toErrorMessage$6(error)}`);
555
+ }
556
+ return require_src.generateServerId();
557
+ }
558
+ function validateTransportType(type) {
559
+ if (!isValidTransportType(type)) throw new Error(`Unknown transport type: '${type}'. Valid options: ${TRANSPORT_TYPE_STDIO}, ${TRANSPORT_TYPE_HTTP}, ${TRANSPORT_TYPE_SSE}, ${TRANSPORT_TYPE_STDIO_HTTP}`);
560
+ return type;
561
+ }
562
+ function validateProxyMode(mode) {
563
+ if (!isValidProxyMode(mode)) throw new Error(`Unknown proxy mode: '${mode}'. Valid options: meta, flat, search`);
564
+ }
565
+ function createTransportConfig(options, mode) {
566
+ return {
567
+ mode,
568
+ port: options.port || Number(process.env.MCP_PORT) || DEFAULT_PORT,
569
+ host: options.host || process.env.MCP_HOST || DEFAULT_HOST
570
+ };
571
+ }
572
+ function createServerOptions(options, resolvedConfigPath, serverId) {
573
+ return {
574
+ configFilePath: resolvedConfigPath,
575
+ noCache: options.cache === false,
576
+ serverId,
577
+ definitionsCachePath: options.definitionsCache,
578
+ clearDefinitionsCache: options.clearDefinitionsCache,
579
+ proxyMode: options.proxyMode
580
+ };
581
+ }
582
+ function formatStartError(type, host, port, error) {
583
+ const startErrorMessage = toErrorMessage$6(error);
584
+ if (type === TRANSPORT_TYPE_STDIO) return `Failed to start MCP server with transport '${type}': ${startErrorMessage}`;
585
+ return `Failed to start MCP server with transport '${type}' on ${host}:${port}: ${startErrorMessage}`;
586
+ }
587
+ function createRuntimeRecord(serverId, config, shutdownToken, configPath) {
588
+ return {
589
+ serverId,
590
+ host: config.host ?? DEFAULT_HOST,
591
+ port: config.port ?? DEFAULT_PORT,
592
+ transport: RUNTIME_TRANSPORT,
593
+ shutdownToken,
594
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
595
+ pid: process.pid,
596
+ configPath
597
+ };
598
+ }
599
+ function createHttpAdminOptions(serverId, shutdownToken, onShutdownRequested) {
600
+ return {
601
+ serverId,
602
+ shutdownToken,
603
+ onShutdownRequested
604
+ };
605
+ }
606
+ async function removeRuntimeRecord(runtimeStateService, serverId) {
607
+ try {
608
+ await runtimeStateService.remove(serverId);
609
+ } catch (error) {
610
+ throw new Error(`Failed to remove runtime state for '${serverId}': ${toErrorMessage$6(error)}`);
611
+ }
612
+ }
613
+ async function writeRuntimeRecord(runtimeStateService, record) {
614
+ try {
615
+ await runtimeStateService.write(record);
616
+ } catch (error) {
617
+ throw new Error(`Failed to persist runtime state for '${record.serverId}': ${toErrorMessage$6(error)}`);
618
+ }
619
+ }
620
+ async function stopOwnedHttpTransport(handler, runtimeStateService, serverId) {
621
+ try {
622
+ try {
623
+ await handler.stop();
624
+ } catch (error) {
625
+ throw new Error(`Failed to stop owned HTTP transport '${serverId}': ${toErrorMessage$6(error)}`);
626
+ }
627
+ } finally {
628
+ await removeRuntimeRecord(runtimeStateService, serverId);
629
+ }
630
+ }
631
+ async function cleanupFailedRuntimeStartup(handler, runtimeStateService, serverId) {
632
+ try {
633
+ try {
634
+ await handler.stop();
635
+ } catch (error) {
636
+ throw new Error(`Failed to stop HTTP transport during cleanup for '${serverId}': ${toErrorMessage$6(error)}`);
637
+ }
638
+ } finally {
639
+ await removeRuntimeRecord(runtimeStateService, serverId);
640
+ }
641
+ }
642
+ async function stopTransportWithContext(label, stopOperation) {
643
+ try {
644
+ await stopOperation();
645
+ } catch (error) {
646
+ throw new Error(`${label}: ${toErrorMessage$6(error)}`);
647
+ }
648
+ }
649
+ async function removeRuntimeRecordDuringStop(runtimeStateService, serverId) {
650
+ try {
651
+ await removeRuntimeRecord(runtimeStateService, serverId);
652
+ } catch (error) {
653
+ throw new Error(`Failed to remove runtime state during HTTP stop callback for '${serverId}': ${toErrorMessage$6(error)}`);
654
+ }
655
+ }
656
+ async function createStdioHttpInternalTransport(serverOptions, config, adminOptions) {
657
+ try {
658
+ return new require_src.HttpTransportHandler(await require_src.createServer(serverOptions), config, adminOptions);
659
+ } catch (error) {
660
+ throw new Error(`Failed to create internal HTTP transport for stdio-http proxy: ${toErrorMessage$6(error)}`);
661
+ }
662
+ }
663
+ /**
664
+ * Start MCP server with given transport handler
665
+ * @param handler - The transport handler to start
666
+ * @param onStopped - Optional cleanup callback run after signal-based shutdown
667
+ */
668
+ async function startServer(handler, onStopped) {
669
+ try {
670
+ await handler.start();
671
+ } catch (error) {
672
+ throw new Error(`Failed to start transport handler: ${toErrorMessage$6(error)}`);
673
+ }
674
+ const shutdown = async (signal) => {
675
+ console.error(`\nReceived ${signal}, shutting down gracefully...`);
676
+ try {
677
+ await handler.stop();
678
+ if (onStopped) await onStopped();
679
+ process.exit(0);
680
+ } catch (error) {
681
+ console.error(`Failed to gracefully stop transport during ${signal}: ${toErrorMessage$6(error)}`);
682
+ process.exit(1);
683
+ }
684
+ };
685
+ process.on("SIGINT", async () => await shutdown("SIGINT"));
686
+ process.on("SIGTERM", async () => await shutdown("SIGTERM"));
687
+ }
688
+ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPath) {
689
+ const runtimeStateService = new require_src.RuntimeStateService();
690
+ const shutdownToken = (0, node_crypto.randomUUID)();
691
+ const runtimeRecord = createRuntimeRecord(serverOptions.serverId ?? require_src.generateServerId(), config, shutdownToken, resolvedConfigPath);
692
+ let handler;
693
+ let isStopping = false;
694
+ const stopHandler = async () => {
695
+ if (isStopping) return;
696
+ isStopping = true;
697
+ try {
698
+ await stopOwnedHttpTransport(handler, runtimeStateService, runtimeRecord.serverId);
699
+ process.exit(0);
700
+ } catch (error) {
701
+ throw new Error(`Failed to stop HTTP runtime '${runtimeRecord.serverId}' from admin shutdown: ${toErrorMessage$6(error)}`);
702
+ }
703
+ };
704
+ try {
705
+ handler = new require_src.HttpTransportHandler(await require_src.createServer(serverOptions), config, createHttpAdminOptions(runtimeRecord.serverId, shutdownToken, stopHandler));
706
+ } catch (error) {
707
+ throw new Error(`Failed to create HTTP runtime server: ${toErrorMessage$6(error)}`);
708
+ }
709
+ try {
710
+ await startServer(handler, async () => {
711
+ await removeRuntimeRecordDuringStop(runtimeStateService, runtimeRecord.serverId);
712
+ });
713
+ await writeRuntimeRecord(runtimeStateService, runtimeRecord);
714
+ } catch (error) {
715
+ await cleanupFailedRuntimeStartup(handler, runtimeStateService, runtimeRecord.serverId);
716
+ throw new Error(`Failed to start HTTP runtime '${runtimeRecord.serverId}': ${toErrorMessage$6(error)}`);
717
+ }
718
+ console.error(`Runtime state: http://${runtimeRecord.host}:${runtimeRecord.port} (${runtimeRecord.serverId})`);
719
+ }
720
+ async function stopInternalHttpTransport(stdioHttpHandler, httpHandler, ownsInternalHttpTransport) {
721
+ try {
722
+ const stopOperations = [stopTransportWithContext(STDIO_HTTP_PROXY_STOP_LABEL, async () => {
723
+ await stdioHttpHandler.stop();
724
+ })];
725
+ if (ownsInternalHttpTransport && httpHandler) stopOperations.push(stopTransportWithContext(INTERNAL_HTTP_STOP_LABEL, async () => {
726
+ await httpHandler.stop();
727
+ }));
728
+ await Promise.all(stopOperations);
729
+ } catch (error) {
730
+ throw new Error(`Failed to stop stdio-http transport: ${toErrorMessage$6(error)}`);
731
+ }
732
+ }
733
+ async function startStdioTransport(serverOptions) {
734
+ try {
735
+ await startServer(new require_src.StdioTransportHandler(await require_src.createServer(serverOptions)));
736
+ } catch (error) {
737
+ throw new Error(`Failed to start stdio transport: ${toErrorMessage$6(error)}`);
738
+ }
739
+ }
740
+ async function startSseTransport(serverOptions, config) {
741
+ try {
742
+ await startServer(new require_src.SseTransportHandler(await require_src.createServer(serverOptions), config));
743
+ } catch (error) {
744
+ throw new Error(`Failed to start SSE transport: ${toErrorMessage$6(error)}`);
745
+ }
746
+ }
747
+ async function startStdioHttpTransport(serverOptions, config, resolvedConfigPath) {
748
+ try {
749
+ const stdioHttpHandler = new require_src.StdioHttpTransportHandler({ endpoint: new URL(`http://${config.host}:${config.port}${MCP_ENDPOINT_PATH}`) });
750
+ const runtimeStateService = new require_src.RuntimeStateService();
751
+ const serverId = serverOptions.serverId ?? require_src.generateServerId();
752
+ const shutdownToken = (0, node_crypto.randomUUID)();
753
+ let httpHandler = null;
754
+ let ownsInternalHttpTransport = false;
755
+ let isStopping = false;
756
+ const stopOwnedRuntime = async () => {
757
+ if (isStopping) return;
758
+ isStopping = true;
759
+ try {
760
+ await Promise.all([stopInternalHttpTransport(stdioHttpHandler, httpHandler, ownsInternalHttpTransport), removeRuntimeRecord(runtimeStateService, serverId)]);
761
+ ownsInternalHttpTransport = false;
762
+ process.exit(0);
763
+ } catch (error) {
764
+ console.error(`Unexpected error during admin shutdown: ${toErrorMessage$6(error)}`);
765
+ process.exit(1);
766
+ }
767
+ };
768
+ const adminOptions = createHttpAdminOptions(serverId, shutdownToken, stopOwnedRuntime);
769
+ await startServer({
770
+ async start() {
771
+ let initialProxyConnectError;
772
+ try {
773
+ await stdioHttpHandler.start();
774
+ return;
775
+ } catch (error) {
776
+ initialProxyConnectError = error;
777
+ }
778
+ try {
779
+ httpHandler = await createStdioHttpInternalTransport(serverOptions, config, adminOptions);
780
+ await httpHandler.start();
781
+ ownsInternalHttpTransport = true;
782
+ } catch (error) {
783
+ if (!isAddressInUseError(error)) throw new Error(`Failed to start internal HTTP transport for stdio-http proxy: ${toErrorMessage$6(error)}`);
784
+ }
785
+ try {
786
+ await stdioHttpHandler.start();
787
+ } catch (error) {
788
+ let rollbackStopErrorMessage = "";
789
+ if (ownsInternalHttpTransport && httpHandler) {
790
+ try {
791
+ await httpHandler.stop();
792
+ } catch (stopError) {
793
+ rollbackStopErrorMessage = toErrorMessage$6(stopError);
794
+ }
795
+ ownsInternalHttpTransport = false;
796
+ }
797
+ const retryErrorMessage = toErrorMessage$6(error);
798
+ const initialErrorMessage = toErrorMessage$6(initialProxyConnectError);
799
+ const rollbackMessage = rollbackStopErrorMessage ? `; rollback stop failed: ${rollbackStopErrorMessage}` : "";
800
+ throw new Error(`Failed to start stdio-http proxy bridge: initial connect failed (${initialErrorMessage}); retry failed (${retryErrorMessage})${rollbackMessage}`);
801
+ }
802
+ if (ownsInternalHttpTransport) try {
803
+ await writeRuntimeRecord(runtimeStateService, createRuntimeRecord(serverId, config, shutdownToken, resolvedConfigPath));
804
+ } catch (error) {
805
+ throw new Error(`Failed to persist runtime state for stdio-http server '${serverId}': ${toErrorMessage$6(error)}`);
806
+ }
807
+ },
808
+ async stop() {
809
+ try {
810
+ await Promise.all([stopInternalHttpTransport(stdioHttpHandler, httpHandler, ownsInternalHttpTransport), removeRuntimeRecord(runtimeStateService, serverId)]);
811
+ ownsInternalHttpTransport = false;
812
+ } catch (error) {
813
+ ownsInternalHttpTransport = false;
814
+ throw new Error(`Failed during stdio-http shutdown for '${serverId}': ${toErrorMessage$6(error)}`);
815
+ }
816
+ }
817
+ });
818
+ } catch (error) {
819
+ throw new Error(`Failed to start stdio-http transport: ${toErrorMessage$6(error)}`);
820
+ }
821
+ }
822
+ async function startTransport(transportType, options, resolvedConfigPath, serverOptions) {
823
+ try {
824
+ if (transportType === TRANSPORT_TYPE_STDIO) {
825
+ await startStdioTransport(serverOptions);
826
+ return;
827
+ }
828
+ if (transportType === TRANSPORT_TYPE_HTTP) {
829
+ await createAndStartHttpRuntime(serverOptions, createTransportConfig(options, require_src.TRANSPORT_MODE.HTTP), resolvedConfigPath);
830
+ return;
831
+ }
832
+ if (transportType === TRANSPORT_TYPE_SSE) {
833
+ await startSseTransport(serverOptions, createTransportConfig(options, require_src.TRANSPORT_MODE.SSE));
834
+ return;
835
+ }
836
+ await startStdioHttpTransport(serverOptions, createTransportConfig(options, require_src.TRANSPORT_MODE.HTTP), resolvedConfigPath);
837
+ } catch (error) {
838
+ throw new Error(`Failed to start transport '${transportType}': ${toErrorMessage$6(error)}`);
839
+ }
840
+ }
841
+ /**
842
+ * MCP Serve command
843
+ */
844
+ 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/stdio-http internal HTTP)", (val) => parseInt(val, 10), DEFAULT_PORT).option("--host <host>", "Host to bind to (http/sse/stdio-http internal 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 one-mcp 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) => {
845
+ try {
846
+ const transportType = validateTransportType(options.type.toLowerCase());
847
+ validateProxyMode(options.proxyMode);
848
+ const resolvedConfigPath = options.config || await findConfigFileAsync() || void 0;
849
+ await startTransport(transportType, options, resolvedConfigPath, createServerOptions(options, resolvedConfigPath, await resolveServerId(options, resolvedConfigPath)));
850
+ } catch (error) {
851
+ const rawTransportType = options.type.toLowerCase();
852
+ const transportType = isValidTransportType(rawTransportType) ? rawTransportType : TRANSPORT_TYPE_STDIO;
853
+ console.error(formatStartError(transportType, options.host, options.port, error));
854
+ process.exit(1);
855
+ }
856
+ });
857
+
567
858
  //#endregion
568
859
  //#region src/commands/list-tools.ts
569
860
  /**
@@ -587,7 +878,7 @@ var PrefetchService = class {
587
878
  * - Hardcoded values (use options or environment variables)
588
879
  * - Not exiting with appropriate exit codes on errors
589
880
  */
590
- function toErrorMessage$4(error) {
881
+ function toErrorMessage$5(error) {
591
882
  return error instanceof Error ? error.message : String(error);
592
883
  }
593
884
  function printSearchResults(result) {
@@ -608,29 +899,29 @@ function printSearchResults(result) {
608
899
  }
609
900
  const searchToolsCommand = new commander.Command("search-tools").description("Search proxied MCP tools by capability or server").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Filter by server name").option("--capability <name>", "Filter by capability tag, summary, tool name, or description").option("--definitions-cache <path>", "Path to definitions cache file").option("-j, --json", "Output as JSON", false).action(async (options) => {
610
901
  try {
611
- const configFilePath = options.config || require_http.findConfigFile();
902
+ const configFilePath = options.config || require_src.findConfigFile();
612
903
  if (!configFilePath) throw new Error("No config file found. Use --config or create mcp-config.yaml");
613
- const config = await new require_http.ConfigFetcherService({ configFilePath }).fetchConfiguration();
614
- const clientManager = new require_http.McpClientManagerService();
904
+ const config = await new require_src.ConfigFetcherService({ configFilePath }).fetchConfiguration();
905
+ const clientManager = new require_src.McpClientManagerService();
615
906
  clientManager.registerServerConfigs(config.mcpServers);
616
907
  const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
617
908
  try {
618
909
  await clientManager.connectToServer(serverName, serverConfig);
619
910
  if (!options.json) console.error(`✓ Connected to ${serverName}`);
620
911
  } catch (error) {
621
- if (!options.json) console.error(`✗ Failed to connect to ${serverName}: ${toErrorMessage$4(error)}`);
912
+ if (!options.json) console.error(`✗ Failed to connect to ${serverName}: ${toErrorMessage$5(error)}`);
622
913
  }
623
914
  });
624
915
  await Promise.all(connectionPromises);
625
916
  if (clientManager.getAllClients().length === 0) throw new Error("No MCP servers connected");
626
- const cachePath = options.definitionsCache || require_http.DefinitionsCacheService.getDefaultCachePath(configFilePath);
917
+ const cachePath = options.definitionsCache || require_src.DefinitionsCacheService.getDefaultCachePath(configFilePath);
627
918
  let cacheData;
628
919
  try {
629
- cacheData = await require_http.DefinitionsCacheService.readFromFile(cachePath);
920
+ cacheData = await require_src.DefinitionsCacheService.readFromFile(cachePath);
630
921
  } catch {
631
922
  cacheData = void 0;
632
923
  }
633
- const textBlock = (await new require_http.SearchListToolsTool(clientManager, new require_http.DefinitionsCacheService(clientManager, void 0, { cacheData })).execute({
924
+ const textBlock = (await new require_src.SearchListToolsTool(clientManager, new require_src.DefinitionsCacheService(clientManager, void 0, { cacheData })).execute({
634
925
  capability: options.capability,
635
926
  serverName: options.server
636
927
  })).content.find((content) => content.type === "text");
@@ -642,7 +933,7 @@ const searchToolsCommand = new commander.Command("search-tools").description("Se
642
933
  }
643
934
  await clientManager.disconnectAll();
644
935
  } catch (error) {
645
- console.error(`Error executing search-tools: ${toErrorMessage$4(error)}`);
936
+ console.error(`Error executing search-tools: ${toErrorMessage$5(error)}`);
646
937
  process.exit(1);
647
938
  }
648
939
  });
@@ -675,13 +966,13 @@ const searchToolsCommand = new commander.Command("search-tools").description("Se
675
966
  */
676
967
  const describeToolsCommand = new commander.Command("describe-tools").description("Describe specific MCP tools").argument("<toolNames...>", "Tool names to describe").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Filter by server name").option("-j, --json", "Output as JSON", false).action(async (toolNames, options) => {
677
968
  try {
678
- const configFilePath = options.config || require_http.findConfigFile();
969
+ const configFilePath = options.config || require_src.findConfigFile();
679
970
  if (!configFilePath) {
680
971
  console.error("Error: No config file found. Use --config or create mcp-config.yaml");
681
972
  process.exit(1);
682
973
  }
683
- const config = await new require_http.ConfigFetcherService({ configFilePath }).fetchConfiguration();
684
- const clientManager = new require_http.McpClientManagerService();
974
+ const config = await new require_src.ConfigFetcherService({ configFilePath }).fetchConfiguration();
975
+ const clientManager = new require_src.McpClientManagerService();
685
976
  const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
686
977
  try {
687
978
  await clientManager.connectToServer(serverName, serverConfig);
@@ -698,7 +989,7 @@ const describeToolsCommand = new commander.Command("describe-tools").description
698
989
  }
699
990
  const cwd = process.env.PROJECT_PATH || process.cwd();
700
991
  const skillPaths = config.skills?.paths || [];
701
- const skillService = skillPaths.length > 0 ? new require_http.SkillService(cwd, skillPaths) : void 0;
992
+ const skillService = skillPaths.length > 0 ? new require_src.SkillService(cwd, skillPaths) : void 0;
702
993
  const foundTools = [];
703
994
  const foundSkills = [];
704
995
  const notFoundTools = [...toolNames];
@@ -833,7 +1124,7 @@ const describeToolsCommand = new commander.Command("describe-tools").description
833
1124
  */
834
1125
  const useToolCommand = new commander.Command("use-tool").description("Execute an MCP tool with arguments").argument("<toolName>", "Tool name to execute").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Server name (required if tool exists on multiple servers)").option("-a, --args <json>", "Tool arguments as JSON string", "{}").option("-j, --json", "Output as JSON", false).action(async (toolName, options) => {
835
1126
  try {
836
- const configFilePath = options.config || require_http.findConfigFile();
1127
+ const configFilePath = options.config || require_src.findConfigFile();
837
1128
  if (!configFilePath) {
838
1129
  console.error("Error: No config file found. Use --config or create mcp-config.yaml");
839
1130
  process.exit(1);
@@ -845,8 +1136,8 @@ const useToolCommand = new commander.Command("use-tool").description("Execute an
845
1136
  console.error("Error: Invalid JSON in --args");
846
1137
  process.exit(1);
847
1138
  }
848
- const config = await new require_http.ConfigFetcherService({ configFilePath }).fetchConfiguration();
849
- const clientManager = new require_http.McpClientManagerService();
1139
+ const config = await new require_src.ConfigFetcherService({ configFilePath }).fetchConfiguration();
1140
+ const clientManager = new require_src.McpClientManagerService();
850
1141
  const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
851
1142
  try {
852
1143
  await clientManager.connectToServer(serverName, serverConfig);
@@ -916,7 +1207,7 @@ const useToolCommand = new commander.Command("use-tool").description("Execute an
916
1207
  const cwd = process.env.PROJECT_PATH || process.cwd();
917
1208
  const skillPaths = config.skills?.paths || [];
918
1209
  if (skillPaths.length > 0) try {
919
- const skillService = new require_http.SkillService(cwd, skillPaths);
1210
+ const skillService = new require_src.SkillService(cwd, skillPaths);
920
1211
  const skillName = toolName.startsWith("skill__") ? toolName.slice(7) : toolName;
921
1212
  const skill = await skillService.getSkill(skillName);
922
1213
  if (skill) {
@@ -1001,7 +1292,7 @@ const useToolCommand = new commander.Command("use-tool").description("Execute an
1001
1292
  * - Hardcoded values (use options or environment variables)
1002
1293
  * - Not exiting with appropriate exit codes on errors
1003
1294
  */
1004
- function toErrorMessage$3(error) {
1295
+ function toErrorMessage$4(error) {
1005
1296
  return error instanceof Error ? error.message : String(error);
1006
1297
  }
1007
1298
  /**
@@ -1009,16 +1300,16 @@ function toErrorMessage$3(error) {
1009
1300
  */
1010
1301
  const listResourcesCommand = new commander.Command("list-resources").description("List all available resources from connected MCP servers").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Filter by server name").option("-j, --json", "Output as JSON", false).action(async (options) => {
1011
1302
  try {
1012
- const configFilePath = options.config || require_http.findConfigFile();
1303
+ const configFilePath = options.config || require_src.findConfigFile();
1013
1304
  if (!configFilePath) throw new Error("No config file found. Use --config or create mcp-config.yaml");
1014
- const config = await new require_http.ConfigFetcherService({ configFilePath }).fetchConfiguration();
1015
- const clientManager = new require_http.McpClientManagerService();
1305
+ const config = await new require_src.ConfigFetcherService({ configFilePath }).fetchConfiguration();
1306
+ const clientManager = new require_src.McpClientManagerService();
1016
1307
  await Promise.all(Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
1017
1308
  try {
1018
1309
  await clientManager.connectToServer(serverName, serverConfig);
1019
1310
  if (!options.json) console.error(`✓ Connected to ${serverName}`);
1020
1311
  } catch (error) {
1021
- if (!options.json) console.error(`✗ Failed to connect to ${serverName}: ${toErrorMessage$3(error)}`);
1312
+ if (!options.json) console.error(`✗ Failed to connect to ${serverName}: ${toErrorMessage$4(error)}`);
1022
1313
  }
1023
1314
  }));
1024
1315
  const clients = options.server ? [clientManager.getClient(options.server)].filter((c) => c !== void 0) : clientManager.getAllClients();
@@ -1041,7 +1332,7 @@ const listResourcesCommand = new commander.Command("list-resources").description
1041
1332
  }
1042
1333
  }));
1043
1334
  for (const { serverName, resources, error } of resourceResults) {
1044
- if (error && !options.json) console.error(`Failed to list resources from ${serverName}: ${toErrorMessage$3(error)}`);
1335
+ if (error && !options.json) console.error(`Failed to list resources from ${serverName}: ${toErrorMessage$4(error)}`);
1045
1336
  resourcesByServer[serverName] = resources;
1046
1337
  }
1047
1338
  if (options.json) console.log(JSON.stringify(resourcesByServer, null, 2));
@@ -1055,7 +1346,7 @@ const listResourcesCommand = new commander.Command("list-resources").description
1055
1346
  }
1056
1347
  await clientManager.disconnectAll();
1057
1348
  } catch (error) {
1058
- console.error(`Error executing list-resources: ${toErrorMessage$3(error)}`);
1349
+ console.error(`Error executing list-resources: ${toErrorMessage$4(error)}`);
1059
1350
  process.exit(1);
1060
1351
  }
1061
1352
  });
@@ -1083,7 +1374,7 @@ const listResourcesCommand = new commander.Command("list-resources").description
1083
1374
  * - Hardcoded values (use options or environment variables)
1084
1375
  * - Not exiting with appropriate exit codes on errors
1085
1376
  */
1086
- function toErrorMessage$2(error) {
1377
+ function toErrorMessage$3(error) {
1087
1378
  return error instanceof Error ? error.message : String(error);
1088
1379
  }
1089
1380
  /**
@@ -1091,16 +1382,16 @@ function toErrorMessage$2(error) {
1091
1382
  */
1092
1383
  const readResourceCommand = new commander.Command("read-resource").description("Read a resource by URI from a connected MCP server").argument("<uri>", "Resource URI to read").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Server name (required if resource exists on multiple servers)").option("-j, --json", "Output as JSON", false).action(async (uri, options) => {
1093
1384
  try {
1094
- const configFilePath = options.config || require_http.findConfigFile();
1385
+ const configFilePath = options.config || require_src.findConfigFile();
1095
1386
  if (!configFilePath) throw new Error("No config file found. Use --config or create mcp-config.yaml");
1096
- const config = await new require_http.ConfigFetcherService({ configFilePath }).fetchConfiguration();
1097
- const clientManager = new require_http.McpClientManagerService();
1387
+ const config = await new require_src.ConfigFetcherService({ configFilePath }).fetchConfiguration();
1388
+ const clientManager = new require_src.McpClientManagerService();
1098
1389
  await Promise.all(Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
1099
1390
  try {
1100
1391
  await clientManager.connectToServer(serverName, serverConfig);
1101
1392
  if (!options.json) console.error(`✓ Connected to ${serverName}`);
1102
1393
  } catch (error) {
1103
- console.error(`✗ Failed to connect to ${serverName}: ${toErrorMessage$2(error)}`);
1394
+ console.error(`✗ Failed to connect to ${serverName}: ${toErrorMessage$3(error)}`);
1104
1395
  }
1105
1396
  }));
1106
1397
  const clients = clientManager.getAllClients();
@@ -1135,7 +1426,7 @@ const readResourceCommand = new commander.Command("read-resource").description("
1135
1426
  const matchingServers = [];
1136
1427
  for (const { serverName, hasResource, error } of searchResults) {
1137
1428
  if (error) {
1138
- console.error(`Failed to list resources from ${serverName}: ${toErrorMessage$2(error)}`);
1429
+ console.error(`Failed to list resources from ${serverName}: ${toErrorMessage$3(error)}`);
1139
1430
  continue;
1140
1431
  }
1141
1432
  if (hasResource) matchingServers.push(serverName);
@@ -1152,28 +1443,28 @@ const readResourceCommand = new commander.Command("read-resource").description("
1152
1443
  else console.log(JSON.stringify(content, null, 2));
1153
1444
  await clientManager.disconnectAll();
1154
1445
  } catch (error) {
1155
- console.error(`Error executing read-resource: ${toErrorMessage$2(error)}`);
1446
+ console.error(`Error executing read-resource: ${toErrorMessage$3(error)}`);
1156
1447
  process.exit(1);
1157
1448
  }
1158
1449
  });
1159
1450
 
1160
1451
  //#endregion
1161
1452
  //#region src/commands/list-prompts.ts
1162
- function toErrorMessage$1(error) {
1453
+ function toErrorMessage$2(error) {
1163
1454
  return error instanceof Error ? error.message : String(error);
1164
1455
  }
1165
1456
  const listPromptsCommand = new commander.Command("list-prompts").description("List all available prompts from connected MCP servers").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Filter by server name").option("-j, --json", "Output as JSON", false).action(async (options) => {
1166
1457
  try {
1167
- const configFilePath = options.config || require_http.findConfigFile();
1458
+ const configFilePath = options.config || require_src.findConfigFile();
1168
1459
  if (!configFilePath) throw new Error("No config file found. Use --config or create mcp-config.yaml");
1169
- const config = await new require_http.ConfigFetcherService({ configFilePath }).fetchConfiguration();
1170
- const clientManager = new require_http.McpClientManagerService();
1460
+ const config = await new require_src.ConfigFetcherService({ configFilePath }).fetchConfiguration();
1461
+ const clientManager = new require_src.McpClientManagerService();
1171
1462
  await Promise.all(Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
1172
1463
  try {
1173
1464
  await clientManager.connectToServer(serverName, serverConfig);
1174
1465
  if (!options.json) console.error(`✓ Connected to ${serverName}`);
1175
1466
  } catch (error) {
1176
- if (!options.json) console.error(`✗ Failed to connect to ${serverName}: ${toErrorMessage$1(error)}`);
1467
+ if (!options.json) console.error(`✗ Failed to connect to ${serverName}: ${toErrorMessage$2(error)}`);
1177
1468
  }
1178
1469
  }));
1179
1470
  const clients = options.server ? [clientManager.getClient(options.server)].filter((client) => client !== void 0) : clientManager.getAllClients();
@@ -1184,7 +1475,7 @@ const listPromptsCommand = new commander.Command("list-prompts").description("Li
1184
1475
  promptsByServer[client.serverName] = await client.listPrompts();
1185
1476
  } catch (error) {
1186
1477
  promptsByServer[client.serverName] = [];
1187
- if (!options.json) console.error(`Failed to list prompts from ${client.serverName}: ${toErrorMessage$1(error)}`);
1478
+ if (!options.json) console.error(`Failed to list prompts from ${client.serverName}: ${toErrorMessage$2(error)}`);
1188
1479
  }
1189
1480
  }));
1190
1481
  if (options.json) console.log(JSON.stringify(promptsByServer, null, 2));
@@ -1204,19 +1495,19 @@ const listPromptsCommand = new commander.Command("list-prompts").description("Li
1204
1495
  }
1205
1496
  await clientManager.disconnectAll();
1206
1497
  } catch (error) {
1207
- console.error(`Error executing list-prompts: ${toErrorMessage$1(error)}`);
1498
+ console.error(`Error executing list-prompts: ${toErrorMessage$2(error)}`);
1208
1499
  process.exit(1);
1209
1500
  }
1210
1501
  });
1211
1502
 
1212
1503
  //#endregion
1213
1504
  //#region src/commands/get-prompt.ts
1214
- function toErrorMessage(error) {
1505
+ function toErrorMessage$1(error) {
1215
1506
  return error instanceof Error ? error.message : String(error);
1216
1507
  }
1217
1508
  const getPromptCommand = new commander.Command("get-prompt").description("Get a prompt by name from a connected MCP server").argument("<promptName>", "Prompt name to fetch").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Server name (required if prompt exists on multiple servers)").option("-a, --args <json>", "Prompt arguments as JSON string", "{}").option("-j, --json", "Output as JSON", false).action(async (promptName, options) => {
1218
1509
  try {
1219
- const configFilePath = options.config || require_http.findConfigFile();
1510
+ const configFilePath = options.config || require_src.findConfigFile();
1220
1511
  if (!configFilePath) throw new Error("No config file found. Use --config or create mcp-config.yaml");
1221
1512
  let promptArgs = {};
1222
1513
  try {
@@ -1224,14 +1515,14 @@ const getPromptCommand = new commander.Command("get-prompt").description("Get a
1224
1515
  } catch {
1225
1516
  throw new Error("Invalid JSON in --args");
1226
1517
  }
1227
- const config = await new require_http.ConfigFetcherService({ configFilePath }).fetchConfiguration();
1228
- const clientManager = new require_http.McpClientManagerService();
1518
+ const config = await new require_src.ConfigFetcherService({ configFilePath }).fetchConfiguration();
1519
+ const clientManager = new require_src.McpClientManagerService();
1229
1520
  await Promise.all(Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
1230
1521
  try {
1231
1522
  await clientManager.connectToServer(serverName, serverConfig);
1232
1523
  if (!options.json) console.error(`✓ Connected to ${serverName}`);
1233
1524
  } catch (error) {
1234
- if (!options.json) console.error(`✗ Failed to connect to ${serverName}: ${toErrorMessage(error)}`);
1525
+ if (!options.json) console.error(`✗ Failed to connect to ${serverName}: ${toErrorMessage$1(error)}`);
1235
1526
  }
1236
1527
  }));
1237
1528
  const clients = clientManager.getAllClients();
@@ -1254,7 +1545,7 @@ const getPromptCommand = new commander.Command("get-prompt").description("Get a
1254
1545
  try {
1255
1546
  if ((await client$1.listPrompts()).some((prompt$1) => prompt$1.name === promptName)) matchingServers.push(client$1.serverName);
1256
1547
  } catch (error) {
1257
- if (!options.json) console.error(`Failed to list prompts from ${client$1.serverName}: ${toErrorMessage(error)}`);
1548
+ if (!options.json) console.error(`Failed to list prompts from ${client$1.serverName}: ${toErrorMessage$1(error)}`);
1258
1549
  }
1259
1550
  }));
1260
1551
  if (matchingServers.length === 0) throw new Error(`Prompt "${promptName}" not found on any connected server`);
@@ -1270,7 +1561,7 @@ const getPromptCommand = new commander.Command("get-prompt").description("Get a
1270
1561
  }
1271
1562
  await clientManager.disconnectAll();
1272
1563
  } catch (error) {
1273
- console.error(`Error executing get-prompt: ${toErrorMessage(error)}`);
1564
+ console.error(`Error executing get-prompt: ${toErrorMessage$1(error)}`);
1274
1565
  process.exit(1);
1275
1566
  }
1276
1567
  });
@@ -1303,20 +1594,20 @@ const getPromptCommand = new commander.Command("get-prompt").description("Get a
1303
1594
  */
1304
1595
  const prefetchCommand = new commander.Command("prefetch").description("Pre-download packages used by MCP servers (npx, pnpx, uvx, uv)").option("-c, --config <path>", "Path to MCP server configuration file").option("-p, --parallel", "Run prefetch commands in parallel", false).option("-d, --dry-run", "Show what would be prefetched without executing", false).option("-f, --filter <type>", "Filter by package manager type: npx, pnpx, uvx, or uv").option("--definitions-out <path>", "Write discovered definitions to a JSON or YAML cache file").option("--skip-packages", "Skip package prefetch and only build definitions cache", false).option("--clear-definitions-cache", "Delete the definitions cache file before continuing", false).action(async (options) => {
1305
1596
  try {
1306
- const configFilePath = options.config || require_http.findConfigFile();
1597
+ const configFilePath = options.config || require_src.findConfigFile();
1307
1598
  if (!configFilePath) {
1308
1599
  __agiflowai_aicode_utils.print.error("No MCP configuration file found.");
1309
1600
  __agiflowai_aicode_utils.print.info("Use --config <path> to specify a config file, or run \"one-mcp init\" to create one.");
1310
1601
  process.exit(1);
1311
1602
  }
1312
1603
  __agiflowai_aicode_utils.print.info(`Loading configuration from: ${configFilePath}`);
1313
- const mcpConfig = await new require_http.ConfigFetcherService({
1604
+ const mcpConfig = await new require_src.ConfigFetcherService({
1314
1605
  configFilePath,
1315
1606
  useCache: false
1316
1607
  }).fetchConfiguration(true);
1317
- const serverId = mcpConfig.id || require_http.generateServerId();
1318
- const configHash = require_http.DefinitionsCacheService.generateConfigHash(mcpConfig);
1319
- const effectiveDefinitionsPath = options.definitionsOut || require_http.DefinitionsCacheService.getDefaultCachePath(configFilePath);
1608
+ const serverId = mcpConfig.id || require_src.generateServerId();
1609
+ const configHash = require_src.DefinitionsCacheService.generateConfigHash(mcpConfig);
1610
+ const effectiveDefinitionsPath = options.definitionsOut || require_src.DefinitionsCacheService.getDefaultCachePath(configFilePath);
1320
1611
  const prefetchService = new PrefetchService({
1321
1612
  mcpConfig,
1322
1613
  filter: options.filter,
@@ -1327,7 +1618,7 @@ const prefetchCommand = new commander.Command("prefetch").description("Pre-downl
1327
1618
  const shouldWriteDefinitions = Boolean(options.definitionsOut);
1328
1619
  if (options.clearDefinitionsCache) if (options.dryRun) __agiflowai_aicode_utils.print.info(`Would clear definitions cache: ${effectiveDefinitionsPath}`);
1329
1620
  else {
1330
- await require_http.DefinitionsCacheService.clearFile(effectiveDefinitionsPath);
1621
+ await require_src.DefinitionsCacheService.clearFile(effectiveDefinitionsPath);
1331
1622
  __agiflowai_aicode_utils.print.success(`Cleared definitions cache: ${effectiveDefinitionsPath}`);
1332
1623
  }
1333
1624
  if (shouldPrefetchPackages) if (packages.length === 0) {
@@ -1371,9 +1662,9 @@ const prefetchCommand = new commander.Command("prefetch").description("Pre-downl
1371
1662
  if (shouldWriteDefinitions) {
1372
1663
  __agiflowai_aicode_utils.print.newline();
1373
1664
  __agiflowai_aicode_utils.print.info("Collecting definitions cache...");
1374
- const clientManager = new require_http.McpClientManagerService();
1665
+ const clientManager = new require_src.McpClientManagerService();
1375
1666
  const skillPaths = mcpConfig.skills?.paths || [];
1376
- const definitionsCacheService = new require_http.DefinitionsCacheService(clientManager, skillPaths.length > 0 ? new require_http.SkillService(process.cwd(), skillPaths) : void 0);
1667
+ const definitionsCacheService = new require_src.DefinitionsCacheService(clientManager, skillPaths.length > 0 ? new require_src.SkillService(process.cwd(), skillPaths) : void 0);
1377
1668
  await Promise.all(Object.entries(mcpConfig.mcpServers).map(async ([serverName, serverConfig]) => {
1378
1669
  try {
1379
1670
  await clientManager.connectToServer(serverName, serverConfig);
@@ -1385,10 +1676,10 @@ const prefetchCommand = new commander.Command("prefetch").description("Pre-downl
1385
1676
  const definitionsCache = await definitionsCacheService.collectForCache({
1386
1677
  configPath: configFilePath,
1387
1678
  configHash,
1388
- oneMcpVersion: require_http.version,
1679
+ oneMcpVersion: require_src.version,
1389
1680
  serverId
1390
1681
  });
1391
- await require_http.DefinitionsCacheService.writeToFile(effectiveDefinitionsPath, definitionsCache);
1682
+ await require_src.DefinitionsCacheService.writeToFile(effectiveDefinitionsPath, definitionsCache);
1392
1683
  __agiflowai_aicode_utils.print.success(`Definitions cache written: ${effectiveDefinitionsPath} (${Object.keys(definitionsCache.servers).length} servers, ${definitionsCache.skills.length} skills)`);
1393
1684
  if (definitionsCache.failures.length > 0) __agiflowai_aicode_utils.print.warning(`Definitions cache completed with ${definitionsCache.failures.length} server failure(s)`);
1394
1685
  await clientManager.disconnectAll();
@@ -1400,6 +1691,52 @@ const prefetchCommand = new commander.Command("prefetch").description("Pre-downl
1400
1691
  }
1401
1692
  });
1402
1693
 
1694
+ //#endregion
1695
+ //#region src/commands/stop.ts
1696
+ /**
1697
+ * Stop Command
1698
+ *
1699
+ * Stops a running HTTP one-mcp server using the authenticated admin endpoint
1700
+ * and the persisted runtime registry.
1701
+ */
1702
+ function toErrorMessage(error) {
1703
+ return error instanceof Error ? error.message : String(error);
1704
+ }
1705
+ function printStopResult(result) {
1706
+ console.log(`Stopped one-mcp server '${result.serverId}'.`);
1707
+ console.log(`Endpoint: http://${result.host}:${result.port}`);
1708
+ console.log(`Result: ${result.message}`);
1709
+ }
1710
+ /**
1711
+ * Stop a running HTTP one-mcp server.
1712
+ */
1713
+ const stopCommand = new commander.Command("stop").description("Stop a running HTTP one-mcp server").option("--id <id>", "Target server ID from the runtime registry").option("--host <host>", "Target runtime host").option("--port <port>", "Target runtime port", (value) => Number.parseInt(value, 10)).option("-c, --config <path>", "Reserved for future config-based targeting support").option("--token <token>", "Override the persisted shutdown token").option("--force", "Skip server ID verification against the /health response", false).option("-j, --json", "Output as JSON", false).option("--timeout <ms>", "Maximum time to wait for shutdown completion", (value) => Number.parseInt(value, 10), 5e3).action(async (options) => {
1714
+ try {
1715
+ if (options.config) console.error("Warning: --config is not used yet; runtime resolution uses the persisted registry.");
1716
+ const result = await new require_src.StopServerService().stop({
1717
+ serverId: options.id,
1718
+ host: options.host,
1719
+ port: options.port,
1720
+ token: options.token,
1721
+ force: options.force,
1722
+ timeoutMs: options.timeout
1723
+ });
1724
+ if (options.json) {
1725
+ console.log(JSON.stringify(result, null, 2));
1726
+ return;
1727
+ }
1728
+ printStopResult(result);
1729
+ } catch (error) {
1730
+ const errorMessage = `Error executing stop: ${toErrorMessage(error)}`;
1731
+ if (options.json) console.log(JSON.stringify({
1732
+ ok: false,
1733
+ error: errorMessage
1734
+ }, null, 2));
1735
+ else console.error(errorMessage);
1736
+ process.exit(1);
1737
+ }
1738
+ });
1739
+
1403
1740
  //#endregion
1404
1741
  //#region src/cli.ts
1405
1742
  /**
@@ -1426,7 +1763,7 @@ const prefetchCommand = new commander.Command("prefetch").description("Pre-downl
1426
1763
  async function main() {
1427
1764
  try {
1428
1765
  const program = new commander.Command();
1429
- program.name("one-mcp").description("One MCP server package").version(require_http.version);
1766
+ program.name("one-mcp").description("One MCP server package").version(require_src.version);
1430
1767
  program.addCommand(initCommand);
1431
1768
  program.addCommand(mcpServeCommand);
1432
1769
  program.addCommand(searchToolsCommand);
@@ -1437,6 +1774,7 @@ async function main() {
1437
1774
  program.addCommand(listPromptsCommand);
1438
1775
  program.addCommand(getPromptCommand);
1439
1776
  program.addCommand(prefetchCommand);
1777
+ program.addCommand(stopCommand);
1440
1778
  await program.parseAsync(process.argv);
1441
1779
  } catch (error) {
1442
1780
  console.error(`CLI execution failed: ${error instanceof Error ? error.message : error}`);