Skip to main content
Glama
registry.ts4.03 kB
/** * Tool registry for Attio MCP - edge-compatible * * Provides a configuration-based approach to tool registration * without environment variable dependencies. */ import type { HttpClient } from '../api/http-client.js'; import type { ToolResult, ToolRegistryConfig } from '../types/index.js'; import { coreToolDefinitions, getToolDefinitions, type ToolDefinition, } from './definitions.js'; import { getToolHandler } from './handlers.js'; /** * Tool registry instance */ export interface ToolRegistry { /** Get all available tool definitions */ getDefinitions(): ToolDefinition[]; /** Get a specific tool definition by name */ getDefinition(name: string): ToolDefinition | undefined; /** Check if a tool is available */ hasTool(name: string): boolean; /** Execute a tool with the given parameters */ executeTool( client: HttpClient, name: string, params: Record<string, unknown> ): Promise<ToolResult>; /** Get the list of available tool names */ getToolNames(): string[]; } /** * Tools that are read-only (safe for 'search' mode) */ const READ_ONLY_TOOLS = new Set([ 'aaa-health-check', 'records_search', 'records_get_details', 'records_discover_attributes', 'list-notes', ]); /** * Create a tool registry with the given configuration * * @param config - Registry configuration * @returns Tool registry instance * * @example * ```typescript * // Full mode - all tools available * const registry = createToolRegistry({ mode: 'full' }); * * // Search mode - read-only tools only * const registry = createToolRegistry({ mode: 'search' }); * * // Custom tools filter * const registry = createToolRegistry({ * tools: ['records_search', 'records_get_details'] * }); * ``` */ export function createToolRegistry( config: ToolRegistryConfig = {} ): ToolRegistry { const { tools: allowedTools, mode = 'full' } = config; // Determine which tools are available based on mode and filter function isToolAllowed(toolName: string): boolean { // If specific tools are specified, only allow those if (allowedTools && allowedTools.length > 0) { return allowedTools.includes(toolName); } // In search mode, only allow read-only tools if (mode === 'search') { return READ_ONLY_TOOLS.has(toolName); } // In full mode, all tools are allowed return true; } // Get filtered definitions function getFilteredDefinitions(): ToolDefinition[] { return getToolDefinitions().filter((def) => isToolAllowed(def.name)); } return { getDefinitions(): ToolDefinition[] { return getFilteredDefinitions(); }, getDefinition(name: string): ToolDefinition | undefined { if (!isToolAllowed(name)) { return undefined; } return coreToolDefinitions[name]; }, hasTool(name: string): boolean { return isToolAllowed(name) && name in coreToolDefinitions; }, async executeTool( client: HttpClient, name: string, params: Record<string, unknown> ): Promise<ToolResult> { if (!isToolAllowed(name)) { return { content: [ { type: 'text', text: `Error: Tool '${name}' is not available` }, ], isError: true, }; } const handler = getToolHandler(name); if (!handler) { return { content: [{ type: 'text', text: `Error: Unknown tool '${name}'` }], isError: true, }; } try { return await handler(client, params); } catch (error) { const message = error instanceof Error ? error.message : 'Tool execution failed'; return { content: [{ type: 'text', text: `Error: ${message}` }], isError: true, }; } }, getToolNames(): string[] { return getFilteredDefinitions().map((def) => def.name); }, }; } /** * Default tool registry with full mode */ export const defaultRegistry = createToolRegistry({ mode: 'full' });

Implementation Reference

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/kesslerio/attio-mcp-server'

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