mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-16 16:30:15 +01:00
🪂 refactor: MCP Server Init Fallback (#10608)
* 🌿 refactor: MCP Server Init and Registry with Fallback Configs
* chore: Redis Cache Flushing for Cluster Support
This commit is contained in:
parent
1e4c255351
commit
b49545d916
4 changed files with 99 additions and 38 deletions
|
|
@ -34,6 +34,9 @@ export class MCPServersInitializer {
|
|||
public static async initialize(rawConfigs: t.MCPServers): Promise<void> {
|
||||
if (await statusCache.isInitialized()) return;
|
||||
|
||||
/** Store raw configs immediately so they're available even if initialization fails/is slow */
|
||||
registry.setRawConfigs(rawConfigs);
|
||||
|
||||
if (await isLeader()) {
|
||||
// Leader performs initialization
|
||||
await statusCache.reset();
|
||||
|
|
|
|||
|
|
@ -13,12 +13,22 @@ import {
|
|||
*
|
||||
* Provides a unified interface for retrieving server configs with proper fallback hierarchy:
|
||||
* checks shared app servers first, then shared user servers, then private user servers.
|
||||
* Falls back to raw config when servers haven't been initialized yet or failed to initialize.
|
||||
* Handles server lifecycle operations including adding, removing, and querying configurations.
|
||||
*/
|
||||
class MCPServersRegistry {
|
||||
public readonly sharedAppServers = ServerConfigsCacheFactory.create('App', false);
|
||||
public readonly sharedUserServers = ServerConfigsCacheFactory.create('User', false);
|
||||
private readonly privateUserServers: Map<string | undefined, ServerConfigsCache> = new Map();
|
||||
private rawConfigs: t.MCPServers = {};
|
||||
|
||||
/**
|
||||
* Stores the raw MCP configuration as a fallback when servers haven't been initialized yet.
|
||||
* Should be called during initialization before inspecting servers.
|
||||
*/
|
||||
public setRawConfigs(configs: t.MCPServers): void {
|
||||
this.rawConfigs = configs;
|
||||
}
|
||||
|
||||
public async addPrivateUserServer(
|
||||
userId: string,
|
||||
|
|
@ -59,15 +69,32 @@ class MCPServersRegistry {
|
|||
const privateUserServer = await this.privateUserServers.get(userId)?.get(serverName);
|
||||
if (privateUserServer) return privateUserServer;
|
||||
|
||||
/** Fallback to raw config if server hasn't been initialized yet */
|
||||
const rawConfig = this.rawConfigs[serverName];
|
||||
if (rawConfig) return rawConfig as t.ParsedServerConfig;
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public async getAllServerConfigs(userId?: string): Promise<Record<string, t.ParsedServerConfig>> {
|
||||
return {
|
||||
const registryConfigs = {
|
||||
...(await this.sharedAppServers.getAll()),
|
||||
...(await this.sharedUserServers.getAll()),
|
||||
...((await this.privateUserServers.get(userId)?.getAll()) ?? {}),
|
||||
};
|
||||
|
||||
/** Include all raw configs, but registry configs take precedence (they have inspection data) */
|
||||
const allConfigs: Record<string, t.ParsedServerConfig> = {};
|
||||
for (const serverName in this.rawConfigs) {
|
||||
allConfigs[serverName] = this.rawConfigs[serverName] as t.ParsedServerConfig;
|
||||
}
|
||||
|
||||
/** Override with registry configs where available (they have richer data) */
|
||||
for (const serverName in registryConfigs) {
|
||||
allConfigs[serverName] = registryConfigs[serverName];
|
||||
}
|
||||
|
||||
return allConfigs;
|
||||
}
|
||||
|
||||
// TODO: This is currently used to determine if a server requires OAuth. However, this info can
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue