mcp_host/protocol/
version.rs1pub const LATEST_PROTOCOL_VERSION: &str = "2025-11-25";
8
9#[macro_export]
18macro_rules! const_string {
19 ($name:ident = $value:literal) => {
20 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
21 pub struct $name;
22
23 impl $name {
24 pub const VALUE: &'static str = $value;
25
26 pub fn as_str(&self) -> &'static str {
27 Self::VALUE
28 }
29 }
30
31 impl serde::Serialize for $name {
32 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
33 where
34 S: serde::Serializer,
35 {
36 $value.serialize(serializer)
37 }
38 }
39
40 impl<'de> serde::Deserialize<'de> for $name {
41 fn deserialize<D>(deserializer: D) -> Result<$name, D::Error>
42 where
43 D: serde::Deserializer<'de>,
44 {
45 let s: String = serde::Deserialize::deserialize(deserializer)?;
46 if s == $value {
47 Ok($name)
48 } else {
49 Err(serde::de::Error::custom(format!(
50 "expected const string value {:?}, but got {:?}",
51 $value, s
52 )))
53 }
54 }
55 }
56 };
57}
58
59pub use const_string;
61
62pub const JSON_RPC_VERSION: &str = "2.0";
64
65pub const SUPPORTED_PROTOCOL_VERSIONS: &[&str] = &[
69 "2025-11-25", "2025-06-18", ];
72
73pub const DEFAULT_MIN_CLIENT_VERSIONS: &[(&str, &str)] =
77 &[("claude-code", "2.0.56"), ("codex-mcp-client", "0.63.0")];
78
79pub fn is_supported_protocol_version(version: &str) -> bool {
81 SUPPORTED_PROTOCOL_VERSIONS.contains(&version)
82}
83
84pub fn negotiate_protocol_version(client_version: &str) -> Result<String, Vec<String>> {
88 if is_supported_protocol_version(client_version) {
89 Ok(client_version.to_string())
90 } else {
91 Err(SUPPORTED_PROTOCOL_VERSIONS
92 .iter()
93 .map(|v| v.to_string())
94 .collect())
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_supported_version() {
104 assert!(is_supported_protocol_version("2025-11-25"));
105 assert!(is_supported_protocol_version("2025-06-18"));
106 assert!(!is_supported_protocol_version("2024-01-01"));
107 }
108
109 #[test]
110 fn test_negotiate_supported_version() {
111 assert_eq!(
112 negotiate_protocol_version("2025-11-25"),
113 Ok("2025-11-25".to_string())
114 );
115 assert_eq!(
116 negotiate_protocol_version("2025-06-18"),
117 Ok("2025-06-18".to_string())
118 );
119 }
120
121 #[test]
122 fn test_negotiate_unsupported_version() {
123 let result = negotiate_protocol_version("2024-01-01");
124 assert!(result.is_err());
125 let supported = result.unwrap_err();
126 assert_eq!(supported, vec!["2025-11-25", "2025-06-18"]);
127 }
128}