UNPKG

@vibe-kit/grok-cli

Version:

An open-source AI agent that brings the power of Grok directly into your terminal.

152 lines 6.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.McpClient = void 0; const settings_1 = require("../utils/settings"); const mcp_protocol_client_1 = require("./mcp-protocol-client"); class McpClient { constructor() { this.connections = new Map(); this.initialized = false; } async initialize() { if (this.initialized) return; const servers = (0, settings_1.listMcpServers)(); // Connect to servers sequentially to avoid resource conflicts for (const [name, server] of Object.entries(servers)) { try { await this.connectToServer(name, server); } catch (error) { console.warn(`Failed to connect to MCP server '${name}':`, error); } } this.initialized = true; } async connectToServer(name, server, retryCount = 0) { const maxRetries = name === 'github' ? 2 : 1; // Give GitHub extra retries due to Docker startup try { // Auto-detect transport based on server configuration let transport = server.transport; let url = server.url || server.serverUrl; // If URL is provided and starts with http, use SSE transport if (url && (url.startsWith('http://') || url.startsWith('https://'))) { transport = 'sse'; } // Default to stdio if no transport specified if (!transport) { transport = 'stdio'; } if (transport === 'stdio' && !server.command) { throw new Error('Server command is required for stdio transport'); } if (transport === 'sse' && !url) { throw new Error('Server URL is required for SSE transport'); } console.log(`🔌 Connecting to MCP server '${name}'${retryCount > 0 ? ` (retry ${retryCount})` : ''}...`); // Create MCP protocol client const client = new mcp_protocol_client_1.McpProtocolClient({ command: server.command, url: url, args: server.args || [], env: server.env || {}, headers: server.headers || {}, transport }); const connection = { server, client, tools: [], connected: false }; // Connect to the server await client.connect(); // Get available tools const tools = await client.listTools(); connection.tools = tools; connection.connected = true; console.log(`✅ Connected to MCP server '${name}' (${tools.length} tools available)`); this.connections.set(name, connection); } catch (error) { if (retryCount < maxRetries) { console.warn(`⚠️ MCP server '${name}' failed (attempt ${retryCount + 1}/${maxRetries + 1}), retrying...`); // Wait a bit before retrying (especially for Docker) await new Promise(resolve => setTimeout(resolve, 5000)); return this.connectToServer(name, server, retryCount + 1); } else { console.warn(`❌ Failed to connect to MCP server '${name}' after ${maxRetries + 1} attempts:`, error); } // Don't throw - continue with other servers } } async executeTool(toolName, parameters) { // Find which server has this tool for (const [serverName, connection] of this.connections) { if (connection.connected && connection.tools.some(tool => tool.name === toolName)) { return await this.executeToolOnServer(serverName, toolName, parameters); } } throw new Error(`Tool '${toolName}' not found in any connected MCP server`); } async executeToolOnServer(serverName, toolName, parameters) { const connection = this.connections.get(serverName); if (!connection || !connection.connected) { throw new Error(`MCP server '${serverName}' is not connected`); } try { const result = await connection.client.callTool(toolName, parameters); return { success: !result.isError, data: result.content || result.result, error: result.isError ? result.content?.[0]?.text || 'Tool execution failed' : undefined }; } catch (error) { return { success: false, error: error.message }; } } getAvailableTools() { const tools = []; for (const connection of this.connections.values()) { if (connection.connected) { for (const mcpTool of connection.tools) { tools.push({ type: 'function', function: { name: mcpTool.name, description: mcpTool.description, parameters: mcpTool.inputSchema } }); } } } return tools; } async disconnect() { const disconnectPromises = []; for (const connection of this.connections.values()) { if (connection.connected) { disconnectPromises.push(connection.client.disconnect()); } } await Promise.allSettled(disconnectPromises); this.connections.clear(); this.initialized = false; } getConnectedServers() { return Array.from(this.connections.entries()) .filter(([_, connection]) => connection.connected) .map(([name, _]) => name); } isInitialized() { return this.initialized; } } exports.McpClient = McpClient; //# sourceMappingURL=mcp-client.js.map