1
+ use std:: cmp:: Ordering ;
2
+
3
+ use crate :: error:: { McpSdkError , SdkResult } ;
4
+
1
5
/// Formats an assertion error message for unsupported capabilities.
2
6
///
3
7
/// Constructs a string describing that a specific entity (e.g., server or client) lacks
@@ -23,6 +27,126 @@ pub fn format_assertion_message(entity: &str, capability: &str, method_name: &st
23
27
)
24
28
}
25
29
30
+ /// Checks if the client and server protocol versions are compatible by ensuring they are equal.
31
+ ///
32
+ /// This function compares the provided client and server protocol versions. If they are equal,
33
+ /// it returns `Ok(())`, indicating compatibility. If they differ (either the client version is
34
+ /// lower or higher than the server version), it returns an error with details about the
35
+ /// incompatible versions.
36
+ ///
37
+ /// # Arguments
38
+ ///
39
+ /// * `client_protocol_version` - A string slice representing the client's protocol version.
40
+ /// * `server_protocol_version` - A string slice representing the server's protocol version.
41
+ ///
42
+ /// # Returns
43
+ ///
44
+ /// * `Ok(())` if the versions are equal.
45
+ /// * `Err(McpSdkError::IncompatibleProtocolVersion)` if the versions differ, containing the
46
+ /// client and server versions as strings.
47
+ ///
48
+ /// # Examples
49
+ ///
50
+ /// ```
51
+ /// use rust_mcp_sdk::mcp_client::ensure_server_protocole_compatibility;
52
+ /// use rust_mcp_sdk::error::McpSdkError;
53
+ ///
54
+ /// // Compatible versions
55
+ /// let result = ensure_server_protocole_compatibility("2024_11_05", "2024_11_05");
56
+ /// assert!(result.is_ok());
57
+ ///
58
+ /// // Incompatible versions (client < server)
59
+ /// let result = ensure_server_protocole_compatibility("2024_11_05", "2025_03_26");
60
+ /// assert!(matches!(
61
+ /// result,
62
+ /// Err(McpSdkError::IncompatibleProtocolVersion(client, server))
63
+ /// if client == "2024_11_05" && server == "2025_03_26"
64
+ /// ));
65
+ ///
66
+ /// // Incompatible versions (client > server)
67
+ /// let result = ensure_server_protocole_compatibility("2025_03_26", "2024_11_05");
68
+ /// assert!(matches!(
69
+ /// result,
70
+ /// Err(McpSdkError::IncompatibleProtocolVersion(client, server))
71
+ /// if client == "2025_03_26" && server == "2024_11_05"
72
+ /// ));
73
+ /// ```
74
+ #[ allow( unused) ]
75
+ pub fn ensure_server_protocole_compatibility (
76
+ client_protocol_version : & str ,
77
+ server_protocol_version : & str ,
78
+ ) -> SdkResult < ( ) > {
79
+ match client_protocol_version. cmp ( server_protocol_version) {
80
+ Ordering :: Less | Ordering :: Greater => Err ( McpSdkError :: IncompatibleProtocolVersion (
81
+ client_protocol_version. to_string ( ) ,
82
+ server_protocol_version. to_string ( ) ,
83
+ ) ) ,
84
+ Ordering :: Equal => Ok ( ( ) ) ,
85
+ }
86
+ }
87
+
88
+ /// Enforces protocol version compatibility on for MCP Server , allowing the client to use a lower or equal version.
89
+ ///
90
+ /// This function compares the client and server protocol versions. If the client version is
91
+ /// higher than the server version, it returns an error indicating incompatibility. If the
92
+ /// versions are equal, it returns `Ok(None)`, indicating no downgrade is needed. If the client
93
+ /// version is lower, it returns `Ok(Some(client_protocol_version))`, suggesting the server
94
+ /// can use the client's version for compatibility.
95
+ ///
96
+ /// # Arguments
97
+ ///
98
+ /// * `client_protocol_version` - The client's protocol version.
99
+ /// * `server_protocol_version` - The server's protocol version.
100
+ ///
101
+ /// # Returns
102
+ ///
103
+ /// * `Ok(None)` if the versions are equal, indicating no downgrade is needed.
104
+ /// * `Ok(Some(client_protocol_version))` if the client version is lower, returning the client
105
+ /// version to use for compatibility.
106
+ /// * `Err(McpSdkError::IncompatibleProtocolVersion)` if the client version is higher, containing
107
+ /// the client and server versions as strings.
108
+ ///
109
+ /// # Examples
110
+ ///
111
+ /// ```
112
+ /// use rust_mcp_sdk::mcp_server::enforce_compatible_protocol_version;
113
+ /// use rust_mcp_sdk::error::McpSdkError;
114
+ ///
115
+ /// // Equal versions
116
+ /// let result = enforce_compatible_protocol_version("2024_11_05", "2024_11_05");
117
+ /// assert!(matches!(result, Ok(None)));
118
+ ///
119
+ /// // Client version lower (downgrade allowed)
120
+ /// let result = enforce_compatible_protocol_version("2024_11_05", "2025_03_26");
121
+ /// assert!(matches!(result, Ok(Some(ref v)) if v == "2024_11_05"));
122
+ ///
123
+ /// // Client version higher (incompatible)
124
+ /// let result = enforce_compatible_protocol_version("2025_03_26", "2024_11_05");
125
+ /// assert!(matches!(
126
+ /// result,
127
+ /// Err(McpSdkError::IncompatibleProtocolVersion(client, server))
128
+ /// if client == "2025_03_26" && server == "2024_11_05"
129
+ /// ));
130
+ /// ```
131
+ #[ allow( unused) ]
132
+ pub fn enforce_compatible_protocol_version (
133
+ client_protocol_version : & str ,
134
+ server_protocol_version : & str ,
135
+ ) -> SdkResult < Option < String > > {
136
+ match client_protocol_version. cmp ( server_protocol_version) {
137
+ // if client protocol version is higher
138
+ Ordering :: Greater => Err ( McpSdkError :: IncompatibleProtocolVersion (
139
+ client_protocol_version. to_string ( ) ,
140
+ server_protocol_version. to_string ( ) ,
141
+ ) ) ,
142
+ Ordering :: Equal => Ok ( None ) ,
143
+ Ordering :: Less => {
144
+ // return the same version that was received from the client
145
+ Ok ( Some ( client_protocol_version. to_string ( ) ) )
146
+ }
147
+ }
148
+ }
149
+
26
150
/// Removes query string and hash fragment from a URL, returning the base path.
27
151
///
28
152
/// # Arguments
0 commit comments