| const { logger } = require('@librechat/data-schemas'); |
| const { CacheKeys, Constants } = require('librechat-data-provider'); |
| const { findToken, createToken, updateToken, deleteTokens } = require('~/models'); |
| const { getMCPManager, getFlowStateManager } = require('~/config'); |
| const { updateMCPServerTools } = require('~/server/services/Config'); |
| const { getLogStores } = require('~/cache'); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| async function reinitMCPServer({ |
| user, |
| signal, |
| forceNew, |
| serverName, |
| userMCPAuthMap, |
| connectionTimeout, |
| returnOnOAuth = true, |
| oauthStart: _oauthStart, |
| flowManager: _flowManager, |
| }) { |
| |
| let connection = null; |
| |
| let availableTools = null; |
| |
| let tools = null; |
| let oauthRequired = false; |
| let oauthUrl = null; |
| try { |
| const customUserVars = userMCPAuthMap?.[`${Constants.mcp_prefix}${serverName}`]; |
| const flowManager = _flowManager ?? getFlowStateManager(getLogStores(CacheKeys.FLOWS)); |
| const mcpManager = getMCPManager(); |
|
|
| const oauthStart = |
| _oauthStart ?? |
| (async (authURL) => { |
| logger.info(`[MCP Reinitialize] OAuth URL received for ${serverName}`); |
| oauthUrl = authURL; |
| oauthRequired = true; |
| }); |
|
|
| try { |
| connection = await mcpManager.getConnection({ |
| user, |
| signal, |
| forceNew, |
| oauthStart, |
| serverName, |
| flowManager, |
| returnOnOAuth, |
| customUserVars, |
| connectionTimeout, |
| tokenMethods: { |
| findToken, |
| updateToken, |
| createToken, |
| deleteTokens, |
| }, |
| }); |
|
|
| logger.info(`[MCP Reinitialize] Successfully established connection for ${serverName}`); |
| } catch (err) { |
| logger.info(`[MCP Reinitialize] getConnection threw error: ${err.message}`); |
| logger.info( |
| `[MCP Reinitialize] OAuth state - oauthRequired: ${oauthRequired}, oauthUrl: ${oauthUrl ? 'present' : 'null'}`, |
| ); |
|
|
| const isOAuthError = |
| err.message?.includes('OAuth') || |
| err.message?.includes('authentication') || |
| err.message?.includes('401'); |
|
|
| const isOAuthFlowInitiated = err.message === 'OAuth flow initiated - return early'; |
|
|
| if (isOAuthError || oauthRequired || isOAuthFlowInitiated) { |
| logger.info( |
| `[MCP Reinitialize] OAuth required for ${serverName} (isOAuthError: ${isOAuthError}, oauthRequired: ${oauthRequired}, isOAuthFlowInitiated: ${isOAuthFlowInitiated})`, |
| ); |
| oauthRequired = true; |
| } else { |
| logger.error( |
| `[MCP Reinitialize] Error initializing MCP server ${serverName} for user:`, |
| err, |
| ); |
| } |
| } |
|
|
| if (connection && !oauthRequired) { |
| tools = await connection.fetchTools(); |
| availableTools = await updateMCPServerTools({ |
| userId: user.id, |
| serverName, |
| tools, |
| }); |
| } |
|
|
| logger.debug( |
| `[MCP Reinitialize] Sending response for ${serverName} - oauthRequired: ${oauthRequired}, oauthUrl: ${oauthUrl ? 'present' : 'null'}`, |
| ); |
|
|
| const getResponseMessage = () => { |
| if (oauthRequired) { |
| return `MCP server '${serverName}' ready for OAuth authentication`; |
| } |
| if (connection) { |
| return `MCP server '${serverName}' reinitialized successfully`; |
| } |
| return `Failed to reinitialize MCP server '${serverName}'`; |
| }; |
|
|
| const result = { |
| availableTools, |
| success: Boolean((connection && !oauthRequired) || (oauthRequired && oauthUrl)), |
| message: getResponseMessage(), |
| oauthRequired, |
| serverName, |
| oauthUrl, |
| tools, |
| }; |
| logger.debug(`[MCP Reinitialize] Response for ${serverName}:`, result); |
| return result; |
| } catch (error) { |
| logger.error( |
| '[MCP Reinitialize] Error loading MCP Tools, servers may still be initializing:', |
| error, |
| ); |
| } |
| } |
|
|
| module.exports = { |
| reinitMCPServer, |
| }; |
|
|