agent_client_protocol/mcp_server/
context.rs1use crate::{ConnectionTo, role::Role};
2
3#[cfg(feature = "unstable_mcp_over_acp")]
4use crate::schema::v1::{McpConnectionId, McpServerAcpId};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
8#[non_exhaustive]
9pub enum McpConnectionContext {
10 Standalone,
12
13 #[cfg(feature = "unstable_mcp_over_acp")]
15 #[cfg_attr(docsrs, doc(cfg(feature = "unstable_mcp_over_acp")))]
16 Acp {
17 server_id: McpServerAcpId,
19
20 connection_id: McpConnectionId,
22 },
23}
24
25impl McpConnectionContext {
26 #[must_use]
28 pub fn is_standalone(&self) -> bool {
29 matches!(self, Self::Standalone)
30 }
31
32 #[cfg(feature = "unstable_mcp_over_acp")]
36 #[cfg_attr(docsrs, doc(cfg(feature = "unstable_mcp_over_acp")))]
37 #[must_use]
38 pub fn server_id(&self) -> Option<&McpServerAcpId> {
39 match self {
40 Self::Standalone => None,
41 Self::Acp { server_id, .. } => Some(server_id),
42 }
43 }
44
45 #[cfg(feature = "unstable_mcp_over_acp")]
49 #[cfg_attr(docsrs, doc(cfg(feature = "unstable_mcp_over_acp")))]
50 #[must_use]
51 pub fn connection_id(&self) -> Option<&McpConnectionId> {
52 match self {
53 Self::Standalone => None,
54 Self::Acp { connection_id, .. } => Some(connection_id),
55 }
56 }
57}
58
59#[derive(Clone, Debug)]
61pub struct McpConnectionTo<Counterpart: Role> {
62 pub(super) context: McpConnectionContext,
63 pub(super) connection: ConnectionTo<Counterpart>,
64}
65
66impl<Counterpart: Role> McpConnectionTo<Counterpart> {
67 #[must_use]
69 pub fn context(&self) -> &McpConnectionContext {
70 &self.context
71 }
72
73 #[cfg(feature = "unstable_mcp_over_acp")]
77 #[cfg_attr(docsrs, doc(cfg(feature = "unstable_mcp_over_acp")))]
78 #[must_use]
79 pub fn server_id(&self) -> Option<&McpServerAcpId> {
80 self.context.server_id()
81 }
82
83 #[cfg(feature = "unstable_mcp_over_acp")]
87 #[cfg_attr(docsrs, doc(cfg(feature = "unstable_mcp_over_acp")))]
88 #[must_use]
89 pub fn connection_id(&self) -> Option<&McpConnectionId> {
90 self.context.connection_id()
91 }
92
93 #[must_use]
98 pub fn connection(&self) -> &ConnectionTo<Counterpart> {
99 &self.connection
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::McpConnectionContext;
106
107 #[test]
108 fn standalone_context_is_explicit() {
109 let context = McpConnectionContext::Standalone;
110
111 assert!(context.is_standalone());
112
113 #[cfg(feature = "unstable_mcp_over_acp")]
114 {
115 assert_eq!(context.server_id(), None);
116 assert_eq!(context.connection_id(), None);
117 }
118 }
119
120 #[cfg(feature = "unstable_mcp_over_acp")]
121 #[test]
122 fn acp_context_exposes_server_and_connection_ids() {
123 use crate::schema::v1::{McpConnectionId, McpServerAcpId};
124
125 let server_id = McpServerAcpId::new("server-id");
126 let connection_id = McpConnectionId::new("connection-id");
127 let context = McpConnectionContext::Acp {
128 server_id: server_id.clone(),
129 connection_id: connection_id.clone(),
130 };
131
132 assert!(!context.is_standalone());
133 assert_eq!(context.server_id(), Some(&server_id));
134 assert_eq!(context.connection_id(), Some(&connection_id));
135 }
136}