Uh oh!
There was an error while loading. Please reload this page.
feat: relax outputSchema to accept non-object JSON Schema types (SEP-2106) - #895
Conversation
michaelneale
commented
Jun 9, 2026
thanks @branben if you can run a fmt over this to get CI happy - I think this is then good to merge, thanks! |
branben
commented
Jun 10, 2026
just checked on this @michaelneale happy I could contribute! |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| assert!(tool.output_schema.is_some()); | ||
| let schema_str = serde_json::to_string(tool.output_schema.as_ref().unwrap()).unwrap(); | ||
| assert!(schema_str.contains("\"type\":\"integer\"")); |
There was a problem hiding this comment.
To prevent false positives
| assert!(schema_str.contains("\"type\":\"integer\"")); | |
| assert_eq!(schema.get("type"),Some(&serde_json::json!("integer"))); |
There was a problem hiding this comment.
@branben You marked this as resolved but it still doesn't seem to be fixed!
Thanks for the review @DaleSeo! All 4 comments addressed in the latest push:
The Please let me know where else I can make meaningful contributions if there's a specific pain point that's bugging the team! |
DaleSeo
commented
Jun 29, 2026
@branben You might've forgotten to push those fixes? I'm still seeing the original code. 😅 |
47e5d23 to
6588978Compare…urns Result - Add strip_output() that strips title/description without validating type (Dale modelcontextprotocol#1) - Change schema_for_output to return Arc<JsonObject> instead of Result (Dale modelcontextprotocol#2) - Cache only Arc<JsonObject> success values, not Result (Dale modelcontextprotocol#3) - Remove dead unwrap_or_else panic paths in with_output_schema, ToolBase, and macros - Tighten test assertions from contains to assert_eq on type field (Dale modelcontextprotocol#4) - Update test_schema_for_output_rejects_primitive to accept_primitive (SEP-2106) Co-authored-by: Orca <help@stably.ai>
Add tests verifying schema_for_output accepts non-object types: - test_tool_builder_methods: primitive (i32), array (Vec<String>), option - test_structured_output: tool returning Json<Vec<T>> and Json<i32> - test_json_schema_detection: Json<Vec<T>>, Result<Json<Vec<T>>,E>, Json<String> - tool_traits: ToolBase::output_schema with Vec<AddOutput> output type
Add tests identified during code review: - description stripping for primitive types - composition types (Option<String> with anyOf/oneOf/null) - cache correctness (Arc::ptr_eq for repeated calls) - schema_for_input rejecting array types (not just primitives) - schema_for_output accepting unit type ()
6588978 to
28c2bccComparebranben
commented
Jun 30, 2026
| assert!(tool.output_schema.is_some()); | ||
| let schema_str = serde_json::to_string(tool.output_schema.as_ref().unwrap()).unwrap(); | ||
| assert!(schema_str.contains("\"type\":\"integer\"")); |
There was a problem hiding this comment.
@branben You marked this as resolved but it still doesn't seem to be fixed!
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| /// Generate and strip a JSON schema for outputSchema (top-level "title" and | ||
| /// "description" are removed; output schemas are not restricted to root type "object"). | ||
| pub fn schema_for_output<T: JsonSchema + std::any::Any>() -> Arc<JsonObject> { |
There was a problem hiding this comment.
Public API Check is red in CI because the schema_for_output return-type change is a breaking change:
-pub fn ...::schema_for_output<...>() -> Result<Arc<JsonObject>, String>
+pub fn ...::schema_for_output<...>() -> Arc<JsonObject>
Error: The API diff is not allowed as per --deny: Changed items not allowed
That's expected and fine, and the plan is to batch all 2026-07-28 spec breaking changes into v3.0. So this SEP-2106 implementation belongs in that major.
We need to mark the introducing commit breaking though replacing feat: with feat!: so the CI gate computes major and Public API Check passes.
This introduces SEP-2106: schema_for_output no longer validates or returns Result. The public signature changed, so bump major.
…ArrayTool
- Replace loose schema_str.contains(...) assertions with direct
schema.get("type") equality checks in test_tool_builder_methods.rs
and test_structured_output.rs
- Remove redundant ArrayTool fixture and its round-trip
serde_json::from_str test from tool_traits.rs since schema is
already Arc<JsonObject>
- Drop dead schema_str variable in test_structured_output.rsbranben
commented
Jul 1, 2026
Hey again @DaleSeo ! context on this commit ended up getting malformed and rotted from a memory mcp tool as I was working on this, so I apologize for a bit of the run around! Let me know if I'm on the right path here! |
Thanks @DaleSeo you're the GOAT!, are there any other specific pain points I could contribute to that might make the next migration easier? |
Uh oh!
There was an error while loading. Please reload this page.
Summary
Relax
schema_for_outputto accept any JSON Schema 2020-12 root type (arrays, primitives, compositions) foroutputSchema, while keepingschema_for_inputenforcingtype: "object". This implements SEP-2106, which was accepted May 18 2026.PR #860 (merged Jun 2 2026) added title/desc stripping and input validation. This PR covers the remaining work: decoupling the type gate so output schemas are no longer rejected for non-object types.
Changes
crates/rmcp/src/handler/server/common.rs: Splitvalidate_and_stripinto:validate_and_strip_input— keepstype: "object"check for inputSchemavalidate_and_strip_output— strips title/desc, no type check (accepts any JSON Schema root type)crates/rmcp/src/model/tool.rs: Updatedwith_output_schemadoc comment to remove incorrect "root type object" panic referenceOption<T>), unit type,Json<T>macro path,ToolBasetrait path, cache correctness, and negative tests for input rejectionBackward Compatibility
schema_for_outputreturn type unchanged (Result<Arc<JsonObject>, String>)Verification
cargo test -p rmcp --all-features: 424 passed, 0 failedcargo clippy --all-targets --all-features -- -D warnings: No issues found