Skip to content

gesture-rotate, flow-read-prerequisite, flow-execute use top-level oneOf/anyOf in inputSchema, which the Anthropic Messages API rejects #773

Description

@lukeharvey

Environment

  • Client: opencode v1.15.13, argent connected as a local MCP server (argent mcp over stdio)
  • argent: @swmansion/argent@0.20.0 (also reproduced on 0.20.1-next.3)
  • Node: v24.19.0
  • OS: macOS (Darwin 25.5.0, arm64)

Summary

3 of the 73 tools argent's MCP server exposes have oneOf/anyOf at the top level of inputSchema (used to express "either param A or param B" conditional requirements). We hit this in opencode, where the Anthropic Messages API rejects any tool whose input_schema has oneOf/allOf/anyOf at the schema root — even combined with type: object/properties/required — with a 400 error:

tools.N.custom.input_schema: input_schema does not support oneOf, allOf, or anyOf at the top level

Confirmed present in 0.20.0 and 0.20.1-next.3 (schemas are byte-identical between the two).

This is a documented Anthropic API constraint, not an opencode-specific quirk — any MCP client that forwards these three tool schemas to the Anthropic Messages API as custom tools (rather than through some other transport, like Anthropic's server-side MCP connector) would hit the same rejection. We haven't tested other clients against argent directly, but the same root-level-oneOf/anyOf failure mode is well documented across many other MCP servers, including with Claude Code against an unrelated MCP server (anthropics/claude-code#84056, Notion's connector) and in Notion's own MCP server (makenotion/notion-mcp-server#102).

Affected tools

  • gesture-rotateanyOf for radius XOR (radiusX + radiusY)
  • flow-read-prerequisiteoneOf for name XOR flow_path
  • flow-executeoneOf for name XOR flow_path

Repro

npx -y @swmansion/argent@0.20.0 mcp
# send tools/list over stdio JSON-RPC, inspect inputSchema for gesture-rotate /
# flow-read-prerequisite / flow-execute — each has a top-level oneOf/anyOf key
# alongside type/properties/required.

Full schemas (from 0.20.0):

// gesture-rotate
{
  "type": "object",
  "properties": { "udid": {...}, "radius": {...}, "radiusX": {...}, "radiusY": {...}, ... },
  "required": ["udid", "centerX", "centerY", "startAngle", "endAngle"],
  "anyOf": [
    { "required": ["radiusX", "radiusY"] },
    { "required": ["radius"], "not": { "anyOf": [{ "required": ["radiusX"] }, { "required": ["radiusY"] }] } }
  ]
}

// flow-read-prerequisite / flow-execute
{
  "type": "object",
  "properties": { "name": {...}, "flow_path": {...}, ... },
  "required": ["project_root"],
  "oneOf": [{ "required": ["name"] }, { "required": ["flow_path"] }]
}

Suggested fix

Drop the oneOf/anyOf and enforce the XOR requirement at runtime (returning a clear tool error if neither/both are given) instead of via JSON Schema — the tool descriptions already document the requirement in prose, so this changes schema validation only, not documented behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions