Skip to main content
Glama
ToolsMetric.tsx5.75 kB
import { Agent, McpServer } from "@/types"; import { useAccessControlsStore, useSocketStore } from "@/store"; import { useMemo } from "react"; interface UseToolsMetricProps { agents: Agent[]; servers: McpServer[]; } /** * Custom hook to calculate the available tools metric. * Returns a string in the format "{availableTools}/{connectedTools}". * * Available tools are calculated as the unique count of tools from tool groups * assigned to connected agents. If no agents are connected or no tool groups * are assigned, it returns the total connected tools count. */ export const useToolsMetric = ({ agents, servers }: UseToolsMetricProps) => { const toolGroups = useAccessControlsStore((state) => state.toolGroups); const appConfig = useSocketStore((state) => state.appConfig); const connectedClients = useSocketStore( (state) => state.systemState?.connectedClients ?? [], ); const connectedTools = useMemo( () => servers.reduce((total, server) => total + server.tools.length, 0), [servers], ); const toolGroupByNameMap = useMemo(() => { const map = new Map<string, (typeof toolGroups)[0]>(); toolGroups.forEach((group) => { map.set(group.name, group); }); return map; }, [toolGroups]); // Map session IDs to consumer tags for efficient lookup const sessionIdToConsumerTagMap = useMemo(() => { const map = new Map<string, string>(); connectedClients.forEach((client) => { if (client.sessionId && client.consumerTag) { map.set(client.sessionId, client.consumerTag); } }); return map; }, [connectedClients]); const availableTools = useMemo(() => { const connectedAgents = agents.filter( (agent) => agent.status === "connected", ); // If no agents connected, show all connected tools if (connectedAgents.length === 0) { return connectedTools; } if (!appConfig?.permissions?.consumers) { return connectedTools; } try { const assignedToolGroupNames = new Set<string>(); let hasAnyAgentWithAllTools = false; let allAgentsHaveEmptyAllow = true; // Single pass through agents to collect all information for (const agent of connectedAgents) { // Get consumer tags for this agent's sessions const agentConsumerTags: string[] = []; for (const sessionId of agent.sessionIds) { const consumerTag = sessionIdToConsumerTagMap.get(sessionId); if (consumerTag) { agentConsumerTags.push(consumerTag); } } if (agentConsumerTags.length === 0) { allAgentsHaveEmptyAllow = false; continue; } // Check each consumer tag's config let agentHasAllTools = false; let agentHasEmptyAllow = false; let agentHasToolGroups = false; for (const consumerTag of agentConsumerTags) { const consumerConfig = appConfig.permissions.consumers[consumerTag]; // If no consumer config, agent has all tools (falls back to default) if (!consumerConfig) { agentHasAllTools = true; break; } // If _type is "default-allow" with empty block array, agent has all tools if ( consumerConfig._type === "default-allow" && "block" in consumerConfig && Array.isArray(consumerConfig.block) && consumerConfig.block.length === 0 ) { agentHasAllTools = true; break; } // If _type is "default-block" and allow array is empty, agent has 0 tools if ( consumerConfig._type === "default-block" && "allow" in consumerConfig && Array.isArray(consumerConfig.allow) && consumerConfig.allow.length === 0 ) { agentHasEmptyAllow = true; continue; } // Collect tool group names from allow array (default-block) if ( "allow" in consumerConfig && Array.isArray(consumerConfig.allow) && consumerConfig.allow.length > 0 ) { consumerConfig.allow.forEach((groupName) => assignedToolGroupNames.add(groupName), ); agentHasToolGroups = true; } } if (agentHasAllTools) { hasAnyAgentWithAllTools = true; } if (!agentHasEmptyAllow || agentHasToolGroups) { allAgentsHaveEmptyAllow = false; } } // If any agent has all tools enabled, show all connected tools if (hasAnyAgentWithAllTools) { return connectedTools; } // If no tool groups assigned and all agents have empty allow arrays, return 0 if (assignedToolGroupNames.size === 0) { return allAgentsHaveEmptyAllow ? 0 : connectedTools; } // Collect all unique tools from assigned tool groups const uniqueTools = new Set<string>(); for (const groupName of assignedToolGroupNames) { const group = toolGroupByNameMap.get(groupName); if (!group?.services) continue; for (const tools of Object.values(group.services)) { if (Array.isArray(tools)) { for (const tool of tools) { uniqueTools.add(tool); } } } } return uniqueTools.size; } catch (_error) { // Silently fallback to showing all connected tools on error return connectedTools; } }, [ agents, connectedTools, appConfig, toolGroupByNameMap, sessionIdToConsumerTagMap, ]); return useMemo( () => `${availableTools}/${connectedTools}`, [availableTools, connectedTools], ); };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TheLunarCompany/lunar'

If you have feedback or need assistance with the MCP directory API, please join our Discord server