Skip to main content
Glama
dynamicToolMcpServer.ts2.98 kB
import { Server, ServerOptions, } from "@modelcontextprotocol/sdk/server/index.js" import { RegisteredTool } from "@modelcontextprotocol/sdk/server/mcp.js" import { CallToolRequestSchema, ErrorCode, Implementation, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js" import { zodToJsonSchema } from "zod-to-json-schema" type GetToolsFn = () => Promise<Record<string, RegisteredTool>> export class DynamicToolMcpServer { server: Server private getTools: GetToolsFn constructor( serverInfo: Implementation, options: ServerOptions & { getToolsFn: GetToolsFn } ) { this.server = new Server(serverInfo, options) this.getTools = options.getToolsFn this.setHandlers() } private setHandlers() { this.server.assertCanSetRequestHandler( ListToolsRequestSchema.shape.method.value ) this.server.assertCanSetRequestHandler( CallToolRequestSchema.shape.method.value ) this.server.registerCapabilities({ tools: { listChanged: true, }, }) this.server.setRequestHandler(ListToolsRequestSchema, async () => { const tools = await this.getTools() return { tools: Object.entries(tools) .filter(([, tool]) => tool.enabled !== false) .map(([name, tool]) => ({ name, description: tool.description, inputSchema: tool.inputSchema ? zodToJsonSchema(tool.inputSchema, { strictUnions: true }) : { type: "object" }, })), } }) this.server.setRequestHandler( CallToolRequestSchema, async (request, extra) => { const tools = await this.getTools() const tool = tools[request.params.name] console.log(">> Tool", request.params.name, request.params.arguments) if (!tool) { throw new McpError( ErrorCode.InvalidParams, `Tool ${request.params.name} not found` ) } if (tool.enabled === false) { throw new McpError( ErrorCode.InvalidParams, `Tool ${request.params.name} is disabled` ) } const args = request.params.arguments try { if (tool.inputSchema) { const parseResult = await tool.inputSchema.safeParseAsync(args) if (!parseResult.success) { throw new McpError( ErrorCode.InvalidParams, `Invalid arguments: ${parseResult.error.message}` ) } return await tool.callback(parseResult.data, extra) } return await tool.callback(extra) } catch (error) { return { content: [ { type: "text", text: `An error occurred while calling the tool: ${error}`, // XXX Do we need to sanitize this? }, ], } } } ) } }

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/rajnandan1/pd-mcp'

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