File tree Expand file tree Collapse file tree 3 files changed +49
-0
lines changed
Expand file tree Collapse file tree 3 files changed +49
-0
lines changed Original file line number Diff line number Diff line change 11import pick from 'lodash/pick' ;
22import { logger } from '@librechat/data-schemas' ;
3+ import { isEnabled } from '~/utils' ;
34import { CallToolResultSchema , ErrorCode , McpError } from '@modelcontextprotocol/sdk/types.js' ;
45import type { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js' ;
56import type { TokenMethods , IUser } from '@librechat/data-schemas' ;
@@ -118,6 +119,15 @@ export class MCPManager extends UserConnectionManager {
118119 const configs = await MCPServersRegistry . getInstance ( ) . getAllServerConfigs ( ) ;
119120 for ( const [ serverName , config ] of Object . entries ( configs ) ) {
120121 if ( config . serverInstructions != null ) {
122+ // Skip if serverInstructions is true/boolean or "true" string - this means
123+ // instructions should be fetched from server but weren't (e.g., OAuth server
124+ // that couldn't be connected to at startup)
125+ if ( isEnabled ( config . serverInstructions ) && typeof config . serverInstructions !== 'string' ) {
126+ continue ;
127+ }
128+ if ( typeof config . serverInstructions === 'string' && config . serverInstructions . toLowerCase ( ) . trim ( ) === 'true' ) {
129+ continue ;
130+ }
121131 instructions [ serverName ] = config . serverInstructions as string ;
122132 }
123133 }
Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ import { MCPConnection } from './connection';
66import type * as t from './types' ;
77import { ConnectionsRepository } from '~/mcp/ConnectionsRepository' ;
88import { mcpConfig } from './mcpConfig' ;
9+ import { isEnabled } from '~/utils' ;
910
1011/**
1112 * Abstract base class for managing user-specific MCP connections with lifecycle management.
@@ -143,6 +144,25 @@ export abstract class UserConnectionManager {
143144 this . userConnections . get ( userId ) ?. set ( serverName , connection ) ;
144145
145146 logger . info ( `[MCP][User: ${ userId } ][${ serverName } ] Connection successfully established` ) ;
147+
148+ // For OAuth servers, fetch and update serverInstructions if enabled but not yet fetched
149+ if ( config . requiresOAuth && isEnabled ( config . serverInstructions ) ) {
150+ try {
151+ const instructions = connection . client . getInstructions ( ) ;
152+ if ( instructions && typeof instructions === 'string' ) {
153+ await MCPServersRegistry . getInstance ( ) . updateServerInstructions ( serverName , instructions ) ;
154+ logger . debug (
155+ `[MCP][User: ${ userId } ][${ serverName } ] Fetched and updated server instructions` ,
156+ ) ;
157+ }
158+ } catch ( instructionsError ) {
159+ logger . warn (
160+ `[MCP][User: ${ userId } ][${ serverName } ] Failed to fetch server instructions:` ,
161+ instructionsError ,
162+ ) ;
163+ }
164+ }
165+
146166 // Update timestamp on creation
147167 this . updateUserLastActivity ( userId ) ;
148168 return connection ;
Original file line number Diff line number Diff line change @@ -182,6 +182,25 @@ export class MCPServersRegistry {
182182 return parsedConfig ;
183183 }
184184
185+ /**
186+ * Updates the serverInstructions field for a server config.
187+ * Used to set instructions fetched from OAuth servers after successful connection.
188+ * @param serverName - The name of the server
189+ * @param instructions - The instructions string fetched from the server
190+ */
191+ public async updateServerInstructions ( serverName : string , instructions : string ) : Promise < void > {
192+ // Update in cache repository (YAML-defined servers)
193+ const configFromCache = await this . cacheConfigsRepo . get ( serverName ) ;
194+ if ( configFromCache ) {
195+ configFromCache . serverInstructions = instructions ;
196+ await this . cacheConfigsRepo . update ( serverName , configFromCache ) ;
197+ // Clear read-through caches to ensure fresh data on next read
198+ await this . readThroughCache . clear ( ) ;
199+ await this . readThroughCacheAll . clear ( ) ;
200+ logger . debug ( `[MCPServersRegistry] Updated serverInstructions for "${ serverName } "` ) ;
201+ }
202+ }
203+
185204 // TODO: This is currently used to determine if a server requires OAuth. However, this info can
186205 // can be determined through config.requiresOAuth. Refactor usages and remove this method.
187206 public async getOAuthServers ( userId ?: string ) : Promise < Set < string > > {
You can’t perform that action at this time.
0 commit comments