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";