Skip to content

fix(agents): parse disjoint oneOf MCP parameter schemas - #2288

Open
Thilo Schmalfuß (scthi) wants to merge 1 commit into
JetBrains:developfrom
scthi:scthi-koog-schema-parser-fix
Open

Thilo Schmalfuß (scthi) wants to merge 1 commit into
JetBrains:developfrom
scthi:scthi-koog-schema-parser-fix

Conversation

@scthi

Copy link
Copy Markdown

Handle untyped oneOf MCP tool parameters directly in DefaultMcpToolDescriptorParser.

A generic parameter such as {"oneOf":[{"type":"object"},{"type":"string"}]} previously failed with IllegalArgumentException: Parameter ... must have type property. This prevents describing tools that accept either a JSON object or a JSON-encoded string.

Reuse ToolParameterType.AnyOf only for alternatives whose JSON type sets are provably disjoint, where at-least-one and exactly-one are equivalent. Reject overlapping alternatives (including integer/number and overlapping null branches), unsupported sibling constraints, and unrepresentable multi-type arrays rather than silently weakening or truncating them. Preserve existing anyOf overlap behavior and propagate recursion depth through union branches. Document that the descriptor is not a full JSON Schema validator.

Related to #2017 and overlapping open PR #2067. Unlike #2067's unconditional mapping, this deliberately supports only disjoint alternatives and does not add const support.

Validation:

  • Confirmed the generic object/string regression fails with the original missing-type exception when the new oneOf dispatch is removed; it passes when restored.
  • ./gradlew :agents:agents-mcp:jvmTest --tests 'ai.koog.agents.mcp.*ToolDescriptorParserTest' :agents:agents-mcp:ktlintCheck — passed; 39 JVM parser tests (11 new, 28 existing), no failures or skips.
  • ./gradlew :agents:agents-mcp:jsTest — passed; 39 JS parser tests, no failures or skips.
  • ./gradlew :agents:agents-mcp:build and ./gradlew build — blocked before execution by the missing local Android SDK. No claim of a successful full build.

All fixtures are freshly authored and generic. No timeout behavior changes or new public descriptor variants.

Handle untyped object-or-string parameters at the MCP descriptor parser seam. Represent oneOf with the existing AnyOf only when alternatives have disjoint JSON types; reject overlap and unsupported sibling constraints explicitly. Preserve anyOf behavior and propagate recursion depth through unions.

Add generic JVM/JS regression coverage and document the descriptor's limitations. Parser tests (39 on each target) and MCP ktlintCheck pass. Module and full builds are blocked by the missing Android SDK.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@scthi
Thilo Schmalfuß (scthi) marked this pull request as ready for review October 2, 2026 05:27

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant