Skip to content

Publish review_upload as one object so Anthropic accepts it - #621

Merged
thesiti92 merged 2 commits into
mainfrom
fix/flat-upload-schema
Sep 27, 2026
Merged

thesiti92 merged 2 commits into
mainfrom
fix/flat-upload-schema

Conversation

@thesiti92

@thesiti92 thesiti92 commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Fixes a user report: with OpenCode, requests fail with
tools.302.custom.input_schema: input_schema does not support oneOf, allOf, or anyOf at the top level.

The upload tool published uploadSchema, a z.discriminatedUnion, as its input schema, so the JSON Schema had a top-level oneOf. The Anthropic API rejects that. OpenCode forwards MCP schemas unchanged, so enabling Whiteboard broke every request. Claude Code flattens top-level combinators itself, which is why it kept working there.

  • review_upload / session_upload now publish one object: id, repositoryId and kind (enum image | trace | map) are required, and the kind-specific fields (base64, trace, pins, side, model) are optional. The flat shape is derived from uploadSchema.options, so the two can't drift apart.
  • The tool description says which fields each kind takes.
  • The host still validates uploads against the union; only the advertised schema changed.
  • The stdio MCP test now asserts that no published tool has a top-level anyOf, oneOf or allOf. It failed on session_upload before this change.

Pi is unaffected: its package is a skill that shells out to whiteboard api, so no MCP schema goes to the model.

Verification

  • vitest run src/review-api: 315 passed.
  • pnpm lint and the packages/review typecheck are clean.
  • Claude Code 2.1.283 against a stub MCP server serving the new tool list: the model called session_upload with a flat image payload.
  • OpenCode 1.18.30 with anthropic/claude-haiku-4-5 against the same stub server: the old tool list reproduces the reported tools.N.custom.input_schema error, and the new one produces a correct session_upload call.
  • Codex 0.156.1 with gpt-6-sol against the same stub server: the old and new tool lists produce the same session_upload call. OpenAI accepts the top-level oneOf, so Codex was never affected.

The MCP adapter reads tool schemas from the running host, so users get this fix when their Whiteboard Desktop updates.

OpenCode forwards MCP input schemas to the Anthropic API unchanged, and the
API rejects oneOf/anyOf/allOf at the top level of a tool input_schema. The
upload tool published its discriminated union verbatim, so enabling
Whiteboard broke every request. Claude Code flattens such schemas itself,
which hid the problem there.

Publish upload as one object with kind as an enum and the kind-specific
fields optional; the host still validates the union.

Agent-Session: 0e2e21cf-19cf-4e82-b801-11a38760f54a
Agent-Session: ffd15b4f-a561-403e-bf42-e841bd247f58
Agent-Session: 0e2e21cf-19cf-4e82-b801-11a38760f54a
Agent-Session: ffd15b4f-a561-403e-bf42-e841bd247f58
@thesiti92
thesiti92 merged commit 7969b93 into main Sep 27, 2026
1 check passed
@thesiti92
thesiti92 deleted the fix/flat-upload-schema branch September 27, 2026 15:52
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.

2 participants