Skip to main content

agent_client_protocol_schema/v2/
mcp.rs

1//! MCP-over-ACP transport types.
2
3use std::sync::Arc;
4
5use derive_more::{Display, From};
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8use serde_json::value::RawValue;
9use serde_with::skip_serializing_none;
10
11use super::{McpServerAcpId, Meta};
12use crate::IntoOption;
13
14/// **UNSTABLE**
15///
16/// This capability is not part of the spec yet, and may be removed or changed at any point.
17///
18/// A unique identifier for an active MCP-over-ACP connection.
19#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
20#[serde(transparent)]
21#[from(Arc<str>, String, &'static str)]
22#[non_exhaustive]
23pub struct McpConnectionId(pub Arc<str>);
24
25impl McpConnectionId {
26    #[must_use]
27    pub fn new(id: impl Into<Arc<str>>) -> Self {
28        Self(id.into())
29    }
30}
31
32/// **UNSTABLE**
33///
34/// This capability is not part of the spec yet, and may be removed or changed at any point.
35///
36/// Request parameters for `mcp/connect`.
37#[skip_serializing_none]
38#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
39#[serde(rename_all = "camelCase")]
40#[schemars(extend("x-side" = "client", "x-method" = MCP_CONNECT_METHOD_NAME))]
41#[non_exhaustive]
42pub struct ConnectMcpRequest {
43    /// The ACP MCP server ID that was provided by the component declaring the MCP server.
44    pub acp_id: McpServerAcpId,
45    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
46    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
47    /// these keys.
48    ///
49    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
50    #[serde(rename = "_meta")]
51    pub meta: Option<Meta>,
52}
53
54impl ConnectMcpRequest {
55    #[must_use]
56    pub fn new(acp_id: impl Into<McpServerAcpId>) -> Self {
57        Self {
58            acp_id: acp_id.into(),
59            meta: None,
60        }
61    }
62
63    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
64    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
65    /// these keys.
66    ///
67    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
68    #[must_use]
69    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
70        self.meta = meta.into_option();
71        self
72    }
73}
74
75/// **UNSTABLE**
76///
77/// This capability is not part of the spec yet, and may be removed or changed at any point.
78///
79/// Response to `mcp/connect`.
80#[skip_serializing_none]
81#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
82#[serde(rename_all = "camelCase")]
83#[schemars(extend("x-side" = "client", "x-method" = MCP_CONNECT_METHOD_NAME))]
84#[non_exhaustive]
85pub struct ConnectMcpResponse {
86    /// The unique identifier for this MCP-over-ACP connection.
87    pub connection_id: McpConnectionId,
88    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
89    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
90    /// these keys.
91    ///
92    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
93    #[serde(rename = "_meta")]
94    pub meta: Option<Meta>,
95}
96
97impl ConnectMcpResponse {
98    #[must_use]
99    pub fn new(connection_id: impl Into<McpConnectionId>) -> Self {
100        Self {
101            connection_id: connection_id.into(),
102            meta: None,
103        }
104    }
105
106    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
107    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
108    /// these keys.
109    ///
110    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
111    #[must_use]
112    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
113        self.meta = meta.into_option();
114        self
115    }
116}
117
118/// **UNSTABLE**
119///
120/// This capability is not part of the spec yet, and may be removed or changed at any point.
121///
122/// Request parameters for `mcp/message`.
123#[skip_serializing_none]
124#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
125#[serde(rename_all = "camelCase")]
126#[schemars(extend("x-side" = "both", "x-method" = MCP_MESSAGE_METHOD_NAME))]
127#[non_exhaustive]
128pub struct MessageMcpRequest {
129    /// The MCP-over-ACP connection this message is sent on.
130    pub connection_id: McpConnectionId,
131    /// The inner MCP method name.
132    pub method: String,
133    /// Optional inner MCP params.
134    ///
135    /// If omitted or set to `null`, the inner MCP message has no params.
136    #[serde(default)]
137    pub params: Option<serde_json::Map<String, serde_json::Value>>,
138    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
139    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
140    /// these keys.
141    ///
142    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
143    #[serde(rename = "_meta")]
144    pub meta: Option<Meta>,
145}
146
147impl MessageMcpRequest {
148    #[must_use]
149    pub fn new(connection_id: impl Into<McpConnectionId>, method: impl Into<String>) -> Self {
150        Self {
151            connection_id: connection_id.into(),
152            method: method.into(),
153            params: None,
154            meta: None,
155        }
156    }
157
158    /// Optional inner MCP params.
159    ///
160    /// If omitted or set to `null`, the inner MCP message has no params.
161    #[must_use]
162    pub fn params(
163        mut self,
164        params: impl IntoOption<serde_json::Map<String, serde_json::Value>>,
165    ) -> Self {
166        self.params = params.into_option();
167        self
168    }
169
170    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
171    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
172    /// these keys.
173    ///
174    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
175    #[must_use]
176    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
177        self.meta = meta.into_option();
178        self
179    }
180}
181
182/// **UNSTABLE**
183///
184/// This capability is not part of the spec yet, and may be removed or changed at any point.
185///
186/// Notification parameters for `mcp/message`.
187///
188/// This is used when the wrapped MCP message is a notification and the outer JSON-RPC
189/// envelope has no `id`.
190#[skip_serializing_none]
191#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
192#[serde(rename_all = "camelCase")]
193#[schemars(extend("x-side" = "both", "x-method" = MCP_MESSAGE_METHOD_NAME))]
194#[non_exhaustive]
195pub struct MessageMcpNotification {
196    /// The MCP-over-ACP connection this message is sent on.
197    pub connection_id: McpConnectionId,
198    /// The inner MCP method name.
199    pub method: String,
200    /// Optional inner MCP params.
201    ///
202    /// If omitted or set to `null`, the inner MCP message has no params.
203    #[serde(default)]
204    pub params: Option<serde_json::Map<String, serde_json::Value>>,
205    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
206    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
207    /// these keys.
208    ///
209    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
210    #[serde(rename = "_meta")]
211    pub meta: Option<Meta>,
212}
213
214impl MessageMcpNotification {
215    #[must_use]
216    pub fn new(connection_id: impl Into<McpConnectionId>, method: impl Into<String>) -> Self {
217        Self {
218            connection_id: connection_id.into(),
219            method: method.into(),
220            params: None,
221            meta: None,
222        }
223    }
224
225    /// Optional inner MCP params.
226    ///
227    /// If omitted or set to `null`, the inner MCP message has no params.
228    #[must_use]
229    pub fn params(
230        mut self,
231        params: impl IntoOption<serde_json::Map<String, serde_json::Value>>,
232    ) -> Self {
233        self.params = params.into_option();
234        self
235    }
236
237    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
238    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
239    /// these keys.
240    ///
241    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
242    #[must_use]
243    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
244        self.meta = meta.into_option();
245        self
246    }
247}
248
249/// **UNSTABLE**
250///
251/// This capability is not part of the spec yet, and may be removed or changed at any point.
252///
253/// Response to `mcp/message`.
254///
255/// This is the inner MCP response result payload. Any JSON value is valid.
256#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, From)]
257#[serde(transparent)]
258#[schemars(extend("x-side" = "both", "x-method" = MCP_MESSAGE_METHOD_NAME))]
259#[non_exhaustive]
260pub struct MessageMcpResponse(#[schemars(with = "serde_json::Value")] pub Arc<RawValue>);
261
262impl MessageMcpResponse {
263    #[must_use]
264    pub fn new(result: Arc<RawValue>) -> Self {
265        Self(result)
266    }
267}
268
269/// **UNSTABLE**
270///
271/// This capability is not part of the spec yet, and may be removed or changed at any point.
272///
273/// Request parameters for `mcp/disconnect`.
274#[skip_serializing_none]
275#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
276#[serde(rename_all = "camelCase")]
277#[schemars(extend("x-side" = "client", "x-method" = MCP_DISCONNECT_METHOD_NAME))]
278#[non_exhaustive]
279pub struct DisconnectMcpRequest {
280    /// The MCP-over-ACP connection to close.
281    pub connection_id: McpConnectionId,
282    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
283    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
284    /// these keys.
285    ///
286    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
287    #[serde(rename = "_meta")]
288    pub meta: Option<Meta>,
289}
290
291impl DisconnectMcpRequest {
292    #[must_use]
293    pub fn new(connection_id: impl Into<McpConnectionId>) -> Self {
294        Self {
295            connection_id: connection_id.into(),
296            meta: None,
297        }
298    }
299
300    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
301    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
302    /// these keys.
303    ///
304    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
305    #[must_use]
306    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
307        self.meta = meta.into_option();
308        self
309    }
310}
311
312/// **UNSTABLE**
313///
314/// This capability is not part of the spec yet, and may be removed or changed at any point.
315///
316/// Response to `mcp/disconnect`.
317#[skip_serializing_none]
318#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
319#[serde(rename_all = "camelCase")]
320#[schemars(extend("x-side" = "client", "x-method" = MCP_DISCONNECT_METHOD_NAME))]
321#[non_exhaustive]
322pub struct DisconnectMcpResponse {
323    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
324    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
325    /// these keys.
326    ///
327    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
328    #[serde(rename = "_meta")]
329    pub meta: Option<Meta>,
330}
331
332impl DisconnectMcpResponse {
333    #[must_use]
334    pub fn new() -> Self {
335        Self::default()
336    }
337
338    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
339    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
340    /// these keys.
341    ///
342    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
343    #[must_use]
344    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
345        self.meta = meta.into_option();
346        self
347    }
348}
349
350/// Method name for opening an MCP-over-ACP connection.
351pub(crate) const MCP_CONNECT_METHOD_NAME: &str = "mcp/connect";
352/// Method name for exchanging MCP-over-ACP messages.
353pub(crate) const MCP_MESSAGE_METHOD_NAME: &str = "mcp/message";
354/// Method name for closing an MCP-over-ACP connection.
355pub(crate) const MCP_DISCONNECT_METHOD_NAME: &str = "mcp/disconnect";