| |
| |
| |
| |
| const { logger } = require('@librechat/data-schemas'); |
| const { Constants } = require('librechat-data-provider'); |
| const { |
| cacheMCPServerTools, |
| getMCPServerTools, |
| getAppConfig, |
| } = require('~/server/services/Config'); |
| const { getMCPManager } = require('~/config'); |
| const { mcpServersRegistry } = require('@librechat/api'); |
|
|
| |
| |
| |
| const getMCPTools = async (req, res) => { |
| try { |
| const userId = req.user?.id; |
| if (!userId) { |
| logger.warn('[getMCPTools] User ID not found in request'); |
| return res.status(401).json({ message: 'Unauthorized' }); |
| } |
|
|
| const appConfig = req.config ?? (await getAppConfig({ role: req.user?.role })); |
| if (!appConfig?.mcpConfig) { |
| return res.status(200).json({ servers: {} }); |
| } |
|
|
| const mcpManager = getMCPManager(); |
| const configuredServers = Object.keys(appConfig.mcpConfig); |
| const mcpServers = {}; |
|
|
| const cachePromises = configuredServers.map((serverName) => |
| getMCPServerTools(userId, serverName).then((tools) => ({ serverName, tools })), |
| ); |
| const cacheResults = await Promise.all(cachePromises); |
|
|
| const serverToolsMap = new Map(); |
| for (const { serverName, tools } of cacheResults) { |
| if (tools) { |
| serverToolsMap.set(serverName, tools); |
| continue; |
| } |
|
|
| let serverTools; |
| try { |
| serverTools = await mcpManager.getServerToolFunctions(userId, serverName); |
| } catch (error) { |
| logger.error(`[getMCPTools] Error fetching tools for server ${serverName}:`, error); |
| continue; |
| } |
| if (!serverTools) { |
| logger.debug(`[getMCPTools] No tools found for server ${serverName}`); |
| continue; |
| } |
| serverToolsMap.set(serverName, serverTools); |
|
|
| if (Object.keys(serverTools).length > 0) { |
| |
| cacheMCPServerTools({ userId, serverName, serverTools }).catch((err) => |
| logger.error(`[getMCPTools] Failed to cache tools for ${serverName}:`, err), |
| ); |
| } |
| } |
|
|
| |
| for (const serverName of configuredServers) { |
| try { |
| const serverTools = serverToolsMap.get(serverName); |
|
|
| |
| const serverConfig = appConfig.mcpConfig[serverName]; |
| const rawServerConfig = await mcpServersRegistry.getServerConfig(serverName, userId); |
|
|
| |
| const server = { |
| name: serverName, |
| icon: rawServerConfig?.iconPath || '', |
| authenticated: true, |
| authConfig: [], |
| tools: [], |
| }; |
|
|
| |
| if (serverConfig?.customUserVars) { |
| const customVarKeys = Object.keys(serverConfig.customUserVars); |
| if (customVarKeys.length > 0) { |
| server.authConfig = Object.entries(serverConfig.customUserVars).map(([key, value]) => ({ |
| authField: key, |
| label: value.title || key, |
| description: value.description || '', |
| })); |
| server.authenticated = false; |
| } |
| } |
|
|
| |
| if (serverTools) { |
| for (const [toolKey, toolData] of Object.entries(serverTools)) { |
| if (!toolData.function || !toolKey.includes(Constants.mcp_delimiter)) { |
| continue; |
| } |
|
|
| const toolName = toolKey.split(Constants.mcp_delimiter)[0]; |
| server.tools.push({ |
| name: toolName, |
| pluginKey: toolKey, |
| description: toolData.function.description || '', |
| }); |
| } |
| } |
|
|
| |
| if (server.tools.length > 0 || serverConfig) { |
| mcpServers[serverName] = server; |
| } |
| } catch (error) { |
| logger.error(`[getMCPTools] Error loading tools for server ${serverName}:`, error); |
| } |
| } |
|
|
| res.status(200).json({ servers: mcpServers }); |
| } catch (error) { |
| logger.error('[getMCPTools]', error); |
| res.status(500).json({ message: error.message }); |
| } |
| }; |
|
|
| module.exports = { |
| getMCPTools, |
| }; |
|
|