@agiflowai/one-mcp 0.3.19 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,6 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
18
18
  import express from "express";
19
19
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
20
20
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
21
-
22
21
  //#region src/utils/mcpConfigSchema.ts
23
22
  /**
24
23
  * mcpConfigSchema Utilities
@@ -393,7 +392,6 @@ function parseMcpConfig(rawConfig) {
393
392
  const internalConfig = transformClaudeCodeConfig(ClaudeCodeMcpConfigSchema.parse(rawConfig));
394
393
  return InternalMcpConfigSchema.parse(internalConfig);
395
394
  }
396
-
397
395
  //#endregion
398
396
  //#region src/services/RemoteConfigCacheService.ts
399
397
  /**
@@ -613,7 +611,6 @@ var RemoteConfigCacheService = class {
613
611
  this.writeEnabled = enabled;
614
612
  }
615
613
  };
616
-
617
614
  //#endregion
618
615
  //#region src/services/ConfigFetcherService.ts
619
616
  /**
@@ -835,7 +832,6 @@ var ConfigFetcherService = class {
835
832
  return this.cachedConfig !== null && now - this.lastFetchTime < this.cacheTtlMs;
836
833
  }
837
834
  };
838
-
839
835
  //#endregion
840
836
  //#region src/utils/findConfigFile.ts
841
837
  /**
@@ -882,7 +878,6 @@ function findConfigFile() {
882
878
  }
883
879
  return null;
884
880
  }
885
-
886
881
  //#endregion
887
882
  //#region src/utils/parseToolName.ts
888
883
  /**
@@ -904,7 +899,6 @@ function parseToolName(toolName) {
904
899
  };
905
900
  return { actualToolName: toolName };
906
901
  }
907
-
908
902
  //#endregion
909
903
  //#region src/utils/parseFrontMatter.ts
910
904
  /**
@@ -1038,7 +1032,6 @@ function extractSkillFrontMatter(content) {
1038
1032
  };
1039
1033
  return null;
1040
1034
  }
1041
-
1042
1035
  //#endregion
1043
1036
  //#region src/utils/generateServerId.ts
1044
1037
  /**
@@ -1103,7 +1096,6 @@ function generateServerId(length = DEFAULT_ID_LENGTH) {
1103
1096
  }
1104
1097
  return result;
1105
1098
  }
1106
-
1107
1099
  //#endregion
1108
1100
  //#region src/constants/index.ts
1109
1101
  /**
@@ -1123,17 +1115,6 @@ const LOG_PREFIX_SKILL_DETECTION = "[skill-detection]";
1123
1115
  * Log prefix for general MCP capability discovery messages.
1124
1116
  */
1125
1117
  const LOG_PREFIX_CAPABILITY_DISCOVERY = "[capability-discovery]";
1126
- /**
1127
- * Prefix for prompt-based skill locations.
1128
- * Format: "prompt:{serverName}:{promptName}"
1129
- */
1130
- const PROMPT_LOCATION_PREFIX = "prompt:";
1131
- /**
1132
- * Default server ID used when no ID is provided via CLI or config.
1133
- * This fallback is used when auto-generation also fails.
1134
- */
1135
- const DEFAULT_SERVER_ID = "unknown";
1136
-
1137
1118
  //#endregion
1138
1119
  //#region src/services/DefinitionsCacheService.ts
1139
1120
  /**
@@ -1425,7 +1406,6 @@ var DefinitionsCacheService = class {
1425
1406
  return promptSkills;
1426
1407
  }
1427
1408
  };
1428
-
1429
1409
  //#endregion
1430
1410
  //#region src/services/McpClientManagerService.ts
1431
1411
  /** Default connection timeout in milliseconds (30 seconds) */
@@ -1462,8 +1442,8 @@ var McpClient = class {
1462
1442
  this.transport = transport;
1463
1443
  this.client = client;
1464
1444
  }
