fix(client): validate JSON-null structuredContent against outputSchema - #3346
Draft
epistemedeus wants to merge 1 commit into
Draft
Conversation
SEP-2106 allows structuredContent to be JSON null. The client presence check used `is None`, which also matches an omitted field, so a tool that advertised a null-capable outputSchema and returned null was rejected as missing structured content. Use model_fields_set so omitted still fails closed, explicit null is schema-validated, and falsy JSON values (0, false, "") stay checked. Fixes modelcontextprotocol#3345
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 free
to 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 #3345
SEP-2106 allows
structuredContentto be JSON null.validate_tool_resulttreatedstructured_content is Noneas a missing field, so a tool that advertised a null-capableoutputSchemaand returned"structuredContent": nullnever reached jsonschema validation.Pydantic stores both omitted and explicit JSON null as
None. This usesmodel_fields_setas the presence check, matching the TypeScript SDK's=== undefined(not null / not falsy) check.Motivation and Context
Declared
outputSchemawas not validated against a legal JSON-nullstructuredContentvalue. Clients rejected a conforming result as missing instead of schema-checking it. OmittedstructuredContentstill fails closed.How Has This Been Tested?
uv run --frozen pytest tests/client/test_session_promotions.py tests/interaction/lowlevel/test_tools.py::test_declared_output_schema_with_no_structured_content_is_rejected_by_the_client tests/interaction/lowlevel/test_tools.py::test_call_tool_structured_content_violating_output_schema_is_rejected_by_the_client -q24 passed, including new cases for:
{"type": "null"}(accept)0/falseBreaking Changes
None. Omitted
structuredContentstill raises the same RuntimeError. Only an explicit JSON null is now schema-validated.Types of changes
Checklist
help wanted, or I'm a maintainer)Additional context
Not assigned on #3345. Opening as a draft per the small-fix-with-tests shape; CONTRIBUTING may auto-close until a maintainer assigns the issue. Reporter of #3345.
AI assistance: researched and implemented with Grok 4.6; I reviewed the spec text, the TypeScript v2 presence check, Pydantic
model_fields_seton parsedCallToolResult, and the new tests.No protocol change. No new schema surface. Does not duplicate the existing jsonschema check; it only stops the presence check from swallowing JSON null before that check runs.