UNPKG

@agenite/mcp

Version:
148 lines (146 loc) 4.57 kB
import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'; import { Tool } from '@agenite/tool'; // src/mcp.ts var MCPClient = class { constructor(config) { this.config = config; this.clientConfig = { name: this.config.name || "mcp-client", version: this.config.version || "1.0.0" }; Object.entries(this.config.mcpServers).forEach(([name, serverConfig]) => { this.clients.set(name, { client: new Client(this.clientConfig), connected: false, serverConfig }); }); } clients = /* @__PURE__ */ new Map(); clientConfig; /** * Connect to a specific MCP server * @private */ async connect(serverName) { const serverClient = this.clients.get(serverName); if (!serverClient) { throw new Error(`Server ${serverName} not found in configuration`); } if (serverClient.connected) return; const { serverConfig } = serverClient; let transport; if ("url" in serverConfig) { if (!serverConfig.url) { throw new Error("URL is required for SSE transport"); } transport = new SSEClientTransport(new URL(serverConfig.url)); } else if ("command" in serverConfig) { if (!serverConfig.command || !serverConfig.args) { throw new Error("Command and args are required for stdio transport"); } transport = new StdioClientTransport({ command: serverConfig.command, args: serverConfig.args, env: serverConfig.env }); } if (!transport) { throw new Error("Transport is required"); } await serverClient.client.connect(transport); serverClient.connected = true; } /** * Connect to all configured MCP servers * @private */ async connectAll() { const serverNames = Array.from(this.clients.keys()); await Promise.all(serverNames.map((name) => this.connect(name))); } /** * Get available tools from a specific MCP server */ async getTools(serverName) { const serverClient = this.clients.get(serverName); if (!serverClient) { throw new Error(`Server ${serverName} not found in configuration`); } if (!serverClient.connected) { await this.connect(serverName); } const toolList = await serverClient.client.listTools(); return toolList.tools.map((toolSchema) => { return new Tool({ name: `${serverName}.${toolSchema.name}`, description: toolSchema.description || "", inputSchema: toolSchema.inputSchema, execute: async ({ input }) => { const result = await this.callTool( serverName, toolSchema.name, input ); return result; } }); }); } /** * Get available tools from all connected MCP servers as a flat array * This is the preferred method for integration with Agent */ async getAllTools() { await this.connectAll(); const serverNames = Array.from(this.clients.keys()); const toolPromises = serverNames.map((name) => this.getTools(name)); const results = await Promise.all(toolPromises); return results.flat(); } /** * Get available tools from all connected MCP servers organized by server */ async getAllToolsByServer() { await this.connectAll(); const serverNames = Array.from(this.clients.keys()); const toolsPromises = serverNames.map(async (name) => { const tools = await this.getTools(name); return [name, tools]; }); const results = await Promise.all(toolsPromises); return Object.fromEntries(results); } /** * Call a tool on a specific MCP server * @private This is internally used by the Tool execute functions */ async callTool(serverName, toolName, input) { const serverClient = this.clients.get(serverName); if (!serverClient) { throw new Error(`Server ${serverName} not found in configuration`); } if (!serverClient.connected) { await this.connect(serverName); } const result = await serverClient.client.callTool({ name: toolName, arguments: input }); return { isError: !!result.isError, data: result.content }; } /** * Get configured server names */ getServerNames() { return Array.from(this.clients.keys()); } }; export { MCPClient }; //# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map