UNPKG

mcp-use

Version:

A utility library for integrating Model Context Protocol (MCP) with LangChain, Zod, and related tools. Provides helpers for schema conversion, event streaming, and SDK usage.

107 lines (106 loc) 4.91 kB
import { isEqual } from 'lodash-es'; import { logger } from '../logging.js'; import { AcquireActiveMCPServerTool } from './tools/acquire_active_mcp_server.js'; import { AddMCPServerFromConfigTool } from './tools/add_server_from_config.js'; import { ConnectMCPServerTool } from './tools/connect_mcp_server.js'; import { ListMCPServersTool } from './tools/list_mcp_servers.js'; import { ReleaseMCPServerConnectionTool } from './tools/release_mcp_server_connection.js'; export class ServerManager { initializedServers = {}; serverTools = {}; client; adapter; activeServer = null; overrideManagementTools; constructor(client, adapter, managementTools) { this.client = client; this.adapter = adapter; this.overrideManagementTools = managementTools; } setManagementTools(tools) { this.overrideManagementTools = tools; logger.info(`Overriding default management tools with a new set of ${tools.length} tools.`); } logState(context) { const allServerNames = this.client.getServerNames(); const activeSessionNames = Object.keys(this.client.getAllActiveSessions()); if (allServerNames.length === 0) { logger.info('Server Manager State: No servers configured.'); return; } const tableData = allServerNames.map(name => ({ 'Server Name': name, 'Connected': activeSessionNames.includes(name) ? '✅' : '❌', 'Initialized': this.initializedServers[name] ? '✅' : '❌', 'Tool Count': this.serverTools[name]?.length ?? 0, 'Active': this.activeServer === name ? '✅' : '❌', })); logger.info(`Server Manager State: [${context}]`); console.table(tableData); // eslint-disable-line no-console } initialize() { const serverNames = this.client.getServerNames?.(); if (serverNames.length === 0) { logger.warn('No MCP servers defined in client configuration'); } } async prefetchServerTools() { const servers = this.client.getServerNames(); for (const serverName of servers) { try { let session = null; session = this.client.getSession(serverName); logger.debug(`Using existing session for server '${serverName}' to prefetch tools.`); if (!session) { session = await this.client.createSession(serverName).catch((createSessionError) => { logger.warn(`Could not create session for '${serverName}' during prefetch: ${createSessionError}`); return null; }); logger.debug(`Temporarily created session for '${serverName}' to prefetch tools.`); } if (session) { const connector = session.connector; let tools = []; try { tools = await this.adapter.createToolsFromConnectors([connector]); } catch (toolFetchError) { logger.error(`Failed to create tools from connector for server '${serverName}': ${toolFetchError}`); continue; } const cachedTools = this.serverTools[serverName]; const toolsChanged = !cachedTools || !isEqual(cachedTools, tools); if (toolsChanged) { this.serverTools[serverName] = tools; this.initializedServers[serverName] = true; logger.debug(`Prefetched ${tools.length} tools for server '${serverName}'.`); } else { logger.debug(`Tools for server '${serverName}' unchanged, using cached version.`); } } } catch (outerError) { logger.error(`Error prefetching tools for server '${serverName}': ${outerError}`); } } } get tools() { if (logger.level === 'debug') { this.logState('Providing tools to agent'); } const managementTools = this.overrideManagementTools ?? [ new AddMCPServerFromConfigTool(this), new ListMCPServersTool(this), new ConnectMCPServerTool(this), new AcquireActiveMCPServerTool(this), new ReleaseMCPServerConnectionTool(this), ]; if (this.activeServer && this.serverTools[this.activeServer]) { const activeTools = this.serverTools[this.activeServer]; logger.debug(`Adding ${activeTools.length} tools from active server '${this.activeServer}'`); return [...managementTools, ...activeTools]; } return managementTools; } }