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