@agiflowai/one-mcp 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_http = require('./http-23nhycE8.cjs');
2
+ const require_http = require('./http-3v8zyDO3.cjs');
3
3
  let node_fs_promises = require("node:fs/promises");
4
4
  let node_path = require("node:path");
5
5
  let commander = require("commander");
@@ -63,7 +63,7 @@ const mcpServeCommand = new commander.Command("mcp-serve").description("Start MC
63
63
  try {
64
64
  const transportType = options.type.toLowerCase();
65
65
  const serverOptions = {
66
- configFilePath: options.config,
66
+ configFilePath: options.config || require_http.findConfigFile(),
67
67
  noCache: options.cache === false
68
68
  };
69
69
  if (transportType === "stdio") await startServer(new require_http.StdioTransportHandler(await require_http.createServer(serverOptions)));
@@ -115,11 +115,12 @@ const mcpServeCommand = new commander.Command("mcp-serve").description("Start MC
115
115
  */
116
116
  const listToolsCommand = new commander.Command("list-tools").description("List all available tools from connected MCP servers").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Filter by server name").option("-j, --json", "Output as JSON", false).action(async (options) => {
117
117
  try {
118
- if (!options.config) {
119
- console.error("Error: --config is required");
118
+ const configFilePath = options.config || require_http.findConfigFile();
119
+ if (!configFilePath) {
120
+ console.error("Error: No config file found. Use --config or create mcp-config.yaml");
120
121
  process.exit(1);
121
122
  }
122
- const config = await new require_http.ConfigFetcherService({ configFilePath: options.config }).fetchConfiguration();
123
+ const config = await new require_http.ConfigFetcherService({ configFilePath }).fetchConfiguration();
123
124
  const clientManager = new require_http.McpClientManagerService();
124
125
  const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
125
126
  try {
@@ -190,11 +191,12 @@ const listToolsCommand = new commander.Command("list-tools").description("List a
190
191
  */
191
192
  const describeToolsCommand = new commander.Command("describe-tools").description("Describe specific MCP tools").argument("<toolNames...>", "Tool names to describe").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Filter by server name").option("-j, --json", "Output as JSON", false).action(async (toolNames, options) => {
192
193
  try {
193
- if (!options.config) {
194
- console.error("Error: --config is required");
194
+ const configFilePath = options.config || require_http.findConfigFile();
195
+ if (!configFilePath) {
196
+ console.error("Error: No config file found. Use --config or create mcp-config.yaml");
195
197
  process.exit(1);
196
198
  }
197
- const config = await new require_http.ConfigFetcherService({ configFilePath: options.config }).fetchConfiguration();
199
+ const config = await new require_http.ConfigFetcherService({ configFilePath }).fetchConfiguration();
198
200
  const clientManager = new require_http.McpClientManagerService();
199
201
  const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
200
202
  try {
@@ -290,8 +292,9 @@ const describeToolsCommand = new commander.Command("describe-tools").description
290
292
  */
291
293
  const useToolCommand = new commander.Command("use-tool").description("Execute an MCP tool with arguments").argument("<toolName>", "Tool name to execute").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Server name (required if tool exists on multiple servers)").option("-a, --args <json>", "Tool arguments as JSON string", "{}").option("-j, --json", "Output as JSON", false).action(async (toolName, options) => {
292
294
  try {
293
- if (!options.config) {
294
- console.error("Error: --config is required");
295
+ const configFilePath = options.config || require_http.findConfigFile();
296
+ if (!configFilePath) {
297
+ console.error("Error: No config file found. Use --config or create mcp-config.yaml");
295
298
  process.exit(1);
296
299
  }
297
300
  let toolArgs = {};
@@ -301,7 +304,7 @@ const useToolCommand = new commander.Command("use-tool").description("Execute an
301
304
  console.error("Error: Invalid JSON in --args");
302
305
  process.exit(1);
303
306
  }
304
- const config = await new require_http.ConfigFetcherService({ configFilePath: options.config }).fetchConfiguration();
307
+ const config = await new require_http.ConfigFetcherService({ configFilePath }).fetchConfiguration();
305
308
  const clientManager = new require_http.McpClientManagerService();
306
309
  const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
307
310
  try {
@@ -457,7 +460,7 @@ const initCommand = new commander.Command("init").description("Initialize MCP co
457
460
 
458
461
  //#endregion
459
462
  //#region package.json
460
- var version = "0.2.0";
463
+ var version = "0.2.2";
461
464
 
462
465
  //#endregion
463
466
  //#region src/cli.ts
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as McpClientManagerService, i as createServer, n as SseTransportHandler, o as ConfigFetcherService, r as StdioTransportHandler, t as HttpTransportHandler } from "./http-CkWO35l-.mjs";
2
+ import { a as findConfigFile, i as createServer, n as SseTransportHandler, o as McpClientManagerService, r as StdioTransportHandler, s as ConfigFetcherService, t as HttpTransportHandler } from "./http-CzQfsUEI.mjs";
3
3
  import { writeFile } from "node:fs/promises";
4
4
  import { resolve } from "node:path";
5
5
  import { Command } from "commander";
@@ -63,7 +63,7 @@ const mcpServeCommand = new Command("mcp-serve").description("Start MCP server w
63
63
  try {
64
64
  const transportType = options.type.toLowerCase();
65
65
  const serverOptions = {
66
- configFilePath: options.config,
66
+ configFilePath: options.config || findConfigFile(),
67
67
  noCache: options.cache === false
68
68
  };
69
69
  if (transportType === "stdio") await startServer(new StdioTransportHandler(await createServer(serverOptions)));
@@ -115,11 +115,12 @@ const mcpServeCommand = new Command("mcp-serve").description("Start MCP server w
115
115
  */
116
116
  const listToolsCommand = new Command("list-tools").description("List all available tools from connected MCP servers").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Filter by server name").option("-j, --json", "Output as JSON", false).action(async (options) => {
117
117
  try {
118
- if (!options.config) {
119
- console.error("Error: --config is required");
118
+ const configFilePath = options.config || findConfigFile();
119
+ if (!configFilePath) {
120
+ console.error("Error: No config file found. Use --config or create mcp-config.yaml");
120
121
  process.exit(1);
121
122
  }
122
- const config = await new ConfigFetcherService({ configFilePath: options.config }).fetchConfiguration();
123
+ const config = await new ConfigFetcherService({ configFilePath }).fetchConfiguration();
123
124
  const clientManager = new McpClientManagerService();
124
125
  const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
125
126
  try {
@@ -190,11 +191,12 @@ const listToolsCommand = new Command("list-tools").description("List all availab
190
191
  */
191
192
  const describeToolsCommand = new Command("describe-tools").description("Describe specific MCP tools").argument("<toolNames...>", "Tool names to describe").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Filter by server name").option("-j, --json", "Output as JSON", false).action(async (toolNames, options) => {
192
193
  try {
193
- if (!options.config) {
194
- console.error("Error: --config is required");
194
+ const configFilePath = options.config || findConfigFile();
195
+ if (!configFilePath) {
196
+ console.error("Error: No config file found. Use --config or create mcp-config.yaml");
195
197
  process.exit(1);
196
198
  }
197
- const config = await new ConfigFetcherService({ configFilePath: options.config }).fetchConfiguration();
199
+ const config = await new ConfigFetcherService({ configFilePath }).fetchConfiguration();
198
200
  const clientManager = new McpClientManagerService();
199
201
  const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
200
202
  try {
@@ -290,8 +292,9 @@ const describeToolsCommand = new Command("describe-tools").description("Describe
290
292
  */
291
293
  const useToolCommand = new Command("use-tool").description("Execute an MCP tool with arguments").argument("<toolName>", "Tool name to execute").option("-c, --config <path>", "Path to MCP server configuration file").option("-s, --server <name>", "Server name (required if tool exists on multiple servers)").option("-a, --args <json>", "Tool arguments as JSON string", "{}").option("-j, --json", "Output as JSON", false).action(async (toolName, options) => {
292
294
  try {
293
- if (!options.config) {
294
- console.error("Error: --config is required");
295
+ const configFilePath = options.config || findConfigFile();
296
+ if (!configFilePath) {
297
+ console.error("Error: No config file found. Use --config or create mcp-config.yaml");
295
298
  process.exit(1);
296
299
  }
297
300
  let toolArgs = {};
@@ -301,7 +304,7 @@ const useToolCommand = new Command("use-tool").description("Execute an MCP tool
301
304
  console.error("Error: Invalid JSON in --args");
302
305
  process.exit(1);
303
306
  }
304
- const config = await new ConfigFetcherService({ configFilePath: options.config }).fetchConfiguration();
307
+ const config = await new ConfigFetcherService({ configFilePath }).fetchConfiguration();
305
308
  const clientManager = new McpClientManagerService();
306
309
  const connectionPromises = Object.entries(config.mcpServers).map(async ([serverName, serverConfig]) => {
307
310
  try {
@@ -457,7 +460,7 @@ const initCommand = new Command("init").description("Initialize MCP configuratio
457
460
 
458
461
  //#endregion
459
462
  //#region package.json
460
- var version = "0.2.0";
463
+ var version = "0.2.2";
461
464
 
462
465
  //#endregion
463
466
  //#region src/cli.ts
@@ -976,6 +976,75 @@ var McpClientManagerService = class {
976
976
  }
977
977
  };
978
978
 
979
+ //#endregion
980
+ //#region src/utils/findConfigFile.ts
981
+ /**
982
+ * Config File Finder Utility
983
+ *
984
+ * DESIGN PATTERNS:
985
+ * - Utility function pattern for reusable logic
986
+ * - Fail-fast pattern with early returns
987
+ * - Environment variable configuration pattern
988
+ *
989
+ * CODING STANDARDS:
990
+ * - Use sync filesystem operations for config discovery (performance)
991
+ * - Check PROJECT_PATH environment variable first
992
+ * - Fall back to current working directory
993
+ * - Support both .yaml and .json extensions
994
+ * - Return null if no config file is found
995
+ *
996
+ * AVOID:
997
+ * - Throwing errors (return null instead for optional config)
998
+ * - Hardcoded file names without extension variants
999
+ * - Ignoring environment variables
1000
+ */
1001
+ /**
1002
+ * Find MCP configuration file by checking PROJECT_PATH first, then cwd
1003
+ * Looks for both mcp-config.yaml and mcp-config.json
1004
+ *
1005
+ * @returns Absolute path to config file, or null if not found
1006
+ */
1007
+ function findConfigFile() {
1008
+ const configFileNames = [
1009
+ "mcp-config.yaml",
1010
+ "mcp-config.yml",
1011
+ "mcp-config.json"
1012
+ ];
1013
+ const projectPath = process.env.PROJECT_PATH;
1014
+ if (projectPath) for (const fileName of configFileNames) {
1015
+ const configPath = (0, node_path.resolve)(projectPath, fileName);
1016
+ if ((0, node_fs.existsSync)(configPath)) return configPath;
1017
+ }
1018
+ const cwd = process.cwd();
1019
+ for (const fileName of configFileNames) {
1020
+ const configPath = (0, node_path.join)(cwd, fileName);
1021
+ if ((0, node_fs.existsSync)(configPath)) return configPath;
1022
+ }
1023
+ return null;
1024
+ }
1025
+
1026
+ //#endregion
1027
+ //#region src/utils/parseToolName.ts
1028
+ /**
1029
+ * Parse tool name to extract server and actual tool name
1030
+ * Supports both plain tool names and prefixed format: {serverName}__{toolName}
1031
+ *
1032
+ * @param toolName - The tool name to parse (e.g., "my_tool" or "server__my_tool")
1033
+ * @returns Parsed result with optional serverName and actualToolName
1034
+ *
1035
+ * @example
1036
+ * parseToolName("my_tool") // { actualToolName: "my_tool" }
1037
+ * parseToolName("server__my_tool") // { serverName: "server", actualToolName: "my_tool" }
1038
+ */
1039
+ function parseToolName(toolName) {
1040
+ const separatorIndex = toolName.indexOf("__");
1041
+ if (separatorIndex > 0) return {
1042
+ serverName: toolName.substring(0, separatorIndex),
1043
+ actualToolName: toolName.substring(separatorIndex + 2)
1044
+ };
1045
+ return { actualToolName: toolName };
1046
+ }
1047
+
979
1048
  //#endregion
980
1049
  //#region src/tools/DescribeToolsTool.ts
981
1050
  var DescribeToolsTool = class DescribeToolsTool {
@@ -986,46 +1055,50 @@ var DescribeToolsTool = class DescribeToolsTool {
986
1055
  }
987
1056
  async getDefinition() {
988
1057
  const clients = this.clientManager.getAllClients();
989
- const serverDescriptions = await Promise.all(clients.map(async (client) => {
1058
+ const toolToServers = /* @__PURE__ */ new Map();
1059
+ const serverToolsMap = /* @__PURE__ */ new Map();
1060
+ await Promise.all(clients.map(async (client) => {
990
1061
  try {
991
1062
  const tools = await client.listTools();
992
1063
  const blacklist = new Set(client.toolBlacklist || []);
993
1064
  const filteredTools = tools.filter((t) => !blacklist.has(t.name));
994
- const toolList = client.omitToolDescription ? filteredTools.map((t) => t.name).join(", ") : filteredTools.map((t) => `${t.name}: ${t.description || "No description"}`).join("\n");
995
- const instructionLine = client.serverInstruction ? `\n- Description: ${client.serverInstruction}` : "";
996
- return `\n\n### Server: ${client.serverName}${instructionLine}\n- Available tools:${toolList ? "\n" + toolList : ""}`;
1065
+ serverToolsMap.set(client.serverName, filteredTools);
1066
+ for (const tool of filteredTools) {
1067
+ if (!toolToServers.has(tool.name)) toolToServers.set(tool.name, []);
1068
+ toolToServers.get(tool.name).push(client.serverName);
1069
+ }
997
1070
  } catch (error) {
998
1071
  console.error(`Failed to list tools from ${client.serverName}:`, error);
999
- const instructionLine = client.serverInstruction ? `\n- Description: ${client.serverInstruction}` : "";
1000
- return `\n\n**Server: ${client.serverName}**${instructionLine}\n`;
1072
+ serverToolsMap.set(client.serverName, []);
1001
1073
  }
1002
1074
  }));
1075
+ const serverDescriptions = clients.map((client) => {
1076
+ const tools = serverToolsMap.get(client.serverName) || [];
1077
+ const formatToolName = (toolName) => {
1078
+ return (toolToServers.get(toolName) || []).length > 1 ? `${client.serverName}__${toolName}` : toolName;
1079
+ };
1080
+ const toolList = client.omitToolDescription ? tools.map((t) => formatToolName(t.name)).join(", ") : tools.map((t) => `${formatToolName(t.name)}: """${t.description || "No description"}"""`).join("\n");
1081
+ const instructionLine = client.serverInstruction ? `\n"""${client.serverInstruction}"""` : "";
1082
+ return `\n\n### Server: ${client.serverName}${instructionLine}\n\n- Available tools:\n${toolList || "No tools available"}`;
1083
+ });
1003
1084
  return {
1004
1085
  name: DescribeToolsTool.TOOL_NAME,
1005
- description: `Learn how to use multiple MCP tools before using them. Below are supported tools and capabilities.
1006
-
1007
- ## Available MCP Servers:${serverDescriptions.join("")}
1086
+ description: `## Available MCP Servers:${serverDescriptions.join("")}
1008
1087
 
1009
1088
  ## Usage:
1010
- You MUST call this tool with a list of tool names to learn how to use them properly before use_tool; this includes:
1089
+ Before you use any tools above, you MUST call this tool with a list of tool names to learn how to use them properly before use_tool; this includes:
1011
1090
  - Arguments schema needed to pass to the tool use
1012
1091
  - Description about each tool
1013
1092
 
1014
1093
  This tool is optimized for batch queries - you can request multiple tools at once for better performance.`,
1015
1094
  inputSchema: {
1016
1095
  type: "object",
1017
- properties: {
1018
- toolNames: {
1019
- type: "array",
1020
- items: { type: "string" },
1021
- description: "List of tool names to get detailed information about",
1022
- minItems: 1
1023
- },
1024
- serverName: {
1025
- type: "string",
1026
- description: "Optional server name to search within. If not specified, searches all servers."
1027
- }
1028
- },
1096
+ properties: { toolNames: {
1097
+ type: "array",
1098
+ items: { type: "string" },
1099
+ description: "List of tool names to get detailed information about",
1100
+ minItems: 1
1101
+ } },
1029
1102
  required: ["toolNames"],
1030
1103
  additionalProperties: false
1031
1104
  }
@@ -1033,7 +1106,7 @@ This tool is optimized for batch queries - you can request multiple tools at onc
1033
1106
  }
1034
1107
  async execute(input) {
1035
1108
  try {
1036
- const { toolNames, serverName } = input;
1109
+ const { toolNames } = input;
1037
1110
  const clients = this.clientManager.getAllClients();
1038
1111
  if (!toolNames || toolNames.length === 0) return {
1039
1112
  content: [{
@@ -1042,127 +1115,85 @@ This tool is optimized for batch queries - you can request multiple tools at onc
1042
1115
  }],
1043
1116
  isError: true
1044
1117
  };
1045
- if (serverName) {
1046
- const client = this.clientManager.getClient(serverName);
1047
- if (!client) return {
1048
- content: [{
1049
- type: "text",
1050
- text: `Server "${serverName}" not found. Available servers: ${clients.map((c) => c.serverName).join(", ")}`
1051
- }],
1052
- isError: true
1053
- };
1054
- const tools = await client.listTools();
1055
- const blacklist = new Set(client.toolBlacklist || []);
1056
- const filteredTools = tools.filter((t) => !blacklist.has(t.name));
1057
- const foundTools$1 = [];
1058
- const notFoundTools$1 = [];
1059
- for (const toolName of toolNames) {
1060
- if (blacklist.has(toolName)) {
1061
- notFoundTools$1.push(toolName);
1062
- continue;
1063
- }
1064
- const tool = filteredTools.find((t) => t.name === toolName);
1065
- if (tool) foundTools$1.push({
1066
- server: serverName,
1067
- tool: {
1068
- name: tool.name,
1069
- description: tool.description,
1070
- inputSchema: tool.inputSchema
1071
- }
1072
- });
1073
- else notFoundTools$1.push(toolName);
1074
- }
1075
- if (foundTools$1.length === 0) return {
1076
- content: [{
1077
- type: "text",
1078
- text: `None of the requested tools found on server "${serverName}".\nRequested: ${toolNames.join(", ")}\nAvailable tools: ${tools.map((t) => t.name).join(", ")}`
1079
- }],
1080
- isError: true
1081
- };
1082
- const result$1 = { tools: foundTools$1 };
1083
- if (notFoundTools$1.length > 0) {
1084
- result$1.notFound = notFoundTools$1;
1085
- result$1.warning = `Some tools were not found on server "${serverName}": ${notFoundTools$1.join(", ")}`;
1086
- }
1087
- return { content: [{
1088
- type: "text",
1089
- text: JSON.stringify(result$1, null, 2)
1090
- }] };
1091
- }
1092
- const foundTools = [];
1093
- const notFoundTools = [...toolNames];
1094
- const toolMatches = /* @__PURE__ */ new Map();
1095
- const results = await Promise.all(clients.map(async (client) => {
1118
+ const serverToolsMap = /* @__PURE__ */ new Map();
1119
+ const toolToServers = /* @__PURE__ */ new Map();
1120
+ await Promise.all(clients.map(async (client) => {
1096
1121
  try {
1097
1122
  const tools = await client.listTools();
1098
1123
  const blacklist = new Set(client.toolBlacklist || []);
1099
1124
  const filteredTools = tools.filter((t) => !blacklist.has(t.name));
1100
- const matches = [];
1101
- for (const toolName of toolNames) {
1102
- if (blacklist.has(toolName)) continue;
1103
- const tool = filteredTools.find((t) => t.name === toolName);
1104
- if (tool) matches.push({
1105
- toolName,
1106
- server: client.serverName,
1107
- tool
1108
- });
1125
+ serverToolsMap.set(client.serverName, filteredTools);
1126
+ for (const tool of filteredTools) {
1127
+ if (!toolToServers.has(tool.name)) toolToServers.set(tool.name, []);
1128
+ toolToServers.get(tool.name).push(client.serverName);
1109
1129
  }
1110
- return matches;
1111
1130
  } catch (error) {
1112
1131
  console.error(`Failed to list tools from ${client.serverName}:`, error);
1113
- return [];
1132
+ serverToolsMap.set(client.serverName, []);
1114
1133
  }
1115
1134
  }));
1116
- for (const matches of results) for (const match of matches) {
1117
- if (!toolMatches.has(match.toolName)) toolMatches.set(match.toolName, []);
1118
- toolMatches.get(match.toolName).push({
1119
- server: match.server,
1120
- tool: match.tool
1121
- });
1122
- }
1123
- const ambiguousTools = [];
1124
- for (const toolName of toolNames) {
1125
- const matches = toolMatches.get(toolName);
1126
- if (!matches || matches.length === 0) continue;
1127
- if (matches.length === 1) {
1128
- const match = matches[0];
1129
- foundTools.push({
1130
- server: match.server,
1135
+ const foundTools = [];
1136
+ const notFoundTools = [];
1137
+ for (const requestedToolName of toolNames) {
1138
+ const { serverName, actualToolName } = parseToolName(requestedToolName);
1139
+ if (serverName) {
1140
+ const serverTools = serverToolsMap.get(serverName);
1141
+ if (!serverTools) {
1142
+ notFoundTools.push(requestedToolName);
1143
+ continue;
1144
+ }
1145
+ const tool = serverTools.find((t) => t.name === actualToolName);
1146
+ if (tool) foundTools.push({
1147
+ server: serverName,
1131
1148
  tool: {
1132
- name: match.tool.name,
1133
- description: match.tool.description,
1134
- inputSchema: match.tool.inputSchema
1149
+ name: tool.name,
1150
+ description: tool.description,
1151
+ inputSchema: tool.inputSchema
1135
1152
  }
1136
1153
  });
1137
- const idx = notFoundTools.indexOf(toolName);
1138
- if (idx > -1) notFoundTools.splice(idx, 1);
1154
+ else notFoundTools.push(requestedToolName);
1139
1155
  } else {
1140
- ambiguousTools.push({
1141
- toolName,
1142
- servers: matches.map((m) => m.server)
1143
- });
1144
- const idx = notFoundTools.indexOf(toolName);
1145
- if (idx > -1) notFoundTools.splice(idx, 1);
1156
+ const servers = toolToServers.get(actualToolName);
1157
+ if (!servers || servers.length === 0) {
1158
+ notFoundTools.push(requestedToolName);
1159
+ continue;
1160
+ }
1161
+ if (servers.length === 1) {
1162
+ const server = servers[0];
1163
+ const tool = serverToolsMap.get(server).find((t) => t.name === actualToolName);
1164
+ foundTools.push({
1165
+ server,
1166
+ tool: {
1167
+ name: tool.name,
1168
+ description: tool.description,
1169
+ inputSchema: tool.inputSchema
1170
+ }
1171
+ });
1172
+ } else for (const server of servers) {
1173
+ const tool = serverToolsMap.get(server).find((t) => t.name === actualToolName);
1174
+ foundTools.push({
1175
+ server,
1176
+ tool: {
1177
+ name: tool.name,
1178
+ description: tool.description,
1179
+ inputSchema: tool.inputSchema
1180
+ }
1181
+ });
1182
+ }
1146
1183
  }
1147
1184
  }
1148
- if (foundTools.length === 0 && ambiguousTools.length === 0) return {
1185
+ if (foundTools.length === 0) return {
1149
1186
  content: [{
1150
1187
  type: "text",
1151
- text: `None of the requested tools found on any connected server.\nRequested: ${toolNames.join(", ")}\nUse describe_tools without arguments to see available servers.`
1188
+ text: `None of the requested tools found on any connected server.\nRequested: ${toolNames.join(", ")}\nUse describe_tools to see available tools.`
1152
1189
  }],
1153
1190
  isError: true
1154
1191
  };
1155
1192
  const result = { tools: foundTools };
1156
- if (notFoundTools.length > 0) result.notFound = notFoundTools;
1157
- if (ambiguousTools.length > 0) result.ambiguous = ambiguousTools.map((item) => ({
1158
- toolName: item.toolName,
1159
- servers: item.servers,
1160
- message: `Tool "${item.toolName}" found on multiple servers: ${item.servers.join(", ")}. Please specify serverName to disambiguate.`
1161
- }));
1162
- const warnings = [];
1163
- if (notFoundTools.length > 0) warnings.push(`Tools not found: ${notFoundTools.join(", ")}`);
1164
- if (ambiguousTools.length > 0) warnings.push(`Ambiguous tools (specify serverName): ${ambiguousTools.map((t) => t.toolName).join(", ")}`);
1165
- if (warnings.length > 0) result.warnings = warnings;
1193
+ if (notFoundTools.length > 0) {
1194
+ result.notFound = notFoundTools;
1195
+ result.warnings = [`Tools not found: ${notFoundTools.join(", ")}`];
1196
+ }
1166
1197
  return { content: [{
1167
1198
  type: "text",
1168
1199
  text: JSON.stringify(result, null, 2)
@@ -1204,10 +1235,6 @@ var UseToolTool = class UseToolTool {
1204
1235
  toolArgs: {
1205
1236
  type: "object",
1206
1237
  description: "Arguments to pass to the tool, as discovered from describe_tools"
1207
- },
1208
- serverName: {
1209
- type: "string",
1210
- description: "Optional server name to disambiguate when multiple servers have the same tool"
1211
1238
  }
1212
1239
  },
1213
1240
  required: ["toolName"],
@@ -1217,8 +1244,9 @@ var UseToolTool = class UseToolTool {
1217
1244
  }
1218
1245
  async execute(input) {
1219
1246
  try {
1220
- const { toolName, toolArgs = {}, serverName } = input;
1247
+ const { toolName: inputToolName, toolArgs = {} } = input;
1221
1248
  const clients = this.clientManager.getAllClients();
1249
+ const { serverName, actualToolName } = parseToolName(inputToolName);
1222
1250
  if (serverName) {
1223
1251
  const client$1 = this.clientManager.getClient(serverName);
1224
1252
  if (!client$1) return {
@@ -1228,20 +1256,20 @@ var UseToolTool = class UseToolTool {
1228
1256
  }],
1229
1257
  isError: true
1230
1258
  };
1231
- if (client$1.toolBlacklist && client$1.toolBlacklist.includes(toolName)) return {
1259
+ if (client$1.toolBlacklist && client$1.toolBlacklist.includes(actualToolName)) return {
1232
1260
  content: [{
1233
1261
  type: "text",
1234
- text: `Tool "${toolName}" is blacklisted on server "${serverName}" and cannot be executed.`
1262
+ text: `Tool "${actualToolName}" is blacklisted on server "${serverName}" and cannot be executed.`
1235
1263
  }],
1236
1264
  isError: true
1237
1265
  };
1238
1266
  try {
1239
- return await client$1.callTool(toolName, toolArgs);
1267
+ return await client$1.callTool(actualToolName, toolArgs);
1240
1268
  } catch (error) {
1241
1269
  return {
1242
1270
  content: [{
1243
1271
  type: "text",
1244
- text: `Failed to call tool "${toolName}" on server "${serverName}": ${error instanceof Error ? error.message : "Unknown error"}`
1272
+ text: `Failed to call tool "${actualToolName}" on server "${serverName}": ${error instanceof Error ? error.message : "Unknown error"}`
1245
1273
  }],
1246
1274
  isError: true
1247
1275
  };
@@ -1250,8 +1278,8 @@ var UseToolTool = class UseToolTool {
1250
1278
  const matchingServers = [];
1251
1279
  const results = await Promise.all(clients.map(async (client$1) => {
1252
1280
  try {
1253
- if (client$1.toolBlacklist && client$1.toolBlacklist.includes(toolName)) return null;
1254
- if ((await client$1.listTools()).some((t) => t.name === toolName)) return client$1.serverName;
1281
+ if (client$1.toolBlacklist && client$1.toolBlacklist.includes(actualToolName)) return null;
1282
+ if ((await client$1.listTools()).some((t) => t.name === actualToolName)) return client$1.serverName;
1255
1283
  } catch (error) {
1256
1284
  console.error(`Failed to list tools from ${client$1.serverName}:`, error);
1257
1285
  }
@@ -1261,14 +1289,14 @@ var UseToolTool = class UseToolTool {
1261
1289
  if (matchingServers.length === 0) return {
1262
1290
  content: [{
1263
1291
  type: "text",
1264
- text: `Tool "${toolName}" not found on any connected server. Use describe_tools to see available tools.`
1292
+ text: `Tool "${actualToolName}" not found on any connected server. Use describe_tools to see available tools.`
1265
1293
  }],
1266
1294
  isError: true
1267
1295
  };
1268
1296
  if (matchingServers.length > 1) return {
1269
1297
  content: [{
1270
1298
  type: "text",
1271
- text: `Multiple servers provide tool "${toolName}". Please specify serverName. Available servers: ${matchingServers.join(", ")}`
1299
+ text: `Tool "${actualToolName}" found on multiple servers. Use prefixed format to specify: ${matchingServers.map((s) => `${s}__${actualToolName}`).join(", ")}`
1272
1300
  }],
1273
1301
  isError: true
1274
1302
  };
@@ -1282,12 +1310,12 @@ var UseToolTool = class UseToolTool {
1282
1310
  isError: true
1283
1311
  };
1284
1312
  try {
1285
- return await client.callTool(toolName, toolArgs);
1313
+ return await client.callTool(actualToolName, toolArgs);
1286
1314
  } catch (error) {
1287
1315
  return {
1288
1316
  content: [{
1289
1317
  type: "text",
1290
- text: `Failed to call tool "${toolName}": ${error instanceof Error ? error.message : "Unknown error"}`
1318
+ text: `Failed to call tool "${actualToolName}": ${error instanceof Error ? error.message : "Unknown error"}`
1291
1319
  }],
1292
1320
  isError: true
1293
1321
  };
@@ -1482,14 +1510,14 @@ var SseTransportHandler = class {
1482
1510
  }
1483
1511
  }
1484
1512
  async start() {
1485
- return new Promise((resolve, reject) => {
1513
+ return new Promise((resolve$1, reject) => {
1486
1514
  try {
1487
1515
  this.server = this.app.listen(this.config.port, this.config.host, () => {
1488
1516
  console.error(`@agiflowai/one-mcp MCP server started with SSE transport on http://${this.config.host}:${this.config.port}`);
1489
1517
  console.error(`SSE endpoint: http://${this.config.host}:${this.config.port}/sse`);
1490
1518
  console.error(`Messages endpoint: http://${this.config.host}:${this.config.port}/messages`);
1491
1519
  console.error(`Health check: http://${this.config.host}:${this.config.port}/health`);
1492
- resolve();
1520
+ resolve$1();
1493
1521
  });
1494
1522
  this.server.on("error", (error) => {
1495
1523
  reject(error);
@@ -1500,17 +1528,17 @@ var SseTransportHandler = class {
1500
1528
  });
1501
1529
  }
1502
1530
  async stop() {
1503
- return new Promise((resolve, reject) => {
1531
+ return new Promise((resolve$1, reject) => {
1504
1532
  if (this.server) {
1505
1533
  this.sessionManager.clear();
1506
1534
  this.server.close((err) => {
1507
1535
  if (err) reject(err);
1508
1536
  else {
1509
1537
  this.server = null;
1510
- resolve();
1538
+ resolve$1();
1511
1539
  }
1512
1540
  });
1513
- } else resolve();
1541
+ } else resolve$1();
1514
1542
  });
1515
1543
  }
1516
1544
  getPort() {
@@ -1662,12 +1690,12 @@ var HttpTransportHandler = class {
1662
1690
  this.sessionManager.deleteSession(sessionId);
1663
1691
  }
1664
1692
  async start() {
1665
- return new Promise((resolve, reject) => {
1693
+ return new Promise((resolve$1, reject) => {
1666
1694
  try {
1667
1695
  this.server = this.app.listen(this.config.port, this.config.host, () => {
1668
1696
  console.error(`@agiflowai/one-mcp MCP server started on http://${this.config.host}:${this.config.port}/mcp`);
1669
1697
  console.error(`Health check: http://${this.config.host}:${this.config.port}/health`);
1670
- resolve();
1698
+ resolve$1();
1671
1699
  });
1672
1700
  this.server.on("error", (error) => {
1673
1701
  reject(error);
@@ -1678,17 +1706,17 @@ var HttpTransportHandler = class {
1678
1706
  });
1679
1707
  }
1680
1708
  async stop() {
1681
- return new Promise((resolve, reject) => {
1709
+ return new Promise((resolve$1, reject) => {
1682
1710
  if (this.server) {
1683
1711
  this.sessionManager.clear();
1684
1712
  this.server.close((err) => {
1685
1713
  if (err) reject(err);
1686
1714
  else {
1687
1715
  this.server = null;
1688
- resolve();
1716
+ resolve$1();
1689
1717
  }
1690
1718
  });
1691
- } else resolve();
1719
+ } else resolve$1();
1692
1720
  });
1693
1721
  }
1694
1722
  getPort() {
@@ -1741,4 +1769,10 @@ Object.defineProperty(exports, 'createServer', {
1741
1769
  get: function () {
1742
1770
  return createServer;
1743
1771
  }
1772
+ });
1773
+ Object.defineProperty(exports, 'findConfigFile', {
1774
+ enumerable: true,
1775
+ get: function () {
1776
+ return findConfigFile;
1777
+ }
1744
1778
  });
@@ -5,7 +5,7 @@ import { existsSync } from "node:fs";
5
5
  import yaml from "js-yaml";
6
6
  import { z } from "zod";
7
7
  import { createHash, randomUUID } from "node:crypto";
8
- import { join } from "node:path";
8
+ import { join, resolve } from "node:path";
9
9
  import { tmpdir } from "node:os";
10
10
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
11
11
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
@@ -951,6 +951,75 @@ var McpClientManagerService = class {
951
951
  }
952
952
  };
953
953
 
954
+ //#endregion
955
+ //#region src/utils/findConfigFile.ts
956
+ /**
957
+ * Config File Finder Utility
958
+ *
959
+ * DESIGN PATTERNS:
960
+ * - Utility function pattern for reusable logic
961
+ * - Fail-fast pattern with early returns
962
+ * - Environment variable configuration pattern
963
+ *
964
+ * CODING STANDARDS:
965
+ * - Use sync filesystem operations for config discovery (performance)
966
+ * - Check PROJECT_PATH environment variable first
967
+ * - Fall back to current working directory
968
+ * - Support both .yaml and .json extensions
969
+ * - Return null if no config file is found
970
+ *
971
+ * AVOID:
972
+ * - Throwing errors (return null instead for optional config)
973
+ * - Hardcoded file names without extension variants
974
+ * - Ignoring environment variables
975
+ */
976
+ /**
977
+ * Find MCP configuration file by checking PROJECT_PATH first, then cwd
978
+ * Looks for both mcp-config.yaml and mcp-config.json
979
+ *
980
+ * @returns Absolute path to config file, or null if not found
981
+ */
982
+ function findConfigFile() {
983
+ const configFileNames = [
984
+ "mcp-config.yaml",
985
+ "mcp-config.yml",
986
+ "mcp-config.json"
987
+ ];
988
+ const projectPath = process.env.PROJECT_PATH;
989
+ if (projectPath) for (const fileName of configFileNames) {
990
+ const configPath = resolve(projectPath, fileName);
991
+ if (existsSync(configPath)) return configPath;
992
+ }
993
+ const cwd = process.cwd();
994
+ for (const fileName of configFileNames) {
995
+ const configPath = join(cwd, fileName);
996
+ if (existsSync(configPath)) return configPath;
997
+ }
998
+ return null;
999
+ }
1000
+
1001
+ //#endregion
1002
+ //#region src/utils/parseToolName.ts
1003
+ /**
1004
+ * Parse tool name to extract server and actual tool name
1005
+ * Supports both plain tool names and prefixed format: {serverName}__{toolName}
1006
+ *
1007
+ * @param toolName - The tool name to parse (e.g., "my_tool" or "server__my_tool")
1008
+ * @returns Parsed result with optional serverName and actualToolName
1009
+ *
1010
+ * @example
1011
+ * parseToolName("my_tool") // { actualToolName: "my_tool" }
1012
+ * parseToolName("server__my_tool") // { serverName: "server", actualToolName: "my_tool" }
1013
+ */
1014
+ function parseToolName(toolName) {
1015
+ const separatorIndex = toolName.indexOf("__");
1016
+ if (separatorIndex > 0) return {
1017
+ serverName: toolName.substring(0, separatorIndex),
1018
+ actualToolName: toolName.substring(separatorIndex + 2)
1019
+ };
1020
+ return { actualToolName: toolName };
1021
+ }
1022
+
954
1023
  //#endregion
955
1024
  //#region src/tools/DescribeToolsTool.ts
956
1025
  var DescribeToolsTool = class DescribeToolsTool {
@@ -961,46 +1030,50 @@ var DescribeToolsTool = class DescribeToolsTool {
961
1030
  }
962
1031
  async getDefinition() {
963
1032
  const clients = this.clientManager.getAllClients();
964
- const serverDescriptions = await Promise.all(clients.map(async (client) => {
1033
+ const toolToServers = /* @__PURE__ */ new Map();
1034
+ const serverToolsMap = /* @__PURE__ */ new Map();
1035
+ await Promise.all(clients.map(async (client) => {
965
1036
  try {
966
1037
  const tools = await client.listTools();
967
1038
  const blacklist = new Set(client.toolBlacklist || []);
968
1039
  const filteredTools = tools.filter((t) => !blacklist.has(t.name));
969
- const toolList = client.omitToolDescription ? filteredTools.map((t) => t.name).join(", ") : filteredTools.map((t) => `${t.name}: ${t.description || "No description"}`).join("\n");
970
- const instructionLine = client.serverInstruction ? `\n- Description: ${client.serverInstruction}` : "";
971
- return `\n\n### Server: ${client.serverName}${instructionLine}\n- Available tools:${toolList ? "\n" + toolList : ""}`;
1040
+ serverToolsMap.set(client.serverName, filteredTools);
1041
+ for (const tool of filteredTools) {
1042
+ if (!toolToServers.has(tool.name)) toolToServers.set(tool.name, []);
1043
+ toolToServers.get(tool.name).push(client.serverName);
1044
+ }
972
1045
  } catch (error) {
973
1046
  console.error(`Failed to list tools from ${client.serverName}:`, error);
974
- const instructionLine = client.serverInstruction ? `\n- Description: ${client.serverInstruction}` : "";
975
- return `\n\n**Server: ${client.serverName}**${instructionLine}\n`;
1047
+ serverToolsMap.set(client.serverName, []);
976
1048
  }
977
1049
  }));
1050
+ const serverDescriptions = clients.map((client) => {
1051
+ const tools = serverToolsMap.get(client.serverName) || [];
1052
+ const formatToolName = (toolName) => {
1053
+ return (toolToServers.get(toolName) || []).length > 1 ? `${client.serverName}__${toolName}` : toolName;
1054
+ };
1055
+ const toolList = client.omitToolDescription ? tools.map((t) => formatToolName(t.name)).join(", ") : tools.map((t) => `${formatToolName(t.name)}: """${t.description || "No description"}"""`).join("\n");
1056
+ const instructionLine = client.serverInstruction ? `\n"""${client.serverInstruction}"""` : "";
1057
+ return `\n\n### Server: ${client.serverName}${instructionLine}\n\n- Available tools:\n${toolList || "No tools available"}`;
1058
+ });
978
1059
  return {
979
1060
  name: DescribeToolsTool.TOOL_NAME,
980
- description: `Learn how to use multiple MCP tools before using them. Below are supported tools and capabilities.
981
-
982
- ## Available MCP Servers:${serverDescriptions.join("")}
1061
+ description: `## Available MCP Servers:${serverDescriptions.join("")}
983
1062
 
984
1063
  ## Usage:
985
- You MUST call this tool with a list of tool names to learn how to use them properly before use_tool; this includes:
1064
+ Before you use any tools above, you MUST call this tool with a list of tool names to learn how to use them properly before use_tool; this includes:
986
1065
  - Arguments schema needed to pass to the tool use
987
1066
  - Description about each tool
988
1067
 
989
1068
  This tool is optimized for batch queries - you can request multiple tools at once for better performance.`,
990
1069
  inputSchema: {
991
1070
  type: "object",
992
- properties: {
993
- toolNames: {
994
- type: "array",
995
- items: { type: "string" },
996
- description: "List of tool names to get detailed information about",
997
- minItems: 1
998
- },
999
- serverName: {
1000
- type: "string",
1001
- description: "Optional server name to search within. If not specified, searches all servers."
1002
- }
1003
- },
1071
+ properties: { toolNames: {
1072
+ type: "array",
1073
+ items: { type: "string" },
1074
+ description: "List of tool names to get detailed information about",
1075
+ minItems: 1
1076
+ } },
1004
1077
  required: ["toolNames"],
1005
1078
  additionalProperties: false
1006
1079
  }
@@ -1008,7 +1081,7 @@ This tool is optimized for batch queries - you can request multiple tools at onc
1008
1081
  }
1009
1082
  async execute(input) {
1010
1083
  try {
1011
- const { toolNames, serverName } = input;
1084
+ const { toolNames } = input;
1012
1085
  const clients = this.clientManager.getAllClients();
1013
1086
  if (!toolNames || toolNames.length === 0) return {
1014
1087
  content: [{
@@ -1017,127 +1090,85 @@ This tool is optimized for batch queries - you can request multiple tools at onc
1017
1090
  }],
1018
1091
  isError: true
1019
1092
  };
1020
- if (serverName) {
1021
- const client = this.clientManager.getClient(serverName);
1022
- if (!client) return {
1023
- content: [{
1024
- type: "text",
1025
- text: `Server "${serverName}" not found. Available servers: ${clients.map((c) => c.serverName).join(", ")}`
1026
- }],
1027
- isError: true
1028
- };
1029
- const tools = await client.listTools();
1030
- const blacklist = new Set(client.toolBlacklist || []);
1031
- const filteredTools = tools.filter((t) => !blacklist.has(t.name));
1032
- const foundTools$1 = [];
1033
- const notFoundTools$1 = [];
1034
- for (const toolName of toolNames) {
1035
- if (blacklist.has(toolName)) {
1036
- notFoundTools$1.push(toolName);
1037
- continue;
1038
- }
1039
- const tool = filteredTools.find((t) => t.name === toolName);
1040
- if (tool) foundTools$1.push({
1041
- server: serverName,
1042
- tool: {
1043
- name: tool.name,
1044
- description: tool.description,
1045
- inputSchema: tool.inputSchema
1046
- }
1047
- });
1048
- else notFoundTools$1.push(toolName);
1049
- }
1050
- if (foundTools$1.length === 0) return {
1051
- content: [{
1052
- type: "text",
1053
- text: `None of the requested tools found on server "${serverName}".\nRequested: ${toolNames.join(", ")}\nAvailable tools: ${tools.map((t) => t.name).join(", ")}`
1054
- }],
1055
- isError: true
1056
- };
1057
- const result$1 = { tools: foundTools$1 };
1058
- if (notFoundTools$1.length > 0) {
1059
- result$1.notFound = notFoundTools$1;
1060
- result$1.warning = `Some tools were not found on server "${serverName}": ${notFoundTools$1.join(", ")}`;
1061
- }
1062
- return { content: [{
1063
- type: "text",
1064
- text: JSON.stringify(result$1, null, 2)
1065
- }] };
1066
- }
1067
- const foundTools = [];
1068
- const notFoundTools = [...toolNames];
1069
- const toolMatches = /* @__PURE__ */ new Map();
1070
- const results = await Promise.all(clients.map(async (client) => {
1093
+ const serverToolsMap = /* @__PURE__ */ new Map();
1094
+ const toolToServers = /* @__PURE__ */ new Map();
1095
+ await Promise.all(clients.map(async (client) => {
1071
1096
  try {
1072
1097
  const tools = await client.listTools();
1073
1098
  const blacklist = new Set(client.toolBlacklist || []);
1074
1099
  const filteredTools = tools.filter((t) => !blacklist.has(t.name));
1075
- const matches = [];
1076
- for (const toolName of toolNames) {
1077
- if (blacklist.has(toolName)) continue;
1078
- const tool = filteredTools.find((t) => t.name === toolName);
1079
- if (tool) matches.push({
1080
- toolName,
1081
- server: client.serverName,
1082
- tool
1083
- });
1100
+ serverToolsMap.set(client.serverName, filteredTools);
1101
+ for (const tool of filteredTools) {
1102
+ if (!toolToServers.has(tool.name)) toolToServers.set(tool.name, []);
1103
+ toolToServers.get(tool.name).push(client.serverName);
1084
1104
  }
1085
- return matches;
1086
1105
  } catch (error) {
1087
1106
  console.error(`Failed to list tools from ${client.serverName}:`, error);
1088
- return [];
1107
+ serverToolsMap.set(client.serverName, []);
1089
1108
  }
1090
1109
  }));
1091
- for (const matches of results) for (const match of matches) {
1092
- if (!toolMatches.has(match.toolName)) toolMatches.set(match.toolName, []);
1093
- toolMatches.get(match.toolName).push({
1094
- server: match.server,
1095
- tool: match.tool
1096
- });
1097
- }
1098
- const ambiguousTools = [];
1099
- for (const toolName of toolNames) {
1100
- const matches = toolMatches.get(toolName);
1101
- if (!matches || matches.length === 0) continue;
1102
- if (matches.length === 1) {
1103
- const match = matches[0];
1104
- foundTools.push({
1105
- server: match.server,
1110
+ const foundTools = [];
1111
+ const notFoundTools = [];
1112
+ for (const requestedToolName of toolNames) {
1113
+ const { serverName, actualToolName } = parseToolName(requestedToolName);
1114
+ if (serverName) {
1115
+ const serverTools = serverToolsMap.get(serverName);
1116
+ if (!serverTools) {
1117
+ notFoundTools.push(requestedToolName);
1118
+ continue;
1119
+ }
1120
+ const tool = serverTools.find((t) => t.name === actualToolName);
1121
+ if (tool) foundTools.push({
1122
+ server: serverName,
1106
1123
  tool: {
1107
- name: match.tool.name,
1108
- description: match.tool.description,
1109
- inputSchema: match.tool.inputSchema
1124
+ name: tool.name,
1125
+ description: tool.description,
1126
+ inputSchema: tool.inputSchema
1110
1127
  }
1111
1128
  });
1112
- const idx = notFoundTools.indexOf(toolName);
1113
- if (idx > -1) notFoundTools.splice(idx, 1);
1129
+ else notFoundTools.push(requestedToolName);
1114
1130
  } else {
1115
- ambiguousTools.push({
1116
- toolName,
1117
- servers: matches.map((m) => m.server)
1118
- });
1119
- const idx = notFoundTools.indexOf(toolName);
1120
- if (idx > -1) notFoundTools.splice(idx, 1);
1131
+ const servers = toolToServers.get(actualToolName);
1132
+ if (!servers || servers.length === 0) {
1133
+ notFoundTools.push(requestedToolName);
1134
+ continue;
1135
+ }
1136
+ if (servers.length === 1) {
1137
+ const server = servers[0];
1138
+ const tool = serverToolsMap.get(server).find((t) => t.name === actualToolName);
1139
+ foundTools.push({
1140
+ server,
1141
+ tool: {
1142
+ name: tool.name,
1143
+ description: tool.description,
1144
+ inputSchema: tool.inputSchema
1145
+ }
1146
+ });
1147
+ } else for (const server of servers) {
1148
+ const tool = serverToolsMap.get(server).find((t) => t.name === actualToolName);
1149
+ foundTools.push({
1150
+ server,
1151
+ tool: {
1152
+ name: tool.name,
1153
+ description: tool.description,
1154
+ inputSchema: tool.inputSchema
1155
+ }
1156
+ });
1157
+ }
1121
1158
  }
1122
1159
  }
1123
- if (foundTools.length === 0 && ambiguousTools.length === 0) return {
1160
+ if (foundTools.length === 0) return {
1124
1161
  content: [{
1125
1162
  type: "text",
1126
- text: `None of the requested tools found on any connected server.\nRequested: ${toolNames.join(", ")}\nUse describe_tools without arguments to see available servers.`
1163
+ text: `None of the requested tools found on any connected server.\nRequested: ${toolNames.join(", ")}\nUse describe_tools to see available tools.`
1127
1164
  }],
1128
1165
  isError: true
1129
1166
  };
1130
1167
  const result = { tools: foundTools };
1131
- if (notFoundTools.length > 0) result.notFound = notFoundTools;
1132
- if (ambiguousTools.length > 0) result.ambiguous = ambiguousTools.map((item) => ({
1133
- toolName: item.toolName,
1134
- servers: item.servers,
1135
- message: `Tool "${item.toolName}" found on multiple servers: ${item.servers.join(", ")}. Please specify serverName to disambiguate.`
1136
- }));
1137
- const warnings = [];
1138
- if (notFoundTools.length > 0) warnings.push(`Tools not found: ${notFoundTools.join(", ")}`);
1139
- if (ambiguousTools.length > 0) warnings.push(`Ambiguous tools (specify serverName): ${ambiguousTools.map((t) => t.toolName).join(", ")}`);
1140
- if (warnings.length > 0) result.warnings = warnings;
1168
+ if (notFoundTools.length > 0) {
1169
+ result.notFound = notFoundTools;
1170
+ result.warnings = [`Tools not found: ${notFoundTools.join(", ")}`];
1171
+ }
1141
1172
  return { content: [{
1142
1173
  type: "text",
1143
1174
  text: JSON.stringify(result, null, 2)
@@ -1179,10 +1210,6 @@ var UseToolTool = class UseToolTool {
1179
1210
  toolArgs: {
1180
1211
  type: "object",
1181
1212
  description: "Arguments to pass to the tool, as discovered from describe_tools"
1182
- },
1183
- serverName: {
1184
- type: "string",
1185
- description: "Optional server name to disambiguate when multiple servers have the same tool"
1186
1213
  }
1187
1214
  },
1188
1215
  required: ["toolName"],
@@ -1192,8 +1219,9 @@ var UseToolTool = class UseToolTool {
1192
1219
  }
1193
1220
  async execute(input) {
1194
1221
  try {
1195
- const { toolName, toolArgs = {}, serverName } = input;
1222
+ const { toolName: inputToolName, toolArgs = {} } = input;
1196
1223
  const clients = this.clientManager.getAllClients();
1224
+ const { serverName, actualToolName } = parseToolName(inputToolName);
1197
1225
  if (serverName) {
1198
1226
  const client$1 = this.clientManager.getClient(serverName);
1199
1227
  if (!client$1) return {
@@ -1203,20 +1231,20 @@ var UseToolTool = class UseToolTool {
1203
1231
  }],
1204
1232
  isError: true
1205
1233
  };
1206
- if (client$1.toolBlacklist && client$1.toolBlacklist.includes(toolName)) return {
1234
+ if (client$1.toolBlacklist && client$1.toolBlacklist.includes(actualToolName)) return {
1207
1235
  content: [{
1208
1236
  type: "text",
1209
- text: `Tool "${toolName}" is blacklisted on server "${serverName}" and cannot be executed.`
1237
+ text: `Tool "${actualToolName}" is blacklisted on server "${serverName}" and cannot be executed.`
1210
1238
  }],
1211
1239
  isError: true
1212
1240
  };
1213
1241
  try {
1214
- return await client$1.callTool(toolName, toolArgs);
1242
+ return await client$1.callTool(actualToolName, toolArgs);
1215
1243
  } catch (error) {
1216
1244
  return {
1217
1245
  content: [{
1218
1246
  type: "text",
1219
- text: `Failed to call tool "${toolName}" on server "${serverName}": ${error instanceof Error ? error.message : "Unknown error"}`
1247
+ text: `Failed to call tool "${actualToolName}" on server "${serverName}": ${error instanceof Error ? error.message : "Unknown error"}`
1220
1248
  }],
1221
1249
  isError: true
1222
1250
  };
@@ -1225,8 +1253,8 @@ var UseToolTool = class UseToolTool {
1225
1253
  const matchingServers = [];
1226
1254
  const results = await Promise.all(clients.map(async (client$1) => {
1227
1255
  try {
1228
- if (client$1.toolBlacklist && client$1.toolBlacklist.includes(toolName)) return null;
1229
- if ((await client$1.listTools()).some((t) => t.name === toolName)) return client$1.serverName;
1256
+ if (client$1.toolBlacklist && client$1.toolBlacklist.includes(actualToolName)) return null;
1257
+ if ((await client$1.listTools()).some((t) => t.name === actualToolName)) return client$1.serverName;
1230
1258
  } catch (error) {
1231
1259
  console.error(`Failed to list tools from ${client$1.serverName}:`, error);
1232
1260
  }
@@ -1236,14 +1264,14 @@ var UseToolTool = class UseToolTool {
1236
1264
  if (matchingServers.length === 0) return {
1237
1265
  content: [{
1238
1266
  type: "text",
1239
- text: `Tool "${toolName}" not found on any connected server. Use describe_tools to see available tools.`
1267
+ text: `Tool "${actualToolName}" not found on any connected server. Use describe_tools to see available tools.`
1240
1268
  }],
1241
1269
  isError: true
1242
1270
  };
1243
1271
  if (matchingServers.length > 1) return {
1244
1272
  content: [{
1245
1273
  type: "text",
1246
- text: `Multiple servers provide tool "${toolName}". Please specify serverName. Available servers: ${matchingServers.join(", ")}`
1274
+ text: `Tool "${actualToolName}" found on multiple servers. Use prefixed format to specify: ${matchingServers.map((s) => `${s}__${actualToolName}`).join(", ")}`
1247
1275
  }],
1248
1276
  isError: true
1249
1277
  };
@@ -1257,12 +1285,12 @@ var UseToolTool = class UseToolTool {
1257
1285
  isError: true
1258
1286
  };
1259
1287
  try {
1260
- return await client.callTool(toolName, toolArgs);
1288
+ return await client.callTool(actualToolName, toolArgs);
1261
1289
  } catch (error) {
1262
1290
  return {
1263
1291
  content: [{
1264
1292
  type: "text",
1265
- text: `Failed to call tool "${toolName}": ${error instanceof Error ? error.message : "Unknown error"}`
1293
+ text: `Failed to call tool "${actualToolName}": ${error instanceof Error ? error.message : "Unknown error"}`
1266
1294
  }],
1267
1295
  isError: true
1268
1296
  };
@@ -1675,4 +1703,4 @@ var HttpTransportHandler = class {
1675
1703
  };
1676
1704
 
1677
1705
  //#endregion
1678
- export { McpClientManagerService as a, createServer as i, SseTransportHandler as n, ConfigFetcherService as o, StdioTransportHandler as r, HttpTransportHandler as t };
1706
+ export { findConfigFile as a, createServer as i, SseTransportHandler as n, McpClientManagerService as o, StdioTransportHandler as r, ConfigFetcherService as s, HttpTransportHandler as t };
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_http = require('./http-23nhycE8.cjs');
1
+ const require_http = require('./http-3v8zyDO3.cjs');
2
2
 
3
3
  exports.HttpTransportHandler = require_http.HttpTransportHandler;
4
4
  exports.SseTransportHandler = require_http.SseTransportHandler;
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { i as createServer, n as SseTransportHandler, r as StdioTransportHandler, t as HttpTransportHandler } from "./http-CkWO35l-.mjs";
1
+ import { i as createServer, n as SseTransportHandler, r as StdioTransportHandler, t as HttpTransportHandler } from "./http-CzQfsUEI.mjs";
2
2
 
3
3
  export { HttpTransportHandler, SseTransportHandler, StdioTransportHandler, createServer };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agiflowai/one-mcp",
3
3
  "description": "One MCP server package",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "license": "AGPL-3.0",
6
6
  "keywords": [
7
7
  "mcp",
@@ -25,7 +25,7 @@
25
25
  "express": "^4.21.2",
26
26
  "js-yaml": "^4.1.0",
27
27
  "zod": "^3.24.1",
28
- "@agiflowai/aicode-utils": "1.0.3"
28
+ "@agiflowai/aicode-utils": "1.0.4"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/express": "^5.0.0",