Repository navigation
MCP: outputSchema anyOf/oneOf rejected — valid JSON Schema combinators cause entire server to fail #57643
Description
Description
Summary
OpenCode v2.1.0 rejects valid MCP servers whose tools/list returns outputSchema using anyOf or oneOf instead of a simple type: "object". The validation error rejects the entire server before any tools become available, even though the schemas are valid JSON Schema per the MCP specification.
This is a regression — many legitimate MCP servers (e.g., cqs (https://github.com/jamie8johnson/cqs)) intentionally use anyOf/oneOf because tools return different output structures depending on input.
Environment
- opencode version: 2.1.0
- OS: Linux 6.12.77-1-generic (linux x64)
- Terminal: GhosTTY, tmux, xterm-256color
- Shell: /bin/bash
- Install/channel: latest
- Active plugins: None found
Expected Behavior
OpenCode should accept anyOf/oneOf in outputSchema as valid JSON Schema. These are standard JSON Schema combinators supported by the MCP specification. The server should connect and tools should be available.
Actual Behavior
OpenCode's zod validation strictly requires type: "object" at the top level of each outputSchema. When a tool uses anyOf or oneOf without a top-level type field, OpenCode rejects the entire server and marks it as failed. All tools from that server are unavailable.
Additional Context
Example of valid schema rejected by OpenCode
This is a real outputSchema from the cqs cqs_callers tool:
{
"$defs": {
"CallersOutput": { "type": "object", "properties": { ... } },
"KindFallbackOutput": { "type": "object", "properties": { ... } }
},
"anyOf": [
{ "$ref": "#/$defs/CallersOutput", "description": "Function path" },
{ "$ref": "#/$defs/KindFallbackOutput", "description": "Kind mismatch" }
]
}
This is valid JSON Schema and valid MCP protocol. The tool genuinely returns either a CallersOutput or a KindFallbackOutput depending on input — there is no single type: "object" that captures both shapes.
Affected tools in cqs (10 of 31)
| Tool | Schema type | Reason |
|---|---|---|
| cqs_task | anyOf | Full result vs budgeted output |
| cqs_callers | anyOf | Callers result vs kind fallback |
| cqs_callees | anyOf | Callees result vs kind fallback |
| cqs_deps | anyOf | Multiple possible output shapes |
| cqs_impact | oneOf | Function vs fallback impact |
| cqs_test_map | anyOf | Test map vs kind fallback |
| cqs_trace | anyOf | Trace result vs kind fallback |
| cqs_context | anyOf | 3 possible shapes (compact/summary/full) |
| cqs_plan | anyOf | Plan result vs budgeted output |
| cqs_read | anyOf | Full read vs focused read |
The remaining 21 tools have type: "object" and work fine.
cqs maintainers are aware
The cqs project explicitly documents this design decision in issue #2203 (jamie8johnson/cqs#2203) (July 2026): tools use anyOf/oneOf because their outputs are genuinely heterogeneous — there is no single type: "object" that accurately describes the possible return shapes.
Plugins
No response
OpenCode version
2.1.0
Steps to reproduce
- Configure a remote MCP server that returns anyOf in tools.list output schemas (e.g., cqs (https://github.com/jamie8johnson/cqs) at localhost:8117)
- Start a new OpenCode session
- Server fails with error:
MCP server failed: <server_name>
Invalid result for tools/list:
path: ["tools", 3, "outputSchema", "type"]
message: "Invalid input: expected \"object\""
- The same server works fine with curl — tools execute correctly, only the metadata validation fails.
Screenshot
No response
Operating System
Debian 12 / Linux 6.12.77-1-generic (linux x64)
Terminal
GhosTTY, tmux
Activity
opencode-agent commentedon Oct 21, 2026
Thanks for the detailed report. I reproduced this on v2.1.0, and it still happens on the latest
dev(15adc3d91).What I did:
outputSchema(type: "object"). The other uses$defsplus a top-levelanyOfwith notype, likecqs_callers.opencode mcp listreportsfailed: Invalid result for tools/list ... path ["tools",1,"outputSchema","type"] ... expected "object", and neither tool is available."type": "object"to the second schema makes the server connect.The check comes from the MCP SDK's validation of the
tools/listresult, and OpenCode has no fallback for it, so one tool's output schema takes down the whole server. The spec does declareoutputSchemawithtype: "object". Even so, failing every tool on the server is clearly worse than skipping or loosening just that tool's schema, and OpenCode v1 used to tolerate this kind of error.The script below reproduces it. Related: #56116 (a tool call hard-fails when the result doesn't match its output schema).
Reproduction script (repro.sh)
Run it:
bash repro.sh