2025-12-04 21:37:23 +01:00
|
|
|
import { Types } from 'mongoose';
|
|
|
|
|
import {
|
2026-01-23 09:06:29 -05:00
|
|
|
ResourceType,
|
2025-12-04 21:37:23 +01:00
|
|
|
AccessRoleIds,
|
|
|
|
|
PrincipalType,
|
2026-01-23 09:06:29 -05:00
|
|
|
PermissionBits,
|
2025-12-04 21:37:23 +01:00
|
|
|
} from 'librechat-data-provider';
|
2026-01-23 09:06:29 -05:00
|
|
|
import { logger, encryptV2, decryptV2, createMethods } from '@librechat/data-schemas';
|
|
|
|
|
import type { AllMethods, MCPServerDocument } from '@librechat/data-schemas';
|
2025-12-01 00:57:46 +01:00
|
|
|
import type { IServerConfigsRepositoryInterface } from '~/mcp/registry/ServerConfigsRepositoryInterface';
|
2025-12-04 21:37:23 +01:00
|
|
|
import type { ParsedServerConfig, AddServerResult } from '~/mcp/types';
|
2026-01-23 09:06:29 -05:00
|
|
|
import { AccessControlService } from '~/acl/accessControlService';
|
|
|
|
|
|
|
|
|
|
/**
|
🗝️ feat: Credential Variables for DB-Sourced MCP Servers (#12044)
* feat: Allow Credential Variables in Headers for DB-sourced MCP Servers
- Removed the hasCustomUserVars check from ToolService.js, directly retrieving userMCPAuthMap.
- Updated MCPConnectionFactory and related classes to include a dbSourced flag for better handling of database-sourced configurations.
- Added integration tests to ensure proper behavior of dbSourced servers, verifying that sensitive placeholders are not resolved while allowing customUserVars.
- Adjusted various MCP-related files to accommodate the new dbSourced logic, ensuring consistent handling across the codebase.
* chore: MCPConnectionFactory Tests with Additional Flow Metadata for typing
- Updated MCPConnectionFactory tests to include new fields in flowMetadata: serverUrl and state.
- Enhanced mockFlowData in multiple test cases to reflect the updated structure, ensuring comprehensive coverage of the OAuth flow scenarios.
- Added authorization_endpoint to metadata in the test setup for improved validation of the OAuth process.
* refactor: Simplify MCPManager Configuration Handling
- Removed unnecessary type assertions and streamlined the retrieval of server configuration in MCPManager.
- Enhanced the handling of OAuth and database-sourced flags for improved clarity and efficiency.
- Updated tests to reflect changes in user object structure and ensure proper processing of MCP environment variables.
* refactor: Optimize User MCP Auth Map Retrieval in ToolService
- Introduced conditional loading of userMCPAuthMap based on the presence of MCP-delimited tools, improving efficiency by avoiding unnecessary calls.
- Updated the loadToolDefinitionsWrapper and loadAgentTools functions to reflect this change, enhancing overall performance and clarity.
* test: Add userMCPAuthMap gating tests in ToolService
- Introduced new tests to validate the logic for determining if MCP tools are present in the agent's tool list.
- Implemented various scenarios to ensure accurate detection of MCP tools, including edge cases for empty, undefined, and null tool lists.
- Enhanced clarity and coverage of the ToolService capability checking logic.
* refactor: Enhance MCP Environment Variable Processing
- Simplified the handling of the dbSourced parameter in the processMCPEnv function.
- Introduced a failsafe mechanism to derive dbSourced from options if not explicitly provided, improving robustness and clarity in MCP environment variable processing.
* refactor: Update Regex Patterns for Credential Placeholders in ServerConfigsDB
- Modified regex patterns to include additional credential/env placeholders that should not be allowed in user-provided configurations.
- Clarified comments to emphasize the security risks associated with credential exfiltration when MCP servers are shared between users.
* chore: field order
* refactor: Clean Up dbSourced Parameter Handling in processMCPEnv
- Reintroduced the failsafe mechanism for deriving the dbSourced parameter from options, ensuring clarity and robustness in MCP environment variable processing.
- Enhanced code readability by maintaining consistent comment structure.
* refactor: Update MCPOptions Type to Include Optional dbId
- Modified the processMCPEnv function to extend the MCPOptions type, allowing for an optional dbId property.
- Simplified the logic for deriving the dbSourced parameter by directly checking the dbId property, enhancing code clarity and maintainability.
2026-03-03 18:02:37 -05:00
|
|
|
* Regex patterns for credential/env placeholders that should not be allowed in user-provided configs.
|
|
|
|
|
* These would substitute server credentials or the CALLING user's data, creating exfiltration risks
|
|
|
|
|
* when MCP servers are shared between users.
|
2026-01-23 09:06:29 -05:00
|
|
|
*
|
|
|
|
|
* Safe placeholders like {{MCP_API_KEY}} are allowed as they resolve from the user's own plugin auth.
|
|
|
|
|
*/
|
|
|
|
|
const DANGEROUS_CREDENTIAL_PATTERNS = [
|
🗝️ feat: Credential Variables for DB-Sourced MCP Servers (#12044)
* feat: Allow Credential Variables in Headers for DB-sourced MCP Servers
- Removed the hasCustomUserVars check from ToolService.js, directly retrieving userMCPAuthMap.
- Updated MCPConnectionFactory and related classes to include a dbSourced flag for better handling of database-sourced configurations.
- Added integration tests to ensure proper behavior of dbSourced servers, verifying that sensitive placeholders are not resolved while allowing customUserVars.
- Adjusted various MCP-related files to accommodate the new dbSourced logic, ensuring consistent handling across the codebase.
* chore: MCPConnectionFactory Tests with Additional Flow Metadata for typing
- Updated MCPConnectionFactory tests to include new fields in flowMetadata: serverUrl and state.
- Enhanced mockFlowData in multiple test cases to reflect the updated structure, ensuring comprehensive coverage of the OAuth flow scenarios.
- Added authorization_endpoint to metadata in the test setup for improved validation of the OAuth process.
* refactor: Simplify MCPManager Configuration Handling
- Removed unnecessary type assertions and streamlined the retrieval of server configuration in MCPManager.
- Enhanced the handling of OAuth and database-sourced flags for improved clarity and efficiency.
- Updated tests to reflect changes in user object structure and ensure proper processing of MCP environment variables.
* refactor: Optimize User MCP Auth Map Retrieval in ToolService
- Introduced conditional loading of userMCPAuthMap based on the presence of MCP-delimited tools, improving efficiency by avoiding unnecessary calls.
- Updated the loadToolDefinitionsWrapper and loadAgentTools functions to reflect this change, enhancing overall performance and clarity.
* test: Add userMCPAuthMap gating tests in ToolService
- Introduced new tests to validate the logic for determining if MCP tools are present in the agent's tool list.
- Implemented various scenarios to ensure accurate detection of MCP tools, including edge cases for empty, undefined, and null tool lists.
- Enhanced clarity and coverage of the ToolService capability checking logic.
* refactor: Enhance MCP Environment Variable Processing
- Simplified the handling of the dbSourced parameter in the processMCPEnv function.
- Introduced a failsafe mechanism to derive dbSourced from options if not explicitly provided, improving robustness and clarity in MCP environment variable processing.
* refactor: Update Regex Patterns for Credential Placeholders in ServerConfigsDB
- Modified regex patterns to include additional credential/env placeholders that should not be allowed in user-provided configurations.
- Clarified comments to emphasize the security risks associated with credential exfiltration when MCP servers are shared between users.
* chore: field order
* refactor: Clean Up dbSourced Parameter Handling in processMCPEnv
- Reintroduced the failsafe mechanism for deriving the dbSourced parameter from options, ensuring clarity and robustness in MCP environment variable processing.
- Enhanced code readability by maintaining consistent comment structure.
* refactor: Update MCPOptions Type to Include Optional dbId
- Modified the processMCPEnv function to extend the MCPOptions type, allowing for an optional dbId property.
- Simplified the logic for deriving the dbSourced parameter by directly checking the dbId property, enhancing code clarity and maintainability.
2026-03-03 18:02:37 -05:00
|
|
|
/\$\{[^}]+\}/g,
|
2026-01-23 09:06:29 -05:00
|
|
|
/\{\{LIBRECHAT_OPENID_[^}]+\}\}/g,
|
|
|
|
|
/\{\{LIBRECHAT_USER_[^}]+\}\}/g,
|
🗝️ feat: Credential Variables for DB-Sourced MCP Servers (#12044)
* feat: Allow Credential Variables in Headers for DB-sourced MCP Servers
- Removed the hasCustomUserVars check from ToolService.js, directly retrieving userMCPAuthMap.
- Updated MCPConnectionFactory and related classes to include a dbSourced flag for better handling of database-sourced configurations.
- Added integration tests to ensure proper behavior of dbSourced servers, verifying that sensitive placeholders are not resolved while allowing customUserVars.
- Adjusted various MCP-related files to accommodate the new dbSourced logic, ensuring consistent handling across the codebase.
* chore: MCPConnectionFactory Tests with Additional Flow Metadata for typing
- Updated MCPConnectionFactory tests to include new fields in flowMetadata: serverUrl and state.
- Enhanced mockFlowData in multiple test cases to reflect the updated structure, ensuring comprehensive coverage of the OAuth flow scenarios.
- Added authorization_endpoint to metadata in the test setup for improved validation of the OAuth process.
* refactor: Simplify MCPManager Configuration Handling
- Removed unnecessary type assertions and streamlined the retrieval of server configuration in MCPManager.
- Enhanced the handling of OAuth and database-sourced flags for improved clarity and efficiency.
- Updated tests to reflect changes in user object structure and ensure proper processing of MCP environment variables.
* refactor: Optimize User MCP Auth Map Retrieval in ToolService
- Introduced conditional loading of userMCPAuthMap based on the presence of MCP-delimited tools, improving efficiency by avoiding unnecessary calls.
- Updated the loadToolDefinitionsWrapper and loadAgentTools functions to reflect this change, enhancing overall performance and clarity.
* test: Add userMCPAuthMap gating tests in ToolService
- Introduced new tests to validate the logic for determining if MCP tools are present in the agent's tool list.
- Implemented various scenarios to ensure accurate detection of MCP tools, including edge cases for empty, undefined, and null tool lists.
- Enhanced clarity and coverage of the ToolService capability checking logic.
* refactor: Enhance MCP Environment Variable Processing
- Simplified the handling of the dbSourced parameter in the processMCPEnv function.
- Introduced a failsafe mechanism to derive dbSourced from options if not explicitly provided, improving robustness and clarity in MCP environment variable processing.
* refactor: Update Regex Patterns for Credential Placeholders in ServerConfigsDB
- Modified regex patterns to include additional credential/env placeholders that should not be allowed in user-provided configurations.
- Clarified comments to emphasize the security risks associated with credential exfiltration when MCP servers are shared between users.
* chore: field order
* refactor: Clean Up dbSourced Parameter Handling in processMCPEnv
- Reintroduced the failsafe mechanism for deriving the dbSourced parameter from options, ensuring clarity and robustness in MCP environment variable processing.
- Enhanced code readability by maintaining consistent comment structure.
* refactor: Update MCPOptions Type to Include Optional dbId
- Modified the processMCPEnv function to extend the MCPOptions type, allowing for an optional dbId property.
- Simplified the logic for deriving the dbSourced parameter by directly checking the dbId property, enhancing code clarity and maintainability.
2026-03-03 18:02:37 -05:00
|
|
|
/\{\{LIBRECHAT_GRAPH_[^}]+\}\}/g,
|
|
|
|
|
/\{\{LIBRECHAT_BODY_[^}]+\}\}/g,
|
2026-01-23 09:06:29 -05:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sanitizes headers by removing dangerous credential placeholders.
|
|
|
|
|
* This prevents credential exfiltration when MCP servers are shared between users.
|
|
|
|
|
*
|
|
|
|
|
* @param headers - The headers object to sanitize
|
|
|
|
|
* @returns Sanitized headers with dangerous placeholders removed
|
|
|
|
|
*/
|
|
|
|
|
function sanitizeCredentialPlaceholders(
|
|
|
|
|
headers?: Record<string, string>,
|
|
|
|
|
): Record<string, string> | undefined {
|
|
|
|
|
if (!headers) {
|
|
|
|
|
return headers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const sanitized: Record<string, string> = {};
|
|
|
|
|
for (const [key, value] of Object.entries(headers)) {
|
|
|
|
|
let sanitizedValue = value;
|
|
|
|
|
for (const pattern of DANGEROUS_CREDENTIAL_PATTERNS) {
|
|
|
|
|
sanitizedValue = sanitizedValue.replace(pattern, '');
|
|
|
|
|
}
|
|
|
|
|
sanitized[key] = sanitizedValue;
|
|
|
|
|
}
|
|
|
|
|
return sanitized;
|
|
|
|
|
}
|
2025-11-28 16:07:09 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* DB backed config storage
|
|
|
|
|
* Handles CRUD Methods of dynamic mcp servers
|
|
|
|
|
* Will handle Permission ACL
|
|
|
|
|
*/
|
|
|
|
|
export class ServerConfigsDB implements IServerConfigsRepositoryInterface {
|
2025-12-01 00:57:46 +01:00
|
|
|
private _dbMethods: AllMethods;
|
2025-12-04 21:37:23 +01:00
|
|
|
private _aclService: AccessControlService;
|
|
|
|
|
private _mongoose: typeof import('mongoose');
|
|
|
|
|
|
2025-12-01 00:57:46 +01:00
|
|
|
constructor(mongoose: typeof import('mongoose')) {
|
|
|
|
|
if (!mongoose) {
|
|
|
|
|
throw new Error('ServerConfigsDB requires mongoose instance');
|
|
|
|
|
}
|
2025-12-04 21:37:23 +01:00
|
|
|
this._mongoose = mongoose;
|
2025-12-01 00:57:46 +01:00
|
|
|
this._dbMethods = createMethods(mongoose);
|
2025-12-04 21:37:23 +01:00
|
|
|
this._aclService = new AccessControlService(mongoose);
|
2025-12-01 00:57:46 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-04 21:37:23 +01:00
|
|
|
/**
|
|
|
|
|
* Checks if user has access to an MCP server via an agent they can VIEW.
|
|
|
|
|
* @param serverName - The MCP server name to check
|
|
|
|
|
* @param userId - The user ID (optional - if not provided, checks publicly accessible agents)
|
|
|
|
|
* @returns true if user has VIEW access to at least one agent that has this MCP server
|
|
|
|
|
*/
|
|
|
|
|
private async hasAccessViaAgent(serverName: string, userId?: string): Promise<boolean> {
|
|
|
|
|
let accessibleAgentIds: Types.ObjectId[];
|
|
|
|
|
|
|
|
|
|
if (!userId) {
|
2026-01-23 09:06:29 -05:00
|
|
|
/** Publicly accessible agents */
|
2025-12-04 21:37:23 +01:00
|
|
|
accessibleAgentIds = await this._aclService.findPubliclyAccessibleResources({
|
|
|
|
|
resourceType: ResourceType.AGENT,
|
|
|
|
|
requiredPermissions: PermissionBits.VIEW,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
2026-01-23 09:06:29 -05:00
|
|
|
/** User-accessible agents */
|
2025-12-04 21:37:23 +01:00
|
|
|
accessibleAgentIds = await this._aclService.findAccessibleResources({
|
|
|
|
|
userId,
|
|
|
|
|
requiredPermissions: PermissionBits.VIEW,
|
|
|
|
|
resourceType: ResourceType.AGENT,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (accessibleAgentIds.length === 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Agent = this._mongoose.model('Agent');
|
|
|
|
|
const exists = await Agent.exists({
|
|
|
|
|
_id: { $in: accessibleAgentIds },
|
|
|
|
|
mcpServerNames: serverName,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return exists !== null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a new MCP server and grants owner permissions to the user.
|
|
|
|
|
* @param serverName - Temporary server name (not persisted) will be replaced by the nano id generated by the db method
|
|
|
|
|
* @param config - Server configuration to store
|
|
|
|
|
* @param userId - ID of the user creating the server (required)
|
|
|
|
|
* @returns The created server result with serverName and config (including dbId)
|
|
|
|
|
* @throws Error if userId is not provided
|
|
|
|
|
*/
|
|
|
|
|
public async add(
|
|
|
|
|
serverName: string,
|
|
|
|
|
config: ParsedServerConfig,
|
|
|
|
|
userId?: string,
|
|
|
|
|
): Promise<AddServerResult> {
|
|
|
|
|
logger.debug(
|
|
|
|
|
`[ServerConfigsDB.add] Starting Creating server with temp servername: ${serverName} for the user with the ID ${userId}`,
|
|
|
|
|
);
|
|
|
|
|
if (!userId) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
'[ServerConfigsDB.add] User ID is required to create a database-stored MCP server.',
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-01-23 09:06:29 -05:00
|
|
|
|
|
|
|
|
const sanitizedConfig = {
|
|
|
|
|
...config,
|
|
|
|
|
headers: sanitizeCredentialPlaceholders(
|
|
|
|
|
(config as ParsedServerConfig & { headers?: Record<string, string> }).headers,
|
|
|
|
|
),
|
|
|
|
|
} as ParsedServerConfig;
|
|
|
|
|
|
|
|
|
|
/** Transformed user-provided API key config (adds customUserVars and headers) */
|
|
|
|
|
const transformedConfig = this.transformUserApiKeyConfig(sanitizedConfig);
|
|
|
|
|
/** Encrypted config before storing in database */
|
2025-12-12 19:51:49 +01:00
|
|
|
const encryptedConfig = await this.encryptConfig(transformedConfig);
|
2025-12-10 02:10:56 +01:00
|
|
|
const createdServer = await this._dbMethods.createMCPServer({
|
|
|
|
|
config: encryptedConfig,
|
|
|
|
|
author: userId,
|
|
|
|
|
});
|
2025-12-04 21:37:23 +01:00
|
|
|
await this._aclService.grantPermission({
|
|
|
|
|
principalType: PrincipalType.USER,
|
|
|
|
|
principalId: userId,
|
|
|
|
|
resourceType: ResourceType.MCPSERVER,
|
|
|
|
|
resourceId: createdServer._id,
|
|
|
|
|
accessRoleId: AccessRoleIds.MCPSERVER_OWNER,
|
|
|
|
|
grantedBy: userId,
|
|
|
|
|
});
|
|
|
|
|
return {
|
|
|
|
|
serverName: createdServer.serverName,
|
2025-12-10 02:10:56 +01:00
|
|
|
config: await this.mapDBServerToParsedConfig(createdServer),
|
2025-12-04 21:37:23 +01:00
|
|
|
};
|
2025-11-28 16:07:09 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-04 21:37:23 +01:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param serverName mcp server unique identifier "serverName"
|
|
|
|
|
* @param config new Configuration to update
|
|
|
|
|
* @param userId user id required to update DB server config
|
|
|
|
|
*/
|
2025-11-28 16:07:09 +01:00
|
|
|
public async update(
|
|
|
|
|
serverName: string,
|
|
|
|
|
config: ParsedServerConfig,
|
|
|
|
|
userId?: string,
|
|
|
|
|
): Promise<void> {
|
2025-12-04 21:37:23 +01:00
|
|
|
if (!userId) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
'[ServerConfigsDB.update] User ID is required to update a database-stored MCP server.',
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-12 21:04:25 -05:00
|
|
|
const existingServer = await this._dbMethods.findMCPServerByServerName(serverName);
|
2025-12-10 02:10:56 +01:00
|
|
|
|
2026-01-23 09:06:29 -05:00
|
|
|
let configToSave: ParsedServerConfig = {
|
|
|
|
|
...config,
|
|
|
|
|
headers: sanitizeCredentialPlaceholders(
|
|
|
|
|
(config as ParsedServerConfig & { headers?: Record<string, string> }).headers,
|
|
|
|
|
),
|
|
|
|
|
} as ParsedServerConfig;
|
|
|
|
|
|
|
|
|
|
/** Transformed user-provided API key config (adds customUserVars and headers) */
|
2025-12-12 19:51:49 +01:00
|
|
|
configToSave = this.transformUserApiKeyConfig(configToSave);
|
|
|
|
|
|
2026-01-23 09:06:29 -05:00
|
|
|
/** Encrypted config before storing in database */
|
2025-12-12 19:51:49 +01:00
|
|
|
configToSave = await this.encryptConfig(configToSave);
|
|
|
|
|
|
2025-12-10 02:10:56 +01:00
|
|
|
if (!config.oauth?.client_secret && existingServer?.config?.oauth?.client_secret) {
|
|
|
|
|
configToSave = {
|
2025-12-12 19:51:49 +01:00
|
|
|
...configToSave,
|
2025-12-04 21:37:23 +01:00
|
|
|
oauth: {
|
2025-12-12 19:51:49 +01:00
|
|
|
...configToSave.oauth,
|
2025-12-04 21:37:23 +01:00
|
|
|
client_secret: existingServer.config.oauth.client_secret,
|
|
|
|
|
},
|
|
|
|
|
};
|
2025-12-12 19:51:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
config.apiKey?.source === 'admin' &&
|
|
|
|
|
!config.apiKey?.key &&
|
|
|
|
|
existingServer?.config?.apiKey?.source === 'admin' &&
|
|
|
|
|
existingServer?.config?.apiKey?.key
|
|
|
|
|
) {
|
|
|
|
|
configToSave = {
|
|
|
|
|
...configToSave,
|
|
|
|
|
apiKey: {
|
|
|
|
|
source: configToSave.apiKey!.source,
|
|
|
|
|
authorization_type: configToSave.apiKey!.authorization_type,
|
|
|
|
|
custom_header: configToSave.apiKey?.custom_header,
|
|
|
|
|
key: existingServer.config.apiKey.key,
|
|
|
|
|
},
|
|
|
|
|
};
|
2025-12-04 21:37:23 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-10 02:10:56 +01:00
|
|
|
await this._dbMethods.updateMCPServer(serverName, { config: configToSave });
|
2025-11-28 16:07:09 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-04 21:37:23 +01:00
|
|
|
/**
|
|
|
|
|
* Deletes an MCP server and removes all associated ACL entries.
|
|
|
|
|
* @param serverName - The serverName of the server to remove
|
|
|
|
|
* @param userId - User performing the deletion (for logging)
|
|
|
|
|
*/
|
2025-11-28 16:07:09 +01:00
|
|
|
public async remove(serverName: string, userId?: string): Promise<void> {
|
2025-12-04 21:37:23 +01:00
|
|
|
logger.debug(`[ServerConfigsDB.remove] removing ${serverName}. UserId: ${userId}`);
|
|
|
|
|
const deletedServer = await this._dbMethods.deleteMCPServer(serverName);
|
|
|
|
|
if (deletedServer && deletedServer._id) {
|
|
|
|
|
logger.debug(`[ServerConfigsDB.remove] removing all permissions entries of ${serverName}.`);
|
|
|
|
|
await this._aclService.removeAllPermissions({
|
|
|
|
|
resourceType: ResourceType.MCPSERVER,
|
|
|
|
|
resourceId: deletedServer._id!,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
logger.warn(`[ServerConfigsDB.remove] server with serverName ${serverName} does not exist`);
|
2025-11-28 16:07:09 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-04 21:37:23 +01:00
|
|
|
/**
|
|
|
|
|
* Retrieves a single MCP server configuration by its serverName.
|
|
|
|
|
* @param serverName - The serverName of the server to retrieve
|
|
|
|
|
* @param userId - the user id provide the scope of the request. If the user Id is not provided, only publicly visible servers are returned.
|
|
|
|
|
* @returns The parsed server config or undefined if not found. If accessed via agent, consumeOnly will be true.
|
|
|
|
|
*/
|
2025-11-28 16:07:09 +01:00
|
|
|
public async get(serverName: string, userId?: string): Promise<ParsedServerConfig | undefined> {
|
2026-01-12 21:04:25 -05:00
|
|
|
const server = await this._dbMethods.findMCPServerByServerName(serverName);
|
2025-12-04 21:37:23 +01:00
|
|
|
if (!server) return undefined;
|
|
|
|
|
|
|
|
|
|
if (!userId) {
|
|
|
|
|
const directlyAccessibleMCPIds = (
|
|
|
|
|
await this._aclService.findPubliclyAccessibleResources({
|
|
|
|
|
resourceType: ResourceType.MCPSERVER,
|
|
|
|
|
requiredPermissions: PermissionBits.VIEW,
|
|
|
|
|
})
|
|
|
|
|
).map((id) => id.toString());
|
|
|
|
|
if (directlyAccessibleMCPIds.indexOf(server._id.toString()) > -1) {
|
2025-12-10 02:10:56 +01:00
|
|
|
return await this.mapDBServerToParsedConfig(server);
|
2025-12-04 21:37:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const hasAgentAccess = await this.hasAccessViaAgent(serverName);
|
|
|
|
|
if (hasAgentAccess) {
|
|
|
|
|
logger.debug(
|
|
|
|
|
`[ServerConfigsDB.get] accessing ${serverName} via public agent (consumeOnly)`,
|
|
|
|
|
);
|
|
|
|
|
return {
|
2025-12-10 02:10:56 +01:00
|
|
|
...(await this.mapDBServerToParsedConfig(server)),
|
2025-12-04 21:37:23 +01:00
|
|
|
consumeOnly: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const userHasDirectAccess = await this._aclService.checkPermission({
|
|
|
|
|
userId,
|
|
|
|
|
resourceType: ResourceType.MCPSERVER,
|
|
|
|
|
requiredPermission: PermissionBits.VIEW,
|
|
|
|
|
resourceId: server._id,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (userHasDirectAccess) {
|
|
|
|
|
logger.debug(
|
|
|
|
|
`[ServerConfigsDB.get] getting ${serverName} for user with the UserId: ${userId}`,
|
|
|
|
|
);
|
2025-12-10 02:10:56 +01:00
|
|
|
return await this.mapDBServerToParsedConfig(server);
|
2025-12-04 21:37:23 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-23 09:06:29 -05:00
|
|
|
/** Check agent access (user can VIEW an agent that has this MCP server) */
|
2025-12-04 21:37:23 +01:00
|
|
|
const hasAgentAccess = await this.hasAccessViaAgent(serverName, userId);
|
|
|
|
|
if (hasAgentAccess) {
|
|
|
|
|
logger.debug(
|
|
|
|
|
`[ServerConfigsDB.get] user ${userId} accessing ${serverName} via agent (consumeOnly)`,
|
|
|
|
|
);
|
|
|
|
|
return {
|
2025-12-10 02:10:56 +01:00
|
|
|
...(await this.mapDBServerToParsedConfig(server)),
|
2025-12-04 21:37:23 +01:00
|
|
|
consumeOnly: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return undefined;
|
2025-11-28 16:07:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return all DB stored configs (scoped by user Id if provided)
|
|
|
|
|
* @param userId optional user id. if not provided only publicly shared mcp configs will be returned
|
|
|
|
|
* @returns record of parsed configs
|
|
|
|
|
*/
|
|
|
|
|
public async getAll(userId?: string): Promise<Record<string, ParsedServerConfig>> {
|
2025-12-04 21:37:23 +01:00
|
|
|
let directlyAccessibleMCPIds: Types.ObjectId[] = [];
|
|
|
|
|
if (!userId) {
|
|
|
|
|
logger.debug(`[ServerConfigsDB.getAll] fetching all publicly shared mcp servers`);
|
|
|
|
|
directlyAccessibleMCPIds = await this._aclService.findPubliclyAccessibleResources({
|
|
|
|
|
resourceType: ResourceType.MCPSERVER,
|
|
|
|
|
requiredPermissions: PermissionBits.VIEW,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
logger.debug(
|
|
|
|
|
`[ServerConfigsDB.getAll] fetching mcp servers directly shared with the user with ID: ${userId}`,
|
|
|
|
|
);
|
|
|
|
|
directlyAccessibleMCPIds = await this._aclService.findAccessibleResources({
|
|
|
|
|
userId,
|
|
|
|
|
requiredPermissions: PermissionBits.VIEW,
|
|
|
|
|
resourceType: ResourceType.MCPSERVER,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let agentMCPServerNames: string[] = [];
|
|
|
|
|
let accessibleAgentIds: Types.ObjectId[] = [];
|
|
|
|
|
|
|
|
|
|
if (!userId) {
|
|
|
|
|
accessibleAgentIds = await this._aclService.findPubliclyAccessibleResources({
|
|
|
|
|
resourceType: ResourceType.AGENT,
|
|
|
|
|
requiredPermissions: PermissionBits.VIEW,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
accessibleAgentIds = await this._aclService.findAccessibleResources({
|
|
|
|
|
userId,
|
|
|
|
|
requiredPermissions: PermissionBits.VIEW,
|
|
|
|
|
resourceType: ResourceType.AGENT,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (accessibleAgentIds.length > 0) {
|
|
|
|
|
const Agent = this._mongoose.model('Agent');
|
|
|
|
|
const agentsWithMCP = await Agent.find(
|
|
|
|
|
{
|
|
|
|
|
_id: { $in: accessibleAgentIds },
|
|
|
|
|
mcpServerNames: { $exists: true, $not: { $size: 0 } },
|
|
|
|
|
},
|
|
|
|
|
{ mcpServerNames: 1 },
|
|
|
|
|
).lean();
|
|
|
|
|
|
|
|
|
|
agentMCPServerNames = [
|
|
|
|
|
...new Set(
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
|
agentsWithMCP.flatMap((a: any) => a.mcpServerNames || []),
|
|
|
|
|
),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const directResults = await this._dbMethods.getListMCPServersByIds({
|
|
|
|
|
ids: directlyAccessibleMCPIds,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const parsedConfigs: Record<string, ParsedServerConfig> = {};
|
2025-12-10 02:10:56 +01:00
|
|
|
const directData = directResults.data || [];
|
📦 refactor: Consolidate DB models, encapsulating Mongoose usage in `data-schemas` (#11830)
* chore: move database model methods to /packages/data-schemas
* chore: add TypeScript ESLint rule to warn on unused variables
* refactor: model imports to streamline access
- Consolidated model imports across various files to improve code organization and reduce redundancy.
- Updated imports for models such as Assistant, Message, Conversation, and others to a unified import path.
- Adjusted middleware and service files to reflect the new import structure, ensuring functionality remains intact.
- Enhanced test files to align with the new import paths, maintaining test coverage and integrity.
* chore: migrate database models to packages/data-schemas and refactor all direct Mongoose Model usage outside of data-schemas
* test: update agent model mocks in unit tests
- Added `getAgent` mock to `client.test.js` to enhance test coverage for agent-related functionality.
- Removed redundant `getAgent` and `getAgents` mocks from `openai.spec.js` and `responses.unit.spec.js` to streamline test setup and reduce duplication.
- Ensured consistency in agent mock implementations across test files.
* fix: update types in data-schemas
* refactor: enhance type definitions in transaction and spending methods
- Updated type definitions in `checkBalance.ts` to use specific request and response types.
- Refined `spendTokens.ts` to utilize a new `SpendTxData` interface for better clarity and type safety.
- Improved transaction handling in `transaction.ts` by introducing `TransactionResult` and `TxData` interfaces, ensuring consistent data structures across methods.
- Adjusted unit tests in `transaction.spec.ts` to accommodate new type definitions and enhance robustness.
* refactor: streamline model imports and enhance code organization
- Consolidated model imports across various controllers and services to a unified import path, improving code clarity and reducing redundancy.
- Updated multiple files to reflect the new import structure, ensuring all functionalities remain intact.
- Enhanced overall code organization by removing duplicate import statements and optimizing the usage of model methods.
* feat: implement loadAddedAgent and refactor agent loading logic
- Introduced `loadAddedAgent` function to handle loading agents from added conversations, supporting multi-convo parallel execution.
- Created a new `load.ts` file to encapsulate agent loading functionalities, including `loadEphemeralAgent` and `loadAgent`.
- Updated the `index.ts` file to export the new `load` module instead of the deprecated `loadAgent`.
- Enhanced type definitions and improved error handling in the agent loading process.
- Adjusted unit tests to reflect changes in the agent loading structure and ensure comprehensive coverage.
* refactor: enhance balance handling with new update interface
- Introduced `IBalanceUpdate` interface to streamline balance update operations across the codebase.
- Updated `upsertBalanceFields` method signatures in `balance.ts`, `transaction.ts`, and related tests to utilize the new interface for improved type safety.
- Adjusted type imports in `balance.spec.ts` to include `IBalanceUpdate`, ensuring consistency in balance management functionalities.
- Enhanced overall code clarity and maintainability by refining type definitions related to balance operations.
* feat: add unit tests for loadAgent functionality and enhance agent loading logic
- Introduced comprehensive unit tests for the `loadAgent` function, covering various scenarios including null and empty agent IDs, loading of ephemeral agents, and permission checks.
- Enhanced the `initializeClient` function by moving `getConvoFiles` to the correct position in the database method exports, ensuring proper functionality.
- Improved test coverage for agent loading, including handling of non-existent agents and user permissions.
* chore: reorder memory method exports for consistency
- Moved `deleteAllUserMemories` to the correct position in the exported memory methods, ensuring a consistent and logical order of method exports in `memory.ts`.
2026-02-17 18:23:44 -05:00
|
|
|
const directServerNames = new Set(directData.map((s: MCPServerDocument) => s.serverName));
|
2025-12-04 21:37:23 +01:00
|
|
|
|
2025-12-10 02:10:56 +01:00
|
|
|
const directParsed = await Promise.all(
|
📦 refactor: Consolidate DB models, encapsulating Mongoose usage in `data-schemas` (#11830)
* chore: move database model methods to /packages/data-schemas
* chore: add TypeScript ESLint rule to warn on unused variables
* refactor: model imports to streamline access
- Consolidated model imports across various files to improve code organization and reduce redundancy.
- Updated imports for models such as Assistant, Message, Conversation, and others to a unified import path.
- Adjusted middleware and service files to reflect the new import structure, ensuring functionality remains intact.
- Enhanced test files to align with the new import paths, maintaining test coverage and integrity.
* chore: migrate database models to packages/data-schemas and refactor all direct Mongoose Model usage outside of data-schemas
* test: update agent model mocks in unit tests
- Added `getAgent` mock to `client.test.js` to enhance test coverage for agent-related functionality.
- Removed redundant `getAgent` and `getAgents` mocks from `openai.spec.js` and `responses.unit.spec.js` to streamline test setup and reduce duplication.
- Ensured consistency in agent mock implementations across test files.
* fix: update types in data-schemas
* refactor: enhance type definitions in transaction and spending methods
- Updated type definitions in `checkBalance.ts` to use specific request and response types.
- Refined `spendTokens.ts` to utilize a new `SpendTxData` interface for better clarity and type safety.
- Improved transaction handling in `transaction.ts` by introducing `TransactionResult` and `TxData` interfaces, ensuring consistent data structures across methods.
- Adjusted unit tests in `transaction.spec.ts` to accommodate new type definitions and enhance robustness.
* refactor: streamline model imports and enhance code organization
- Consolidated model imports across various controllers and services to a unified import path, improving code clarity and reducing redundancy.
- Updated multiple files to reflect the new import structure, ensuring all functionalities remain intact.
- Enhanced overall code organization by removing duplicate import statements and optimizing the usage of model methods.
* feat: implement loadAddedAgent and refactor agent loading logic
- Introduced `loadAddedAgent` function to handle loading agents from added conversations, supporting multi-convo parallel execution.
- Created a new `load.ts` file to encapsulate agent loading functionalities, including `loadEphemeralAgent` and `loadAgent`.
- Updated the `index.ts` file to export the new `load` module instead of the deprecated `loadAgent`.
- Enhanced type definitions and improved error handling in the agent loading process.
- Adjusted unit tests to reflect changes in the agent loading structure and ensure comprehensive coverage.
* refactor: enhance balance handling with new update interface
- Introduced `IBalanceUpdate` interface to streamline balance update operations across the codebase.
- Updated `upsertBalanceFields` method signatures in `balance.ts`, `transaction.ts`, and related tests to utilize the new interface for improved type safety.
- Adjusted type imports in `balance.spec.ts` to include `IBalanceUpdate`, ensuring consistency in balance management functionalities.
- Enhanced overall code clarity and maintainability by refining type definitions related to balance operations.
* feat: add unit tests for loadAgent functionality and enhance agent loading logic
- Introduced comprehensive unit tests for the `loadAgent` function, covering various scenarios including null and empty agent IDs, loading of ephemeral agents, and permission checks.
- Enhanced the `initializeClient` function by moving `getConvoFiles` to the correct position in the database method exports, ensuring proper functionality.
- Improved test coverage for agent loading, including handling of non-existent agents and user permissions.
* chore: reorder memory method exports for consistency
- Moved `deleteAllUserMemories` to the correct position in the exported memory methods, ensuring a consistent and logical order of method exports in `memory.ts`.
2026-02-17 18:23:44 -05:00
|
|
|
directData.map((s: MCPServerDocument) => this.mapDBServerToParsedConfig(s)),
|
2025-12-10 02:10:56 +01:00
|
|
|
);
|
📦 refactor: Consolidate DB models, encapsulating Mongoose usage in `data-schemas` (#11830)
* chore: move database model methods to /packages/data-schemas
* chore: add TypeScript ESLint rule to warn on unused variables
* refactor: model imports to streamline access
- Consolidated model imports across various files to improve code organization and reduce redundancy.
- Updated imports for models such as Assistant, Message, Conversation, and others to a unified import path.
- Adjusted middleware and service files to reflect the new import structure, ensuring functionality remains intact.
- Enhanced test files to align with the new import paths, maintaining test coverage and integrity.
* chore: migrate database models to packages/data-schemas and refactor all direct Mongoose Model usage outside of data-schemas
* test: update agent model mocks in unit tests
- Added `getAgent` mock to `client.test.js` to enhance test coverage for agent-related functionality.
- Removed redundant `getAgent` and `getAgents` mocks from `openai.spec.js` and `responses.unit.spec.js` to streamline test setup and reduce duplication.
- Ensured consistency in agent mock implementations across test files.
* fix: update types in data-schemas
* refactor: enhance type definitions in transaction and spending methods
- Updated type definitions in `checkBalance.ts` to use specific request and response types.
- Refined `spendTokens.ts` to utilize a new `SpendTxData` interface for better clarity and type safety.
- Improved transaction handling in `transaction.ts` by introducing `TransactionResult` and `TxData` interfaces, ensuring consistent data structures across methods.
- Adjusted unit tests in `transaction.spec.ts` to accommodate new type definitions and enhance robustness.
* refactor: streamline model imports and enhance code organization
- Consolidated model imports across various controllers and services to a unified import path, improving code clarity and reducing redundancy.
- Updated multiple files to reflect the new import structure, ensuring all functionalities remain intact.
- Enhanced overall code organization by removing duplicate import statements and optimizing the usage of model methods.
* feat: implement loadAddedAgent and refactor agent loading logic
- Introduced `loadAddedAgent` function to handle loading agents from added conversations, supporting multi-convo parallel execution.
- Created a new `load.ts` file to encapsulate agent loading functionalities, including `loadEphemeralAgent` and `loadAgent`.
- Updated the `index.ts` file to export the new `load` module instead of the deprecated `loadAgent`.
- Enhanced type definitions and improved error handling in the agent loading process.
- Adjusted unit tests to reflect changes in the agent loading structure and ensure comprehensive coverage.
* refactor: enhance balance handling with new update interface
- Introduced `IBalanceUpdate` interface to streamline balance update operations across the codebase.
- Updated `upsertBalanceFields` method signatures in `balance.ts`, `transaction.ts`, and related tests to utilize the new interface for improved type safety.
- Adjusted type imports in `balance.spec.ts` to include `IBalanceUpdate`, ensuring consistency in balance management functionalities.
- Enhanced overall code clarity and maintainability by refining type definitions related to balance operations.
* feat: add unit tests for loadAgent functionality and enhance agent loading logic
- Introduced comprehensive unit tests for the `loadAgent` function, covering various scenarios including null and empty agent IDs, loading of ephemeral agents, and permission checks.
- Enhanced the `initializeClient` function by moving `getConvoFiles` to the correct position in the database method exports, ensuring proper functionality.
- Improved test coverage for agent loading, including handling of non-existent agents and user permissions.
* chore: reorder memory method exports for consistency
- Moved `deleteAllUserMemories` to the correct position in the exported memory methods, ensuring a consistent and logical order of method exports in `memory.ts`.
2026-02-17 18:23:44 -05:00
|
|
|
directData.forEach((s: MCPServerDocument, i: number) => {
|
2025-12-10 02:10:56 +01:00
|
|
|
parsedConfigs[s.serverName] = directParsed[i];
|
|
|
|
|
});
|
2025-12-04 21:37:23 +01:00
|
|
|
|
|
|
|
|
const agentOnlyServerNames = agentMCPServerNames.filter((name) => !directServerNames.has(name));
|
|
|
|
|
|
|
|
|
|
if (agentOnlyServerNames.length > 0) {
|
|
|
|
|
const agentServers = await this._dbMethods.getListMCPServersByNames({
|
|
|
|
|
names: agentOnlyServerNames,
|
|
|
|
|
});
|
|
|
|
|
|
2025-12-10 02:10:56 +01:00
|
|
|
const agentData = agentServers.data || [];
|
|
|
|
|
const agentParsed = await Promise.all(
|
📦 refactor: Consolidate DB models, encapsulating Mongoose usage in `data-schemas` (#11830)
* chore: move database model methods to /packages/data-schemas
* chore: add TypeScript ESLint rule to warn on unused variables
* refactor: model imports to streamline access
- Consolidated model imports across various files to improve code organization and reduce redundancy.
- Updated imports for models such as Assistant, Message, Conversation, and others to a unified import path.
- Adjusted middleware and service files to reflect the new import structure, ensuring functionality remains intact.
- Enhanced test files to align with the new import paths, maintaining test coverage and integrity.
* chore: migrate database models to packages/data-schemas and refactor all direct Mongoose Model usage outside of data-schemas
* test: update agent model mocks in unit tests
- Added `getAgent` mock to `client.test.js` to enhance test coverage for agent-related functionality.
- Removed redundant `getAgent` and `getAgents` mocks from `openai.spec.js` and `responses.unit.spec.js` to streamline test setup and reduce duplication.
- Ensured consistency in agent mock implementations across test files.
* fix: update types in data-schemas
* refactor: enhance type definitions in transaction and spending methods
- Updated type definitions in `checkBalance.ts` to use specific request and response types.
- Refined `spendTokens.ts` to utilize a new `SpendTxData` interface for better clarity and type safety.
- Improved transaction handling in `transaction.ts` by introducing `TransactionResult` and `TxData` interfaces, ensuring consistent data structures across methods.
- Adjusted unit tests in `transaction.spec.ts` to accommodate new type definitions and enhance robustness.
* refactor: streamline model imports and enhance code organization
- Consolidated model imports across various controllers and services to a unified import path, improving code clarity and reducing redundancy.
- Updated multiple files to reflect the new import structure, ensuring all functionalities remain intact.
- Enhanced overall code organization by removing duplicate import statements and optimizing the usage of model methods.
* feat: implement loadAddedAgent and refactor agent loading logic
- Introduced `loadAddedAgent` function to handle loading agents from added conversations, supporting multi-convo parallel execution.
- Created a new `load.ts` file to encapsulate agent loading functionalities, including `loadEphemeralAgent` and `loadAgent`.
- Updated the `index.ts` file to export the new `load` module instead of the deprecated `loadAgent`.
- Enhanced type definitions and improved error handling in the agent loading process.
- Adjusted unit tests to reflect changes in the agent loading structure and ensure comprehensive coverage.
* refactor: enhance balance handling with new update interface
- Introduced `IBalanceUpdate` interface to streamline balance update operations across the codebase.
- Updated `upsertBalanceFields` method signatures in `balance.ts`, `transaction.ts`, and related tests to utilize the new interface for improved type safety.
- Adjusted type imports in `balance.spec.ts` to include `IBalanceUpdate`, ensuring consistency in balance management functionalities.
- Enhanced overall code clarity and maintainability by refining type definitions related to balance operations.
* feat: add unit tests for loadAgent functionality and enhance agent loading logic
- Introduced comprehensive unit tests for the `loadAgent` function, covering various scenarios including null and empty agent IDs, loading of ephemeral agents, and permission checks.
- Enhanced the `initializeClient` function by moving `getConvoFiles` to the correct position in the database method exports, ensuring proper functionality.
- Improved test coverage for agent loading, including handling of non-existent agents and user permissions.
* chore: reorder memory method exports for consistency
- Moved `deleteAllUserMemories` to the correct position in the exported memory methods, ensuring a consistent and logical order of method exports in `memory.ts`.
2026-02-17 18:23:44 -05:00
|
|
|
agentData.map((s: MCPServerDocument) => this.mapDBServerToParsedConfig(s)),
|
2025-12-10 02:10:56 +01:00
|
|
|
);
|
📦 refactor: Consolidate DB models, encapsulating Mongoose usage in `data-schemas` (#11830)
* chore: move database model methods to /packages/data-schemas
* chore: add TypeScript ESLint rule to warn on unused variables
* refactor: model imports to streamline access
- Consolidated model imports across various files to improve code organization and reduce redundancy.
- Updated imports for models such as Assistant, Message, Conversation, and others to a unified import path.
- Adjusted middleware and service files to reflect the new import structure, ensuring functionality remains intact.
- Enhanced test files to align with the new import paths, maintaining test coverage and integrity.
* chore: migrate database models to packages/data-schemas and refactor all direct Mongoose Model usage outside of data-schemas
* test: update agent model mocks in unit tests
- Added `getAgent` mock to `client.test.js` to enhance test coverage for agent-related functionality.
- Removed redundant `getAgent` and `getAgents` mocks from `openai.spec.js` and `responses.unit.spec.js` to streamline test setup and reduce duplication.
- Ensured consistency in agent mock implementations across test files.
* fix: update types in data-schemas
* refactor: enhance type definitions in transaction and spending methods
- Updated type definitions in `checkBalance.ts` to use specific request and response types.
- Refined `spendTokens.ts` to utilize a new `SpendTxData` interface for better clarity and type safety.
- Improved transaction handling in `transaction.ts` by introducing `TransactionResult` and `TxData` interfaces, ensuring consistent data structures across methods.
- Adjusted unit tests in `transaction.spec.ts` to accommodate new type definitions and enhance robustness.
* refactor: streamline model imports and enhance code organization
- Consolidated model imports across various controllers and services to a unified import path, improving code clarity and reducing redundancy.
- Updated multiple files to reflect the new import structure, ensuring all functionalities remain intact.
- Enhanced overall code organization by removing duplicate import statements and optimizing the usage of model methods.
* feat: implement loadAddedAgent and refactor agent loading logic
- Introduced `loadAddedAgent` function to handle loading agents from added conversations, supporting multi-convo parallel execution.
- Created a new `load.ts` file to encapsulate agent loading functionalities, including `loadEphemeralAgent` and `loadAgent`.
- Updated the `index.ts` file to export the new `load` module instead of the deprecated `loadAgent`.
- Enhanced type definitions and improved error handling in the agent loading process.
- Adjusted unit tests to reflect changes in the agent loading structure and ensure comprehensive coverage.
* refactor: enhance balance handling with new update interface
- Introduced `IBalanceUpdate` interface to streamline balance update operations across the codebase.
- Updated `upsertBalanceFields` method signatures in `balance.ts`, `transaction.ts`, and related tests to utilize the new interface for improved type safety.
- Adjusted type imports in `balance.spec.ts` to include `IBalanceUpdate`, ensuring consistency in balance management functionalities.
- Enhanced overall code clarity and maintainability by refining type definitions related to balance operations.
* feat: add unit tests for loadAgent functionality and enhance agent loading logic
- Introduced comprehensive unit tests for the `loadAgent` function, covering various scenarios including null and empty agent IDs, loading of ephemeral agents, and permission checks.
- Enhanced the `initializeClient` function by moving `getConvoFiles` to the correct position in the database method exports, ensuring proper functionality.
- Improved test coverage for agent loading, including handling of non-existent agents and user permissions.
* chore: reorder memory method exports for consistency
- Moved `deleteAllUserMemories` to the correct position in the exported memory methods, ensuring a consistent and logical order of method exports in `memory.ts`.
2026-02-17 18:23:44 -05:00
|
|
|
agentData.forEach((s: MCPServerDocument, i: number) => {
|
2025-12-10 02:10:56 +01:00
|
|
|
parsedConfigs[s.serverName] = { ...agentParsed[i], consumeOnly: true };
|
|
|
|
|
});
|
2025-12-04 21:37:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parsedConfigs;
|
2025-11-28 16:07:09 +01:00
|
|
|
}
|
|
|
|
|
|
2025-12-04 21:37:23 +01:00
|
|
|
/** No-op for DB storage; logs a warning if called. */
|
2025-11-28 16:07:09 +01:00
|
|
|
public async reset(): Promise<void> {
|
|
|
|
|
logger.warn('Attempt to reset the DB config storage');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-12-04 21:37:23 +01:00
|
|
|
|
2025-12-10 02:10:56 +01:00
|
|
|
/**
|
|
|
|
|
* Maps a MongoDB server document to the ParsedServerConfig format.
|
|
|
|
|
* Decrypts sensitive fields (oauth.client_secret) after retrieval.
|
|
|
|
|
*/
|
|
|
|
|
private async mapDBServerToParsedConfig(
|
|
|
|
|
serverDBDoc: MCPServerDocument,
|
|
|
|
|
): Promise<ParsedServerConfig> {
|
|
|
|
|
const config: ParsedServerConfig = {
|
2025-12-04 21:37:23 +01:00
|
|
|
...serverDBDoc.config,
|
|
|
|
|
dbId: (serverDBDoc._id as Types.ObjectId).toString(),
|
|
|
|
|
updatedAt: serverDBDoc.updatedAt?.getTime(),
|
|
|
|
|
};
|
2025-12-10 02:10:56 +01:00
|
|
|
return await this.decryptConfig(config);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-12 19:51:49 +01:00
|
|
|
/**
|
|
|
|
|
* Transforms user-provided API key config by auto-generating customUserVars and headers.
|
|
|
|
|
* This is a config transformation, not encryption.
|
|
|
|
|
* @param config - The server config to transform
|
|
|
|
|
* @returns The transformed config with customUserVars and headers set up
|
|
|
|
|
*/
|
|
|
|
|
private transformUserApiKeyConfig(config: ParsedServerConfig): ParsedServerConfig {
|
|
|
|
|
if (!config.apiKey || config.apiKey.source !== 'user') {
|
|
|
|
|
return config;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const result = { ...config };
|
|
|
|
|
const headerName =
|
|
|
|
|
result.apiKey!.authorization_type === 'custom'
|
|
|
|
|
? result.apiKey!.custom_header || 'X-Api-Key'
|
|
|
|
|
: 'Authorization';
|
|
|
|
|
|
|
|
|
|
let headerValue: string;
|
|
|
|
|
if (result.apiKey!.authorization_type === 'basic') {
|
|
|
|
|
headerValue = 'Basic {{MCP_API_KEY}}';
|
|
|
|
|
} else if (result.apiKey!.authorization_type === 'bearer') {
|
|
|
|
|
headerValue = 'Bearer {{MCP_API_KEY}}';
|
|
|
|
|
} else {
|
|
|
|
|
headerValue = '{{MCP_API_KEY}}';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.customUserVars = {
|
|
|
|
|
...result.customUserVars,
|
|
|
|
|
MCP_API_KEY: {
|
|
|
|
|
title: 'API Key',
|
|
|
|
|
description: 'Your API key for this MCP server',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
2026-01-23 09:06:29 -05:00
|
|
|
/** Cast to access headers property (not available on Stdio type) */
|
2025-12-12 19:51:49 +01:00
|
|
|
const resultWithHeaders = result as ParsedServerConfig & {
|
|
|
|
|
headers?: Record<string, string>;
|
|
|
|
|
};
|
|
|
|
|
resultWithHeaders.headers = {
|
|
|
|
|
...resultWithHeaders.headers,
|
|
|
|
|
[headerName]: headerValue,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Remove key field since it's user-provided (destructure to omit, not set to undefined)
|
🗝️ feat: Credential Variables for DB-Sourced MCP Servers (#12044)
* feat: Allow Credential Variables in Headers for DB-sourced MCP Servers
- Removed the hasCustomUserVars check from ToolService.js, directly retrieving userMCPAuthMap.
- Updated MCPConnectionFactory and related classes to include a dbSourced flag for better handling of database-sourced configurations.
- Added integration tests to ensure proper behavior of dbSourced servers, verifying that sensitive placeholders are not resolved while allowing customUserVars.
- Adjusted various MCP-related files to accommodate the new dbSourced logic, ensuring consistent handling across the codebase.
* chore: MCPConnectionFactory Tests with Additional Flow Metadata for typing
- Updated MCPConnectionFactory tests to include new fields in flowMetadata: serverUrl and state.
- Enhanced mockFlowData in multiple test cases to reflect the updated structure, ensuring comprehensive coverage of the OAuth flow scenarios.
- Added authorization_endpoint to metadata in the test setup for improved validation of the OAuth process.
* refactor: Simplify MCPManager Configuration Handling
- Removed unnecessary type assertions and streamlined the retrieval of server configuration in MCPManager.
- Enhanced the handling of OAuth and database-sourced flags for improved clarity and efficiency.
- Updated tests to reflect changes in user object structure and ensure proper processing of MCP environment variables.
* refactor: Optimize User MCP Auth Map Retrieval in ToolService
- Introduced conditional loading of userMCPAuthMap based on the presence of MCP-delimited tools, improving efficiency by avoiding unnecessary calls.
- Updated the loadToolDefinitionsWrapper and loadAgentTools functions to reflect this change, enhancing overall performance and clarity.
* test: Add userMCPAuthMap gating tests in ToolService
- Introduced new tests to validate the logic for determining if MCP tools are present in the agent's tool list.
- Implemented various scenarios to ensure accurate detection of MCP tools, including edge cases for empty, undefined, and null tool lists.
- Enhanced clarity and coverage of the ToolService capability checking logic.
* refactor: Enhance MCP Environment Variable Processing
- Simplified the handling of the dbSourced parameter in the processMCPEnv function.
- Introduced a failsafe mechanism to derive dbSourced from options if not explicitly provided, improving robustness and clarity in MCP environment variable processing.
* refactor: Update Regex Patterns for Credential Placeholders in ServerConfigsDB
- Modified regex patterns to include additional credential/env placeholders that should not be allowed in user-provided configurations.
- Clarified comments to emphasize the security risks associated with credential exfiltration when MCP servers are shared between users.
* chore: field order
* refactor: Clean Up dbSourced Parameter Handling in processMCPEnv
- Reintroduced the failsafe mechanism for deriving the dbSourced parameter from options, ensuring clarity and robustness in MCP environment variable processing.
- Enhanced code readability by maintaining consistent comment structure.
* refactor: Update MCPOptions Type to Include Optional dbId
- Modified the processMCPEnv function to extend the MCPOptions type, allowing for an optional dbId property.
- Simplified the logic for deriving the dbSourced parameter by directly checking the dbId property, enhancing code clarity and maintainability.
2026-03-03 18:02:37 -05:00
|
|
|
|
2025-12-12 19:51:49 +01:00
|
|
|
const { key: _removed, ...apiKeyWithoutKey } = result.apiKey!;
|
|
|
|
|
result.apiKey = apiKeyWithoutKey;
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-10 02:10:56 +01:00
|
|
|
/**
|
|
|
|
|
* Encrypts sensitive fields in config before database storage.
|
2025-12-12 19:51:49 +01:00
|
|
|
* Encrypts oauth.client_secret and apiKey.key (when source === 'admin').
|
2025-12-10 02:10:56 +01:00
|
|
|
* Throws on failure to prevent storing plaintext secrets.
|
|
|
|
|
*/
|
|
|
|
|
private async encryptConfig(config: ParsedServerConfig): Promise<ParsedServerConfig> {
|
2025-12-12 19:51:49 +01:00
|
|
|
let result = { ...config };
|
|
|
|
|
|
|
|
|
|
if (result.apiKey?.source === 'admin' && result.apiKey.key) {
|
|
|
|
|
try {
|
|
|
|
|
result.apiKey = {
|
|
|
|
|
...result.apiKey,
|
|
|
|
|
key: await encryptV2(result.apiKey.key),
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error('[ServerConfigsDB.encryptConfig] Failed to encrypt apiKey.key', error);
|
|
|
|
|
throw new Error('Failed to encrypt MCP server configuration');
|
|
|
|
|
}
|
2025-12-10 02:10:56 +01:00
|
|
|
}
|
2025-12-12 19:51:49 +01:00
|
|
|
|
|
|
|
|
if (result.oauth?.client_secret) {
|
|
|
|
|
try {
|
|
|
|
|
result = {
|
|
|
|
|
...result,
|
|
|
|
|
oauth: {
|
|
|
|
|
...result.oauth,
|
|
|
|
|
client_secret: await encryptV2(result.oauth.client_secret),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error('[ServerConfigsDB.encryptConfig] Failed to encrypt client_secret', error);
|
|
|
|
|
throw new Error('Failed to encrypt MCP server configuration');
|
|
|
|
|
}
|
2025-12-10 02:10:56 +01:00
|
|
|
}
|
2025-12-12 19:51:49 +01:00
|
|
|
|
|
|
|
|
return result;
|
2025-12-10 02:10:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Decrypts sensitive fields in config after database retrieval.
|
2025-12-12 19:51:49 +01:00
|
|
|
* Decrypts oauth.client_secret and apiKey.key (when source === 'admin').
|
2025-12-10 02:10:56 +01:00
|
|
|
* Returns config without secret on failure (graceful degradation).
|
|
|
|
|
*/
|
|
|
|
|
private async decryptConfig(config: ParsedServerConfig): Promise<ParsedServerConfig> {
|
2025-12-12 19:51:49 +01:00
|
|
|
let result = { ...config };
|
|
|
|
|
|
|
|
|
|
if (result.apiKey?.source === 'admin' && result.apiKey.key) {
|
|
|
|
|
try {
|
|
|
|
|
result.apiKey = {
|
|
|
|
|
...result.apiKey,
|
|
|
|
|
key: await decryptV2(result.apiKey.key),
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.warn(
|
|
|
|
|
'[ServerConfigsDB.decryptConfig] Failed to decrypt apiKey.key, returning config without key',
|
|
|
|
|
error,
|
|
|
|
|
);
|
🗝️ feat: Credential Variables for DB-Sourced MCP Servers (#12044)
* feat: Allow Credential Variables in Headers for DB-sourced MCP Servers
- Removed the hasCustomUserVars check from ToolService.js, directly retrieving userMCPAuthMap.
- Updated MCPConnectionFactory and related classes to include a dbSourced flag for better handling of database-sourced configurations.
- Added integration tests to ensure proper behavior of dbSourced servers, verifying that sensitive placeholders are not resolved while allowing customUserVars.
- Adjusted various MCP-related files to accommodate the new dbSourced logic, ensuring consistent handling across the codebase.
* chore: MCPConnectionFactory Tests with Additional Flow Metadata for typing
- Updated MCPConnectionFactory tests to include new fields in flowMetadata: serverUrl and state.
- Enhanced mockFlowData in multiple test cases to reflect the updated structure, ensuring comprehensive coverage of the OAuth flow scenarios.
- Added authorization_endpoint to metadata in the test setup for improved validation of the OAuth process.
* refactor: Simplify MCPManager Configuration Handling
- Removed unnecessary type assertions and streamlined the retrieval of server configuration in MCPManager.
- Enhanced the handling of OAuth and database-sourced flags for improved clarity and efficiency.
- Updated tests to reflect changes in user object structure and ensure proper processing of MCP environment variables.
* refactor: Optimize User MCP Auth Map Retrieval in ToolService
- Introduced conditional loading of userMCPAuthMap based on the presence of MCP-delimited tools, improving efficiency by avoiding unnecessary calls.
- Updated the loadToolDefinitionsWrapper and loadAgentTools functions to reflect this change, enhancing overall performance and clarity.
* test: Add userMCPAuthMap gating tests in ToolService
- Introduced new tests to validate the logic for determining if MCP tools are present in the agent's tool list.
- Implemented various scenarios to ensure accurate detection of MCP tools, including edge cases for empty, undefined, and null tool lists.
- Enhanced clarity and coverage of the ToolService capability checking logic.
* refactor: Enhance MCP Environment Variable Processing
- Simplified the handling of the dbSourced parameter in the processMCPEnv function.
- Introduced a failsafe mechanism to derive dbSourced from options if not explicitly provided, improving robustness and clarity in MCP environment variable processing.
* refactor: Update Regex Patterns for Credential Placeholders in ServerConfigsDB
- Modified regex patterns to include additional credential/env placeholders that should not be allowed in user-provided configurations.
- Clarified comments to emphasize the security risks associated with credential exfiltration when MCP servers are shared between users.
* chore: field order
* refactor: Clean Up dbSourced Parameter Handling in processMCPEnv
- Reintroduced the failsafe mechanism for deriving the dbSourced parameter from options, ensuring clarity and robustness in MCP environment variable processing.
- Enhanced code readability by maintaining consistent comment structure.
* refactor: Update MCPOptions Type to Include Optional dbId
- Modified the processMCPEnv function to extend the MCPOptions type, allowing for an optional dbId property.
- Simplified the logic for deriving the dbSourced parameter by directly checking the dbId property, enhancing code clarity and maintainability.
2026-03-03 18:02:37 -05:00
|
|
|
|
2025-12-12 19:51:49 +01:00
|
|
|
const { key: _removedKey, ...apiKeyWithoutKey } = result.apiKey;
|
|
|
|
|
result.apiKey = apiKeyWithoutKey;
|
|
|
|
|
}
|
2025-12-10 02:10:56 +01:00
|
|
|
}
|
2025-12-12 19:51:49 +01:00
|
|
|
|
|
|
|
|
if (result.oauth?.client_secret) {
|
|
|
|
|
const oauthConfig = result.oauth as { client_secret: string } & typeof result.oauth;
|
|
|
|
|
try {
|
|
|
|
|
result = {
|
|
|
|
|
...result,
|
|
|
|
|
oauth: {
|
|
|
|
|
...oauthConfig,
|
|
|
|
|
client_secret: await decryptV2(oauthConfig.client_secret),
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.warn(
|
|
|
|
|
'[ServerConfigsDB.decryptConfig] Failed to decrypt client_secret, returning config without secret',
|
|
|
|
|
error,
|
|
|
|
|
);
|
🗝️ feat: Credential Variables for DB-Sourced MCP Servers (#12044)
* feat: Allow Credential Variables in Headers for DB-sourced MCP Servers
- Removed the hasCustomUserVars check from ToolService.js, directly retrieving userMCPAuthMap.
- Updated MCPConnectionFactory and related classes to include a dbSourced flag for better handling of database-sourced configurations.
- Added integration tests to ensure proper behavior of dbSourced servers, verifying that sensitive placeholders are not resolved while allowing customUserVars.
- Adjusted various MCP-related files to accommodate the new dbSourced logic, ensuring consistent handling across the codebase.
* chore: MCPConnectionFactory Tests with Additional Flow Metadata for typing
- Updated MCPConnectionFactory tests to include new fields in flowMetadata: serverUrl and state.
- Enhanced mockFlowData in multiple test cases to reflect the updated structure, ensuring comprehensive coverage of the OAuth flow scenarios.
- Added authorization_endpoint to metadata in the test setup for improved validation of the OAuth process.
* refactor: Simplify MCPManager Configuration Handling
- Removed unnecessary type assertions and streamlined the retrieval of server configuration in MCPManager.
- Enhanced the handling of OAuth and database-sourced flags for improved clarity and efficiency.
- Updated tests to reflect changes in user object structure and ensure proper processing of MCP environment variables.
* refactor: Optimize User MCP Auth Map Retrieval in ToolService
- Introduced conditional loading of userMCPAuthMap based on the presence of MCP-delimited tools, improving efficiency by avoiding unnecessary calls.
- Updated the loadToolDefinitionsWrapper and loadAgentTools functions to reflect this change, enhancing overall performance and clarity.
* test: Add userMCPAuthMap gating tests in ToolService
- Introduced new tests to validate the logic for determining if MCP tools are present in the agent's tool list.
- Implemented various scenarios to ensure accurate detection of MCP tools, including edge cases for empty, undefined, and null tool lists.
- Enhanced clarity and coverage of the ToolService capability checking logic.
* refactor: Enhance MCP Environment Variable Processing
- Simplified the handling of the dbSourced parameter in the processMCPEnv function.
- Introduced a failsafe mechanism to derive dbSourced from options if not explicitly provided, improving robustness and clarity in MCP environment variable processing.
* refactor: Update Regex Patterns for Credential Placeholders in ServerConfigsDB
- Modified regex patterns to include additional credential/env placeholders that should not be allowed in user-provided configurations.
- Clarified comments to emphasize the security risks associated with credential exfiltration when MCP servers are shared between users.
* chore: field order
* refactor: Clean Up dbSourced Parameter Handling in processMCPEnv
- Reintroduced the failsafe mechanism for deriving the dbSourced parameter from options, ensuring clarity and robustness in MCP environment variable processing.
- Enhanced code readability by maintaining consistent comment structure.
* refactor: Update MCPOptions Type to Include Optional dbId
- Modified the processMCPEnv function to extend the MCPOptions type, allowing for an optional dbId property.
- Simplified the logic for deriving the dbSourced parameter by directly checking the dbId property, enhancing code clarity and maintainability.
2026-03-03 18:02:37 -05:00
|
|
|
|
2025-12-12 19:51:49 +01:00
|
|
|
const { client_secret: _removed, ...oauthWithoutSecret } = oauthConfig;
|
|
|
|
|
result = {
|
|
|
|
|
...result,
|
|
|
|
|
oauth: oauthWithoutSecret,
|
|
|
|
|
};
|
|
|
|
|
}
|
2025-12-10 02:10:56 +01:00
|
|
|
}
|
2025-12-12 19:51:49 +01:00
|
|
|
|
|
|
|
|
return result;
|
2025-12-04 21:37:23 +01:00
|
|
|
}
|
2025-11-28 16:07:09 +01:00
|
|
|
}
|