agentic/mcp/capabilities/
client_capabilities.rs1use crate::mcp::support::{is_empty_object, serialize_bool_as_empty_object};
2use serde::de::{MapAccess, Visitor};
3use serde::ser::SerializeMap;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5use serde_json::Value;
6use serde_with::skip_serializing_none; use std::fmt;
8
9#[derive(Debug, Clone, Default, PartialEq)]
14pub struct ClientCapabilities {
15 pub experimental: Option<Value>, pub roots: Option<ClientRootsCapabilities>,
20
21 pub sampling: bool,
24}
25
26#[skip_serializing_none]
31#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct ClientRootsCapabilities {
34 pub list_changed: Option<bool>,
36}
37
38impl Serialize for ClientCapabilities {
40 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
41 where
42 S: Serializer,
43 {
44 let mut map = serializer.serialize_map(None)?; if let Some(experimental) = &self.experimental {
47 map.serialize_entry("experimental", experimental)?;
48 }
49 if let Some(roots) = &self.roots {
50 map.serialize_entry("roots", roots)?;
51 }
52 serialize_bool_as_empty_object::<S>(&mut map, "sampling", self.sampling)?;
54
55 map.end()
56 }
57}
58
59impl<'de> Deserialize<'de> for ClientCapabilities {
61 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
62 where
63 D: Deserializer<'de>,
64 {
65 struct ClientCapabilitiesVisitor;
66
67 impl<'de> Visitor<'de> for ClientCapabilitiesVisitor {
68 type Value = ClientCapabilities;
69
70 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
71 formatter.write_str("a map representing ClientCapabilities")
72 }
73
74 fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
75 where
76 M: MapAccess<'de>,
77 {
78 let mut experimental: Option<Value> = None;
79 let mut roots: Option<ClientRootsCapabilities> = None;
80 let mut sampling: bool = false; while let Some(key) = map.next_key::<String>()? {
83 match key.as_str() {
84 "experimental" => {
85 experimental = Some(map.next_value()?);
86 }
87 "roots" => {
88 roots = Some(map.next_value()?);
89 }
90 "sampling" => {
91 let sampling_value: Value = map.next_value()?;
93 if is_empty_object(&sampling_value) {
95 sampling = true;
96 }
97 }
99 _ => {
101 let _ = map.next_value::<Value>()?;
102 }
103 }
104 }
105
106 Ok(ClientCapabilities {
107 experimental,
108 roots,
109 sampling,
110 })
111 }
112 }
113
114 deserializer.deserialize_map(ClientCapabilitiesVisitor)
115 }
116}