From 53a934d944746562d3a51b079ad441e5a606ca33 Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Fri, 15 Aug 2025 11:45:37 +0200 Subject: [PATCH] Fix: Convert MCP string parameters to appropriate types Add convertMCPArgs function to properly convert string parameters from MCP tools to their expected types (numbers, booleans, objects, arrays) before passing them to tool execution functions. --- packages/opencode/src/session/index.ts | 55 +++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts index 222cf82576..8306091358 100644 --- a/packages/opencode/src/session/index.ts +++ b/packages/opencode/src/session/index.ts @@ -47,6 +47,56 @@ import { Wildcard } from "../util/wildcard" import { ulid } from "ulid" import { defer } from "../util/defer" +/** + * Converts string parameters to their appropriate types based on the schema + * This fixes an issue where MCP tools receive all parameters as strings + */ +function convertMCPArgs(args: Record, schema: any): Record { + if (!schema || !args) return args + + const converted: Record = {} + + for (const [key, value] of Object.entries(args)) { + // If the value is not a string, keep it as is + if (typeof value !== "string") { + converted[key] = value + continue + } + + // Try to parse as JSON first (for arrays, objects, booleans, numbers) + try { + converted[key] = JSON.parse(value) + continue + } catch { + // If JSON parsing fails, continue with type inference + } + + // Try to convert to number if it looks like a number + if (/^-?\d+(\.\d+)?$/.test(value)) { + const num = parseFloat(value) + if (!isNaN(num)) { + converted[key] = num + continue + } + } + + // Try to convert to boolean + if (value.toLowerCase() === "true") { + converted[key] = true + continue + } + if (value.toLowerCase() === "false") { + converted[key] = false + continue + } + + // Keep as string if no conversion applies + converted[key] = value + } + + return converted +} + export namespace Session { const log = Log.create({ service: "session" }) @@ -845,7 +895,10 @@ export namespace Session { const execute = item.execute if (!execute) continue item.execute = async (args, opts) => { - const result = await execute(args, opts) + // Convert string parameters to appropriate types + const convertedArgs = convertMCPArgs(args, item.inputSchema) + + const result = await execute(convertedArgs, opts) const output = result.content .filter((x: any) => x.type === "text") .map((x: any) => x.text)