{"version":3,"sources":["/Users/shyun/comcom/ain-enterprise/ain-adk/dist/cjs/chunk-WDZJWNHK.cjs","../../src/modules/mcp/mcp.module.ts"],"names":[],"mappings":"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","file":"/Users/shyun/comcom/ain-enterprise/ain-adk/dist/cjs/chunk-WDZJWNHK.cjs","sourcesContent":[null,"import { Client as MCPClient } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport { WebSocketClientTransport } from \"@modelcontextprotocol/sdk/client/websocket.js\";\nimport {\n\tCONNECTOR_PROTOCOL_TYPE,\n\ttype ConnectorTool,\n} from \"@/types/connector.js\";\nimport type { MCPConfig } from \"@/types/mcp.js\";\nimport { loggers } from \"@/utils/logger.js\";\nimport { withAdkThinkingArg } from \"@/utils/tool-args.js\";\nimport { MCPConnector } from \"./mcp.connector.js\";\n\n/**\n * Module for managing Model Context Protocol (MCP) server connections.\n *\n * This module handles the lifecycle of MCP client connections, discovers\n * available tools from connected servers, and provides an interface for\n * executing those tools. Multiple MCP servers can be connected simultaneously.\n */\nexport class MCPModule {\n\tprivate mcpConnectors: Map<string, MCPConnector> = new Map();\n\n\taddMCPConnector(configs: { [name: string]: MCPConfig }): void {\n\t\tfor (const [name, config] of Object.entries(configs)) {\n\t\t\tconst conn = new MCPConnector(name, config);\n\t\t\tthis.mcpConnectors.set(name, conn);\n\t\t}\n\t}\n\n\tprivate getOrCreateClient(connector: MCPConnector): MCPClient {\n\t\tconnector.client ??= new MCPClient({\n\t\t\tname: connector.name,\n\t\t\tversion: \"1.0.0\",\n\t\t});\n\t\treturn connector.client;\n\t}\n\n\tasync connectToServers(): Promise<void> {\n\t\tfor (const [name, conn] of this.mcpConnectors.entries()) {\n\t\t\ttry {\n\t\t\t\tconst mcpClient = this.getOrCreateClient(conn);\n\t\t\t\tconst config = conn.config;\n\t\t\t\tswitch (config.type) {\n\t\t\t\t\tcase \"stdio\": {\n\t\t\t\t\t\tconst transport = new StdioClientTransport(config.params);\n\t\t\t\t\t\tawait mcpClient.connect(transport);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"websocket\": {\n\t\t\t\t\t\tconst transport = new WebSocketClientTransport(config.url);\n\t\t\t\t\t\tawait mcpClient.connect(transport);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"sse\": {\n\t\t\t\t\t\tconst transport = new SSEClientTransport(\n\t\t\t\t\t\t\tconfig.url,\n\t\t\t\t\t\t\tconfig.options,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tawait mcpClient.connect(transport);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"streamableHttp\": {\n\t\t\t\t\t\tconst transport = new StreamableHTTPClientTransport(\n\t\t\t\t\t\t\tconfig.url,\n\t\t\t\t\t\t\tconfig.options,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tawait mcpClient.connect(transport);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// This cannot happen.\n\t\t\t\t\t\tloggers.mcp.error(\"Unsupported MCP config type\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst toolList = await mcpClient.listTools();\n\t\t\t\tconn.tools = toolList.tools.map((tool) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttoolName: `${name}-${tool.name}`, // to avoid tool name duplication\n\t\t\t\t\t\tconnectorName: name,\n\t\t\t\t\t\tprotocol: CONNECTOR_PROTOCOL_TYPE.MCP,\n\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\tinputSchema: tool.inputSchema,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t\tloggers.mcp.info(\"Connected to MCP server with tools:\", {\n\t\t\t\t\ttools: conn.tools.map((tool) => tool.toolName),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tloggers.mcp.error(`Failed to connect to MCP server ${name}`, { error });\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns all available tools from connected MCP servers.\n\t *\n\t * @returns Array of MCPTool instances representing available tools\n\t */\n\tgetTools(prompt: string): Array<ConnectorTool> {\n\t\tconst allTools: Array<ConnectorTool> = [];\n\t\tfor (const conn of this.mcpConnectors.values()) {\n\t\t\tif (!conn.enabled) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const tool of conn.tools) {\n\t\t\t\tallTools.push({\n\t\t\t\t\ttoolName: tool.toolName,\n\t\t\t\t\tconnectorName: tool.connectorName,\n\t\t\t\t\tprotocol: tool.protocol,\n\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\tinputSchema: withAdkThinkingArg(tool.inputSchema, prompt),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn allTools;\n\t}\n\n\t/**\n\t * Executes a tool on its corresponding MCP server.\n\t *\n\t * @param tool - The MCPTool instance to execute\n\t * @param _args - Arguments to pass to the tool\n\t * @returns Promise resolving to the tool's execution result\n\t * @throws Error if the MCP server for the tool is not found\n\t */\n\tasync useTool(\n\t\ttool: ConnectorTool,\n\t\t_args?: Record<string, unknown>,\n\t): Promise<string> {\n\t\tconst { connectorName, toolName } = tool;\n\t\tconst connector = this.mcpConnectors.get(connectorName);\n\t\tconst client = connector?.client;\n\n\t\ttry {\n\t\t\tif (!client) {\n\t\t\t\tthrow new Error(`Invalid MCP Tool ${toolName}`);\n\t\t\t}\n\n\t\t\t// `${name}-${tool.name}` => tool.name\n\t\t\tconst mcpToolName = toolName.slice(connectorName.length + 1);\n\t\t\t// Per-connector timeout override (defaults to the SDK's 60s when unset).\n\t\t\t// resetTimeoutOnProgress lets a tool that streams progress notifications\n\t\t\t// keep the call alive past the base timeout.\n\t\t\tconst requestTimeoutMs = connector?.config.requestTimeoutMs;\n\t\t\tconst result = await client.callTool(\n\t\t\t\t{\n\t\t\t\t\tname: mcpToolName,\n\t\t\t\t\targuments: _args,\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\trequestTimeoutMs !== undefined\n\t\t\t\t\t? { timeout: requestTimeoutMs, resetTimeoutOnProgress: true }\n\t\t\t\t\t: undefined,\n\t\t\t);\n\t\t\tconst toolResult =\n\t\t\t\t`[Bot Called Tool ${toolName} with args ${JSON.stringify(_args)}]\\n` +\n\t\t\t\tJSON.stringify(result.content, null, 2);\n\t\t\treturn toolResult;\n\t\t} catch (error) {\n\t\t\tloggers.mcp.error(\"Failed to call tool\", { error });\n\t\t\tconst toolResult = `[Bot Called Tool ${toolName} with args ${JSON.stringify(_args)}]\\n${typeof error === \"string\" ? error : JSON.stringify(error, null, 2)}`;\n\t\t\treturn toolResult;\n\t\t}\n\t}\n\n\t/**\n\t * Closes all MCP client connections.\n\t *\n\t * Should be called when shutting down the application to ensure\n\t * all MCP connections are properly closed.\n\t */\n\tasync cleanup() {\n\t\tconst results = await Promise.allSettled(\n\t\t\tArray.from(this.mcpConnectors.entries()).map(async ([name, conn]) => {\n\t\t\t\tif (conn.client) {\n\t\t\t\t\tawait conn.client.close();\n\t\t\t\t}\n\t\t\t\treturn name;\n\t\t\t}),\n\t\t);\n\t\tfor (const result of results) {\n\t\t\tif (result.status === \"rejected\") {\n\t\t\t\tloggers.mcp.error(\"Failed to close MCP connector\", {\n\t\t\t\t\terror: result.reason,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n}\n"]}