From 9f9c65f8b9977e25dcd733c2b383a8e25108125a Mon Sep 17 00:00:00 2001 From: Pajito_S Date: Fri, 22 May 2026 18:48:03 +0530 Subject: [PATCH] fix: parse JSON-string MCP tool arguments before type check Some LLMs (DeepSeek V4 Pro, others) emit MCP tool call arguments as JSON-encoded strings (e.g. '{"headless": true}') rather than as native objects. This causes validateParams() to reject valid MCP tool calls with 'Invalid JSON argument' errors. The fix adds a JSON.parse() guard before the existing type check, falling through silently if parsing fails. The existing code path then handles it as before (either accepts the object or rejects malformed input). This matches the fix applied to Roo Code v3.54.0 which was field- tested across multiple MCP providers (playwright-stealth etc). --- src/core/tools/UseMcpToolTool.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/core/tools/UseMcpToolTool.ts b/src/core/tools/UseMcpToolTool.ts index 7cbc09bfd7..cc1ee7a96b 100644 --- a/src/core/tools/UseMcpToolTool.ts +++ b/src/core/tools/UseMcpToolTool.ts @@ -111,7 +111,14 @@ export class UseMcpToolTool extends BaseTool<"use_mcp_tool"> { return { isValid: false } } - // Native-only: arguments are already a structured object. + // Some LLMs emit arguments as JSON-encoded strings rather than objects. + // Parse them early so the type check below sees the unwrapped object. + if (typeof params.arguments === "string") { + try { + params.arguments = JSON.parse(params.arguments) + } catch {} + } + let parsedArguments: Record | undefined if (params.arguments !== undefined) { if (typeof params.arguments !== "object" || params.arguments === null || Array.isArray(params.arguments)) {