1465
- setChildProcess(process$1) {
1466
- this.childProcess = process$1;
1445
+ setChildProcess(process) {
1446
+ this.childProcess = process;
1467
1447
  }
1468
1448
  setConnected(connected) {
1469
1449
  this.connected = connected;
@@ -1717,7 +1697,6 @@ var McpClientManagerService = class {
1717
1697
  return this.clients.has(serverName);
1718
1698
  }
1719
1699
  };
1720
-
1721
1700
  //#endregion
1722
1701
  //#region src/services/SkillService.ts
1723
1702
  /**
@@ -2072,11 +2051,9 @@ var SkillService = class {
2072
2051
  };
2073
2052
  }
2074
2053
  };
2075
-
2076
2054
  //#endregion
2077
2055
  //#region src/templates/toolkit-description.liquid?raw
2078
2056
  var toolkit_description_default = "<toolkit id=\"{{ serverId }}\">\n<instruction>\nBefore you use any capabilities below, you MUST call this tool with a list of names to learn how to use them properly; this includes:\n- For tools: Arguments schema needed to pass to use_tool\n- For skills: Detailed instructions that will expand when invoked (Prefer to be explored first when relevant)\n\nThis tool is optimized for batch queries - you can request multiple capabilities at once for better performance.\n\nHow to invoke:\n- For MCP tools: Use use_tool with toolName and toolArgs based on the schema\n- For skills: Use this tool with the skill name to get expanded instructions\n</instruction>\n\n<available_capabilities>\n{% for server in servers -%}\n<group name=\"{{ server.name }}\">\n{% if server.instruction -%}\n<group_instruction>{{ server.instruction }}</group_instruction>\n{% endif -%}\n{% if server.omitToolDescription -%}\n{% for toolName in server.toolNames -%}\n<item name=\"{{ toolName }}\"></item>\n{% endfor -%}\n{% else -%}\n{% for tool in server.tools -%}\n<item name=\"{{ tool.displayName }}\"><description>{{ tool.description | default: \"No description\" }}</description></item>\n{% endfor -%}\n{% endif -%}\n</group>\n{% endfor -%}\n{% if skills.size > 0 -%}\n<group name=\"skills\">\n{% for skill in skills -%}\n<item name=\"{{ skill.displayName }}\"><description>{{ skill.description }}</description></item>\n{% endfor -%}\n</group>\n{% endif -%}\n</available_capabilities>\n</toolkit>\n";
2079
-
2080
2057
  //#endregion
2081
2058
  //#region src/tools/DescribeToolsTool.ts
2082
2059
  /**
@@ -2126,7 +2103,7 @@ var DescribeToolsTool = class DescribeToolsTool {
2126
2103
  constructor(clientManager, skillService, serverId, definitionsCacheService) {
2127
2104
  this.clientManager = clientManager;
2128
2105
  this.skillService = skillService;
2129
- this.serverId = serverId || DEFAULT_SERVER_ID;
2106
+ this.serverId = serverId || "unknown";
2130
2107
  this.definitionsCacheService = definitionsCacheService || new DefinitionsCacheService(clientManager, skillService);
2131
2108
  }
2132
2109
  /**
@@ -2242,7 +2219,7 @@ var DescribeToolsTool = class DescribeToolsTool {
2242
2219
  }).join("\n") || "";
2243
2220
  return {
2244
2221
  name: promptSkill.skill.name,
2245
- location: promptSkill.skill.folder || `${PROMPT_LOCATION_PREFIX}${promptSkill.serverName}/${promptSkill.promptName}`,
2222
+ location: promptSkill.skill.folder || `prompt:${promptSkill.serverName}/${promptSkill.promptName}`,
2246
2223
  instructions: formatSkillInstructions(promptSkill.skill.name, rawInstructions)
2247
2224
  };
2248
2225
  } catch (error) {
@@ -2405,41 +2382,41 @@ var DescribeToolsTool = class DescribeToolsTool {
2405
2382
  }
2406
2383
  }
2407
2384
  const lookupResults = await Promise.all(toolNames.map(async (requestedName) => {
2408
- const result$1 = {
2385
+ const result = {
2409
2386
  tools: [],
2410
2387
  skills: [],
2411
2388
  notFound: null
2412
2389
  };
2413
- if (requestedName.startsWith(SKILL_PREFIX)) {
2414
- const skillName = requestedName.slice(SKILL_PREFIX.length);
2390
+ if (requestedName.startsWith("skill__")) {
2391
+ const skillName = requestedName.slice(7);
2415
2392
  if (this.skillService) {
2416
2393
  const skill = await this.skillService.getSkill(skillName);
2417
2394
  if (skill) {
2418
- result$1.skills.push({
2395
+ result.skills.push({
2419
2396
  name: skill.name,
2420
2397
  location: skill.basePath,
2421
2398
  instructions: formatSkillInstructions(skill.name, skill.content)
2422
2399
  });
2423
- return result$1;
2400
+ return result;
2424
2401
  }
2425
2402
  }
2426
2403
  const promptSkillContent = await this.getPromptSkillContent(skillName);
2427
2404
  if (promptSkillContent) {
2428
- result$1.skills.push(promptSkillContent);
2429
- return result$1;
2405
+ result.skills.push(promptSkillContent);
2406
+ return result;
2430
2407
  }
2431
- result$1.notFound = requestedName;
2432
- return result$1;
2408
+ result.notFound = requestedName;
2409
+ return result;
2433
2410
  }
2434
2411
  const { serverName, actualToolName } = parseToolName(requestedName);
2435
2412
  if (serverName) {
2436
2413
  const serverTools = serverToolsMap.get(serverName);
2437
2414
  if (!serverTools) {
2438
- result$1.notFound = requestedName;
2439
- return result$1;
2415
+ result.notFound = requestedName;
2416
+ return result;
2440
2417
  }
2441
2418
  const tool = serverTools.find((t) => t.name === actualToolName);
2442
- if (tool) result$1.tools.push({
2419
+ if (tool) result.tools.push({
2443
2420
  server: serverName,
2444
2421
  tool: {
2445
2422
  name: tool.name,
@@ -2447,34 +2424,34 @@ var DescribeToolsTool = class DescribeToolsTool {
2447
2424
  inputSchema: tool.inputSchema
2448
2425
  }
2449
2426
  });
2450
- else result$1.notFound = requestedName;
2451
- return result$1;
2427
+ else result.notFound = requestedName;
2428
+ return result;
2452
2429
  }
2453
2430
  const servers = toolToServers.get(actualToolName);
2454
2431
  if (!servers || servers.length === 0) {
2455
2432
  if (this.skillService) {
2456
2433
  const skill = await this.skillService.getSkill(actualToolName);
2457
2434
  if (skill) {
2458
- result$1.skills.push({
2435
+ result.skills.push({
2459
2436
  name: skill.name,
2460
2437
  location: skill.basePath,
2461
2438
  instructions: formatSkillInstructions(skill.name, skill.content)
2462
2439
  });
2463
- return result$1;
2440
+ return result;
2464
2441
  }
2465
2442
  }
2466
2443
  const promptSkillContent = await this.getPromptSkillContent(actualToolName);
2467
2444
  if (promptSkillContent) {
2468
- result$1.skills.push(promptSkillContent);
2469
- return result$1;
2445
+ result.skills.push(promptSkillContent);
2446
+ return result;
2470
2447
  }
2471
- result$1.notFound = requestedName;
2472
- return result$1;
2448
+ result.notFound = requestedName;
2449
+ return result;
2473
2450
  }
2474
2451
  if (servers.length === 1) {
2475
2452
  const server = servers[0];
2476
2453
  const tool = serverToolsMap.get(server).find((t) => t.name === actualToolName);
2477
- result$1.tools.push({
2454
+ result.tools.push({
2478
2455
  server,
2479
2456
  tool: {
2480
2457
  name: tool.name,
@@ -2484,7 +2461,7 @@ var DescribeToolsTool = class DescribeToolsTool {
2484
2461
  });
2485
2462
  } else for (const server of servers) {
2486
2463
  const tool = serverToolsMap.get(server).find((t) => t.name === actualToolName);
2487
- result$1.tools.push({
2464
+ result.tools.push({
2488
2465
  server,
2489
2466
  tool: {
2490
2467
  name: tool.name,
@@ -2493,15 +2470,15 @@ var DescribeToolsTool = class DescribeToolsTool {
2493
2470
  }
2494
2471
  });
2495
2472
  }
2496
- return result$1;
2473
+ return result;
2497
2474
  }));
2498
2475
  const foundTools = [];
2499
2476
  const foundSkills = [];
2500
2477
  const notFoundItems = [];
2501
- for (const result$1 of lookupResults) {
2502
- foundTools.push(...result$1.tools);
2503
- foundSkills.push(...result$1.skills);
2504
- if (result$1.notFound) notFoundItems.push(result$1.notFound);
2478
+ for (const result of lookupResults) {
2479
+ foundTools.push(...result.tools);
2480
+ foundSkills.push(...result.skills);
2481
+ if (result.notFound) notFoundItems.push(result.notFound);
2505
2482
  }
2506
2483
  if (foundTools.length === 0 && foundSkills.length === 0) return {
2507
2484
  content: [{
@@ -2540,7 +2517,6 @@ var DescribeToolsTool = class DescribeToolsTool {
2540
2517
  }
2541
2518
  }
2542
2519
  };
2543
-
2544
2520
  //#endregion
2545
2521
  //#region src/utils/toolCapabilities.ts
2546
2522
  const TOOL_CAPABILITIES_META_KEY = "agiflowai/capabilities";
@@ -2552,7 +2528,6 @@ function getToolCapabilities(tool) {
2552
2528
  function getUniqueSortedCapabilities(tools) {
2553
2529
  return Array.from(new Set(tools.flatMap((tool) => getToolCapabilities(tool)))).sort();
2554
2530
  }
2555
-
2556
2531
  //#endregion
2557
2532
  //#region src/tools/SearchListToolsTool.ts
2558
2533
  var SearchListToolsTool = class SearchListToolsTool {
@@ -2619,17 +2594,15 @@ var SearchListToolsTool = class SearchListToolsTool {
2619
2594
  capabilities: getToolCapabilities(tool)
2620
2595
  }))
2621
2596
  })).filter((server) => server.tools.length > 0);
2622
- const result = { servers: filteredServers };
2623
2597
  return {
2624
2598
  content: [{
2625
2599
  type: "text",
2626
- text: JSON.stringify(result, null, 2)
2600
+ text: JSON.stringify({ servers: filteredServers }, null, 2)
2627
2601
  }],
2628
2602
  isError: filteredServers.length === 0 ? true : void 0
2629
2603
  };
2630
2604
  }
2631
2605
  };
2632
-
2633
2606
  //#endregion
2634
2607
  //#region src/tools/UseToolTool.ts
2635
2608
  /**
@@ -2662,7 +2635,7 @@ var UseToolTool = class UseToolTool {
2662
2635
  this.clientManager = clientManager;
2663
2636
  this.skillService = skillService;
2664
2637
  this.definitionsCacheService = definitionsCacheService || new DefinitionsCacheService(clientManager, skillService);
2665
- this.serverId = serverId || DEFAULT_SERVER_ID;
2638
+ this.serverId = serverId || "unknown";
2666
2639
  }
2667
2640
  /**
2668
2641
  * Returns the MCP tool definition with name, description, and input schema.
@@ -2757,8 +2730,8 @@ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverI
2757
2730
  async execute(input) {
2758
2731
  try {
2759
2732
  const { toolName: inputToolName, toolArgs = {} } = input;
2760
- if (inputToolName.startsWith(SKILL_PREFIX)) {
2761
- const skillName = inputToolName.slice(SKILL_PREFIX.length);
2733
+ if (inputToolName.startsWith("skill__")) {
2734
+ const skillName = inputToolName.slice(7);
2762
2735
  if (this.skillService) {
2763
2736
  const skill = await this.skillService.getSkill(skillName);
2764
2737
  if (skill) return this.executeSkill(skill);
@@ -2843,11 +2816,9 @@ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverI
2843
2816
  }
2844
2817
  }
2845
2818
  };
2846
-
2847
2819
  //#endregion
2848
2820
  //#region package.json
2849
- var version = "0.3.18";
2850
-
2821
+ var version = "0.3.19";
2851
2822
  //#endregion
2852
2823
  //#region src/server/index.ts
2853
2824
  /**
@@ -3199,7 +3170,6 @@ async function createSessionServer(shared) {
3199
3170
  async function createServer(options) {
3200
3171
  return createSessionServer(await initializeSharedServices(options));
3201
3172
  }
3202
-
3203
3173
  //#endregion
3204
3174
  //#region src/types/index.ts
3205
3175
  /**
@@ -3210,7 +3180,6 @@ const TRANSPORT_MODE = {
3210
3180
  HTTP: "http",
3211
3181
  SSE: "sse"
3212
3182
  };
3213
-
3214
3183
  //#endregion
3215
3184
  //#region src/transports/http.ts
3216
3185
  /**
@@ -3240,6 +3209,7 @@ const TRANSPORT_MODE = {
3240
3209
  */
3241
3210
  var HttpFullSessionManager = class {
3242
3211
  sessions = /* @__PURE__ */ new Map();
3212
+ closingSessions = /* @__PURE__ */ new Set();
3243
3213
  getSession(sessionId) {
3244
3214
  return this.sessions.get(sessionId);
3245
3215
  }
@@ -3250,26 +3220,35 @@ var HttpFullSessionManager = class {
3250
3220
  });
3251
3221
  }
