fix: streamline tool filtering logic and add group-based filtering (#476)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
samanhappy
2025-12-04 15:10:49 +08:00
committed by GitHub
parent cb77593fd7
commit 8d420a927b

View File

@@ -956,23 +956,14 @@ Available servers: ${serversList}`,
for (const serverInfo of filteredServerInfos) { for (const serverInfo of filteredServerInfos) {
if (serverInfo.tools && serverInfo.tools.length > 0) { if (serverInfo.tools && serverInfo.tools.length > 0) {
// Filter tools based on server configuration // Filter tools based on server configuration
let enabledTools = await filterToolsByConfig(serverInfo.name, serverInfo.tools); let tools = await filterToolsByConfig(serverInfo.name, serverInfo.tools);
// If this is a group request, apply group-level tool filtering // If this is a group request, apply group-level tool filtering
if (group) { tools = await filterToolsByGroup(group, serverInfo.name, tools);
const serverConfig = await getServerConfigInGroup(group, serverInfo.name);
if (serverConfig && serverConfig.tools !== 'all' && Array.isArray(serverConfig.tools)) {
// Filter tools based on group configuration
const allowedToolNames = serverConfig.tools.map(
(toolName: string) => `${serverInfo.name}${getNameSeparator()}${toolName}`,
);
enabledTools = enabledTools.filter((tool) => allowedToolNames.includes(tool.name));
}
}
// Apply custom descriptions from server configuration // Apply custom descriptions from server configuration
const serverConfig = await getServerDao().findById(serverInfo.name); const serverConfig = await getServerDao().findById(serverInfo.name);
const toolsWithCustomDescriptions = enabledTools.map((tool) => { const toolsWithCustomDescriptions = tools.map((tool) => {
const toolConfig = serverConfig?.tools?.[tool.name]; const toolConfig = serverConfig?.tools?.[tool.name];
return { return {
...tool, ...tool,
@@ -1019,12 +1010,15 @@ export const handleCallToolRequest = async (request: any, extra: any) => {
// Determine server filtering based on group // Determine server filtering based on group
const sessionId = extra.sessionId || ''; const sessionId = extra.sessionId || '';
const group = getGroup(sessionId); let group = getGroup(sessionId);
let servers: string[] | undefined = undefined; // No server filtering by default let servers: string[] | undefined = undefined; // No server filtering by default
// If group is in format $smart/{group}, filter servers to that group // If group is in format $smart/{group}, filter servers to that group
if (group?.startsWith('$smart/')) { if (group?.startsWith('$smart/')) {
const targetGroup = group.substring(7); const targetGroup = group.substring(7);
if (targetGroup) {
group = targetGroup;
}
const serversInGroup = await getServersInGroup(targetGroup); const serversInGroup = await getServersInGroup(targetGroup);
if (serversInGroup !== undefined && serversInGroup !== null) { if (serversInGroup !== undefined && serversInGroup !== null) {
servers = serversInGroup; servers = serversInGroup;
@@ -1056,8 +1050,8 @@ export const handleCallToolRequest = async (request: any, extra: any) => {
const actualTool = server.tools.find((tool) => tool.name === result.toolName); const actualTool = server.tools.find((tool) => tool.name === result.toolName);
if (actualTool) { if (actualTool) {
// Check if the tool is enabled in configuration // Check if the tool is enabled in configuration
const enabledTools = await filterToolsByConfig(server.name, [actualTool]); const tools = await filterToolsByConfig(server.name, [actualTool]);
if (enabledTools.length > 0) { if (tools.length > 0) {
// Apply custom description from configuration // Apply custom description from configuration
const serverConfig = await getServerDao().findById(server.name); const serverConfig = await getServerDao().findById(server.name);
const toolConfig = serverConfig?.tools?.[actualTool.name]; const toolConfig = serverConfig?.tools?.[actualTool.name];
@@ -1083,19 +1077,24 @@ export const handleCallToolRequest = async (request: any, extra: any) => {
); );
// Now filter the resolved tools // Now filter the resolved tools
const tools = await Promise.all( const filterResults = await Promise.all(
resolvedTools.filter(async (tool) => { resolvedTools.map(async (tool) => {
// Additional filter to remove tools that are disabled
if (tool.name) { if (tool.name) {
const serverName = tool.serverName; const serverName = tool.serverName;
if (serverName) { if (serverName) {
const enabledTools = await filterToolsByConfig(serverName, [tool as Tool]); let tools = await filterToolsByConfig(serverName, [tool as Tool]);
return enabledTools.length > 0; if (tools.length === 0) {
return false;
}
tools = await filterToolsByGroup(group, serverName, tools);
return tools.length > 0;
} }
} }
return true; // Keep fallback results return true;
}), }),
); );
const tools = resolvedTools.filter((_, i) => filterResults[i]);
// Add usage guidance to the response // Add usage guidance to the response
const response = { const response = {
@@ -1487,3 +1486,18 @@ export const createMcpServer = (name: string, version: string, group?: string):
server.setRequestHandler(ListPromptsRequestSchema, handleListPromptsRequest); server.setRequestHandler(ListPromptsRequestSchema, handleListPromptsRequest);
return server; return server;
}; };
// Filter tools based on group configuration
async function filterToolsByGroup(group: string | undefined, serverName: string, tools: Tool[]) {
if (group) {
const serverConfig = await getServerConfigInGroup(group, serverName);
if (serverConfig && serverConfig.tools !== 'all' && Array.isArray(serverConfig.tools)) {
// Filter tools based on group configuration
const allowedToolNames = serverConfig.tools.map(
(toolName: string) => `${serverName}${getNameSeparator()}${toolName}`,
);
tools = tools.filter((tool) => allowedToolNames.includes(tool.name));
}
}
return tools;
}