Skip to content

schema_for_type uses AddNullable which is non-compliant with JSON Schema 2020-12 #663

@mwotton

Description

@mwotton

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions