@agiflowai/one-mcp 0.3.18 → 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.
- package/dist/cli.cjs +95 -153
- package/dist/cli.mjs +56 -114
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +1 -12
- package/dist/index.d.mts +1 -11
- package/dist/index.mjs +2 -3
- package/dist/{src-DPIjPYdS.mjs → src-BhNZiv0s.mjs} +84 -173
- package/dist/{src-hm1dRqUF.cjs → src-Cc3lEKJ5.cjs} +233 -327
- package/package.json +15 -15
|
@@ -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
|
|
1466
|
-
this.childProcess = process
|
|
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 ||
|
|
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 ||
|
|
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
|
|
2385
|
+
const result = {
|
|
2409
2386
|
tools: [],
|
|
2410
2387
|
skills: [],
|
|
2411
2388
|
notFound: null
|
|
2412
2389
|
};
|
|
2413
|
-
if (requestedName.startsWith(
|
|
2414
|
-
const skillName = requestedName.slice(
|
|
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
|
|
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
|
|
2400
|
+
return result;
|
|
2424
2401
|
}
|
|
2425
2402
|
}
|
|
2426
2403
|
const promptSkillContent = await this.getPromptSkillContent(skillName);
|
|
2427
2404
|
if (promptSkillContent) {
|
|
2428
|
-
result
|
|
2429
|
-
return result
|
|
2405
|
+
result.skills.push(promptSkillContent);
|
|
2406
|
+
return result;
|
|
2430
2407
|
}
|
|
2431
|
-
result
|
|
2432
|
-
return result
|
|
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
|
|
2439
|
-
return result
|
|
2415
|
+
result.notFound = requestedName;
|
|
2416
|
+
return result;
|
|
2440
2417
|
}
|
|
2441
2418
|
const tool = serverTools.find((t) => t.name === actualToolName);
|
|
2442
|
-
if (tool) result
|
|
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
|
|
2451
|
-
return result
|
|
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
|
|
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
|
|
2440
|
+
return result;
|
|
2464
2441
|
}
|
|
2465
2442
|
}
|
|
2466
2443
|
const promptSkillContent = await this.getPromptSkillContent(actualToolName);
|
|
2467
2444
|
if (promptSkillContent) {
|
|
2468
|
-
result
|
|
2469
|
-
return result
|
|
2445
|
+
result.skills.push(promptSkillContent);
|
|
2446
|
+
return result;
|
|
2470
2447
|
}
|
|
2471
|
-
result
|
|
2472
|
-
return result
|
|
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
|
|
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
|
|
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
|
|
2473
|
+
return result;
|
|
2497
2474
|
}));
|
|
2498
2475
|
const foundTools = [];
|
|
2499
2476
|
const foundSkills = [];
|
|
2500
2477
|
const notFoundItems = [];
|
|
2501
|
-
for (const result
|
|
2502
|
-
foundTools.push(...result
|
|
2503
|
-
foundSkills.push(...result
|
|
2504
|
-
if (result
|
|
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(
|
|
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 ||
|
|
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(
|
|
2761
|
-
const skillName = inputToolName.slice(
|
|
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.
|
|
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)
|
|
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(
|
|
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
|
|
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
|
|
3386
|
+
res.status(404).json(payload);
|
|
3408
3387
|
return;
|
|
3409
3388
|
}
|
|
3410
3389
|
if (!this.isAuthorizedShutdownRequest(req)) {
|
|
3411
|
-
const payload
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
3647
|
+
resolve();
|
|
3670
3648
|
}
|
|
3671
3649
|
});
|
|
3672
|
-
} else resolve
|
|
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
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
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
|
|
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}
|
|
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
|
|
4053
|
-
setTimeout(resolve
|
|
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 ??
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
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(
|
|
4155
|
-
await sleep(
|
|
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 };
|