Skip to main content
Glama
index.ts3.66 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { createExecuteSqlToolHandler } from "./execute-sql.js"; import { createSearchDatabaseObjectsToolHandler, searchDatabaseObjectsSchema } from "./search-objects.js"; import { ConnectorManager } from "../connectors/manager.js"; import { getExecuteSqlMetadata, getSearchObjectsMetadata } from "../utils/tool-metadata.js"; import { isReadOnlySQL } from "../utils/allowed-keywords.js"; import { createCustomToolHandler, buildZodSchemaFromParameters } from "./custom-tool-handler.js"; import type { ToolConfig } from "../types/config.js"; import { getToolRegistry } from "./registry.js"; import { BUILTIN_TOOL_EXECUTE_SQL, BUILTIN_TOOL_SEARCH_OBJECTS } from "./builtin-tools.js"; /** * Register all tool handlers with the MCP server * Iterates through all enabled tools from the registry and registers them * @param server - The MCP server instance */ export function registerTools(server: McpServer): void { const sourceIds = ConnectorManager.getAvailableSourceIds(); if (sourceIds.length === 0) { throw new Error("No database sources configured"); } const registry = getToolRegistry(); // Register all enabled tools (both built-in and custom) for each source for (const sourceId of sourceIds) { const enabledTools = registry.getEnabledToolConfigs(sourceId); for (const toolConfig of enabledTools) { // Register based on tool name (built-in vs custom) if (toolConfig.name === BUILTIN_TOOL_EXECUTE_SQL) { registerExecuteSqlTool(server, sourceId); } else if (toolConfig.name === BUILTIN_TOOL_SEARCH_OBJECTS) { registerSearchObjectsTool(server, sourceId); } else { // Custom tool registerCustomTool(server, sourceId, toolConfig); } } } } /** * Register execute_sql tool for a source */ function registerExecuteSqlTool( server: McpServer, sourceId: string ): void { const metadata = getExecuteSqlMetadata(sourceId); server.registerTool( metadata.name, { description: metadata.description, inputSchema: metadata.schema, annotations: metadata.annotations, }, createExecuteSqlToolHandler(sourceId) ); } /** * Register search_objects tool for a source */ function registerSearchObjectsTool( server: McpServer, sourceId: string ): void { const metadata = getSearchObjectsMetadata(sourceId); server.registerTool( metadata.name, { description: metadata.description, inputSchema: searchDatabaseObjectsSchema, annotations: { title: metadata.title, readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, }, createSearchDatabaseObjectsToolHandler(sourceId) ); } /** * Register a custom tool */ function registerCustomTool( server: McpServer, sourceId: string, toolConfig: ToolConfig ): void { const sourceConfig = ConnectorManager.getSourceConfig(sourceId)!; const dbType = sourceConfig.type; const isReadOnly = isReadOnlySQL(toolConfig.statement!, dbType); const zodSchema = buildZodSchemaFromParameters(toolConfig.parameters); server.registerTool( toolConfig.name, { description: toolConfig.description, inputSchema: zodSchema, annotations: { title: `${toolConfig.name} (${dbType})`, readOnlyHint: isReadOnly, destructiveHint: !isReadOnly, idempotentHint: isReadOnly, openWorldHint: false, }, }, createCustomToolHandler(toolConfig) ); console.error(` - ${toolConfig.name} → ${toolConfig.source} (${dbType})`); }

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/bytebase/dbhub'

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