🚀 feat: Enhance MCP Connections For Multi-User Support (#6610)

* feat: first pass, multi-user connections

* 🔧 refactor: Enhance MCPConnection logging with user-specific prefixes

* 🔧 chore: Update @modelcontextprotocol/sdk dependency to version 1.8.0

* feat: idle timeout for user mcp connections

* chore: increase user connection idle timeout to 15 minutes

* feat: implement graceful shutdown for MCP servers on termination signal

* feat: implement user idle timeout management and last activity tracking

* feat: enhance MCP options to support custom headers and user ID in environment variable processing

* feat: update user last activity tracking in MCPManager

* refactor: remove default OpenRouter completions URL from OpenAIClient

* refactor: simplify log messages by removing redundant 'App' prefix in MCPManager

* refactor: show Agents Builder even if not using Agents endpoint

* refactor: remove redundant 'App' prefix from disconnect error log messages in MCPManager

* refactor: remove 'App' prefix from log prefix in MCPConnection

* chore: remove unecessary comment

* fix: allow error propagation during MCPManager initialization
This commit is contained in:
Danny Avila 2025-03-28 15:21:10 -04:00 committed by GitHub
parent e630c0a00d
commit a10bc87979
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 667 additions and 430 deletions

View file

@ -13,7 +13,7 @@ const { logger, getMCPManager } = require('~/config');
* Creates a general tool for an entire action set.
*
* @param {Object} params - The parameters for loading action sets.
* @param {ServerRequest} params.req - The name of the tool.
* @param {ServerRequest} params.req - The Express request object, containing user/request info.
* @param {string} params.toolKey - The toolKey for the tool.
* @param {import('@librechat/agents').Providers | EModelEndpoint} params.provider - The provider for the tool.
* @param {string} params.model - The model for the tool.
@ -37,6 +37,15 @@ async function createMCPTool({ req, toolKey, provider }) {
}
const [toolName, serverName] = toolKey.split(Constants.mcp_delimiter);
const userId = req.user?.id;
if (!userId) {
logger.error(
`[MCP][${serverName}][${toolName}] User ID not found on request. Cannot create tool.`,
);
throw new Error(`User ID not found on request. Cannot create tool for ${toolKey}.`);
}
/** @type {(toolArguments: Object | string, config?: GraphRunnableConfig) => Promise<unknown>} */
const _call = async (toolArguments, config) => {
try {
@ -47,9 +56,11 @@ async function createMCPTool({ req, toolKey, provider }) {
provider,
toolArguments,
options: {
userId,
signal: config?.signal,
},
});
if (isAssistantsEndpoint(provider) && Array.isArray(result)) {
return result[0];
}
@ -58,7 +69,6 @@ async function createMCPTool({ req, toolKey, provider }) {
}
return result;
} catch (error) {
logger.error(`${toolName} MCP server tool call failed`, error);
return `${toolName} MCP server tool call failed.`;
}
};