-
Notifications
You must be signed in to change notification settings - Fork 462
Description
Problem
The schema_for_type() function in crates/rmcp/src/handler/server/common.rs uses AddNullable::default() as a transform when generating JSON Schema 2020-12 schemas:
let mut settings = SchemaSettings::draft2020_12();
settings.transforms = vec![Box::new(schemars::transform::AddNullable::default())];However, the nullable keyword is an OpenAPI 3.0 extension, not part of JSON Schema 2020-12. This causes validation failures with strict JSON Schema validators.
Background
PR #549 updated schema_for_type() to use SchemaSettings::draft2020_12() to align with the MCP spec update (modelcontextprotocol/modelcontextprotocol#655), but it retained the AddNullable transform from the previous Draft 7 implementation.
The nullable keyword originated from OpenAPI 3.0 and was never part of any JSON Schema draft. In JSON Schema 2020-12, nullable types should be represented using:
{"type": ["string", "null"]}(type array with null){"anyOf": [{"type": "string"}, {"type": "null"}]}
Impact
- Strict JSON Schema 2020-12 validators (like mcporter) reject schemas containing
nullable - Generated tool schemas may fail validation in environments with strict schema checking
- The `` declaration claims 2020-12 compliance but includes non-2020-12 keywords
Example
With the current implementation, an optional string field produces:
{
"nullable": true,
"type": "string"
}This should instead be:
{
"type": ["string", "null"]
}Suggested Fix
Remove or conditionally disable the AddNullable transform when using SchemaSettings::draft2020_12():
let mut settings = SchemaSettings::draft2020_12();
// Do not add AddNullable - nullable is OpenAPI 3.0, not JSON Schema 2020-12
let generator = settings.into_generator();References
- PR fix(shemars): use JSON Schema 2020-12 as Default Dialect #549: Switched to JSON Schema 2020-12 but retained AddNullable
- JSON Schema 2020-12 Specification
- OpenAPI 3.0 nullable extension
- schemars AddNullable documentation