Skip to content

Commit 2570c2b

Browse files
authored
feat!: add support for multiple active schema versions with versioned module access (#73)
1 parent 5e85573 commit 2570c2b

14 files changed

+166
-89
lines changed

Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,12 @@ features = ["2025_03_26", "schema_utils"]
3636
[features]
3737

3838
# defalt features
39-
default = ["2025_03_26", "schema_utils"] # Default features
39+
default = ["latest", "schema_utils"] # Default features
4040

4141
# activates the latest MCP schema version, this will be updated once a new version of schema is published
4242
latest = ["2025_03_26"]
43-
4443
# enabled mcp schema version 2025_03_26
45-
2025_03_26 = []
44+
2025_03_26 = ["latest"]
4645
# enabled mcp schema version 2024_11_05
4746
2024_11_05 = []
4847
# enabled draft mcp schema

README.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,30 +76,29 @@ This repository provides all official released versions the schema , including d
7676

7777
### How to switch between different schema versions?
7878

79+
By default, the latest version of the MCP Protocol schema is enabled.
80+
7981
Each schema version has a corresponding Cargo feature that can be enabled in your project's Cargo.toml.
80-
By default, the version `2025_03_26` of the schema is active.
82+
83+
Multiple schema versions may be enabled concurrently if needed. Non-default versions are available under explicitly named modules, for example:
84+
85+
- rust_mcp_schema::mcp_2024_11_05
86+
- rust_mcp_schema::mcp_draft"
8187

8288
Example: enable `2024_11_05` version of the shema:
8389

8490
<!-- x-release-please-start-version -->
8591

8692
```toml
8793
# Cargo.toml
88-
rust-mcp-schema = { version: 0.5.2 , features=["2024_11_05"] }
89-
```
90-
91-
Example: enable `latest` version of the shema:
92-
93-
```toml
94-
#Cargo.toml
95-
rust-mcp-schema = { version: 0.5.2 , features=["latest"] }
94+
rust-mcp-schema = { version: 0.5.2 , default-features = false, features=["2024_11_05"] }
9695
```
9796

9897
Example: enable `draft`` version of the shema (2024_11_05) :
9998

10099
```toml
101100
#Cargo.toml
102-
rust-mcp-schema = { version: 0.5.2 , features=["draft"] }
101+
rust-mcp-schema = { version: 0.5.2 , default-features = false, features=["draft"] }
103102
```
104103

105104
<!-- x-release-please-end -->

examples/mcp_client_handle_message.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1+
#[cfg(feature = "latest")]
12
use rust_mcp_schema::schema_utils::*;
3+
#[cfg(feature = "latest")]
24
use rust_mcp_schema::*;
5+
6+
#[cfg(feature = "2024_11_05")]
7+
use rust_mcp_schema::mcp_2024_11_05::schema_utils::*;
8+
#[cfg(feature = "2024_11_05")]
9+
use rust_mcp_schema::mcp_2024_11_05::*;
10+
11+
#[cfg(feature = "draft")]
12+
use rust_mcp_schema::mcp_draft::schema_utils::*;
13+
#[cfg(feature = "draft")]
14+
use rust_mcp_schema::mcp_draft::*;
15+
316
use std::str::FromStr;
417

518
type AppError = RpcError;

examples/mcp_server_handle_message.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1+
#[cfg(feature = "latest")]
12
use rust_mcp_schema::schema_utils::*;
3+
#[cfg(feature = "latest")]
24
use rust_mcp_schema::*;
5+
6+
#[cfg(feature = "2024_11_05")]
7+
use rust_mcp_schema::mcp_2024_11_05::schema_utils::*;
8+
#[cfg(feature = "2024_11_05")]
9+
use rust_mcp_schema::mcp_2024_11_05::*;
10+
11+
#[cfg(feature = "draft")]
12+
use rust_mcp_schema::mcp_draft::schema_utils::*;
13+
#[cfg(feature = "draft")]
14+
use rust_mcp_schema::mcp_draft::*;
15+
316
use std::str::FromStr;
417

518
type AppError = RpcError;

scripts/run_test.sh

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#!/bin/bash
22

33
# common features (always included in the tests)
4-
COMMON_FEATURES=("schema_utils")
4+
COMMON_FEATURES=("schema_utils")
55

66
# schema versions features (tested one at a time)
77
SCHEMA_VERSION_FEATURES=("2025_03_26", "2024_11_05", "draft")
88

9-
# space-separated string
9+
# space-separated string
1010
COMMON_FEATURES_STR="${COMMON_FEATURES[*]}"
1111

1212
for FEATURE in "${SCHEMA_VERSION_FEATURES[@]}"; do
@@ -18,10 +18,6 @@ for FEATURE in "${SCHEMA_VERSION_FEATURES[@]}"; do
1818
echo "❌ Tests failed for: --features \"$COMMON_FEATURES_STR $FEATURE\""
1919
exit 1
2020
fi
21-
22-
echo
23-
echo "🚀 Running documentation tests with: --features \"$COMMON_FEATURES_STR $FEATURE\""
24-
cargo test --doc --no-default-features --features "$COMMON_FEATURES_STR $FEATURE"
2521

2622
# stop on failure
2723
if [ $? -ne 0 ]; then
@@ -30,4 +26,10 @@ for FEATURE in "${SCHEMA_VERSION_FEATURES[@]}"; do
3026
fi
3127
done
3228

33-
echo "✅ All tests passed!"
29+
# Get the first feature from the array
30+
FEATURE="${SCHEMA_VERSION_FEATURES[0]}"
31+
echo
32+
echo "🚀 Running documentation tests with: --features \"$COMMON_FEATURES_STR $FEATURE\""
33+
cargo test --doc --no-default-features --features "$COMMON_FEATURES_STR $FEATURE"
34+
35+
echo "✅ All tests passed!"

src/generated_schema.rs

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,65 @@
1-
/// Schema Version: 2024_11_05
2-
#[cfg(feature = "2024_11_05")]
3-
#[path = "generated_schema/2024_11_05/mcp_schema.rs"]
4-
mod mcp_schema;
1+
macro_rules! define_schema_version {
2+
(
3+
$feature:literal,
4+
$mod_name:ident,
5+
$schema_path:literal,
6+
$utils_path:literal,
7+
$schema_mod:ident,
8+
$utils_mod:ident
9+
) => {
10+
#[cfg(feature = $feature)]
11+
#[path = $schema_path]
12+
mod $schema_mod;
513

6-
#[cfg(feature = "2024_11_05")]
7-
pub use mcp_schema::*;
14+
#[cfg(all(feature = "schema_utils", feature = $feature))]
15+
#[path = $utils_path]
16+
mod $utils_mod;
817

9-
#[cfg(all(feature = "schema_utils", feature = "2024_11_05"))]
10-
#[path = "generated_schema/2024_11_05/schema_utils.rs"]
11-
pub mod schema_utils;
18+
#[cfg(feature = $feature)]
19+
pub mod $mod_name {
20+
pub use super::$schema_mod::*;
1221

13-
/// Schema Version: 2025_03_26
14-
#[cfg(feature = "2025_03_26")]
15-
#[path = "generated_schema/2025_03_26/mcp_schema.rs"]
16-
mod mcp_schema;
22+
#[cfg(feature = "schema_utils")]
23+
pub mod schema_utils {
24+
pub use super::super::$utils_mod::*;
25+
}
26+
}
27+
};
28+
}
1729

30+
/// Latest MCP Protocol 2025_03_26
1831
#[cfg(feature = "2025_03_26")]
19-
pub use mcp_schema::*;
32+
pub use mcp_2025_03_26::*;
2033

21-
#[cfg(all(feature = "schema_utils", feature = "2025_03_26"))]
22-
#[path = "generated_schema/2025_03_26/schema_utils.rs"]
23-
pub mod schema_utils;
34+
#[cfg(feature = "2025_03_26")]
35+
define_schema_version!(
36+
"2025_03_26",
37+
mcp_2025_03_26,
38+
"generated_schema/2025_03_26/mcp_schema.rs",
39+
"generated_schema/2025_03_26/schema_utils.rs",
40+
__int_2025_03_26,
41+
__int_utils_2025_03_26
42+
);
2443

25-
/// Schema Version: draft
26-
#[cfg(feature = "draft")]
27-
#[path = "generated_schema/draft/mcp_schema.rs"]
28-
mod mcp_schema;
44+
#[cfg(feature = "2024_11_05")]
45+
define_schema_version!(
46+
"2024_11_05",
47+
mcp_2024_11_05,
48+
"generated_schema/2024_11_05/mcp_schema.rs",
49+
"generated_schema/2024_11_05/schema_utils.rs",
50+
__int_2024_11_05,
51+
__int_utils_2024_11_05
52+
);
2953

3054
#[cfg(feature = "draft")]
31-
pub use mcp_schema::*;
32-
33-
#[cfg(all(feature = "schema_utils", feature = "draft"))]
34-
#[path = "generated_schema/draft/schema_utils.rs"]
35-
pub mod schema_utils;
55+
define_schema_version!(
56+
"draft",
57+
mcp_draft,
58+
"generated_schema/draft/mcp_schema.rs",
59+
"generated_schema/draft/schema_utils.rs",
60+
__int_draft,
61+
__int_utils_draft
62+
);
3663

3764
#[path = "generated_schema/protocol_version.rs"]
3865
mod protocol_version;

src/generated_schema/2024_11_05/schema_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::generated_schema::*;
1+
use crate::generated_schema::mcp_2024_11_05::*;
22
use serde::ser::SerializeStruct;
33
use serde_json::{json, Value};
44
use std::hash::{Hash, Hasher};

src/generated_schema/draft/schema_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::generated_schema::*;
1+
use crate::generated_schema::mcp_draft::*;
22
use serde::ser::SerializeStruct;
33
use serde_json::{json, Value};
44
use std::hash::{Hash, Hasher};

src/rust-mcp-schema.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
/// modules
22
mod generated_schema;
33

4-
/// re-exports
5-
#[cfg(feature = "schema_utils")]
6-
pub use generated_schema::schema_utils;
74
pub use generated_schema::*;

tests/2024_11_05_exclusive.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ pub mod common;
44

55
#[cfg(feature = "2024_11_05")]
66
mod test_2024_11_05_exclusive {
7-
use rust_mcp_schema::schema_utils::*;
8-
use rust_mcp_schema::*;
7+
use rust_mcp_schema::mcp_2024_11_05::schema_utils::*;
8+
use rust_mcp_schema::mcp_2024_11_05::*;
99

1010
use super::common::{get_message, re_serialize};
1111

@@ -73,7 +73,7 @@ mod test_2024_11_05_exclusive {
7373

7474
#[test]
7575
fn test_server_list_resource_templates_result_sample() {
76-
let message = get_message("res_template_list");
76+
let message = get_message("res_template_list", LATEST_PROTOCOL_VERSION);
7777
assert!(matches!(message, ServerMessage::Response(server_message)
7878
if matches!(&server_message.result, ResultFromServer::ServerResult(server_result)
7979
if matches!(server_result, ServerResult::ListResourceTemplatesResult(_)))
@@ -82,7 +82,7 @@ mod test_2024_11_05_exclusive {
8282

8383
#[test]
8484
fn test_client_list_resource_templates_request_sample() {
85-
let message = get_message("req_template_list");
85+
let message = get_message("req_template_list", LATEST_PROTOCOL_VERSION);
8686
assert!(matches!(message, ClientMessage::Request(client_message)
8787
if matches!(&client_message.request, RequestFromClient::ClientRequest(client_request)
8888
if matches!(client_request, ClientRequest::ListResourceTemplatesRequest(_)))

0 commit comments

Comments
 (0)