Skip to main content

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