Skip to content

Commit 76cdf48

Browse files
authored
fix(shemars): use JSON Schema 2020-12 as Default Dialect (#549)
TODO: Not fully compatible with 2020-12 yet.
1 parent 1d38d68 commit 76cdf48

File tree

4 files changed

+57
-21
lines changed

4 files changed

+57
-21
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "mai
2828
Basic dependencies:
2929
- [tokio required](https://github.com/tokio-rs/tokio)
3030
- [serde required](https://github.com/serde-rs/serde)
31-
31+
Json Schema generation(Must follow the 2020-12 version):
32+
- [shemars required](https://github.com/GREsau/schemars)
3233

3334

3435
### Build a Client

crates/rmcp/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ schemars = ["dep:schemars"]
143143

144144
[dev-dependencies]
145145
tokio = { version = "1", features = ["full"] }
146-
schemars = { version = "1.0", features = ["chrono04"] }
146+
schemars = { version = "1.1.0", features = ["chrono04"] }
147147

148148
anyhow = "1.0"
149149
tracing-subscriber = { version = "0.3", features = [

crates/rmcp/src/handler/server/common.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ use crate::{
1111
/// A shortcut for generating a JSON schema for a type.
1212
pub fn schema_for_type<T: JsonSchema>() -> JsonObject {
1313
// explicitly to align json schema version to official specifications.
14-
// https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-03-26/schema.json
15-
// TODO: update to 2020-12 waiting for the mcp spec update
16-
let mut settings = SchemaSettings::draft07();
14+
// refer to https://github.com/modelcontextprotocol/modelcontextprotocol/pull/655 for details.
15+
let mut settings = SchemaSettings::draft2020_12();
1716
settings.transforms = vec![Box::new(schemars::transform::AddNullable::default())];
1817
let generator = settings.into_generator();
1918
let schema = generator.into_root_schema_for::<T>();

crates/rmcp/tests/test_complex_schema.rs

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,60 @@ impl Demo {
4343
}
4444
}
4545

46+
fn expected_schema() -> serde_json::Value {
47+
serde_json::json!({
48+
"$defs": {
49+
"ChatMessage": {
50+
"properties": {
51+
"content": {
52+
"type": "string"
53+
},
54+
"role": {
55+
"$ref": "#/$defs/ChatRole"
56+
}
57+
},
58+
"required": [
59+
"role",
60+
"content"
61+
],
62+
"type": "object"
63+
},
64+
"ChatRole": {
65+
"enum": [
66+
"System",
67+
"User",
68+
"Assistant",
69+
"Tool"
70+
],
71+
"type": "string"
72+
}
73+
},
74+
"$schema": "https://json-schema.org/draft/2020-12/schema",
75+
"properties": {
76+
"messages": {
77+
"items": {
78+
"$ref": "#/$defs/ChatMessage"
79+
},
80+
"type": "array"
81+
},
82+
"system": {
83+
"nullable": true,
84+
"type": "string"
85+
}
86+
},
87+
"required": [
88+
"messages"
89+
],
90+
"title": "ChatRequest",
91+
"type": "object"
92+
})
93+
}
94+
4695
#[test]
4796
fn test_complex_schema() {
4897
let attr = Demo::chat_tool_attr();
4998
let input_schema = attr.input_schema;
50-
let enum_number = input_schema
51-
.get("definitions")
52-
.unwrap()
53-
.as_object()
54-
.unwrap()
55-
.get("ChatRole")
56-
.unwrap()
57-
.as_object()
58-
.unwrap()
59-
.get("enum")
60-
.unwrap()
61-
.as_array()
62-
.unwrap()
63-
.len();
64-
assert_eq!(enum_number, 4);
65-
println!("{}", serde_json::to_string_pretty(&input_schema).unwrap());
99+
let expected = expected_schema();
100+
let produced = serde_json::Value::Object(input_schema.as_ref().clone());
101+
assert_eq!(produced, expected, "schema mismatch");
66102
}

0 commit comments

Comments
 (0)