Repository navigation
Conversation
iborakove
force-pushed
the
fix/mcp-tool-arg-types-13350-upstream
branch
from
October 24, 2026 14:22
647763e to
9da7044
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #13350. Related: #13386 addresses the same issue.
Some models send non-string MCP tool arguments as JSON text, for example
{"paths": "[\"a.txt\", \"b.txt\"]"}for an array parameter or"false"for a boolean.coerceArgsToSchemaonly handled the opposite case (re-stringifying objects forstringparameters), so these values reached MCP servers as strings and failed input validation with errors such asexpected array, received string.coerceArgsToSchema(core/tools/parseArgs.ts) now decodes a string argument only when its property schema rejects strings and accepts the decoded JSON type. All other values pass through unchanged, and the MCP server remains responsible for validation.nullare decoded withJSON.parse;"True"/"FALSE"are accepted asgetBooleanArgaccepts them. Integers beyondNumber.MAX_SAFE_INTEGERand non-finite numbers stay strings, so no precision is lost.type(including type arrays),enum,const,anyOf/oneOf(union),allOf(intersection), boolean schemas and local$refs. Keywords that can only narrow a schema (not,if/then/else, formats, ranges) are ignored, so a type the schema accepts is never excluded."string",["string", "array"], a string branch inanyOf, a stringenum/const, or no type constraint), the value is left as is, e.g."[1]"for astring | arrayparameter.$refonce and detects recursive references. Schemas that exceed the budget or recurse leave the argument unchanged, so pathological schemas take bounded time instead of exponential time or a stack overflow.#,#/…) are followed, through own properties only. References into or across a nested schema resource ($id, oridin draft 4),$dynamicRef/$recursiveRef, and remote or unresolvable references leave the argument unchanged.Scope: argument normalization in the core tool-call path used by the IDE extensions. The CLI's MCP implementation in
extensions/cliis unchanged.Checklist
Screen recording or screenshot
Not applicable: no UI changes.
Tests
core/tools/parseArgs.vitest.ts: decoding of each JSON type; valid strings preserved fortype,anyOf/oneOf,enum/constand untyped schemas; malformed or mismatched values left unchanged; numeric strings never truncated or rounded;$ref,anyOf,oneOfandallOfresolution; adversarial schemas: an exponential$refdiamond, budget exhaustion (deep nesting, long$refchains, wideanyOf), recursive references, nested$idresources,$dynamicRefand malformed references.core/tools/callTool.vitest.ts(new): the MCP client receives native types (aneditsarray and adryRunboolean) across repeatededit_filecalls.coresuite: 1,694 tests passed, 0 failed.tsc --noEmitforcoreandextensions/vscode, ESLint and Prettier pass.