3252
3222
  async deleteSession(sessionId) {
3223
+ if (this.closingSessions.has(sessionId)) return;
3253
3224
  const session = this.sessions.get(sessionId);
3254
- if (session) try {
3225
+ if (!session) return;
3226
+ this.closingSessions.add(sessionId);
3227
+ this.sessions.delete(sessionId);
3228
+ try {
3255
3229
  await session.server.close();
3256
3230
  } catch (error) {
3257
3231
  throw new Error(`Failed to close MCP server for session '${sessionId}': ${toErrorMessage$2(error)}`);
3232
+ } finally {
3233
+ this.closingSessions.delete(sessionId);
3258
3234
  }
3259
- this.sessions.delete(sessionId);
3260
3235
  }
3261
3236
  hasSession(sessionId) {
3262
3237
  return this.sessions.has(sessionId);
3263
3238
  }
3264
3239
  async clear() {
3240
+ const sessions = Array.from(this.sessions.entries());
3241
+ this.sessions.clear();
3265
3242
  try {
3266
- await Promise.all(Array.from(this.sessions.values()).map(async (session) => {
3243
+ await Promise.all(sessions.map(async ([sessionId, session]) => {
3244
+ this.closingSessions.add(sessionId);
3267
3245
  await session.server.close();
3268
3246
  }));
3269
3247
  } catch (error) {
3270
3248
  throw new Error(`Failed to clear sessions: ${toErrorMessage$2(error)}`);
3249
+ } finally {
3250
+ for (const [sessionId] of sessions) this.closingSessions.delete(sessionId);
3271
3251
  }
3272
- this.sessions.clear();
3273
3252
  }
3274
3253
  };
3275
3254
  function toErrorMessage$2(error) {
@@ -3399,21 +3378,21 @@ var HttpTransportHandler = class {
3399
3378
  async handleAdminShutdownRequest(req, res) {
3400
3379
  try {
3401
3380
  if (!this.adminOptions?.onShutdownRequested) {
3402
- const payload$1 = {
3381
+ const payload = {
3403
3382
  ok: false,
3404
3383
  message: "Shutdown endpoint is not enabled for this server instance.",
3405
3384
  serverId: this.adminOptions?.serverId
3406
3385
  };
3407
- res.status(404).json(payload$1);
3386
+ res.status(404).json(payload);
3408
3387
  return;
3409
3388
  }
3410
3389
  if (!this.isAuthorizedShutdownRequest(req)) {
3411
- const payload$1 = {
3390
+ const payload = {
3412
3391
  ok: false,
3413
3392
  message: "Unauthorized shutdown request: invalid or missing shutdown token.",
3414
3393
  serverId: this.adminOptions?.serverId
3415
3394
  };
3416
- res.status(401).json(payload$1);
3395
+ res.status(401).json(payload);
3417
3396
  return;
3418
3397
  }
3419
3398
  const payload = {
@@ -3537,7 +3516,6 @@ var HttpTransportHandler = class {
3537
3516
  return this.config.host;
3538
3517
  }
3539
3518
  };
3540
-
3541
3519
  //#endregion
3542
3520
  //#region src/transports/sse.ts
3543
3521
  /**
@@ -3641,14 +3619,14 @@ var SseTransportHandler = class {
3641
3619
  }
3642
3620
  }
3643
3621
  async start() {
3644
- return new Promise((resolve$1, reject) => {
3622
+ return new Promise((resolve, reject) => {
3645
3623
  try {
3646
3624
  this.server = this.app.listen(this.config.port, this.config.host, () => {
3647
3625
  console.error(`@agiflowai/one-mcp MCP server started with SSE transport on http://${this.config.host}:${this.config.port}`);
3648
3626
  console.error(`SSE endpoint: http://${this.config.host}:${this.config.port}/sse`);
3649
3627
  console.error(`Messages endpoint: http://${this.config.host}:${this.config.port}/messages`);
3650
3628
  console.error(`Health check: http://${this.config.host}:${this.config.port}/health`);
3651
- resolve$1();
3629
+ resolve();
3652
3630
  });
3653
3631
  this.server.on("error", (error) => {
3654
3632
  reject(error);
@@ -3659,17 +3637,17 @@ var SseTransportHandler = class {
3659
3637
  });
3660
3638
  }
3661
3639
  async stop() {
3662
- return new Promise((resolve$1, reject) => {
3640
+ return new Promise((resolve, reject) => {
3663
3641
  if (this.server) {
3664
3642
  this.sessionManager.clear();
3665
3643
  this.server.close((err) => {
3666
3644
  if (err) reject(err);
3667
3645
  else {
3668
3646
  this.server = null;
3669
- resolve$1();
3647
+ resolve();
3670
3648
  }
3671
3649
  });
3672
- } else resolve$1();
3650
+ } else resolve();
3673
3651
  });
3674
3652
  }
3675
3653
  getPort() {
@@ -3679,7 +3657,6 @@ var SseTransportHandler = class {
3679
3657
  return this.config.host;
3680
3658
  }
3681
3659
  };
3682
-
3683
3660
  //#endregion
3684
3661
  //#region src/transports/stdio.ts
3685
3662
  /**
@@ -3704,7 +3681,6 @@ var StdioTransportHandler = class {
3704
3681
  }
3705
3682
  }
3706
3683
  };
3707
-
3708
3684
  //#endregion
3709
3685
  //#region src/transports/stdio-http.ts
3710
3686
  /**
@@ -3847,7 +3823,6 @@ var StdioHttpTransportHandler = class {
3847
3823
  return proxyServer;
3848
3824
  }
3849
3825
  };
3850
-
3851
3826
  //#endregion
3852
3827
  //#region src/services/RuntimeStateService.ts
3853
3828
  /**
@@ -3946,61 +3921,16 @@ var RuntimeStateService = class RuntimeStateService {
3946
3921
  await rm(this.getRecordPath(serverId), { force: true });
3947
3922
  }
3948
3923
  };
3949
-
3950
- //#endregion
3951
- //#region src/services/StopServerService/constants.ts
3952
- /**
3953
- * StopServerService constants.
3954
- */
3955
- /** Maximum time in milliseconds to wait for a shutdown to complete. */
3956
- const DEFAULT_STOP_TIMEOUT_MS = 5e3;
3957
- /** Minimum timeout in milliseconds for individual health check requests. */
3958
- const HEALTH_REQUEST_TIMEOUT_FLOOR_MS = 250;
3959
- /** Delay in milliseconds between shutdown polling attempts. */
3960
- const SHUTDOWN_POLL_INTERVAL_MS = 200;
3961
3924
  /** Path for the runtime health check endpoint. */
3962
3925
  const HEALTH_CHECK_PATH = "/health";
3963
- /** Path for the authenticated admin shutdown endpoint. */
3964
- const ADMIN_SHUTDOWN_PATH = "/admin/shutdown";
3965
- /** HTTP GET method identifier. */
3966
- const HTTP_METHOD_GET = "GET";
3967
- /** HTTP POST method identifier. */
3968
- const HTTP_METHOD_POST = "POST";
3969
- /** HTTP header name for bearer token authorization. */
3970
- const AUTHORIZATION_HEADER_NAME = "Authorization";
3971
- /** Prefix for bearer token values in the Authorization header. */
3972
- const BEARER_TOKEN_PREFIX = "Bearer ";
3973
3926
  /** HTTP protocol scheme prefix for URL construction. */
3974
3927
  const HTTP_PROTOCOL = "http://";
3975
- /** Separator between host and port in URL construction. */
3976
- const URL_PORT_SEPARATOR = ":";
3977
- /** Loopback hostname. */
3978
- const LOOPBACK_HOST_LOCALHOST = "localhost";
3979
- /** IPv4 loopback address. */
3980
- const LOOPBACK_HOST_IPV4 = "127.0.0.1";
3981
- /** IPv6 loopback address. */
3982
- const LOOPBACK_HOST_IPV6 = "::1";
3983
3928
  /** Hosts that are safe to send admin requests to (loopback only). */
3984
3929
  const ALLOWED_HOSTS = new Set([
3985
- LOOPBACK_HOST_LOCALHOST,
3986
- LOOPBACK_HOST_IPV4,
3987
- LOOPBACK_HOST_IPV6
3930
+ "localhost",
3931
+ "127.0.0.1",
3932
+ "::1"
3988
3933
  ]);
3989
- /** Expected status value in a healthy runtime response. */
3990
- const HEALTH_STATUS_OK = "ok";
3991
- /** Expected transport value in a healthy runtime response. */
3992
- const HEALTH_TRANSPORT_HTTP = "http";
3993
- /** Property key for status field in health responses. */
3994
- const KEY_STATUS = "status";
3995
- /** Property key for transport field in health responses. */
3996
- const KEY_TRANSPORT = "transport";
3997
- /** Property key for serverId field in runtime responses. */
3998
- const KEY_SERVER_ID = "serverId";
3999
- /** Property key for ok field in shutdown responses. */
4000
- const KEY_OK = "ok";
4001
- /** Property key for message field in shutdown responses. */
4002
- const KEY_MESSAGE = "message";
4003
-
4004
3934
  //#endregion
4005
3935
  //#region src/services/StopServerService/types.ts
4006
3936
  /**
@@ -4019,19 +3949,8 @@ function toRecord(value) {
4019
3949
  function isHealthResponse(value) {
4020
3950
  if (typeof value !== "object" || value === null) return false;
4021
3951
  const record = toRecord(value);
4022
- return KEY_STATUS in record && record[KEY_STATUS] === HEALTH_STATUS_OK && KEY_TRANSPORT in record && record[KEY_TRANSPORT] === HEALTH_TRANSPORT_HTTP && (!(KEY_SERVER_ID in record) || record[KEY_SERVER_ID] === void 0 || typeof record[KEY_SERVER_ID] === "string");
3952
+ return "status" in record && record["status"] === "ok" && "transport" in record && record["transport"] === "http" && (!("serverId" in record) || record["serverId"] === void 0 || typeof record["serverId"] === "string");
4023
3953
  }
4024
- /**
4025
- * Type guard for shutdown responses.
4026
- * @param value - Candidate payload to validate
4027
- * @returns True when payload matches shutdown response shape
4028
- */
4029
- function isShutdownResponse(value) {
4030
- if (typeof value !== "object" || value === null) return false;
4031
- const record = toRecord(value);
4032
- return KEY_OK in record && typeof record[KEY_OK] === "boolean" && KEY_MESSAGE in record && typeof record[KEY_MESSAGE] === "string" && (!(KEY_SERVER_ID in record) || record[KEY_SERVER_ID] === void 0 || typeof record[KEY_SERVER_ID] === "string");
4033
- }
4034
-
4035
3954
  //#endregion
4036
3955
  //#region src/services/StopServerService/StopServerService.ts
4037
3956
  /**
@@ -4043,14 +3962,14 @@ function isShutdownResponse(value) {
4043
3962
  */
4044
3963
  function buildRuntimeUrl(runtime, path) {
4045
3964
  if (!ALLOWED_HOSTS.has(runtime.host)) throw new Error(`Refusing to connect to non-loopback host '${runtime.host}'. Only ${Array.from(ALLOWED_HOSTS).join(", ")} are allowed.`);
4046
- return `${HTTP_PROTOCOL}${runtime.host}${URL_PORT_SEPARATOR}${runtime.port}${path}`;
3965
+ return `${HTTP_PROTOCOL}${runtime.host}:${runtime.port}${path}`;
4047
3966
  }
4048
3967
  function toErrorMessage(error) {
4049
3968
  return error instanceof Error ? error.message : String(error);
4050
3969
  }
4051
3970
  function sleep(delayMs) {
4052
- return new Promise((resolve$1) => {
4053
- setTimeout(resolve$1, delayMs);
3971
+ return new Promise((resolve) => {
3972
+ setTimeout(resolve, delayMs);
4054
3973
  });
4055
3974
  }
4056
3975
  /**
@@ -4067,7 +3986,7 @@ var StopServerService = class {
4067
3986
  * @returns Stop result payload
4068
3987
  */
4069
3988
  async stop(request) {
4070
- const timeoutMs = request.timeoutMs ?? DEFAULT_STOP_TIMEOUT_MS;
3989
+ const timeoutMs = request.timeoutMs ?? 5e3;
4071
3990
  const runtime = await this.resolveRuntime(request);
4072
3991
  const health = await this.fetchHealth(runtime, timeoutMs);
4073
3992
  if (!health.reachable) {
@@ -4075,9 +3994,7 @@ var StopServerService = class {
4075
3994
  throw new Error(`Runtime '${runtime.serverId}' is not reachable at http://${runtime.host}:${runtime.port}. Removed stale runtime record.`);
4076
3995
  }
4077
3996
  if (!request.force && health.payload?.serverId && health.payload.serverId !== runtime.serverId) throw new Error(`Refusing to stop runtime at http://${runtime.host}:${runtime.port}: expected server ID '${runtime.serverId}' but health endpoint reported '${health.payload.serverId}'. Use --force to override.`);
4078
- const shutdownToken = request.token ?? runtime.shutdownToken;
4079
- if (!shutdownToken) throw new Error(`No shutdown token available for runtime '${runtime.serverId}'.`);
4080
- const shutdownResponse = await this.requestShutdown(runtime, shutdownToken, timeoutMs);
3997
+ this.requestLocalShutdown(runtime);
4081
3998
  await this.waitForShutdown(runtime, timeoutMs);
4082
3999
  await this.runtimeStateService.remove(runtime.serverId);
4083
4000
  return {
@@ -4085,7 +4002,7 @@ var StopServerService = class {
4085
4002
  serverId: runtime.serverId,
4086
4003
  host: runtime.host,
4087
4004
  port: runtime.port,
4088
- message: shutdownResponse.message
4005
+ message: `Sent SIGTERM to local process ${runtime.pid} and the runtime stopped gracefully.`
4089
4006
  };
4090
4007
  }
4091
4008
  /**
@@ -4113,7 +4030,7 @@ var StopServerService = class {
4113
4030
  */
4114
4031
  async fetchHealth(runtime, timeoutMs) {
4115
4032
  try {
4116
- const response = await this.fetchWithTimeout(buildRuntimeUrl(runtime, HEALTH_CHECK_PATH), { method: HTTP_METHOD_GET }, timeoutMs);
4033
+ const response = await this.fetchWithTimeout(buildRuntimeUrl(runtime, HEALTH_CHECK_PATH), { method: "GET" }, timeoutMs);
4117
4034
  if (!response.ok) return { reachable: false };
4118
4035
  const payload = await response.json();
4119
4036
  if (!isHealthResponse(payload)) throw new Error("Received invalid health response payload.");
@@ -4125,22 +4042,14 @@ var StopServerService = class {
4125
4042
  return { reachable: false };
4126
4043
  }
4127
4044
  }
4128
- /**
4129
- * Send authenticated shutdown request to the admin endpoint.
4130
- * @param runtime - Runtime to stop
4131
- * @param shutdownToken - Bearer token for the admin endpoint
4132
- * @param timeoutMs - Request timeout in milliseconds
4133
- * @returns Parsed shutdown response payload
4134
- */
4135
- async requestShutdown(runtime, shutdownToken, timeoutMs) {
4136
- const response = await this.fetchWithTimeout(buildRuntimeUrl(runtime, ADMIN_SHUTDOWN_PATH), {
4137
- method: HTTP_METHOD_POST,
4138
- headers: { [AUTHORIZATION_HEADER_NAME]: `${BEARER_TOKEN_PREFIX}${shutdownToken}` }
4139
- }, timeoutMs);
4140
- const payload = await response.json();
4141
- if (!isShutdownResponse(payload)) throw new Error("Received invalid shutdown response payload.");
4142
- if (!response.ok || !payload.ok) throw new Error(payload.message);
4143
- return payload;
4045
+ requestLocalShutdown(runtime) {
4046
+ try {
4047
+ process.kill(runtime.pid, "SIGTERM");
4048
+ } catch (error) {
4049
+ if (isNodeError(error) && error.code === "ESRCH") throw new Error(`Runtime '${runtime.serverId}' is not running anymore (pid ${runtime.pid} does not exist).`);
4050
+ if (isNodeError(error) && error.code === "EPERM") throw new Error(`Permission denied when signaling runtime '${runtime.serverId}' (pid ${runtime.pid}).`);
4051
+ throw new Error(`Failed to signal runtime '${runtime.serverId}' (pid ${runtime.pid}): ${toErrorMessage(error)}`);
4052
+ }
4144
4053
  }
4145
4054
  /**
4146
4055
  * Poll until the target runtime is no longer reachable.
@@ -4151,8 +4060,8 @@ var StopServerService = class {
4151
4060
  async waitForShutdown(runtime, timeoutMs) {
4152
4061
  const deadline = Date.now() + timeoutMs;
4153
4062
  while (Date.now() < deadline) {
4154
- if (!(await this.fetchHealth(runtime, Math.max(HEALTH_REQUEST_TIMEOUT_FLOOR_MS, deadline - Date.now()))).reachable) return;
4155
- await sleep(SHUTDOWN_POLL_INTERVAL_MS);
4063
+ if (!(await this.fetchHealth(runtime, Math.max(250, deadline - Date.now()))).reachable) return;
4064
+ await sleep(200);
4156
4065
  }
4157
4066
  throw new Error(`Timed out waiting for runtime '${runtime.serverId}' to stop at http://${runtime.host}:${runtime.port}.`);
4158
4067
  }
@@ -4180,6 +4089,8 @@ var StopServerService = class {
4180
4089
  }
4181
4090
  }
4182
4091
  };
4183
-
4092
+ function isNodeError(error) {
4093
+ return typeof error === "object" && error !== null && "code" in error;
4094
+ }
4184
4095
  //#endregion
4185
- export { DefinitionsCacheService as _, SseTransportHandler as a, ConfigFetcherService as b, createServer as c, version as d, UseToolTool as f, McpClientManagerService as g, SkillService as h, StdioTransportHandler as i, createSessionServer as l, DescribeToolsTool as m, RuntimeStateService as n, HttpTransportHandler as o, SearchListToolsTool as p, StdioHttpTransportHandler as r, TRANSPORT_MODE as s, StopServerService as t, initializeSharedServices as u, generateServerId as v, findConfigFile as y };
4096
+ export { DefinitionsCacheService as _, SseTransportHandler as a, ConfigFetcherService as b, createServer as c, version as d, UseToolTool as f, McpClientManagerService as g, SkillService as h, StdioTransportHandler as i, createSessionServer as l, DescribeToolsTool as m, RuntimeStateService as n, HttpTransportHandler as o, SearchListToolsTool as p, StdioHttpTransportHandler as r, TRANSPORT_MODE as s, StopServerService as t, initializeSharedServices as u, generateServerId as v, findConfigFile as y };