Skip to main content
Glama
ToolCallHandler.ts4.04 kB
import { IServerRegistry } from "../../interfaces/IServerRegistry.js"; import { IToolsParser } from "../../interfaces/IToolsParser.js"; import { ISandboxManager } from "../../interfaces/ISandboxManager.js"; import { IVectorStore } from "../../interfaces/IVectorStore.js"; import { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; /** * Tool response type matching MCP SDK format */ export type ToolResponse = CallToolResult; /** * Arguments for get_tools_overview */ interface GetToolsOverviewArgs { toolPaths: string[]; } /** * Arguments for semantic_search_tools */ interface SemanticSearchArgs { query: string; limit?: number; } /** * Arguments for run_functions_code */ interface RunCodeArgs { code: string; } /** * ToolCallHandler handles execution of tool calls * Implements dependency injection pattern for better testability */ export class ToolCallHandler { constructor( private serverRegistry: IServerRegistry, private toolsParser: IToolsParser, private sandboxManager: ISandboxManager, private vectorStore: IVectorStore ) {} /** * Handle get_mcps_servers_overview tool call */ async handleGetServersOverview(): Promise<ToolResponse> { const overview = this.toolsParser.getServersOverview( this.serverRegistry.getAllServers() ); return { content: [ { type: "text", text: overview, }, ], }; } /** * Handle get_tools_overview tool call */ async handleGetToolsOverview(args: GetToolsOverviewArgs): Promise<ToolResponse> { const { toolPaths } = args; try { const toolsJson = this.toolsParser.getToolsOverview( this.serverRegistry.getAllServers(), toolPaths ); return { content: [ { type: "text", text: toolsJson, }, ], }; } catch (error) { return this.formatError(error as Error); } } /** * Handle semantic_search_tools tool call */ async handleSemanticSearch(args: SemanticSearchArgs): Promise<ToolResponse> { const { query, limit = 5 } = args; if (typeof query !== "string") { return { content: [ { type: "text", text: "Error: query must be a string", }, ], }; } try { const results = await this.vectorStore.search(query, limit); const formattedResults = results.map(r => ({ serverName: r.serverName, toolName: r.toolName, description: r.description, similarityScore: r.score.toFixed(3), fullPath: `${r.serverName}/${r.toolName}` })); return { content: [ { type: "text", text: JSON.stringify(formattedResults, null, 2), }, ], }; } catch (error) { return this.formatError(error as Error); } } /** * Handle run_functions_code tool call */ async handleRunCode(args: RunCodeArgs): Promise<ToolResponse> { const { code } = args; if (typeof code !== "string") { return { content: [ { type: "text", text: "Error: code must be a string", }, ], }; } try { const result = await this.sandboxManager.execute(code); // The sandbox now returns parsed data directly from tools // Simply stringify the result for output const content = JSON.stringify(result, null, 2); return { content: [ { type: "text", text: content, }, ], }; } catch (error) { return this.formatError(error as Error); } } /** * Format error response */ private formatError(error: Error): ToolResponse { const errorMessage = error.message || String(error); return { content: [ { type: "text", text: `Error: ${errorMessage}`, }, ], }; } }

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/eliavamar/mcp-of-mcps'

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