mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 17:00:15 +01:00
* feat: MCP Connection management overhaul - Making MCPManager manageable Refactor the monolithic MCPManager into focused, single-responsibility classes: • MCPServersRegistry: Server configuration discovery and metadata management • UserConnectionManager: Manages user-level connections • ConnectionsRepository: Low-level connection pool with lazy loading • MCPConnectionFactory: Handles MCP connection creation with OAuth support New Features: • Lazy loading of app-level connections for horizontal scaling • Automatic reconnection for app-level connections • Enhanced OAuth detection with explicit requiresOAuth flag • Centralized MCP configuration management Bug Fixes: • App-level connection detection in MCPManager.callTool • MCP Connection Reinitialization route behavior Optimizations: • MCPConnection.isConnected() caching to reduce overhead • Concurrent server metadata retrieval instead of sequential This refactoring addresses scalability bottlenecks and improves reliability while maintaining backward compatibility with existing configurations. * feat: Enabled import order in eslint. * # Moved tests to __tests__ folder # added tests for MCPServersRegistry.ts * # Add unit tests for ConnectionsRepository functionality * # Add unit tests for MCPConnectionFactory functionality * # Reorganize MCP connection tests and improve error handling * # reordering imports * # Update testPathIgnorePatterns in jest.config.mjs to exclude development TypeScript files * # removed mcp/manager.ts
57 lines
1.7 KiB
JavaScript
57 lines
1.7 KiB
JavaScript
const { logger } = require('@librechat/data-schemas');
|
|
const { getCachedTools, setCachedTools } = require('./Config');
|
|
const { CacheKeys } = require('librechat-data-provider');
|
|
const { createMCPManager } = require('~/config');
|
|
const { getLogStores } = require('~/cache');
|
|
|
|
/**
|
|
* Initialize MCP servers
|
|
* @param {import('express').Application} app - Express app instance
|
|
*/
|
|
async function initializeMCPs(app) {
|
|
const mcpServers = app.locals.mcpConfig;
|
|
if (!mcpServers) {
|
|
return;
|
|
}
|
|
|
|
// Filter out servers with startup: false
|
|
const filteredServers = {};
|
|
for (const [name, config] of Object.entries(mcpServers)) {
|
|
if (config.startup === false) {
|
|
logger.info(`Skipping MCP server '${name}' due to startup: false`);
|
|
continue;
|
|
}
|
|
filteredServers[name] = config;
|
|
}
|
|
|
|
if (Object.keys(filteredServers).length === 0) {
|
|
logger.info('[MCP] No MCP servers to initialize (all skipped or none configured)');
|
|
return;
|
|
}
|
|
|
|
logger.info('Initializing MCP servers...');
|
|
const mcpManager = await createMCPManager(mcpServers);
|
|
|
|
try {
|
|
delete app.locals.mcpConfig;
|
|
const cachedTools = await getCachedTools();
|
|
|
|
if (!cachedTools) {
|
|
logger.warn('No available tools found in cache during MCP initialization');
|
|
return;
|
|
}
|
|
|
|
const mcpTools = mcpManager.getAppToolFunctions();
|
|
await setCachedTools({ ...cachedTools, ...mcpTools }, { isGlobal: true });
|
|
|
|
const cache = getLogStores(CacheKeys.CONFIG_STORE);
|
|
await cache.delete(CacheKeys.TOOLS);
|
|
logger.debug('Cleared tools array cache after MCP initialization');
|
|
|
|
logger.info('MCP servers initialized successfully');
|
|
} catch (error) {
|
|
logger.error('Failed to initialize MCP servers:', error);
|
|
}
|
|
}
|
|
|
|
module.exports = initializeMCPs;
|