@agiflowai/one-mcp 0.2.7 → 0.3.1
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/README.md +34 -0
- package/dist/cli.cjs +477 -13
- package/dist/cli.mjs +478 -14
- package/dist/{http-B4NAfsQl.cjs → http-C4IfZSwW.cjs} +111 -16
- package/dist/{http-DSkkpGJU.mjs → http-xi_ha63Y.mjs} +112 -17
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
|
@@ -231,6 +231,7 @@ const ClaudeCodeStdioServerSchema = zod.z.object({
|
|
|
231
231
|
env: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
232
232
|
disabled: zod.z.boolean().optional(),
|
|
233
233
|
instruction: zod.z.string().optional(),
|
|
234
|
+
timeout: zod.z.number().positive().optional(),
|
|
234
235
|
config: AdditionalConfigSchema
|
|
235
236
|
});
|
|
236
237
|
const ClaudeCodeHttpServerSchema = zod.z.object({
|
|
@@ -239,6 +240,7 @@ const ClaudeCodeHttpServerSchema = zod.z.object({
|
|
|
239
240
|
type: zod.z.enum(["http", "sse"]).optional(),
|
|
240
241
|
disabled: zod.z.boolean().optional(),
|
|
241
242
|
instruction: zod.z.string().optional(),
|
|
243
|
+
timeout: zod.z.number().positive().optional(),
|
|
242
244
|
config: AdditionalConfigSchema
|
|
243
245
|
});
|
|
244
246
|
const ClaudeCodeServerConfigSchema = zod.z.union([ClaudeCodeStdioServerSchema, ClaudeCodeHttpServerSchema]);
|
|
@@ -269,6 +271,7 @@ const SkillsConfigSchema = zod.z.object({ paths: zod.z.array(zod.z.string()) });
|
|
|
269
271
|
* Full Claude Code MCP configuration schema
|
|
270
272
|
*/
|
|
271
273
|
const ClaudeCodeMcpConfigSchema = zod.z.object({
|
|
274
|
+
id: zod.z.string().optional(),
|
|
272
275
|
mcpServers: zod.z.record(zod.z.string(), ClaudeCodeServerConfigSchema),
|
|
273
276
|
remoteConfigs: zod.z.array(RemoteConfigSourceSchema).optional(),
|
|
274
277
|
skills: SkillsConfigSchema.optional()
|
|
@@ -309,6 +312,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
|
|
|
309
312
|
toolBlacklist: zod.z.array(zod.z.string()).optional(),
|
|
310
313
|
omitToolDescription: zod.z.boolean().optional(),
|
|
311
314
|
prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
|
|
315
|
+
timeout: zod.z.number().positive().optional(),
|
|
312
316
|
transport: zod.z.literal("stdio"),
|
|
313
317
|
config: McpStdioConfigSchema
|
|
314
318
|
}),
|
|
@@ -318,6 +322,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
|
|
|
318
322
|
toolBlacklist: zod.z.array(zod.z.string()).optional(),
|
|
319
323
|
omitToolDescription: zod.z.boolean().optional(),
|
|
320
324
|
prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
|
|
325
|
+
timeout: zod.z.number().positive().optional(),
|
|
321
326
|
transport: zod.z.literal("http"),
|
|
322
327
|
config: McpHttpConfigSchema
|
|
323
328
|
}),
|
|
@@ -327,6 +332,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
|
|
|
327
332
|
toolBlacklist: zod.z.array(zod.z.string()).optional(),
|
|
328
333
|
omitToolDescription: zod.z.boolean().optional(),
|
|
329
334
|
prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
|
|
335
|
+
timeout: zod.z.number().positive().optional(),
|
|
330
336
|
transport: zod.z.literal("sse"),
|
|
331
337
|
config: McpSseConfigSchema
|
|
332
338
|
})
|
|
@@ -335,6 +341,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
|
|
|
335
341
|
* Full internal MCP configuration schema
|
|
336
342
|
*/
|
|
337
343
|
const InternalMcpConfigSchema = zod.z.object({
|
|
344
|
+
id: zod.z.string().optional(),
|
|
338
345
|
mcpServers: zod.z.record(zod.z.string(), McpServerConfigSchema),
|
|
339
346
|
skills: SkillsConfigSchema.optional()
|
|
340
347
|
});
|
|
@@ -360,6 +367,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
360
367
|
toolBlacklist: stdioConfig.config?.toolBlacklist,
|
|
361
368
|
omitToolDescription: stdioConfig.config?.omitToolDescription,
|
|
362
369
|
prompts: stdioConfig.config?.prompts,
|
|
370
|
+
timeout: stdioConfig.timeout,
|
|
363
371
|
transport: "stdio",
|
|
364
372
|
config: {
|
|
365
373
|
command: interpolatedCommand,
|
|
@@ -378,6 +386,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
378
386
|
toolBlacklist: httpConfig.config?.toolBlacklist,
|
|
379
387
|
omitToolDescription: httpConfig.config?.omitToolDescription,
|
|
380
388
|
prompts: httpConfig.config?.prompts,
|
|
389
|
+
timeout: httpConfig.timeout,
|
|
381
390
|
transport,
|
|
382
391
|
config: {
|
|
383
392
|
url: interpolatedUrl,
|
|
@@ -387,6 +396,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
387
396
|
}
|
|
388
397
|
}
|
|
389
398
|
return {
|
|
399
|
+
id: claudeConfig.id,
|
|
390
400
|
mcpServers: transformedServers,
|
|
391
401
|
skills: claudeConfig.skills
|
|
392
402
|
};
|
|
@@ -836,6 +846,8 @@ var ConfigFetcherService = class {
|
|
|
836
846
|
|
|
837
847
|
//#endregion
|
|
838
848
|
//#region src/services/McpClientManagerService.ts
|
|
849
|
+
/** Default connection timeout in milliseconds (30 seconds) */
|
|
850
|
+
const DEFAULT_CONNECTION_TIMEOUT_MS = 3e4;
|
|
839
851
|
/**
|
|
840
852
|
* MCP Client wrapper for managing individual server connections
|
|
841
853
|
* This is an internal class used by McpClientManagerService
|
|
@@ -941,8 +953,10 @@ var McpClientManagerService = class {
|
|
|
941
953
|
}
|
|
942
954
|
/**
|
|
943
955
|
* Connect to an MCP server based on its configuration with timeout
|
|
956
|
+
* Uses the timeout from server config, falling back to default (30s)
|
|
944
957
|
*/
|
|
945
|
-
async connectToServer(serverName, config
|
|
958
|
+
async connectToServer(serverName, config) {
|
|
959
|
+
const timeoutMs = config.timeout ?? DEFAULT_CONNECTION_TIMEOUT_MS;
|
|
946
960
|
if (this.clients.has(serverName)) throw new Error(`Client for ${serverName} is already connected`);
|
|
947
961
|
const client = new __modelcontextprotocol_sdk_client_index_js.Client({
|
|
948
962
|
name: `@agiflowai/one-mcp-client`,
|
|
@@ -1237,6 +1251,71 @@ function extractSkillFrontMatter(content) {
|
|
|
1237
1251
|
return null;
|
|
1238
1252
|
}
|
|
1239
1253
|
|
|
1254
|
+
//#endregion
|
|
1255
|
+
//#region src/utils/generateServerId.ts
|
|
1256
|
+
/**
|
|
1257
|
+
* generateServerId Utilities
|
|
1258
|
+
*
|
|
1259
|
+
* DESIGN PATTERNS:
|
|
1260
|
+
* - Pure functions with no side effects
|
|
1261
|
+
* - Single responsibility per function
|
|
1262
|
+
* - Functional programming approach
|
|
1263
|
+
*
|
|
1264
|
+
* CODING STANDARDS:
|
|
1265
|
+
* - Export individual functions, not classes
|
|
1266
|
+
* - Use descriptive function names with verbs
|
|
1267
|
+
* - Add JSDoc comments for complex logic
|
|
1268
|
+
* - Keep functions small and focused
|
|
1269
|
+
*
|
|
1270
|
+
* AVOID:
|
|
1271
|
+
* - Side effects (mutating external state)
|
|
1272
|
+
* - Stateful logic (use services for state)
|
|
1273
|
+
* - Complex external dependencies
|
|
1274
|
+
*/
|
|
1275
|
+
/**
|
|
1276
|
+
* Character set for generating human-readable IDs.
|
|
1277
|
+
* Excludes confusing characters: 0, O, 1, l, I
|
|
1278
|
+
*/
|
|
1279
|
+
const CHARSET = "23456789abcdefghjkmnpqrstuvwxyz";
|
|
1280
|
+
/**
|
|
1281
|
+
* Default length for generated server IDs (6 characters)
|
|
1282
|
+
*/
|
|
1283
|
+
const DEFAULT_ID_LENGTH = 6;
|
|
1284
|
+
/**
|
|
1285
|
+
* Generate a short, human-readable server ID.
|
|
1286
|
+
*
|
|
1287
|
+
* Uses Node.js crypto.randomBytes for cryptographically secure randomness
|
|
1288
|
+
* with rejection sampling to avoid modulo bias.
|
|
1289
|
+
*
|
|
1290
|
+
* The generated ID:
|
|
1291
|
+
* - Is 6 characters long by default
|
|
1292
|
+
* - Uses only lowercase alphanumeric characters
|
|
1293
|
+
* - Excludes confusing characters (0, O, 1, l, I)
|
|
1294
|
+
*
|
|
1295
|
+
* @param length - Length of the ID to generate (default: 6)
|
|
1296
|
+
* @returns A random, human-readable ID
|
|
1297
|
+
*
|
|
1298
|
+
* @example
|
|
1299
|
+
* generateServerId() // "abc234"
|
|
1300
|
+
* generateServerId(4) // "x7mn"
|
|
1301
|
+
*/
|
|
1302
|
+
function generateServerId(length = DEFAULT_ID_LENGTH) {
|
|
1303
|
+
const charsetLength = 31;
|
|
1304
|
+
const maxUnbiased = Math.floor(256 / charsetLength) * charsetLength - 1;
|
|
1305
|
+
let result = "";
|
|
1306
|
+
let remaining = length;
|
|
1307
|
+
while (remaining > 0) {
|
|
1308
|
+
const bytes = (0, node_crypto.randomBytes)(remaining);
|
|
1309
|
+
for (let i = 0; i < bytes.length && remaining > 0; i++) {
|
|
1310
|
+
const byte = bytes[i];
|
|
1311
|
+
if (byte > maxUnbiased) continue;
|
|
1312
|
+
result += CHARSET[byte % charsetLength];
|
|
1313
|
+
remaining--;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
return result;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1240
1319
|
//#endregion
|
|
1241
1320
|
//#region src/services/SkillService.ts
|
|
1242
1321
|
/**
|
|
@@ -1514,7 +1593,7 @@ var SkillService = class {
|
|
|
1514
1593
|
* Prefix added to skill names when they clash with MCP tool names.
|
|
1515
1594
|
* This ensures skills can be uniquely identified even when a tool has the same name.
|
|
1516
1595
|
*/
|
|
1517
|
-
const SKILL_PREFIX
|
|
1596
|
+
const SKILL_PREFIX = "skill__";
|
|
1518
1597
|
/**
|
|
1519
1598
|
* Log prefix for skill detection messages.
|
|
1520
1599
|
* Used to easily filter skill detection logs in stderr output.
|
|
@@ -1525,10 +1604,15 @@ const LOG_PREFIX_SKILL_DETECTION = "[skill-detection]";
|
|
|
1525
1604
|
* Format: "prompt:{serverName}:{promptName}"
|
|
1526
1605
|
*/
|
|
1527
1606
|
const PROMPT_LOCATION_PREFIX = "prompt:";
|
|
1607
|
+
/**
|
|
1608
|
+
* Default server ID used when no ID is provided via CLI or config.
|
|
1609
|
+
* This fallback is used when auto-generation also fails.
|
|
1610
|
+
*/
|
|
1611
|
+
const DEFAULT_SERVER_ID = "unknown";
|
|
1528
1612
|
|
|
1529
1613
|
//#endregion
|
|
1530
1614
|
//#region src/templates/toolkit-description.liquid?raw
|
|
1531
|
-
var toolkit_description_default = "<toolkit>\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";
|
|
1615
|
+
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";
|
|
1532
1616
|
|
|
1533
1617
|
//#endregion
|
|
1534
1618
|
//#region src/tools/DescribeToolsTool.ts
|
|
@@ -1567,14 +1651,18 @@ var DescribeToolsTool = class DescribeToolsTool {
|
|
|
1567
1651
|
liquid = new liquidjs.Liquid();
|
|
1568
1652
|
/** Cache for auto-detected skills from prompt front-matter */
|
|
1569
1653
|
autoDetectedSkillsCache = null;
|
|
1654
|
+
/** Unique server identifier for this one-mcp instance */
|
|
1655
|
+
serverId;
|
|
1570
1656
|
/**
|
|
1571
1657
|
* Creates a new DescribeToolsTool instance
|
|
1572
1658
|
* @param clientManager - The MCP client manager for accessing remote servers
|
|
1573
1659
|
* @param skillService - Optional skill service for loading skills
|
|
1660
|
+
* @param serverId - Unique server identifier for this one-mcp instance
|
|
1574
1661
|
*/
|
|
1575
|
-
constructor(clientManager, skillService) {
|
|
1662
|
+
constructor(clientManager, skillService, serverId) {
|
|
1576
1663
|
this.clientManager = clientManager;
|
|
1577
1664
|
this.skillService = skillService;
|
|
1665
|
+
this.serverId = serverId || DEFAULT_SERVER_ID;
|
|
1578
1666
|
}
|
|
1579
1667
|
/**
|
|
1580
1668
|
* Clears the cached auto-detected skills from prompt front-matter.
|
|
@@ -1799,14 +1887,15 @@ var DescribeToolsTool = class DescribeToolsTool {
|
|
|
1799
1887
|
const clashesWithMcpTool = allToolNames.has(skill.name);
|
|
1800
1888
|
return {
|
|
1801
1889
|
name: skill.name,
|
|
1802
|
-
displayName: clashesWithMcpTool ? `${SKILL_PREFIX
|
|
1890
|
+
displayName: clashesWithMcpTool ? `${SKILL_PREFIX}${skill.name}` : skill.name,
|
|
1803
1891
|
description: skill.description
|
|
1804
1892
|
};
|
|
1805
1893
|
});
|
|
1806
1894
|
return {
|
|
1807
1895
|
content: await this.liquid.parseAndRender(toolkit_description_default, {
|
|
1808
1896
|
servers,
|
|
1809
|
-
skills
|
|
1897
|
+
skills,
|
|
1898
|
+
serverId: this.serverId
|
|
1810
1899
|
}),
|
|
1811
1900
|
toolNames: allToolNames
|
|
1812
1901
|
};
|
|
@@ -1892,8 +1981,8 @@ var DescribeToolsTool = class DescribeToolsTool {
|
|
|
1892
1981
|
const foundSkills = [];
|
|
1893
1982
|
const notFoundItems = [];
|
|
1894
1983
|
for (const requestedName of toolNames) {
|
|
1895
|
-
if (requestedName.startsWith(SKILL_PREFIX
|
|
1896
|
-
const skillName = requestedName.slice(SKILL_PREFIX
|
|
1984
|
+
if (requestedName.startsWith(SKILL_PREFIX)) {
|
|
1985
|
+
const skillName = requestedName.slice(SKILL_PREFIX.length);
|
|
1897
1986
|
if (this.skillService) {
|
|
1898
1987
|
const skill = await this.skillService.getSkill(skillName);
|
|
1899
1988
|
if (skill) {
|
|
@@ -2017,10 +2106,6 @@ var DescribeToolsTool = class DescribeToolsTool {
|
|
|
2017
2106
|
//#endregion
|
|
2018
2107
|
//#region src/tools/UseToolTool.ts
|
|
2019
2108
|
/**
|
|
2020
|
-
* Prefix used to identify skill invocations (e.g., skill__pdf)
|
|
2021
|
-
*/
|
|
2022
|
-
const SKILL_PREFIX = "skill__";
|
|
2023
|
-
/**
|
|
2024
2109
|
* UseToolTool executes MCP tools and skills with proper error handling.
|
|
2025
2110
|
*
|
|
2026
2111
|
* This tool supports three invocation patterns:
|
|
@@ -2037,14 +2122,18 @@ var UseToolTool = class UseToolTool {
|
|
|
2037
2122
|
static TOOL_NAME = "use_tool";
|
|
2038
2123
|
clientManager;
|
|
2039
2124
|
skillService;
|
|
2125
|
+
/** Unique server identifier for this one-mcp instance */
|
|
2126
|
+
serverId;
|
|
2040
2127
|
/**
|
|
2041
2128
|
* Creates a new UseToolTool instance
|
|
2042
2129
|
* @param clientManager - The MCP client manager for accessing remote servers
|
|
2043
2130
|
* @param skillService - Optional skill service for loading and executing skills
|
|
2131
|
+
* @param serverId - Unique server identifier for this one-mcp instance
|
|
2044
2132
|
*/
|
|
2045
|
-
constructor(clientManager, skillService) {
|
|
2133
|
+
constructor(clientManager, skillService, serverId) {
|
|
2046
2134
|
this.clientManager = clientManager;
|
|
2047
2135
|
this.skillService = skillService;
|
|
2136
|
+
this.serverId = serverId || DEFAULT_SERVER_ID;
|
|
2048
2137
|
}
|
|
2049
2138
|
/**
|
|
2050
2139
|
* Returns the MCP tool definition with name, description, and input schema.
|
|
@@ -2060,6 +2149,8 @@ var UseToolTool = class UseToolTool {
|
|
|
2060
2149
|
description: `Execute an MCP tool (NOT Skill) with provided arguments. You MUST call describe_tools first to discover the tool's correct arguments. Then to use tool:
|
|
2061
2150
|
- Provide toolName and toolArgs based on the schema
|
|
2062
2151
|
- If multiple servers provide the same tool, specify serverName
|
|
2152
|
+
|
|
2153
|
+
IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverId}".
|
|
2063
2154
|
`,
|
|
2064
2155
|
inputSchema: {
|
|
2065
2156
|
type: "object",
|
|
@@ -2146,7 +2237,7 @@ var UseToolTool = class UseToolTool {
|
|
|
2146
2237
|
try {
|
|
2147
2238
|
const { toolName: inputToolName, toolArgs = {} } = input;
|
|
2148
2239
|
if (inputToolName.startsWith(SKILL_PREFIX)) {
|
|
2149
|
-
const skillName = inputToolName.slice(
|
|
2240
|
+
const skillName = inputToolName.slice(SKILL_PREFIX.length);
|
|
2150
2241
|
if (this.skillService) {
|
|
2151
2242
|
const skill = await this.skillService.getSkill(skillName);
|
|
2152
2243
|
if (skill) return this.executeSkill(skill);
|
|
@@ -2281,6 +2372,7 @@ async function createServer(options) {
|
|
|
2281
2372
|
} });
|
|
2282
2373
|
const clientManager = new McpClientManagerService();
|
|
2283
2374
|
let configSkills;
|
|
2375
|
+
let configId;
|
|
2284
2376
|
if (options?.configFilePath) {
|
|
2285
2377
|
let config;
|
|
2286
2378
|
try {
|
|
@@ -2292,6 +2384,7 @@ async function createServer(options) {
|
|
|
2292
2384
|
throw new Error(`Failed to load MCP configuration from '${options.configFilePath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
2293
2385
|
}
|
|
2294
2386
|
configSkills = config.skills;
|
|
2387
|
+
configId = config.id;
|
|
2295
2388
|
const failedConnections = [];
|
|
2296
2389
|
const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
|
|
2297
2390
|
try {
|
|
@@ -2310,13 +2403,15 @@ async function createServer(options) {
|
|
|
2310
2403
|
if (failedConnections.length > 0 && failedConnections.length < Object.keys(config.mcpServers).length) console.error(`Warning: Some MCP server connections failed: ${failedConnections.map((f) => f.serverName).join(", ")}`);
|
|
2311
2404
|
if (failedConnections.length > 0 && failedConnections.length === Object.keys(config.mcpServers).length) throw new Error(`All MCP server connections failed: ${failedConnections.map((f) => `${f.serverName}: ${f.error.message}`).join(", ")}`);
|
|
2312
2405
|
}
|
|
2406
|
+
const serverId = options?.serverId || configId || generateServerId();
|
|
2407
|
+
console.error(`[one-mcp] Server ID: ${serverId}`);
|
|
2313
2408
|
const skillsConfig = options?.skills || configSkills;
|
|
2314
2409
|
const toolsRef = { describeTools: null };
|
|
2315
2410
|
const skillService = skillsConfig && skillsConfig.paths.length > 0 ? new SkillService(process.cwd(), skillsConfig.paths, { onCacheInvalidated: () => {
|
|
2316
2411
|
toolsRef.describeTools?.clearAutoDetectedSkillsCache();
|
|
2317
2412
|
} }) : void 0;
|
|
2318
|
-
const describeTools = new DescribeToolsTool(clientManager, skillService);
|
|
2319
|
-
const useTool = new UseToolTool(clientManager, skillService);
|
|
2413
|
+
const describeTools = new DescribeToolsTool(clientManager, skillService, serverId);
|
|
2414
|
+
const useTool = new UseToolTool(clientManager, skillService, serverId);
|
|
2320
2415
|
toolsRef.describeTools = describeTools;
|
|
2321
2416
|
if (skillService) skillService.startWatching().catch((error) => {
|
|
2322
2417
|
console.error(`[skill-watcher] File watcher failed (non-critical): ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
@@ -4,7 +4,7 @@ import { access, mkdir, readFile, readdir, stat, unlink, watch, writeFile } from
|
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import yaml from "js-yaml";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
7
|
+
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
8
8
|
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
9
9
|
import { tmpdir } from "node:os";
|
|
10
10
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
@@ -202,6 +202,7 @@ const ClaudeCodeStdioServerSchema = z.object({
|
|
|
202
202
|
env: z.record(z.string(), z.string()).optional(),
|
|
203
203
|
disabled: z.boolean().optional(),
|
|
204
204
|
instruction: z.string().optional(),
|
|
205
|
+
timeout: z.number().positive().optional(),
|
|
205
206
|
config: AdditionalConfigSchema
|
|
206
207
|
});
|
|
207
208
|
const ClaudeCodeHttpServerSchema = z.object({
|
|
@@ -210,6 +211,7 @@ const ClaudeCodeHttpServerSchema = z.object({
|
|
|
210
211
|
type: z.enum(["http", "sse"]).optional(),
|
|
211
212
|
disabled: z.boolean().optional(),
|
|
212
213
|
instruction: z.string().optional(),
|
|
214
|
+
timeout: z.number().positive().optional(),
|
|
213
215
|
config: AdditionalConfigSchema
|
|
214
216
|
});
|
|
215
217
|
const ClaudeCodeServerConfigSchema = z.union([ClaudeCodeStdioServerSchema, ClaudeCodeHttpServerSchema]);
|
|
@@ -240,6 +242,7 @@ const SkillsConfigSchema = z.object({ paths: z.array(z.string()) });
|
|
|
240
242
|
* Full Claude Code MCP configuration schema
|
|
241
243
|
*/
|
|
242
244
|
const ClaudeCodeMcpConfigSchema = z.object({
|
|
245
|
+
id: z.string().optional(),
|
|
243
246
|
mcpServers: z.record(z.string(), ClaudeCodeServerConfigSchema),
|
|
244
247
|
remoteConfigs: z.array(RemoteConfigSourceSchema).optional(),
|
|
245
248
|
skills: SkillsConfigSchema.optional()
|
|
@@ -280,6 +283,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
|
|
|
280
283
|
toolBlacklist: z.array(z.string()).optional(),
|
|
281
284
|
omitToolDescription: z.boolean().optional(),
|
|
282
285
|
prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
|
|
286
|
+
timeout: z.number().positive().optional(),
|
|
283
287
|
transport: z.literal("stdio"),
|
|
284
288
|
config: McpStdioConfigSchema
|
|
285
289
|
}),
|
|
@@ -289,6 +293,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
|
|
|
289
293
|
toolBlacklist: z.array(z.string()).optional(),
|
|
290
294
|
omitToolDescription: z.boolean().optional(),
|
|
291
295
|
prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
|
|
296
|
+
timeout: z.number().positive().optional(),
|
|
292
297
|
transport: z.literal("http"),
|
|
293
298
|
config: McpHttpConfigSchema
|
|
294
299
|
}),
|
|
@@ -298,6 +303,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
|
|
|
298
303
|
toolBlacklist: z.array(z.string()).optional(),
|
|
299
304
|
omitToolDescription: z.boolean().optional(),
|
|
300
305
|
prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
|
|
306
|
+
timeout: z.number().positive().optional(),
|
|
301
307
|
transport: z.literal("sse"),
|
|
302
308
|
config: McpSseConfigSchema
|
|
303
309
|
})
|
|
@@ -306,6 +312,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
|
|
|
306
312
|
* Full internal MCP configuration schema
|
|
307
313
|
*/
|
|
308
314
|
const InternalMcpConfigSchema = z.object({
|
|
315
|
+
id: z.string().optional(),
|
|
309
316
|
mcpServers: z.record(z.string(), McpServerConfigSchema),
|
|
310
317
|
skills: SkillsConfigSchema.optional()
|
|
311
318
|
});
|
|
@@ -331,6 +338,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
331
338
|
toolBlacklist: stdioConfig.config?.toolBlacklist,
|
|
332
339
|
omitToolDescription: stdioConfig.config?.omitToolDescription,
|
|
333
340
|
prompts: stdioConfig.config?.prompts,
|
|
341
|
+
timeout: stdioConfig.timeout,
|
|
334
342
|
transport: "stdio",
|
|
335
343
|
config: {
|
|
336
344
|
command: interpolatedCommand,
|
|
@@ -349,6 +357,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
349
357
|
toolBlacklist: httpConfig.config?.toolBlacklist,
|
|
350
358
|
omitToolDescription: httpConfig.config?.omitToolDescription,
|
|
351
359
|
prompts: httpConfig.config?.prompts,
|
|
360
|
+
timeout: httpConfig.timeout,
|
|
352
361
|
transport,
|
|
353
362
|
config: {
|
|
354
363
|
url: interpolatedUrl,
|
|
@@ -358,6 +367,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
358
367
|
}
|
|
359
368
|
}
|
|
360
369
|
return {
|
|
370
|
+
id: claudeConfig.id,
|
|
361
371
|
mcpServers: transformedServers,
|
|
362
372
|
skills: claudeConfig.skills
|
|
363
373
|
};
|
|
@@ -807,6 +817,8 @@ var ConfigFetcherService = class {
|
|
|
807
817
|
|
|
808
818
|
//#endregion
|
|
809
819
|
//#region src/services/McpClientManagerService.ts
|
|
820
|
+
/** Default connection timeout in milliseconds (30 seconds) */
|
|
821
|
+
const DEFAULT_CONNECTION_TIMEOUT_MS = 3e4;
|
|
810
822
|
/**
|
|
811
823
|
* MCP Client wrapper for managing individual server connections
|
|
812
824
|
* This is an internal class used by McpClientManagerService
|
|
@@ -912,8 +924,10 @@ var McpClientManagerService = class {
|
|
|
912
924
|
}
|
|
913
925
|
/**
|
|
914
926
|
* Connect to an MCP server based on its configuration with timeout
|
|
927
|
+
* Uses the timeout from server config, falling back to default (30s)
|
|
915
928
|
*/
|
|
916
|
-
async connectToServer(serverName, config
|
|
929
|
+
async connectToServer(serverName, config) {
|
|
930
|
+
const timeoutMs = config.timeout ?? DEFAULT_CONNECTION_TIMEOUT_MS;
|
|
917
931
|
if (this.clients.has(serverName)) throw new Error(`Client for ${serverName} is already connected`);
|
|
918
932
|
const client = new Client({
|
|
919
933
|
name: `@agiflowai/one-mcp-client`,
|
|
@@ -1208,6 +1222,71 @@ function extractSkillFrontMatter(content) {
|
|
|
1208
1222
|
return null;
|
|
1209
1223
|
}
|
|
1210
1224
|
|
|
1225
|
+
//#endregion
|
|
1226
|
+
//#region src/utils/generateServerId.ts
|
|
1227
|
+
/**
|
|
1228
|
+
* generateServerId Utilities
|
|
1229
|
+
*
|
|
1230
|
+
* DESIGN PATTERNS:
|
|
1231
|
+
* - Pure functions with no side effects
|
|
1232
|
+
* - Single responsibility per function
|
|
1233
|
+
* - Functional programming approach
|
|
1234
|
+
*
|
|
1235
|
+
* CODING STANDARDS:
|
|
1236
|
+
* - Export individual functions, not classes
|
|
1237
|
+
* - Use descriptive function names with verbs
|
|
1238
|
+
* - Add JSDoc comments for complex logic
|
|
1239
|
+
* - Keep functions small and focused
|
|
1240
|
+
*
|
|
1241
|
+
* AVOID:
|
|
1242
|
+
* - Side effects (mutating external state)
|
|
1243
|
+
* - Stateful logic (use services for state)
|
|
1244
|
+
* - Complex external dependencies
|
|
1245
|
+
*/
|
|
1246
|
+
/**
|
|
1247
|
+
* Character set for generating human-readable IDs.
|
|
1248
|
+
* Excludes confusing characters: 0, O, 1, l, I
|
|
1249
|
+
*/
|
|
1250
|
+
const CHARSET = "23456789abcdefghjkmnpqrstuvwxyz";
|
|
1251
|
+
/**
|
|
1252
|
+
* Default length for generated server IDs (6 characters)
|
|
1253
|
+
*/
|
|
1254
|
+
const DEFAULT_ID_LENGTH = 6;
|
|
1255
|
+
/**
|
|
1256
|
+
* Generate a short, human-readable server ID.
|
|
1257
|
+
*
|
|
1258
|
+
* Uses Node.js crypto.randomBytes for cryptographically secure randomness
|
|
1259
|
+
* with rejection sampling to avoid modulo bias.
|
|
1260
|
+
*
|
|
1261
|
+
* The generated ID:
|
|
1262
|
+
* - Is 6 characters long by default
|
|
1263
|
+
* - Uses only lowercase alphanumeric characters
|
|
1264
|
+
* - Excludes confusing characters (0, O, 1, l, I)
|
|
1265
|
+
*
|
|
1266
|
+
* @param length - Length of the ID to generate (default: 6)
|
|
1267
|
+
* @returns A random, human-readable ID
|
|
1268
|
+
*
|
|
1269
|
+
* @example
|
|
1270
|
+
* generateServerId() // "abc234"
|
|
1271
|
+
* generateServerId(4) // "x7mn"
|
|
1272
|
+
*/
|
|
1273
|
+
function generateServerId(length = DEFAULT_ID_LENGTH) {
|
|
1274
|
+
const charsetLength = 31;
|
|
1275
|
+
const maxUnbiased = Math.floor(256 / charsetLength) * charsetLength - 1;
|
|
1276
|
+
let result = "";
|
|
1277
|
+
let remaining = length;
|
|
1278
|
+
while (remaining > 0) {
|
|
1279
|
+
const bytes = randomBytes(remaining);
|
|
1280
|
+
for (let i = 0; i < bytes.length && remaining > 0; i++) {
|
|
1281
|
+
const byte = bytes[i];
|
|
1282
|
+
if (byte > maxUnbiased) continue;
|
|
1283
|
+
result += CHARSET[byte % charsetLength];
|
|
1284
|
+
remaining--;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
return result;
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1211
1290
|
//#endregion
|
|
1212
1291
|
//#region src/services/SkillService.ts
|
|
1213
1292
|
/**
|
|
@@ -1485,7 +1564,7 @@ var SkillService = class {
|
|
|
1485
1564
|
* Prefix added to skill names when they clash with MCP tool names.
|
|
1486
1565
|
* This ensures skills can be uniquely identified even when a tool has the same name.
|
|
1487
1566
|
*/
|
|
1488
|
-
const SKILL_PREFIX
|
|
1567
|
+
const SKILL_PREFIX = "skill__";
|
|
1489
1568
|
/**
|
|
1490
1569
|
* Log prefix for skill detection messages.
|
|
1491
1570
|
* Used to easily filter skill detection logs in stderr output.
|
|
@@ -1496,10 +1575,15 @@ const LOG_PREFIX_SKILL_DETECTION = "[skill-detection]";
|
|
|
1496
1575
|
* Format: "prompt:{serverName}:{promptName}"
|
|
1497
1576
|
*/
|
|
1498
1577
|
const PROMPT_LOCATION_PREFIX = "prompt:";
|
|
1578
|
+
/**
|
|
1579
|
+
* Default server ID used when no ID is provided via CLI or config.
|
|
1580
|
+
* This fallback is used when auto-generation also fails.
|
|
1581
|
+
*/
|
|
1582
|
+
const DEFAULT_SERVER_ID = "unknown";
|
|
1499
1583
|
|
|
1500
1584
|
//#endregion
|
|
1501
1585
|
//#region src/templates/toolkit-description.liquid?raw
|
|
1502
|
-
var toolkit_description_default = "<toolkit>\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";
|
|
1586
|
+
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";
|
|
1503
1587
|
|
|
1504
1588
|
//#endregion
|
|
1505
1589
|
//#region src/tools/DescribeToolsTool.ts
|
|
@@ -1538,14 +1622,18 @@ var DescribeToolsTool = class DescribeToolsTool {
|
|
|
1538
1622
|
liquid = new Liquid();
|
|
1539
1623
|
/** Cache for auto-detected skills from prompt front-matter */
|
|
1540
1624
|
autoDetectedSkillsCache = null;
|
|
1625
|
+
/** Unique server identifier for this one-mcp instance */
|
|
1626
|
+
serverId;
|
|
1541
1627
|
/**
|
|
1542
1628
|
* Creates a new DescribeToolsTool instance
|
|
1543
1629
|
* @param clientManager - The MCP client manager for accessing remote servers
|
|
1544
1630
|
* @param skillService - Optional skill service for loading skills
|
|
1631
|
+
* @param serverId - Unique server identifier for this one-mcp instance
|
|
1545
1632
|
*/
|
|
1546
|
-
constructor(clientManager, skillService) {
|
|
1633
|
+
constructor(clientManager, skillService, serverId) {
|
|
1547
1634
|
this.clientManager = clientManager;
|
|
1548
1635
|
this.skillService = skillService;
|
|
1636
|
+
this.serverId = serverId || DEFAULT_SERVER_ID;
|
|
1549
1637
|
}
|
|
1550
1638
|
/**
|
|
1551
1639
|
* Clears the cached auto-detected skills from prompt front-matter.
|
|
@@ -1770,14 +1858,15 @@ var DescribeToolsTool = class DescribeToolsTool {
|
|
|
1770
1858
|
const clashesWithMcpTool = allToolNames.has(skill.name);
|
|
1771
1859
|
return {
|
|
1772
1860
|
name: skill.name,
|
|
1773
|
-
displayName: clashesWithMcpTool ? `${SKILL_PREFIX
|
|
1861
|
+
displayName: clashesWithMcpTool ? `${SKILL_PREFIX}${skill.name}` : skill.name,
|
|
1774
1862
|
description: skill.description
|
|
1775
1863
|
};
|
|
1776
1864
|
});
|
|
1777
1865
|
return {
|
|
1778
1866
|
content: await this.liquid.parseAndRender(toolkit_description_default, {
|
|
1779
1867
|
servers,
|
|
1780
|
-
skills
|
|
1868
|
+
skills,
|
|
1869
|
+
serverId: this.serverId
|
|
1781
1870
|
}),
|
|
1782
1871
|
toolNames: allToolNames
|
|
1783
1872
|
};
|
|
@@ -1863,8 +1952,8 @@ var DescribeToolsTool = class DescribeToolsTool {
|
|
|
1863
1952
|
const foundSkills = [];
|
|
1864
1953
|
const notFoundItems = [];
|
|
1865
1954
|
for (const requestedName of toolNames) {
|
|
1866
|
-
if (requestedName.startsWith(SKILL_PREFIX
|
|
1867
|
-
const skillName = requestedName.slice(SKILL_PREFIX
|
|
1955
|
+
if (requestedName.startsWith(SKILL_PREFIX)) {
|
|
1956
|
+
const skillName = requestedName.slice(SKILL_PREFIX.length);
|
|
1868
1957
|
if (this.skillService) {
|
|
1869
1958
|
const skill = await this.skillService.getSkill(skillName);
|
|
1870
1959
|
if (skill) {
|
|
@@ -1988,10 +2077,6 @@ var DescribeToolsTool = class DescribeToolsTool {
|
|
|
1988
2077
|
//#endregion
|
|
1989
2078
|
//#region src/tools/UseToolTool.ts
|
|
1990
2079
|
/**
|
|
1991
|
-
* Prefix used to identify skill invocations (e.g., skill__pdf)
|
|
1992
|
-
*/
|
|
1993
|
-
const SKILL_PREFIX = "skill__";
|
|
1994
|
-
/**
|
|
1995
2080
|
* UseToolTool executes MCP tools and skills with proper error handling.
|
|
1996
2081
|
*
|
|
1997
2082
|
* This tool supports three invocation patterns:
|
|
@@ -2008,14 +2093,18 @@ var UseToolTool = class UseToolTool {
|
|
|
2008
2093
|
static TOOL_NAME = "use_tool";
|
|
2009
2094
|
clientManager;
|
|
2010
2095
|
skillService;
|
|
2096
|
+
/** Unique server identifier for this one-mcp instance */
|
|
2097
|
+
serverId;
|
|
2011
2098
|
/**
|
|
2012
2099
|
* Creates a new UseToolTool instance
|
|
2013
2100
|
* @param clientManager - The MCP client manager for accessing remote servers
|
|
2014
2101
|
* @param skillService - Optional skill service for loading and executing skills
|
|
2102
|
+
* @param serverId - Unique server identifier for this one-mcp instance
|
|
2015
2103
|
*/
|
|
2016
|
-
constructor(clientManager, skillService) {
|
|
2104
|
+
constructor(clientManager, skillService, serverId) {
|
|
2017
2105
|
this.clientManager = clientManager;
|
|
2018
2106
|
this.skillService = skillService;
|
|
2107
|
+
this.serverId = serverId || DEFAULT_SERVER_ID;
|
|
2019
2108
|
}
|
|
2020
2109
|
/**
|
|
2021
2110
|
* Returns the MCP tool definition with name, description, and input schema.
|
|
@@ -2031,6 +2120,8 @@ var UseToolTool = class UseToolTool {
|
|
|
2031
2120
|
description: `Execute an MCP tool (NOT Skill) with provided arguments. You MUST call describe_tools first to discover the tool's correct arguments. Then to use tool:
|
|
2032
2121
|
- Provide toolName and toolArgs based on the schema
|
|
2033
2122
|
- If multiple servers provide the same tool, specify serverName
|
|
2123
|
+
|
|
2124
|
+
IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverId}".
|
|
2034
2125
|
`,
|
|
2035
2126
|
inputSchema: {
|
|
2036
2127
|
type: "object",
|
|
@@ -2117,7 +2208,7 @@ var UseToolTool = class UseToolTool {
|
|
|
2117
2208
|
try {
|
|
2118
2209
|
const { toolName: inputToolName, toolArgs = {} } = input;
|
|
2119
2210
|
if (inputToolName.startsWith(SKILL_PREFIX)) {
|
|
2120
|
-
const skillName = inputToolName.slice(
|
|
2211
|
+
const skillName = inputToolName.slice(SKILL_PREFIX.length);
|
|
2121
2212
|
if (this.skillService) {
|
|
2122
2213
|
const skill = await this.skillService.getSkill(skillName);
|
|
2123
2214
|
if (skill) return this.executeSkill(skill);
|
|
@@ -2252,6 +2343,7 @@ async function createServer(options) {
|
|
|
2252
2343
|
} });
|
|
2253
2344
|
const clientManager = new McpClientManagerService();
|
|
2254
2345
|
let configSkills;
|
|
2346
|
+
let configId;
|
|
2255
2347
|
if (options?.configFilePath) {
|
|
2256
2348
|
let config;
|
|
2257
2349
|
try {
|
|
@@ -2263,6 +2355,7 @@ async function createServer(options) {
|
|
|
2263
2355
|
throw new Error(`Failed to load MCP configuration from '${options.configFilePath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
2264
2356
|
}
|
|
2265
2357
|
configSkills = config.skills;
|
|
2358
|
+
configId = config.id;
|
|
2266
2359
|
const failedConnections = [];
|
|
2267
2360
|
const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
|
|
2268
2361
|
try {
|
|
@@ -2281,13 +2374,15 @@ async function createServer(options) {
|
|
|
2281
2374
|
if (failedConnections.length > 0 && failedConnections.length < Object.keys(config.mcpServers).length) console.error(`Warning: Some MCP server connections failed: ${failedConnections.map((f) => f.serverName).join(", ")}`);
|
|
2282
2375
|
if (failedConnections.length > 0 && failedConnections.length === Object.keys(config.mcpServers).length) throw new Error(`All MCP server connections failed: ${failedConnections.map((f) => `${f.serverName}: ${f.error.message}`).join(", ")}`);
|
|
2283
2376
|
}
|
|
2377
|
+
const serverId = options?.serverId || configId || generateServerId();
|
|
2378
|
+
console.error(`[one-mcp] Server ID: ${serverId}`);
|
|
2284
2379
|
const skillsConfig = options?.skills || configSkills;
|
|
2285
2380
|
const toolsRef = { describeTools: null };
|
|
2286
2381
|
const skillService = skillsConfig && skillsConfig.paths.length > 0 ? new SkillService(process.cwd(), skillsConfig.paths, { onCacheInvalidated: () => {
|
|
2287
2382
|
toolsRef.describeTools?.clearAutoDetectedSkillsCache();
|
|
2288
2383
|
} }) : void 0;
|
|
2289
|
-
const describeTools = new DescribeToolsTool(clientManager, skillService);
|
|
2290
|
-
const useTool = new UseToolTool(clientManager, skillService);
|
|
2384
|
+
const describeTools = new DescribeToolsTool(clientManager, skillService, serverId);
|
|
2385
|
+
const useTool = new UseToolTool(clientManager, skillService, serverId);
|
|
2291
2386
|
toolsRef.describeTools = describeTools;
|
|
2292
2387
|
if (skillService) skillService.startWatching().catch((error) => {
|
|
2293
2388
|
console.error(`[skill-watcher] File watcher failed (non-critical): ${error instanceof Error ? error.message : "Unknown error"}`);
|
package/dist/index.cjs
CHANGED