From 5747904b851d1e8053ec57b787da4f0f94ca005e Mon Sep 17 00:00:00 2001 From: Joaquin Coromina Date: Thu, 22 May 2025 15:42:16 -0400 Subject: [PATCH] Created getMCPTools function which transforms the MCP tool to a similar shape to voidTools, also created a helper functions which turns InputSchema into params --- .../contrib/void/common/mcpService.ts | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/src/vs/workbench/contrib/void/common/mcpService.ts b/src/vs/workbench/contrib/void/common/mcpService.ts index d6a77a74..71677a74 100644 --- a/src/vs/workbench/contrib/void/common/mcpService.ts +++ b/src/vs/workbench/contrib/void/common/mcpService.ts @@ -34,7 +34,7 @@ export interface IMCPService { readonly state: MCPServiceState; // NOT persisted onDidChangeState: Event; - getCurrentMCPToolNames(): InternalToolInfo[]; + getMCPTools(): Record; // TOOL_TODO!!!! implement getMCPTools here, which gets merged with builtins in prompts.ts. Should generally be the same shape as voidTools in prompts.ts. @@ -179,30 +179,45 @@ class MCPService extends Disposable implements IMCPService { } } - public getCurrentMCPToolNames(): InternalToolInfo[] { - const allTools = Object.entries(this.state.mcpServerOfName).flatMap(([serverName, server]) => { - return server.tools?.map(tool => { - // Convert JsonSchema to the expected format - const convertedParams: { [paramName: string]: { description: string } } = {}; + public getMCPTools(): Record { + const allTools: Record = {}; + for (const serverName in this.state.mcpServerOfName) { + const server = this.state.mcpServerOfName[serverName]; + if (server.tools) { + server.tools.forEach(tool => { + allTools[tool.name] = { + description: tool.description || '', + params: this._transformInputSchemaToParams(tool.inputSchema), + name: tool.name, + mcpServerName: serverName, + }; + }); + } + } + return allTools + } - // Assuming tool.inputSchema has a 'properties' field that contains parameter definitions - if (tool.inputSchema && tool.inputSchema.properties) { - Object.entries(tool.inputSchema.properties).forEach(([paramName, paramSchema]: [string, any]) => { - convertedParams[paramName] = { - description: paramSchema.description || '' - }; - }); - } + private _transformInputSchemaToParams(inputSchema?: Record): { [paramName: string]: { description: string } } { - return { - description: tool.description || '', - params: convertedParams, - name: tool.name, - serverName, - }; - }); - }).filter(s => s !== undefined) - return allTools; + // Check if inputSchema is valid + if (!inputSchema || !inputSchema.properties) return {}; + + const params: { [paramName: string]: { description: string } } = {}; + Object.keys(inputSchema.properties).forEach(paramName => { + const propertyValues = inputSchema.properties[paramName]; + + // Check if propertyValues is not an object + if (typeof propertyValues !== 'object') { + console.warn(`Invalid property value for ${paramName}: expected object, got ${typeof propertyValues}`); + return; // in forEach the return is equivalent to continue + } + + // Add the parameter to the params object + params[paramName] = { + description: JSON.stringify(propertyValues.description || '', null, 2) || '', + } + }); + return params; } private async _getMCPConfigFilePath(): Promise { @@ -295,7 +310,7 @@ class MCPService extends Disposable implements IMCPService { } // public getMCPToolFns(): MCPToolResultType { - // const tools = this.getCurrentMCPToolNames(); + // const tools = this.getMCPTools(); // const toolFns: MCPToolResultType = {}; // tools.forEach((tool) => {