1+ use std:: cmp:: Ordering ;
2+
3+ use crate :: error:: { McpSdkError , SdkResult } ;
4+
15/// Formats an assertion error message for unsupported capabilities.
26///
37/// 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
2327 )
2428}
2529
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+
26150/// Removes query string and hash fragment from a URL, returning the base path.
27151///
28152/// # Arguments
0 commit comments