mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 17:30:16 +01:00
📡 refactor: MCP Runtime Config Sync with Redis Distributed Locking (#10352)
* 🔄 Refactoring: MCP Runtime Configuration Reload
- PrivateServerConfigs own cache classes (inMemory and Redis).
- Connections staleness detection by comparing (connection.createdAt and config.LastUpdatedAt)
- ConnectionsRepo access Registry instead of in memory config dict and renew stale connections
- MCPManager: adjusted init of ConnectionsRepo (app level)
- UserConnectionManager: renew stale connections
- skipped test, to test "should only clear keys in its own namespace"
- MCPPrivateServerLoader: new component to manage logic of loading / editing private servers on runtime
- PrivateServersLoadStatusCache to track private server cache status
- New unit and integration tests.
Misc:
- add es lint rule to enforce line between class methods
* Fix cluster mode batch update and delete workarround. Fixed unit tests for cluster mode.
* Fix Keyv redis clear cache namespace awareness issue + Integration tests fixes
* chore: address copilot comments
* Fixing rebase issue: removed the mcp config fallback in single getServerConfig method:
- to not to interfere with the logic of the right Tier (APP/USER/Private)
- If userId is null, the getServerConfig should not return configs that are a SharedUser tier and not APP tier
* chore: add dev-staging branch to workflow triggers for backend, cache integration, and ESLint checks
---------
Co-authored-by: Atef Bellaaj <slalom.bellaaj@external.daimlertruck.com>
This commit is contained in:
parent
52e6796635
commit
ac68e629e6
49 changed files with 5244 additions and 257 deletions
|
|
@ -54,13 +54,15 @@ export abstract class UserConnectionManager {
|
|||
throw new McpError(ErrorCode.InvalidRequest, `[MCP] User object missing id property`);
|
||||
}
|
||||
|
||||
if (this.appConnections!.has(serverName)) {
|
||||
if (await this.appConnections!.has(serverName)) {
|
||||
throw new McpError(
|
||||
ErrorCode.InvalidRequest,
|
||||
`[MCP][User: ${userId}] Trying to create user-specific connection for app-level server "${serverName}"`,
|
||||
);
|
||||
}
|
||||
|
||||
const config = await serversRegistry.getServerConfig(serverName, userId);
|
||||
|
||||
const userServerMap = this.userConnections.get(userId);
|
||||
let connection = forceNew ? undefined : userServerMap?.get(serverName);
|
||||
const now = Date.now();
|
||||
|
|
@ -77,7 +79,15 @@ export abstract class UserConnectionManager {
|
|||
}
|
||||
connection = undefined; // Force creation of a new connection
|
||||
} else if (connection) {
|
||||
if (await connection.isConnected()) {
|
||||
if (!config || (config.lastUpdatedAt && connection.isStale(config.lastUpdatedAt))) {
|
||||
if (config) {
|
||||
logger.info(
|
||||
`[MCP][User: ${userId}][${serverName}] Config was updated, disconnecting stale connection`,
|
||||
);
|
||||
}
|
||||
await this.disconnectUserConnection(userId, serverName);
|
||||
connection = undefined;
|
||||
} else if (await connection.isConnected()) {
|
||||
logger.debug(`[MCP][User: ${userId}][${serverName}] Reusing active connection`);
|
||||
this.updateUserLastActivity(userId);
|
||||
return connection;
|
||||
|
|
@ -91,12 +101,7 @@ export abstract class UserConnectionManager {
|
|||
}
|
||||
}
|
||||
|
||||
// If no valid connection exists, create a new one
|
||||
if (!connection) {
|
||||
logger.info(`[MCP][User: ${userId}][${serverName}] Establishing new connection`);
|
||||
}
|
||||
|
||||
const config = await serversRegistry.getServerConfig(serverName, userId);
|
||||
// Now check if config exists for new connection creation
|
||||
if (!config) {
|
||||
throw new McpError(
|
||||
ErrorCode.InvalidRequest,
|
||||
|
|
@ -104,6 +109,9 @@ export abstract class UserConnectionManager {
|
|||
);
|
||||
}
|
||||
|
||||
// If no valid connection exists, create a new one
|
||||
logger.info(`[MCP][User: ${userId}][${serverName}] Establishing new connection`);
|
||||
|
||||
try {
|
||||
connection = await MCPConnectionFactory.create(
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue