Uh oh!
There was an error while loading. Please reload this page.
Implements outputSchema validation - #566
Merged
alexhancock merged 3 commits intoDec 8, 2025
Merged
Conversation
DaleSeo
marked this pull request as ready for review
November 29, 2025 19:22
DaleSeo
commented
Dec 4, 2025
MemberAuthor
Hi @jokemanfire, @4t145, @alexhancock, could one of you please review this PR? Thanks! 🙏 |
alexhancock
previously approved these changes
Dec 8, 2025
alexhancock
left a comment
Contributor
There was a problem hiding this comment.
Good catch. LGTM other than the one recommendation!
| } | ||
| /// Call [`schema_for_output`] with a cache. | ||
| pub fn cached_schema_for_output<T: JsonSchema + std::any::Any>() -> Result<Arc<JsonObject>, String> |
Contributor
There was a problem hiding this comment.
I think I would just fold this caching logic into schema_for_output and only have the one public method
MemberAuthor
There was a problem hiding this comment.
Thanks for the suggestion, @alexhancock! I've consolidated the caching logic into schema_for_output.
alexhancock
approved these changes
Dec 8, 2025
Uh oh!
There was an error while loading. Please reload this page.
Merged
oriyadid
commented
Dec 8, 2025
Thank you for fixing this, much appreciated! |
Merged
daixijun pushed a commit
to daixijun/mcp-rust-sdk
that referenced
this pull request
Dec 9, 2025
* feat: implement output schema validation * fix: calculator example comply MCP spec * refactor: merge cached_schema_for_output into schema_for_output
9 tasks
takumi-earth pushed a commit
to earthlings-dev/rmcp
that referenced
this pull request
Jan 27, 2026
* feat: implement output schema validation * fix: calculator example comply MCP spec * refactor: merge cached_schema_for_output into schema_for_output
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#532
Implements validation to enforce MCP specification requirement that tool
outputSchemamust have a root type of"object". Tools using structured output (Json<T>) where T is a primitive type will fail at compile time with clear error messages.Motivation and Context
As reported in issue #532, the MCP specification requires tool
outputSchemato have a root type of"object"(see MCP Tool Schema). The Rust SDK did not validate this, allowing spec-violating schemas to be generated.The latest spec published on Nov 25 states this more clearly:
How Has This Been Tested?
Noticed the
subtool in the calculator example in the repo doesn't comply with the MCP spec, which causes an issue with MCP Insepctor.rust-sdk/examples/servers/src/common/calculator.rs
Lines 46 to 49 in 94428d5
Now that the output schema validation is in place, the server panics during startup:
After fixing the calculator example code so that the
subtool returns unstructured output just like thesumtool, the server starts up without any issues and works well with the MCP Inspector.As suggested in issue #532, wrapping the primitive type also works as expected.
Breaking Changes
Existing valid code works unchanged:
i32,String) with no output stream continues to work<Json<i32>,<Json<String>) fails to compileTypes of changes
Checklist
Additional context
The TypeScript SDK also enforces this requirement in the Tool schema definition here: