2025-08-20 12:19:29 -04:00
|
|
|
const { logger } = require('@librechat/data-schemas');
|
|
|
|
|
const { CacheKeys, Constants } = require('librechat-data-provider');
|
|
|
|
|
const { getCachedTools, setCachedTools } = require('./getCachedTools');
|
|
|
|
|
const { getLogStores } = require('~/cache');
|
|
|
|
|
|
|
|
|
|
/**
|
2025-09-21 07:56:40 -04:00
|
|
|
* Updates MCP tools in the cache for a specific server
|
2025-08-20 12:19:29 -04:00
|
|
|
* @param {Object} params - Parameters for updating MCP tools
|
2025-10-30 22:09:56 +01:00
|
|
|
* @param {string} params.userId - User ID for user-specific caching
|
2025-08-20 12:19:29 -04:00
|
|
|
* @param {string} params.serverName - MCP server name
|
|
|
|
|
* @param {Array} params.tools - Array of tool objects from MCP server
|
2025-08-23 03:27:05 -04:00
|
|
|
* @returns {Promise<LCAvailableTools>}
|
2025-08-20 12:19:29 -04:00
|
|
|
*/
|
2025-10-30 22:09:56 +01:00
|
|
|
async function updateMCPServerTools({ userId, serverName, tools }) {
|
2025-08-20 12:19:29 -04:00
|
|
|
try {
|
2025-09-21 07:56:40 -04:00
|
|
|
const serverTools = {};
|
2025-08-20 12:19:29 -04:00
|
|
|
const mcpDelimiter = Constants.mcp_delimiter;
|
|
|
|
|
|
2025-11-18 18:28:57 -05:00
|
|
|
if (tools == null || tools.length === 0) {
|
|
|
|
|
logger.debug(`[MCP Cache] No tools to update for server ${serverName} (user: ${userId})`);
|
|
|
|
|
return serverTools;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-20 12:19:29 -04:00
|
|
|
for (const tool of tools) {
|
2025-09-21 07:56:40 -04:00
|
|
|
const name = `${tool.name}${mcpDelimiter}${serverName}`;
|
|
|
|
|
serverTools[name] = {
|
2025-08-20 12:19:29 -04:00
|
|
|
type: 'function',
|
|
|
|
|
['function']: {
|
|
|
|
|
name,
|
|
|
|
|
description: tool.description,
|
|
|
|
|
parameters: tool.inputSchema,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-30 22:09:56 +01:00
|
|
|
await setCachedTools(serverTools, { userId, serverName });
|
2025-08-20 12:19:29 -04:00
|
|
|
|
|
|
|
|
const cache = getLogStores(CacheKeys.CONFIG_STORE);
|
|
|
|
|
await cache.delete(CacheKeys.TOOLS);
|
2025-10-30 22:09:56 +01:00
|
|
|
logger.debug(
|
|
|
|
|
`[MCP Cache] Updated ${tools.length} tools for server ${serverName} (user: ${userId})`,
|
|
|
|
|
);
|
2025-09-21 07:56:40 -04:00
|
|
|
return serverTools;
|
2025-08-20 12:19:29 -04:00
|
|
|
} catch (error) {
|
2025-10-30 22:09:56 +01:00
|
|
|
logger.error(`[MCP Cache] Failed to update tools for ${serverName} (user: ${userId}):`, error);
|
2025-08-20 12:19:29 -04:00
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Merges app-level tools with global tools
|
|
|
|
|
* @param {import('@librechat/api').LCAvailableTools} appTools
|
|
|
|
|
* @returns {Promise<void>}
|
|
|
|
|
*/
|
|
|
|
|
async function mergeAppTools(appTools) {
|
|
|
|
|
try {
|
|
|
|
|
const count = Object.keys(appTools).length;
|
|
|
|
|
if (!count) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-09-21 07:56:40 -04:00
|
|
|
const cachedTools = await getCachedTools();
|
2025-08-20 12:19:29 -04:00
|
|
|
const mergedTools = { ...cachedTools, ...appTools };
|
2025-09-21 07:56:40 -04:00
|
|
|
await setCachedTools(mergedTools);
|
2025-08-20 12:19:29 -04:00
|
|
|
const cache = getLogStores(CacheKeys.CONFIG_STORE);
|
|
|
|
|
await cache.delete(CacheKeys.TOOLS);
|
|
|
|
|
logger.debug(`Merged ${count} app-level tools`);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error('Failed to merge app-level tools:', error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-09-21 07:56:40 -04:00
|
|
|
* Caches MCP server tools (no longer merges with global)
|
2025-08-20 12:19:29 -04:00
|
|
|
* @param {object} params
|
2025-10-30 22:09:56 +01:00
|
|
|
* @param {string} params.userId - User ID for user-specific caching
|
2025-09-21 07:56:40 -04:00
|
|
|
* @param {string} params.serverName
|
|
|
|
|
* @param {import('@librechat/api').LCAvailableTools} params.serverTools
|
2025-08-20 12:19:29 -04:00
|
|
|
* @returns {Promise<void>}
|
|
|
|
|
*/
|
2025-10-30 22:09:56 +01:00
|
|
|
async function cacheMCPServerTools({ userId, serverName, serverTools }) {
|
2025-08-20 12:19:29 -04:00
|
|
|
try {
|
2025-09-21 07:56:40 -04:00
|
|
|
const count = Object.keys(serverTools).length;
|
2025-08-20 12:19:29 -04:00
|
|
|
if (!count) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-09-21 07:56:40 -04:00
|
|
|
// Only cache server-specific tools, no merging with global
|
2025-10-30 22:09:56 +01:00
|
|
|
await setCachedTools(serverTools, { userId, serverName });
|
|
|
|
|
logger.debug(`Cached ${count} MCP server tools for ${serverName} (user: ${userId})`);
|
2025-08-20 12:19:29 -04:00
|
|
|
} catch (error) {
|
2025-10-30 22:09:56 +01:00
|
|
|
logger.error(`Failed to cache MCP server tools for ${serverName} (user: ${userId}):`, error);
|
2025-08-20 12:19:29 -04:00
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
|
mergeAppTools,
|
2025-09-21 07:56:40 -04:00
|
|
|
cacheMCPServerTools,
|
|
|
|
|
updateMCPServerTools,
|
2025-08-20 12:19:29 -04:00
|
|
|
};
|