Skip to content

fix: coerce MCP tool args to match schema string types#11852

Merged
RomneyDa merged 2 commits intomainfrom
json-args
Mar 25, 2026
Merged

fix: coerce MCP tool args to match schema string types#11852
RomneyDa merged 2 commits intomainfrom
json-args

Conversation

@RomneyDa
Copy link
Collaborator

@RomneyDa RomneyDa commented Mar 25, 2026

Summary

  • Fixes MCP tools receiving parsed JSON objects instead of strings when the tool's input schema defines a parameter as type: "string" (e.g. write_file content parameter)
  • Adds coerceArgsToSchema() that checks the tool's inputSchema and re-stringifies any values that were deeply parsed by JSON.parse() but should remain as strings
  • Built-in tools already handled this via getStringArg(), but MCP tools with dynamic schemas had no equivalent fix

Test plan

  • Added unit tests for coerceArgsToSchema() covering: object→string coercion, array→string coercion, no-op for already-string values, no-op for non-string schema types, no schema, mixed args, immutability
  • All 49 tests in parseArgs.vitest.ts pass

Fixes #8510


Summary by cubic

Coerces MCP tool args to match string-typed schema params so tools don’t receive parsed objects/arrays. Applies before calling the MCP client to fix cases like write_file where JSON content must remain a string.

  • Bug Fixes
    • Added coerceArgsToSchema() that re-stringifies only object/array values when the schema says type: "string", and used it before MCP callTool.
    • Added tests for object/array-to-string, skipping numbers/booleans, mixed args, and immutability.

Written for commit 42d2037. Summary will update on new commits.

When tool call arguments are parsed via JSON.parse(), string-typed
parameters containing valid JSON (e.g. file content for .json files)
get deeply parsed into objects. Built-in tools handle this via
getStringArg(), but MCP tools with dynamic schemas had no equivalent
fix, causing write_file and similar tools to receive objects instead
of strings.

Add coerceArgsToSchema() that checks the tool's inputSchema and
re-stringifies any values that should be strings before passing
args to the MCP client.

Fixes #8510
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Mar 25, 2026
@continue
Copy link
Contributor

continue bot commented Mar 25, 2026

Documentation Review

No documentation updates needed for this PR.

Reasoning: This PR is an internal bug fix that transparently handles edge cases in MCP tool argument parsing. The coerceArgsToSchema() function automatically re-stringifies values when the tool's schema expects type: "string" but receives a parsed JSON object (e.g., JSON file content passed to write_file).

This fix:

  • Requires no user action or configuration changes
  • Is applied automatically to all MCP tool calls
  • Doesn't change how users configure or interact with MCP servers

The existing MCP documentation covers configuration, setup, and transport types—documenting internal argument coercion mechanics would add unnecessary implementation detail that doesn't help developers use Continue more effectively.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="core/tools/parseArgs.ts">

<violation number="1" location="core/tools/parseArgs.ts:51">
P2: This coercion is too broad for `type: "string"`: it also converts number/boolean inputs to strings, which can mask invalid tool arguments instead of only fixing deep-parsed object/array values.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Only re-stringify values that are objects or arrays (the actual
deep-parsing issue). Numbers and booleans passed to a string-typed
parameter are left as-is so they surface as type errors rather than
being silently converted.
@RomneyDa RomneyDa requested a review from a team as a code owner March 25, 2026 23:19
@RomneyDa RomneyDa requested review from sestinj and removed request for a team March 25, 2026 23:19
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Mar 25, 2026
@github-project-automation github-project-automation bot moved this from Todo to In Progress in Issues and PRs Mar 25, 2026
@RomneyDa RomneyDa merged commit ff89a88 into main Mar 25, 2026
66 checks passed
@RomneyDa RomneyDa deleted the json-args branch March 25, 2026 23:39
@github-project-automation github-project-automation bot moved this from In Progress to Done in Issues and PRs Mar 25, 2026
@github-actions github-actions bot locked and limited conversation to collaborators Mar 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Continue keeps sending json object as string as opposed to json.stringify() as parameter to mcp tools

2 participants