mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-19 09:50:15 +01:00
🧰 refactor: Decouple MCP Tools from System Tools (#9748)
This commit is contained in:
parent
9d2aba5df5
commit
386900fb4f
29 changed files with 1032 additions and 1195 deletions
|
|
@ -1,32 +1,37 @@
|
|||
import { useMemo } from 'react';
|
||||
import { Constants, EModelEndpoint } from 'librechat-data-provider';
|
||||
import { Constants } from 'librechat-data-provider';
|
||||
import type { TPlugin } from 'librechat-data-provider';
|
||||
import { useAvailableToolsQuery, useGetStartupConfig } from '~/data-provider';
|
||||
import { useMCPToolsQuery, useGetStartupConfig } from '~/data-provider';
|
||||
|
||||
/**
|
||||
* Hook for fetching and filtering MCP tools based on server configuration
|
||||
* Uses the dedicated MCP tools query instead of filtering from general tools
|
||||
*/
|
||||
export function useGetMCPTools() {
|
||||
const { data: startupConfig } = useGetStartupConfig();
|
||||
const { data: rawMcpTools } = useAvailableToolsQuery(EModelEndpoint.agents, {
|
||||
|
||||
// Use dedicated MCP tools query
|
||||
const { data: rawMcpTools } = useMCPToolsQuery({
|
||||
select: (data: TPlugin[]) => {
|
||||
// Group tools by server for easier management
|
||||
const mcpToolsMap = new Map<string, TPlugin>();
|
||||
data.forEach((tool) => {
|
||||
const isMCP = tool.pluginKey.includes(Constants.mcp_delimiter);
|
||||
if (isMCP) {
|
||||
const parts = tool.pluginKey.split(Constants.mcp_delimiter);
|
||||
const serverName = parts[parts.length - 1];
|
||||
if (!mcpToolsMap.has(serverName)) {
|
||||
mcpToolsMap.set(serverName, {
|
||||
name: serverName,
|
||||
pluginKey: tool.pluginKey,
|
||||
authConfig: tool.authConfig,
|
||||
authenticated: tool.authenticated,
|
||||
});
|
||||
}
|
||||
const parts = tool.pluginKey.split(Constants.mcp_delimiter);
|
||||
const serverName = parts[parts.length - 1];
|
||||
if (!mcpToolsMap.has(serverName)) {
|
||||
mcpToolsMap.set(serverName, {
|
||||
name: serverName,
|
||||
pluginKey: tool.pluginKey,
|
||||
authConfig: tool.authConfig,
|
||||
authenticated: tool.authenticated,
|
||||
});
|
||||
}
|
||||
});
|
||||
return Array.from(mcpToolsMap.values());
|
||||
},
|
||||
});
|
||||
|
||||
// Filter out servers that have chatMenu disabled
|
||||
const mcpToolDetails = useMemo(() => {
|
||||
if (!rawMcpTools || !startupConfig?.mcpServers) {
|
||||
return rawMcpTools;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export function useMCPServerManager({ conversationId }: { conversationId?: strin
|
|||
showToast({ message: localize('com_nav_mcp_vars_updated'), status: 'success' });
|
||||
|
||||
await Promise.all([
|
||||
queryClient.refetchQueries([QueryKeys.tools]),
|
||||
queryClient.refetchQueries([QueryKeys.mcpTools]),
|
||||
queryClient.refetchQueries([QueryKeys.mcpAuthValues]),
|
||||
queryClient.refetchQueries([QueryKeys.mcpConnectionStatus]),
|
||||
]);
|
||||
|
|
@ -170,7 +170,7 @@ export function useMCPServerManager({ conversationId }: { conversationId?: strin
|
|||
setMCPValues([...currentValues, serverName]);
|
||||
}
|
||||
|
||||
await queryClient.invalidateQueries([QueryKeys.tools]);
|
||||
await queryClient.invalidateQueries([QueryKeys.mcpTools]);
|
||||
|
||||
// This delay is to ensure UI has updated with new connection status before cleanup
|
||||
// Otherwise servers will show as disconnected for a second after OAuth flow completes
|
||||
|
|
|
|||
|
|
@ -1,79 +1,52 @@
|
|||
import { useMemo } from 'react';
|
||||
import { Constants } from 'librechat-data-provider';
|
||||
import type { AgentToolType } from 'librechat-data-provider';
|
||||
import type { TPlugin } from 'librechat-data-provider';
|
||||
import type { MCPServerInfo } from '~/common';
|
||||
|
||||
type GroupedToolType = AgentToolType & { tools?: AgentToolType[] };
|
||||
type GroupedToolsRecord = Record<string, GroupedToolType>;
|
||||
|
||||
interface VisibleToolsResult {
|
||||
toolIds: string[];
|
||||
mcpServerNames: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom hook to calculate visible tool IDs based on selected tools and their parent groups.
|
||||
* If any subtool of a group is selected, the parent group tool is also made visible.
|
||||
* Custom hook to calculate visible tool IDs based on selected tools.
|
||||
* Separates regular LibreChat tools from MCP servers.
|
||||
*
|
||||
* @param selectedToolIds - Array of selected tool IDs
|
||||
* @param allTools - Record of all available tools
|
||||
* @param regularTools - Array of regular LibreChat tools
|
||||
* @param mcpServersMap - Map of all MCP servers
|
||||
* @returns Object containing separate arrays of visible tool IDs for regular and MCP tools
|
||||
*/
|
||||
export function useVisibleTools(
|
||||
selectedToolIds: string[] | undefined,
|
||||
allTools: GroupedToolsRecord | undefined,
|
||||
regularTools: TPlugin[] | undefined,
|
||||
mcpServersMap: Map<string, MCPServerInfo>,
|
||||
): VisibleToolsResult {
|
||||
return useMemo(() => {
|
||||
const mcpServers = new Set<string>();
|
||||
const selectedSet = new Set<string>();
|
||||
const regularToolIds = new Set<string>();
|
||||
const regularToolIds: string[] = [];
|
||||
|
||||
for (const toolId of selectedToolIds ?? []) {
|
||||
if (!toolId.includes(Constants.mcp_delimiter)) {
|
||||
selectedSet.add(toolId);
|
||||
continue;
|
||||
}
|
||||
const serverName = toolId.split(Constants.mcp_delimiter)[1];
|
||||
if (!serverName) {
|
||||
continue;
|
||||
}
|
||||
mcpServers.add(serverName);
|
||||
}
|
||||
|
||||
if (allTools) {
|
||||
for (const [toolId, toolObj] of Object.entries(allTools)) {
|
||||
if (selectedSet.has(toolId)) {
|
||||
regularToolIds.add(toolId);
|
||||
}
|
||||
|
||||
if (toolObj.tools?.length) {
|
||||
for (const subtool of toolObj.tools) {
|
||||
if (selectedSet.has(subtool.tool_id)) {
|
||||
regularToolIds.add(toolId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// MCP tools/servers
|
||||
if (toolId.includes(Constants.mcp_delimiter)) {
|
||||
const serverName = toolId.split(Constants.mcp_delimiter)[1];
|
||||
if (serverName) {
|
||||
mcpServers.add(serverName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mcpServersMap) {
|
||||
for (const [mcpServerName] of mcpServersMap) {
|
||||
if (mcpServers.has(mcpServerName)) {
|
||||
continue;
|
||||
}
|
||||
/** Legacy check */
|
||||
if (selectedSet.has(mcpServerName)) {
|
||||
mcpServers.add(mcpServerName);
|
||||
}
|
||||
// Legacy MCP server check (just server name)
|
||||
else if (mcpServersMap.has(toolId)) {
|
||||
mcpServers.add(toolId);
|
||||
}
|
||||
// Regular LibreChat tools
|
||||
else if (regularTools?.some((t) => t.pluginKey === toolId)) {
|
||||
regularToolIds.push(toolId);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
toolIds: Array.from(regularToolIds).sort((a, b) => a.localeCompare(b)),
|
||||
toolIds: regularToolIds.sort((a, b) => a.localeCompare(b)),
|
||||
mcpServerNames: Array.from(mcpServers).sort((a, b) => a.localeCompare(b)),
|
||||
};
|
||||
}, [allTools, mcpServersMap, selectedToolIds]);
|
||||
}, [regularTools, mcpServersMap, selectedToolIds]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue