agent_client_protocol_schema/
agent.rs

1//! Methods and notifications the agent handles/receives.
2//!
3//! This module defines the Agent trait and all associated types for implementing
4//! an AI coding agent that follows the Agent Client Protocol (ACP).
5
6use std::{path::PathBuf, sync::Arc};
7
8use derive_more::{Display, From};
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11
12use crate::{
13    ClientCapabilities, ContentBlock, ExtNotification, ExtRequest, ExtResponse, IntoOption, Meta,
14    ProtocolVersion, SessionId,
15};
16
17// Initialize
18
19/// Request parameters for the initialize method.
20///
21/// Sent by the client to establish connection and negotiate capabilities.
22///
23/// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
24#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
25#[schemars(extend("x-side" = "agent", "x-method" = INITIALIZE_METHOD_NAME))]
26#[serde(rename_all = "camelCase")]
27#[non_exhaustive]
28pub struct InitializeRequest {
29    /// The latest protocol version supported by the client.
30    pub protocol_version: ProtocolVersion,
31    /// Capabilities supported by the client.
32    #[serde(default)]
33    pub client_capabilities: ClientCapabilities,
34    /// Information about the Client name and version sent to the Agent.
35    ///
36    /// Note: in future versions of the protocol, this will be required.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub client_info: Option<Implementation>,
39    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
40    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
41    /// these keys.
42    ///
43    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
44    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
45    pub meta: Option<Meta>,
46}
47
48impl InitializeRequest {
49    #[must_use]
50    pub fn new(protocol_version: ProtocolVersion) -> Self {
51        Self {
52            protocol_version,
53            client_capabilities: ClientCapabilities::default(),
54            client_info: None,
55            meta: None,
56        }
57    }
58
59    /// Capabilities supported by the client.
60    #[must_use]
61    pub fn client_capabilities(mut self, client_capabilities: ClientCapabilities) -> Self {
62        self.client_capabilities = client_capabilities;
63        self
64    }
65
66    /// Information about the Client name and version sent to the Agent.
67    #[must_use]
68    pub fn client_info(mut self, client_info: impl IntoOption<Implementation>) -> Self {
69        self.client_info = client_info.into_option();
70        self
71    }
72
73    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
74    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
75    /// these keys.
76    ///
77    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
78    #[must_use]
79    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
80        self.meta = meta.into_option();
81        self
82    }
83}
84
85/// Response to the `initialize` method.
86///
87/// Contains the negotiated protocol version and agent capabilities.
88///
89/// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
90#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
91#[schemars(extend("x-side" = "agent", "x-method" = INITIALIZE_METHOD_NAME))]
92#[serde(rename_all = "camelCase")]
93#[non_exhaustive]
94pub struct InitializeResponse {
95    /// The protocol version the client specified if supported by the agent,
96    /// or the latest protocol version supported by the agent.
97    ///
98    /// The client should disconnect, if it doesn't support this version.
99    pub protocol_version: ProtocolVersion,
100    /// Capabilities supported by the agent.
101    #[serde(default)]
102    pub agent_capabilities: AgentCapabilities,
103    /// Authentication methods supported by the agent.
104    #[serde(default)]
105    pub auth_methods: Vec<AuthMethod>,
106    /// Information about the Agent name and version sent to the Client.
107    ///
108    /// Note: in future versions of the protocol, this will be required.
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub agent_info: Option<Implementation>,
111    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
112    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
113    /// these keys.
114    ///
115    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
116    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
117    pub meta: Option<Meta>,
118}
119
120impl InitializeResponse {
121    #[must_use]
122    pub fn new(protocol_version: ProtocolVersion) -> Self {
123        Self {
124            protocol_version,
125            agent_capabilities: AgentCapabilities::default(),
126            auth_methods: vec![],
127            agent_info: None,
128            meta: None,
129        }
130    }
131
132    /// Capabilities supported by the agent.
133    #[must_use]
134    pub fn agent_capabilities(mut self, agent_capabilities: AgentCapabilities) -> Self {
135        self.agent_capabilities = agent_capabilities;
136        self
137    }
138
139    /// Authentication methods supported by the agent.
140    #[must_use]
141    pub fn auth_methods(mut self, auth_methods: Vec<AuthMethod>) -> Self {
142        self.auth_methods = auth_methods;
143        self
144    }
145
146    /// Information about the Agent name and version sent to the Client.
147    #[must_use]
148    pub fn agent_info(mut self, agent_info: impl IntoOption<Implementation>) -> Self {
149        self.agent_info = agent_info.into_option();
150        self
151    }
152
153    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
154    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
155    /// these keys.
156    ///
157    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
158    #[must_use]
159    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
160        self.meta = meta.into_option();
161        self
162    }
163}
164
165/// Metadata about the implementation of the client or agent.
166/// Describes the name and version of an MCP implementation, with an optional
167/// title for UI representation.
168#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
169#[serde(rename_all = "camelCase")]
170#[non_exhaustive]
171pub struct Implementation {
172    /// Intended for programmatic or logical use, but can be used as a display
173    /// name fallback if title isn’t present.
174    pub name: String,
175    /// Intended for UI and end-user contexts — optimized to be human-readable
176    /// and easily understood.
177    ///
178    /// If not provided, the name should be used for display.
179    pub title: Option<String>,
180    /// Version of the implementation. Can be displayed to the user or used
181    /// for debugging or metrics purposes. (e.g. "1.0.0").
182    pub version: String,
183    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
184    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
185    /// these keys.
186    ///
187    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
188    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
189    pub meta: Option<Meta>,
190}
191
192impl Implementation {
193    pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
194        Self {
195            name: name.into(),
196            title: None,
197            version: version.into(),
198            meta: None,
199        }
200    }
201
202    /// Intended for UI and end-user contexts — optimized to be human-readable
203    /// and easily understood.
204    ///
205    /// If not provided, the name should be used for display.
206    #[must_use]
207    pub fn title(mut self, title: impl IntoOption<String>) -> Self {
208        self.title = title.into_option();
209        self
210    }
211
212    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
213    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
214    /// these keys.
215    ///
216    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
217    #[must_use]
218    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
219        self.meta = meta.into_option();
220        self
221    }
222}
223
224// Authentication
225
226/// Request parameters for the authenticate method.
227///
228/// Specifies which authentication method to use.
229#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
230#[schemars(extend("x-side" = "agent", "x-method" = AUTHENTICATE_METHOD_NAME))]
231#[serde(rename_all = "camelCase")]
232#[non_exhaustive]
233pub struct AuthenticateRequest {
234    /// The ID of the authentication method to use.
235    /// Must be one of the methods advertised in the initialize response.
236    pub method_id: AuthMethodId,
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    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
243    pub meta: Option<Meta>,
244}
245
246impl AuthenticateRequest {
247    #[must_use]
248    pub fn new(method_id: impl Into<AuthMethodId>) -> Self {
249        Self {
250            method_id: method_id.into(),
251            meta: None,
252        }
253    }
254
255    #[must_use]
256    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
257        self.meta = meta.into_option();
258        self
259    }
260}
261
262/// Response to the `authenticate` method.
263#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
264#[serde(rename_all = "camelCase")]
265#[schemars(extend("x-side" = "agent", "x-method" = AUTHENTICATE_METHOD_NAME))]
266#[non_exhaustive]
267pub struct AuthenticateResponse {
268    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
269    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
270    /// these keys.
271    ///
272    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
273    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
274    pub meta: Option<Meta>,
275}
276
277impl AuthenticateResponse {
278    #[must_use]
279    pub fn new() -> Self {
280        Self::default()
281    }
282
283    #[must_use]
284    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
285        self.meta = meta.into_option();
286        self
287    }
288}
289
290#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
291#[serde(transparent)]
292#[from(Arc<str>, String, &'static str)]
293#[non_exhaustive]
294pub struct AuthMethodId(pub Arc<str>);
295
296impl AuthMethodId {
297    pub fn new(id: impl Into<Arc<str>>) -> Self {
298        Self(id.into())
299    }
300}
301
302/// Describes an available authentication method.
303#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
304#[serde(rename_all = "camelCase")]
305#[non_exhaustive]
306pub struct AuthMethod {
307    /// Unique identifier for this authentication method.
308    pub id: AuthMethodId,
309    /// Human-readable name of the authentication method.
310    pub name: String,
311    /// Optional description providing more details about this authentication method.
312    pub description: Option<String>,
313    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
314    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
315    /// these keys.
316    ///
317    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
318    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
319    pub meta: Option<Meta>,
320}
321
322impl AuthMethod {
323    pub fn new(id: impl Into<AuthMethodId>, name: impl Into<String>) -> Self {
324        Self {
325            id: id.into(),
326            name: name.into(),
327            description: None,
328            meta: None,
329        }
330    }
331
332    /// Optional description providing more details about this authentication method.
333    #[must_use]
334    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
335        self.description = description.into_option();
336        self
337    }
338
339    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
340    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
341    /// these keys.
342    ///
343    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
344    #[must_use]
345    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
346        self.meta = meta.into_option();
347        self
348    }
349}
350
351// New session
352
353/// Request parameters for creating a new session.
354///
355/// See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)
356#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
357#[schemars(extend("x-side" = "agent", "x-method" = SESSION_NEW_METHOD_NAME))]
358#[serde(rename_all = "camelCase")]
359#[non_exhaustive]
360pub struct NewSessionRequest {
361    /// The working directory for this session. Must be an absolute path.
362    pub cwd: PathBuf,
363    /// List of MCP (Model Context Protocol) servers the agent should connect to.
364    pub mcp_servers: Vec<McpServer>,
365    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
366    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
367    /// these keys.
368    ///
369    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
370    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
371    pub meta: Option<Meta>,
372}
373
374impl NewSessionRequest {
375    pub fn new(cwd: impl Into<PathBuf>) -> Self {
376        Self {
377            cwd: cwd.into(),
378            mcp_servers: vec![],
379            meta: None,
380        }
381    }
382
383    /// List of MCP (Model Context Protocol) servers the agent should connect to.
384    #[must_use]
385    pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
386        self.mcp_servers = mcp_servers;
387        self
388    }
389
390    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
391    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
392    /// these keys.
393    ///
394    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
395    #[must_use]
396    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
397        self.meta = meta.into_option();
398        self
399    }
400}
401
402/// Response from creating a new session.
403///
404/// See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)
405#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
406#[schemars(extend("x-side" = "agent", "x-method" = SESSION_NEW_METHOD_NAME))]
407#[serde(rename_all = "camelCase")]
408#[non_exhaustive]
409pub struct NewSessionResponse {
410    /// Unique identifier for the created session.
411    ///
412    /// Used in all subsequent requests for this conversation.
413    pub session_id: SessionId,
414    /// Initial mode state if supported by the Agent
415    ///
416    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
417    #[serde(skip_serializing_if = "Option::is_none")]
418    pub modes: Option<SessionModeState>,
419    /// **UNSTABLE**
420    ///
421    /// This capability is not part of the spec yet, and may be removed or changed at any point.
422    ///
423    /// Initial model state if supported by the Agent
424    #[cfg(feature = "unstable_session_model")]
425    #[serde(skip_serializing_if = "Option::is_none")]
426    pub models: Option<SessionModelState>,
427    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
428    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
429    /// these keys.
430    ///
431    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
432    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
433    pub meta: Option<Meta>,
434}
435
436impl NewSessionResponse {
437    #[must_use]
438    pub fn new(session_id: impl Into<SessionId>) -> Self {
439        Self {
440            session_id: session_id.into(),
441            modes: None,
442            #[cfg(feature = "unstable_session_model")]
443            models: None,
444            meta: None,
445        }
446    }
447
448    /// Initial mode state if supported by the Agent
449    ///
450    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
451    #[must_use]
452    pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
453        self.modes = modes.into_option();
454        self
455    }
456
457    /// **UNSTABLE**
458    ///
459    /// This capability is not part of the spec yet, and may be removed or changed at any point.
460    ///
461    /// Initial model state if supported by the Agent
462    #[cfg(feature = "unstable_session_model")]
463    #[must_use]
464    pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
465        self.models = models.into_option();
466        self
467    }
468
469    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
470    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
471    /// these keys.
472    ///
473    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
474    #[must_use]
475    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
476        self.meta = meta.into_option();
477        self
478    }
479}
480
481// Load session
482
483/// Request parameters for loading an existing session.
484///
485/// Only available if the Agent supports the `loadSession` capability.
486///
487/// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
488#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
489#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
490#[serde(rename_all = "camelCase")]
491#[non_exhaustive]
492pub struct LoadSessionRequest {
493    /// List of MCP servers to connect to for this session.
494    pub mcp_servers: Vec<McpServer>,
495    /// The working directory for this session.
496    pub cwd: PathBuf,
497    /// The ID of the session to load.
498    pub session_id: SessionId,
499    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
500    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
501    /// these keys.
502    ///
503    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
504    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
505    pub meta: Option<Meta>,
506}
507
508impl LoadSessionRequest {
509    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
510        Self {
511            mcp_servers: vec![],
512            cwd: cwd.into(),
513            session_id: session_id.into(),
514            meta: None,
515        }
516    }
517
518    /// List of MCP servers to connect to for this session.
519    #[must_use]
520    pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
521        self.mcp_servers = mcp_servers;
522        self
523    }
524
525    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
526    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
527    /// these keys.
528    ///
529    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
530    #[must_use]
531    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
532        self.meta = meta.into_option();
533        self
534    }
535}
536
537/// Response from loading an existing session.
538#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
539#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
540#[serde(rename_all = "camelCase")]
541#[non_exhaustive]
542pub struct LoadSessionResponse {
543    /// Initial mode state if supported by the Agent
544    ///
545    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
546    #[serde(default, skip_serializing_if = "Option::is_none")]
547    pub modes: Option<SessionModeState>,
548    /// **UNSTABLE**
549    ///
550    /// This capability is not part of the spec yet, and may be removed or changed at any point.
551    ///
552    /// Initial model state if supported by the Agent
553    #[cfg(feature = "unstable_session_model")]
554    #[serde(default, skip_serializing_if = "Option::is_none")]
555    pub models: Option<SessionModelState>,
556    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
557    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
558    /// these keys.
559    ///
560    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
561    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
562    pub meta: Option<Meta>,
563}
564
565impl LoadSessionResponse {
566    #[must_use]
567    pub fn new() -> Self {
568        Self::default()
569    }
570
571    /// Initial mode state if supported by the Agent
572    ///
573    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
574    #[must_use]
575    pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
576        self.modes = modes.into_option();
577        self
578    }
579
580    /// **UNSTABLE**
581    ///
582    /// This capability is not part of the spec yet, and may be removed or changed at any point.
583    ///
584    /// Initial model state if supported by the Agent
585    #[cfg(feature = "unstable_session_model")]
586    #[must_use]
587    pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
588        self.models = models.into_option();
589        self
590    }
591
592    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
593    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
594    /// these keys.
595    ///
596    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
597    #[must_use]
598    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
599        self.meta = meta.into_option();
600        self
601    }
602}
603
604// Fork session
605
606/// **UNSTABLE**
607///
608/// This capability is not part of the spec yet, and may be removed or changed at any point.
609///
610/// Request parameters for forking an existing session.
611///
612/// Creates a new session based on the context of an existing one, allowing
613/// operations like generating summaries without affecting the original session's history.
614///
615/// Only available if the Agent supports the `session.fork` capability.
616#[cfg(feature = "unstable_session_fork")]
617#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
618#[schemars(extend("x-side" = "agent", "x-method" = SESSION_FORK_METHOD_NAME))]
619#[serde(rename_all = "camelCase")]
620#[non_exhaustive]
621pub struct ForkSessionRequest {
622    /// The ID of the session to fork.
623    pub session_id: SessionId,
624    /// The working directory for this session.
625    pub cwd: PathBuf,
626    /// List of MCP servers to connect to for this session.
627    #[serde(default, skip_serializing_if = "Vec::is_empty")]
628    pub mcp_servers: Vec<McpServer>,
629    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
630    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
631    /// these keys.
632    ///
633    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
634    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
635    pub meta: Option<Meta>,
636}
637
638#[cfg(feature = "unstable_session_fork")]
639impl ForkSessionRequest {
640    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
641        Self {
642            session_id: session_id.into(),
643            cwd: cwd.into(),
644            mcp_servers: vec![],
645            meta: None,
646        }
647    }
648
649    /// List of MCP servers to connect to for this session.
650    #[must_use]
651    pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
652        self.mcp_servers = mcp_servers;
653        self
654    }
655
656    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
657    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
658    /// these keys.
659    ///
660    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
661    #[must_use]
662    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
663        self.meta = meta.into_option();
664        self
665    }
666}
667
668/// **UNSTABLE**
669///
670/// This capability is not part of the spec yet, and may be removed or changed at any point.
671///
672/// Response from forking an existing session.
673#[cfg(feature = "unstable_session_fork")]
674#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
675#[schemars(extend("x-side" = "agent", "x-method" = SESSION_FORK_METHOD_NAME))]
676#[serde(rename_all = "camelCase")]
677#[non_exhaustive]
678pub struct ForkSessionResponse {
679    /// Unique identifier for the newly created forked session.
680    pub session_id: SessionId,
681    /// Initial mode state if supported by the Agent
682    ///
683    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
684    #[serde(skip_serializing_if = "Option::is_none")]
685    pub modes: Option<SessionModeState>,
686    /// **UNSTABLE**
687    ///
688    /// This capability is not part of the spec yet, and may be removed or changed at any point.
689    ///
690    /// Initial model state if supported by the Agent
691    #[cfg(feature = "unstable_session_model")]
692    #[serde(skip_serializing_if = "Option::is_none")]
693    pub models: Option<SessionModelState>,
694    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
695    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
696    /// these keys.
697    ///
698    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
699    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
700    pub meta: Option<Meta>,
701}
702
703#[cfg(feature = "unstable_session_fork")]
704impl ForkSessionResponse {
705    #[must_use]
706    pub fn new(session_id: impl Into<SessionId>) -> Self {
707        Self {
708            session_id: session_id.into(),
709            modes: None,
710            #[cfg(feature = "unstable_session_model")]
711            models: None,
712            meta: None,
713        }
714    }
715
716    /// Initial mode state if supported by the Agent
717    ///
718    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
719    #[must_use]
720    pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
721        self.modes = modes.into_option();
722        self
723    }
724
725    /// **UNSTABLE**
726    ///
727    /// This capability is not part of the spec yet, and may be removed or changed at any point.
728    ///
729    /// Initial model state if supported by the Agent
730    #[cfg(feature = "unstable_session_model")]
731    #[must_use]
732    pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
733        self.models = models.into_option();
734        self
735    }
736
737    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
738    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
739    /// these keys.
740    ///
741    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
742    #[must_use]
743    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
744        self.meta = meta.into_option();
745        self
746    }
747}
748
749// Resume session
750
751/// **UNSTABLE**
752///
753/// This capability is not part of the spec yet, and may be removed or changed at any point.
754///
755/// Request parameters for resuming an existing session.
756///
757/// Resumes an existing session without returning previous messages (unlike `session/load`).
758/// This is useful for agents that can resume sessions but don't implement full session loading.
759///
760/// Only available if the Agent supports the `session.resume` capability.
761#[cfg(feature = "unstable_session_resume")]
762#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
763#[schemars(extend("x-side" = "agent", "x-method" = SESSION_RESUME_METHOD_NAME))]
764#[serde(rename_all = "camelCase")]
765#[non_exhaustive]
766pub struct ResumeSessionRequest {
767    /// The ID of the session to resume.
768    pub session_id: SessionId,
769    /// The working directory for this session.
770    pub cwd: PathBuf,
771    /// List of MCP servers to connect to for this session.
772    #[serde(default, skip_serializing_if = "Vec::is_empty")]
773    pub mcp_servers: Vec<McpServer>,
774    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
775    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
776    /// these keys.
777    ///
778    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
779    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
780    pub meta: Option<Meta>,
781}
782
783#[cfg(feature = "unstable_session_resume")]
784impl ResumeSessionRequest {
785    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
786        Self {
787            session_id: session_id.into(),
788            cwd: cwd.into(),
789            mcp_servers: vec![],
790            meta: None,
791        }
792    }
793
794    /// List of MCP servers to connect to for this session.
795    #[must_use]
796    pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
797        self.mcp_servers = mcp_servers;
798        self
799    }
800
801    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
802    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
803    /// these keys.
804    ///
805    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
806    #[must_use]
807    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
808        self.meta = meta.into_option();
809        self
810    }
811}
812
813/// **UNSTABLE**
814///
815/// This capability is not part of the spec yet, and may be removed or changed at any point.
816///
817/// Response from resuming an existing session.
818#[cfg(feature = "unstable_session_resume")]
819#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
820#[schemars(extend("x-side" = "agent", "x-method" = SESSION_RESUME_METHOD_NAME))]
821#[serde(rename_all = "camelCase")]
822#[non_exhaustive]
823pub struct ResumeSessionResponse {
824    /// Initial mode state if supported by the Agent
825    ///
826    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
827    #[serde(default, skip_serializing_if = "Option::is_none")]
828    pub modes: Option<SessionModeState>,
829    /// **UNSTABLE**
830    ///
831    /// This capability is not part of the spec yet, and may be removed or changed at any point.
832    ///
833    /// Initial model state if supported by the Agent
834    #[cfg(feature = "unstable_session_model")]
835    #[serde(default, skip_serializing_if = "Option::is_none")]
836    pub models: Option<SessionModelState>,
837    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
838    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
839    /// these keys.
840    ///
841    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
842    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
843    pub meta: Option<Meta>,
844}
845
846#[cfg(feature = "unstable_session_resume")]
847impl ResumeSessionResponse {
848    #[must_use]
849    pub fn new() -> Self {
850        Self::default()
851    }
852
853    /// Initial mode state if supported by the Agent
854    ///
855    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
856    #[must_use]
857    pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
858        self.modes = modes.into_option();
859        self
860    }
861
862    /// **UNSTABLE**
863    ///
864    /// This capability is not part of the spec yet, and may be removed or changed at any point.
865    ///
866    /// Initial model state if supported by the Agent
867    #[cfg(feature = "unstable_session_model")]
868    #[must_use]
869    pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
870        self.models = models.into_option();
871        self
872    }
873
874    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
875    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
876    /// these keys.
877    ///
878    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
879    #[must_use]
880    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
881        self.meta = meta.into_option();
882        self
883    }
884}
885
886// List sessions
887
888/// **UNSTABLE**
889///
890/// This capability is not part of the spec yet, and may be removed or changed at any point.
891///
892/// Request parameters for listing existing sessions.
893///
894/// Only available if the Agent supports the `listSessions` capability.
895#[cfg(feature = "unstable_session_list")]
896#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
897#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
898#[serde(rename_all = "camelCase")]
899#[non_exhaustive]
900pub struct ListSessionsRequest {
901    /// Filter sessions by working directory. Must be an absolute path.
902    #[serde(skip_serializing_if = "Option::is_none")]
903    pub cwd: Option<PathBuf>,
904    /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
905    #[serde(skip_serializing_if = "Option::is_none")]
906    pub cursor: Option<String>,
907    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
908    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
909    /// these keys.
910    ///
911    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
912    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
913    pub meta: Option<Meta>,
914}
915
916#[cfg(feature = "unstable_session_list")]
917impl ListSessionsRequest {
918    #[must_use]
919    pub fn new() -> Self {
920        Self::default()
921    }
922
923    /// Filter sessions by working directory. Must be an absolute path.
924    #[must_use]
925    pub fn cwd(mut self, cwd: impl IntoOption<PathBuf>) -> Self {
926        self.cwd = cwd.into_option();
927        self
928    }
929
930    /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
931    #[must_use]
932    pub fn cursor(mut self, cursor: impl IntoOption<String>) -> Self {
933        self.cursor = cursor.into_option();
934        self
935    }
936
937    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
938    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
939    /// these keys.
940    ///
941    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
942    #[must_use]
943    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
944        self.meta = meta.into_option();
945        self
946    }
947}
948
949/// **UNSTABLE**
950///
951/// This capability is not part of the spec yet, and may be removed or changed at any point.
952///
953/// Response from listing sessions.
954#[cfg(feature = "unstable_session_list")]
955#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
956#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
957#[serde(rename_all = "camelCase")]
958#[non_exhaustive]
959pub struct ListSessionsResponse {
960    /// Array of session information objects
961    pub sessions: Vec<SessionInfo>,
962    /// Opaque cursor token. If present, pass this in the next request's cursor parameter
963    /// to fetch the next page. If absent, there are no more results.
964    #[serde(skip_serializing_if = "Option::is_none")]
965    pub next_cursor: Option<String>,
966    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
967    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
968    /// these keys.
969    ///
970    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
971    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
972    pub meta: Option<Meta>,
973}
974
975#[cfg(feature = "unstable_session_list")]
976impl ListSessionsResponse {
977    #[must_use]
978    pub fn new(sessions: Vec<SessionInfo>) -> Self {
979        Self {
980            sessions,
981            next_cursor: None,
982            meta: None,
983        }
984    }
985
986    #[must_use]
987    pub fn next_cursor(mut self, next_cursor: impl IntoOption<String>) -> Self {
988        self.next_cursor = next_cursor.into_option();
989        self
990    }
991
992    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
993    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
994    /// these keys.
995    ///
996    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
997    #[must_use]
998    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
999        self.meta = meta.into_option();
1000        self
1001    }
1002}
1003
1004/// **UNSTABLE**
1005///
1006/// This capability is not part of the spec yet, and may be removed or changed at any point.
1007///
1008/// Information about a session returned by session/list
1009#[cfg(feature = "unstable_session_list")]
1010#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1011#[serde(rename_all = "camelCase")]
1012#[non_exhaustive]
1013pub struct SessionInfo {
1014    /// Unique identifier for the session
1015    pub session_id: SessionId,
1016    /// The working directory for this session. Must be an absolute path.
1017    pub cwd: PathBuf,
1018    /// Human-readable title for the session
1019    #[serde(skip_serializing_if = "Option::is_none")]
1020    pub title: Option<String>,
1021    /// ISO 8601 timestamp of last activity
1022    #[serde(skip_serializing_if = "Option::is_none")]
1023    pub updated_at: Option<String>,
1024    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1025    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1026    /// these keys.
1027    ///
1028    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1029    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1030    pub meta: Option<Meta>,
1031}
1032
1033#[cfg(feature = "unstable_session_list")]
1034impl SessionInfo {
1035    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
1036        Self {
1037            session_id: session_id.into(),
1038            cwd: cwd.into(),
1039            title: None,
1040            updated_at: None,
1041            meta: None,
1042        }
1043    }
1044
1045    /// Human-readable title for the session
1046    #[must_use]
1047    pub fn title(mut self, title: impl IntoOption<String>) -> Self {
1048        self.title = title.into_option();
1049        self
1050    }
1051
1052    /// ISO 8601 timestamp of last activity
1053    #[must_use]
1054    pub fn updated_at(mut self, updated_at: impl IntoOption<String>) -> Self {
1055        self.updated_at = updated_at.into_option();
1056        self
1057    }
1058
1059    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1060    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1061    /// these keys.
1062    ///
1063    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1064    #[must_use]
1065    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1066        self.meta = meta.into_option();
1067        self
1068    }
1069}
1070
1071// Session modes
1072
1073/// The set of modes and the one currently active.
1074#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1075#[serde(rename_all = "camelCase")]
1076#[non_exhaustive]
1077pub struct SessionModeState {
1078    /// The current mode the Agent is in.
1079    pub current_mode_id: SessionModeId,
1080    /// The set of modes that the Agent can operate in
1081    pub available_modes: Vec<SessionMode>,
1082    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1083    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1084    /// these keys.
1085    ///
1086    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1087    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1088    pub meta: Option<Meta>,
1089}
1090
1091impl SessionModeState {
1092    #[must_use]
1093    pub fn new(
1094        current_mode_id: impl Into<SessionModeId>,
1095        available_modes: Vec<SessionMode>,
1096    ) -> Self {
1097        Self {
1098            current_mode_id: current_mode_id.into(),
1099            available_modes,
1100            meta: None,
1101        }
1102    }
1103
1104    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1105    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1106    /// these keys.
1107    ///
1108    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1109    #[must_use]
1110    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1111        self.meta = meta.into_option();
1112        self
1113    }
1114}
1115
1116/// A mode the agent can operate in.
1117///
1118/// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
1119#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1120#[serde(rename_all = "camelCase")]
1121#[non_exhaustive]
1122pub struct SessionMode {
1123    pub id: SessionModeId,
1124    pub name: String,
1125    #[serde(default, skip_serializing_if = "Option::is_none")]
1126    pub description: Option<String>,
1127    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1128    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1129    /// these keys.
1130    ///
1131    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1132    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1133    pub meta: Option<Meta>,
1134}
1135
1136impl SessionMode {
1137    pub fn new(id: impl Into<SessionModeId>, name: impl Into<String>) -> Self {
1138        Self {
1139            id: id.into(),
1140            name: name.into(),
1141            description: None,
1142            meta: None,
1143        }
1144    }
1145
1146    #[must_use]
1147    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1148        self.description = description.into_option();
1149        self
1150    }
1151
1152    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1153    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1154    /// these keys.
1155    ///
1156    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1157    #[must_use]
1158    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1159        self.meta = meta.into_option();
1160        self
1161    }
1162}
1163
1164/// Unique identifier for a Session Mode.
1165#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1166#[serde(transparent)]
1167#[from(Arc<str>, String, &'static str)]
1168#[non_exhaustive]
1169pub struct SessionModeId(pub Arc<str>);
1170
1171impl SessionModeId {
1172    pub fn new(id: impl Into<Arc<str>>) -> Self {
1173        Self(id.into())
1174    }
1175}
1176
1177/// Request parameters for setting a session mode.
1178#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1179#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
1180#[serde(rename_all = "camelCase")]
1181#[non_exhaustive]
1182pub struct SetSessionModeRequest {
1183    /// The ID of the session to set the mode for.
1184    pub session_id: SessionId,
1185    /// The ID of the mode to set.
1186    pub mode_id: SessionModeId,
1187    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1188    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1189    /// these keys.
1190    ///
1191    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1192    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1193    pub meta: Option<Meta>,
1194}
1195
1196impl SetSessionModeRequest {
1197    #[must_use]
1198    pub fn new(session_id: impl Into<SessionId>, mode_id: impl Into<SessionModeId>) -> Self {
1199        Self {
1200            session_id: session_id.into(),
1201            mode_id: mode_id.into(),
1202            meta: None,
1203        }
1204    }
1205
1206    #[must_use]
1207    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1208        self.meta = meta.into_option();
1209        self
1210    }
1211}
1212
1213/// Response to `session/set_mode` method.
1214#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1215#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
1216#[serde(rename_all = "camelCase")]
1217#[non_exhaustive]
1218pub struct SetSessionModeResponse {
1219    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1220    pub meta: Option<Meta>,
1221}
1222
1223impl SetSessionModeResponse {
1224    #[must_use]
1225    pub fn new() -> Self {
1226        Self::default()
1227    }
1228
1229    #[must_use]
1230    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1231        self.meta = meta.into_option();
1232        self
1233    }
1234}
1235
1236// MCP
1237
1238/// Configuration for connecting to an MCP (Model Context Protocol) server.
1239///
1240/// MCP servers provide tools and context that the agent can use when
1241/// processing prompts.
1242///
1243/// See protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)
1244#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1245#[serde(tag = "type", rename_all = "snake_case")]
1246#[non_exhaustive]
1247pub enum McpServer {
1248    /// HTTP transport configuration
1249    ///
1250    /// Only available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.
1251    Http(McpServerHttp),
1252    /// SSE transport configuration
1253    ///
1254    /// Only available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.
1255    Sse(McpServerSse),
1256    /// Stdio transport configuration
1257    ///
1258    /// All Agents MUST support this transport.
1259    #[serde(untagged)]
1260    Stdio(McpServerStdio),
1261}
1262
1263/// HTTP transport configuration for MCP.
1264#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1265#[serde(rename_all = "camelCase")]
1266#[non_exhaustive]
1267pub struct McpServerHttp {
1268    /// Human-readable name identifying this MCP server.
1269    pub name: String,
1270    /// URL to the MCP server.
1271    pub url: String,
1272    /// HTTP headers to set when making requests to the MCP server.
1273    pub headers: Vec<HttpHeader>,
1274    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1275    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1276    /// these keys.
1277    ///
1278    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1279    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1280    pub meta: Option<Meta>,
1281}
1282
1283impl McpServerHttp {
1284    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1285        Self {
1286            name: name.into(),
1287            url: url.into(),
1288            headers: Vec::new(),
1289            meta: None,
1290        }
1291    }
1292
1293    /// HTTP headers to set when making requests to the MCP server.
1294    #[must_use]
1295    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1296        self.headers = headers;
1297        self
1298    }
1299
1300    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1301    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1302    /// these keys.
1303    ///
1304    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1305    #[must_use]
1306    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1307        self.meta = meta.into_option();
1308        self
1309    }
1310}
1311
1312/// SSE transport configuration for MCP.
1313#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1314#[serde(rename_all = "camelCase")]
1315#[non_exhaustive]
1316pub struct McpServerSse {
1317    /// Human-readable name identifying this MCP server.
1318    pub name: String,
1319    /// URL to the MCP server.
1320    pub url: String,
1321    /// HTTP headers to set when making requests to the MCP server.
1322    pub headers: Vec<HttpHeader>,
1323    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1324    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1325    /// these keys.
1326    ///
1327    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1328    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1329    pub meta: Option<Meta>,
1330}
1331
1332impl McpServerSse {
1333    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1334        Self {
1335            name: name.into(),
1336            url: url.into(),
1337            headers: Vec::new(),
1338            meta: None,
1339        }
1340    }
1341
1342    /// HTTP headers to set when making requests to the MCP server.
1343    #[must_use]
1344    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1345        self.headers = headers;
1346        self
1347    }
1348
1349    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1350    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1351    /// these keys.
1352    ///
1353    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1354    #[must_use]
1355    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1356        self.meta = meta.into_option();
1357        self
1358    }
1359}
1360
1361/// Stdio transport configuration for MCP.
1362#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1363#[serde(rename_all = "camelCase")]
1364#[non_exhaustive]
1365pub struct McpServerStdio {
1366    /// Human-readable name identifying this MCP server.
1367    pub name: String,
1368    /// Path to the MCP server executable.
1369    pub command: PathBuf,
1370    /// Command-line arguments to pass to the MCP server.
1371    pub args: Vec<String>,
1372    /// Environment variables to set when launching the MCP server.
1373    pub env: Vec<EnvVariable>,
1374    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1375    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1376    /// these keys.
1377    ///
1378    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1379    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1380    pub meta: Option<Meta>,
1381}
1382
1383impl McpServerStdio {
1384    pub fn new(name: impl Into<String>, command: impl Into<PathBuf>) -> Self {
1385        Self {
1386            name: name.into(),
1387            command: command.into(),
1388            args: Vec::new(),
1389            env: Vec::new(),
1390            meta: None,
1391        }
1392    }
1393
1394    /// Command-line arguments to pass to the MCP server.
1395    #[must_use]
1396    pub fn args(mut self, args: Vec<String>) -> Self {
1397        self.args = args;
1398        self
1399    }
1400
1401    /// Environment variables to set when launching the MCP server.
1402    #[must_use]
1403    pub fn env(mut self, env: Vec<EnvVariable>) -> Self {
1404        self.env = env;
1405        self
1406    }
1407
1408    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1409    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1410    /// these keys.
1411    ///
1412    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1413    #[must_use]
1414    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1415        self.meta = meta.into_option();
1416        self
1417    }
1418}
1419
1420/// An environment variable to set when launching an MCP server.
1421#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1422#[serde(rename_all = "camelCase")]
1423#[non_exhaustive]
1424pub struct EnvVariable {
1425    /// The name of the environment variable.
1426    pub name: String,
1427    /// The value to set for the environment variable.
1428    pub value: String,
1429    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1430    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1431    /// these keys.
1432    ///
1433    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1434    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1435    pub meta: Option<Meta>,
1436}
1437
1438impl EnvVariable {
1439    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1440        Self {
1441            name: name.into(),
1442            value: value.into(),
1443            meta: None,
1444        }
1445    }
1446
1447    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1448    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1449    /// these keys.
1450    ///
1451    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1452    #[must_use]
1453    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1454        self.meta = meta.into_option();
1455        self
1456    }
1457}
1458
1459/// An HTTP header to set when making requests to the MCP server.
1460#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1461#[serde(rename_all = "camelCase")]
1462#[non_exhaustive]
1463pub struct HttpHeader {
1464    /// The name of the HTTP header.
1465    pub name: String,
1466    /// The value to set for the HTTP header.
1467    pub value: String,
1468    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1469    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1470    /// these keys.
1471    ///
1472    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1473    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1474    pub meta: Option<Meta>,
1475}
1476
1477impl HttpHeader {
1478    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1479        Self {
1480            name: name.into(),
1481            value: value.into(),
1482            meta: None,
1483        }
1484    }
1485
1486    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1487    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1488    /// these keys.
1489    ///
1490    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1491    #[must_use]
1492    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1493        self.meta = meta.into_option();
1494        self
1495    }
1496}
1497
1498// Prompt
1499
1500/// Request parameters for sending a user prompt to the agent.
1501///
1502/// Contains the user's message and any additional context.
1503///
1504/// See protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)
1505#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
1506#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1507#[serde(rename_all = "camelCase")]
1508#[non_exhaustive]
1509pub struct PromptRequest {
1510    /// The ID of the session to send this user message to
1511    pub session_id: SessionId,
1512    /// The blocks of content that compose the user's message.
1513    ///
1514    /// As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],
1515    /// while other variants are optionally enabled via [`PromptCapabilities`].
1516    ///
1517    /// The Client MUST adapt its interface according to [`PromptCapabilities`].
1518    ///
1519    /// The client MAY include referenced pieces of context as either
1520    /// [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].
1521    ///
1522    /// When available, [`ContentBlock::Resource`] is preferred
1523    /// as it avoids extra round-trips and allows the message to include
1524    /// pieces of context from sources the agent may not have access to.
1525    pub prompt: Vec<ContentBlock>,
1526    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1527    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1528    /// these keys.
1529    ///
1530    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1531    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1532    pub meta: Option<Meta>,
1533}
1534
1535impl PromptRequest {
1536    #[must_use]
1537    pub fn new(session_id: impl Into<SessionId>, prompt: Vec<ContentBlock>) -> Self {
1538        Self {
1539            session_id: session_id.into(),
1540            prompt,
1541            meta: None,
1542        }
1543    }
1544
1545    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1546    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1547    /// these keys.
1548    ///
1549    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1550    #[must_use]
1551    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1552        self.meta = meta.into_option();
1553        self
1554    }
1555}
1556
1557/// Response from processing a user prompt.
1558///
1559/// See protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)
1560#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1561#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1562#[serde(rename_all = "camelCase")]
1563#[non_exhaustive]
1564pub struct PromptResponse {
1565    /// Indicates why the agent stopped processing the turn.
1566    pub stop_reason: StopReason,
1567    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1568    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1569    /// these keys.
1570    ///
1571    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1572    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1573    pub meta: Option<Meta>,
1574}
1575
1576impl PromptResponse {
1577    #[must_use]
1578    pub fn new(stop_reason: StopReason) -> Self {
1579        Self {
1580            stop_reason,
1581            meta: None,
1582        }
1583    }
1584
1585    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1586    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1587    /// these keys.
1588    ///
1589    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1590    #[must_use]
1591    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1592        self.meta = meta.into_option();
1593        self
1594    }
1595}
1596
1597/// Reasons why an agent stops processing a prompt turn.
1598///
1599/// See protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)
1600#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1601#[serde(rename_all = "snake_case")]
1602#[non_exhaustive]
1603pub enum StopReason {
1604    /// The turn ended successfully.
1605    EndTurn,
1606    /// The turn ended because the agent reached the maximum number of tokens.
1607    MaxTokens,
1608    /// The turn ended because the agent reached the maximum number of allowed
1609    /// agent requests between user turns.
1610    MaxTurnRequests,
1611    /// The turn ended because the agent refused to continue. The user prompt
1612    /// and everything that comes after it won't be included in the next
1613    /// prompt, so this should be reflected in the UI.
1614    Refusal,
1615    /// The turn was cancelled by the client via `session/cancel`.
1616    ///
1617    /// This stop reason MUST be returned when the client sends a `session/cancel`
1618    /// notification, even if the cancellation causes exceptions in underlying operations.
1619    /// Agents should catch these exceptions and return this semantically meaningful
1620    /// response to confirm successful cancellation.
1621    Cancelled,
1622}
1623
1624// Model
1625
1626/// **UNSTABLE**
1627///
1628/// This capability is not part of the spec yet, and may be removed or changed at any point.
1629///
1630/// The set of models and the one currently active.
1631#[cfg(feature = "unstable_session_model")]
1632#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1633#[serde(rename_all = "camelCase")]
1634#[non_exhaustive]
1635pub struct SessionModelState {
1636    /// The current model the Agent is in.
1637    pub current_model_id: ModelId,
1638    /// The set of models that the Agent can use
1639    pub available_models: Vec<ModelInfo>,
1640    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1641    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1642    /// these keys.
1643    ///
1644    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1645    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1646    pub meta: Option<Meta>,
1647}
1648
1649#[cfg(feature = "unstable_session_model")]
1650impl SessionModelState {
1651    #[must_use]
1652    pub fn new(current_model_id: impl Into<ModelId>, available_models: Vec<ModelInfo>) -> Self {
1653        Self {
1654            current_model_id: current_model_id.into(),
1655            available_models,
1656            meta: None,
1657        }
1658    }
1659
1660    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1661    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1662    /// these keys.
1663    ///
1664    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1665    #[must_use]
1666    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1667        self.meta = meta.into_option();
1668        self
1669    }
1670}
1671
1672/// **UNSTABLE**
1673///
1674/// This capability is not part of the spec yet, and may be removed or changed at any point.
1675///
1676/// A unique identifier for a model.
1677#[cfg(feature = "unstable_session_model")]
1678#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
1679#[serde(transparent)]
1680#[from(Arc<str>, String, &'static str)]
1681#[non_exhaustive]
1682pub struct ModelId(pub Arc<str>);
1683
1684#[cfg(feature = "unstable_session_model")]
1685impl ModelId {
1686    pub fn new(id: impl Into<Arc<str>>) -> Self {
1687        Self(id.into())
1688    }
1689}
1690
1691/// **UNSTABLE**
1692///
1693/// This capability is not part of the spec yet, and may be removed or changed at any point.
1694///
1695/// Information about a selectable model.
1696#[cfg(feature = "unstable_session_model")]
1697#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1698#[serde(rename_all = "camelCase")]
1699#[non_exhaustive]
1700pub struct ModelInfo {
1701    /// Unique identifier for the model.
1702    pub model_id: ModelId,
1703    /// Human-readable name of the model.
1704    pub name: String,
1705    /// Optional description of the model.
1706    #[serde(default, skip_serializing_if = "Option::is_none")]
1707    pub description: Option<String>,
1708    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1709    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1710    /// these keys.
1711    ///
1712    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1713    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1714    pub meta: Option<Meta>,
1715}
1716
1717#[cfg(feature = "unstable_session_model")]
1718impl ModelInfo {
1719    pub fn new(model_id: impl Into<ModelId>, name: impl Into<String>) -> Self {
1720        Self {
1721            model_id: model_id.into(),
1722            name: name.into(),
1723            description: None,
1724            meta: None,
1725        }
1726    }
1727
1728    /// Optional description of the model.
1729    #[must_use]
1730    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1731        self.description = description.into_option();
1732        self
1733    }
1734
1735    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1736    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1737    /// these keys.
1738    ///
1739    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1740    #[must_use]
1741    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1742        self.meta = meta.into_option();
1743        self
1744    }
1745}
1746
1747/// **UNSTABLE**
1748///
1749/// This capability is not part of the spec yet, and may be removed or changed at any point.
1750///
1751/// Request parameters for setting a session model.
1752#[cfg(feature = "unstable_session_model")]
1753#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1754#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1755#[serde(rename_all = "camelCase")]
1756#[non_exhaustive]
1757pub struct SetSessionModelRequest {
1758    /// The ID of the session to set the model for.
1759    pub session_id: SessionId,
1760    /// The ID of the model to set.
1761    pub model_id: ModelId,
1762    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1763    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1764    /// these keys.
1765    ///
1766    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1767    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1768    pub meta: Option<Meta>,
1769}
1770
1771#[cfg(feature = "unstable_session_model")]
1772impl SetSessionModelRequest {
1773    #[must_use]
1774    pub fn new(session_id: impl Into<SessionId>, model_id: impl Into<ModelId>) -> Self {
1775        Self {
1776            session_id: session_id.into(),
1777            model_id: model_id.into(),
1778            meta: None,
1779        }
1780    }
1781
1782    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1783    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1784    /// these keys.
1785    ///
1786    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1787    #[must_use]
1788    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1789        self.meta = meta.into_option();
1790        self
1791    }
1792}
1793
1794/// **UNSTABLE**
1795///
1796/// This capability is not part of the spec yet, and may be removed or changed at any point.
1797///
1798/// Response to `session/set_model` method.
1799#[cfg(feature = "unstable_session_model")]
1800#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1801#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1802#[serde(rename_all = "camelCase")]
1803#[non_exhaustive]
1804pub struct SetSessionModelResponse {
1805    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1806    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1807    /// these keys.
1808    ///
1809    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1810    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1811    pub meta: Option<Meta>,
1812}
1813
1814#[cfg(feature = "unstable_session_model")]
1815impl SetSessionModelResponse {
1816    #[must_use]
1817    pub fn new() -> Self {
1818        Self::default()
1819    }
1820
1821    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1822    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1823    /// these keys.
1824    ///
1825    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1826    #[must_use]
1827    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1828        self.meta = meta.into_option();
1829        self
1830    }
1831}
1832
1833// Capabilities
1834
1835/// Capabilities supported by the agent.
1836///
1837/// Advertised during initialization to inform the client about
1838/// available features and content types.
1839///
1840/// See protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)
1841#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1842#[serde(rename_all = "camelCase")]
1843#[non_exhaustive]
1844pub struct AgentCapabilities {
1845    /// Whether the agent supports `session/load`.
1846    #[serde(default)]
1847    pub load_session: bool,
1848    /// Prompt capabilities supported by the agent.
1849    #[serde(default)]
1850    pub prompt_capabilities: PromptCapabilities,
1851    /// MCP capabilities supported by the agent.
1852    #[serde(default)]
1853    pub mcp_capabilities: McpCapabilities,
1854    #[serde(default)]
1855    pub session_capabilities: SessionCapabilities,
1856    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1857    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1858    /// these keys.
1859    ///
1860    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1861    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1862    pub meta: Option<Meta>,
1863}
1864
1865impl AgentCapabilities {
1866    #[must_use]
1867    pub fn new() -> Self {
1868        Self::default()
1869    }
1870
1871    /// Whether the agent supports `session/load`.
1872    #[must_use]
1873    pub fn load_session(mut self, load_session: bool) -> Self {
1874        self.load_session = load_session;
1875        self
1876    }
1877
1878    /// Prompt capabilities supported by the agent.
1879    #[must_use]
1880    pub fn prompt_capabilities(mut self, prompt_capabilities: PromptCapabilities) -> Self {
1881        self.prompt_capabilities = prompt_capabilities;
1882        self
1883    }
1884
1885    /// MCP capabilities supported by the agent.
1886    #[must_use]
1887    pub fn mcp_capabilities(mut self, mcp_capabilities: McpCapabilities) -> Self {
1888        self.mcp_capabilities = mcp_capabilities;
1889        self
1890    }
1891
1892    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1893    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1894    /// these keys.
1895    ///
1896    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1897    #[must_use]
1898    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1899        self.meta = meta.into_option();
1900        self
1901    }
1902}
1903
1904/// Session capabilities supported by the agent.
1905///
1906/// As a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.
1907///
1908/// Optionally, they **MAY** support other session methods and notifications by specifying additional capabilities.
1909///
1910/// Note: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.
1911///
1912/// See protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)
1913#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1914#[non_exhaustive]
1915pub struct SessionCapabilities {
1916    /// **UNSTABLE**
1917    ///
1918    /// This capability is not part of the spec yet, and may be removed or changed at any point.
1919    ///
1920    /// Whether the agent supports `session/list`.
1921    #[cfg(feature = "unstable_session_list")]
1922    #[serde(skip_serializing_if = "Option::is_none")]
1923    pub list: Option<SessionListCapabilities>,
1924    /// **UNSTABLE**
1925    ///
1926    /// This capability is not part of the spec yet, and may be removed or changed at any point.
1927    ///
1928    /// Whether the agent supports `session/fork`.
1929    #[cfg(feature = "unstable_session_fork")]
1930    #[serde(skip_serializing_if = "Option::is_none")]
1931    pub fork: Option<SessionForkCapabilities>,
1932    /// **UNSTABLE**
1933    ///
1934    /// This capability is not part of the spec yet, and may be removed or changed at any point.
1935    ///
1936    /// Whether the agent supports `session/resume`.
1937    #[cfg(feature = "unstable_session_resume")]
1938    #[serde(skip_serializing_if = "Option::is_none")]
1939    pub resume: Option<SessionResumeCapabilities>,
1940    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1941    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1942    /// these keys.
1943    ///
1944    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1945    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1946    pub meta: Option<Meta>,
1947}
1948
1949impl SessionCapabilities {
1950    #[must_use]
1951    pub fn new() -> Self {
1952        Self::default()
1953    }
1954
1955    #[cfg(feature = "unstable_session_list")]
1956    /// Whether the agent supports `session/list`.
1957    #[must_use]
1958    pub fn list(mut self, list: impl IntoOption<SessionListCapabilities>) -> Self {
1959        self.list = list.into_option();
1960        self
1961    }
1962
1963    #[cfg(feature = "unstable_session_fork")]
1964    /// Whether the agent supports `session/fork`.
1965    #[must_use]
1966    pub fn fork(mut self, fork: impl IntoOption<SessionForkCapabilities>) -> Self {
1967        self.fork = fork.into_option();
1968        self
1969    }
1970
1971    #[cfg(feature = "unstable_session_resume")]
1972    /// Whether the agent supports `session/resume`.
1973    #[must_use]
1974    pub fn resume(mut self, resume: impl IntoOption<SessionResumeCapabilities>) -> Self {
1975        self.resume = resume.into_option();
1976        self
1977    }
1978
1979    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1980    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1981    /// these keys.
1982    ///
1983    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1984    #[must_use]
1985    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1986        self.meta = meta.into_option();
1987        self
1988    }
1989}
1990
1991/// Capabilities for the `session/list` method.
1992///
1993/// By supplying `{}` it means that the agent supports listing of sessions.
1994///
1995/// Further capabilities can be added in the future for other means of filtering or searching the list.
1996#[cfg(feature = "unstable_session_list")]
1997#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1998#[non_exhaustive]
1999pub struct SessionListCapabilities {
2000    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2001    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2002    /// these keys.
2003    ///
2004    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2005    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2006    pub meta: Option<Meta>,
2007}
2008
2009#[cfg(feature = "unstable_session_list")]
2010impl SessionListCapabilities {
2011    #[must_use]
2012    pub fn new() -> Self {
2013        Self::default()
2014    }
2015    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2016    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2017    /// these keys.
2018    ///
2019    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2020    #[must_use]
2021    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2022        self.meta = meta.into_option();
2023        self
2024    }
2025}
2026
2027/// **UNSTABLE**
2028///
2029/// This capability is not part of the spec yet, and may be removed or changed at any point.
2030///
2031/// Capabilities for the `session/fork` method.
2032///
2033/// By supplying `{}` it means that the agent supports forking of sessions.
2034#[cfg(feature = "unstable_session_fork")]
2035#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2036#[non_exhaustive]
2037pub struct SessionForkCapabilities {
2038    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2039    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2040    /// these keys.
2041    ///
2042    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2043    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2044    pub meta: Option<Meta>,
2045}
2046
2047#[cfg(feature = "unstable_session_fork")]
2048impl SessionForkCapabilities {
2049    #[must_use]
2050    pub fn new() -> Self {
2051        Self::default()
2052    }
2053
2054    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2055    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2056    /// these keys.
2057    ///
2058    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2059    #[must_use]
2060    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2061        self.meta = meta.into_option();
2062        self
2063    }
2064}
2065
2066/// **UNSTABLE**
2067///
2068/// This capability is not part of the spec yet, and may be removed or changed at any point.
2069///
2070/// Capabilities for the `session/resume` method.
2071///
2072/// By supplying `{}` it means that the agent supports resuming of sessions.
2073#[cfg(feature = "unstable_session_resume")]
2074#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2075#[non_exhaustive]
2076pub struct SessionResumeCapabilities {
2077    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2078    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2079    /// these keys.
2080    ///
2081    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2082    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2083    pub meta: Option<Meta>,
2084}
2085
2086#[cfg(feature = "unstable_session_resume")]
2087impl SessionResumeCapabilities {
2088    #[must_use]
2089    pub fn new() -> Self {
2090        Self::default()
2091    }
2092
2093    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2094    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2095    /// these keys.
2096    ///
2097    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2098    #[must_use]
2099    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2100        self.meta = meta.into_option();
2101        self
2102    }
2103}
2104
2105/// Prompt capabilities supported by the agent in `session/prompt` requests.
2106///
2107/// Baseline agent functionality requires support for [`ContentBlock::Text`]
2108/// and [`ContentBlock::ResourceLink`] in prompt requests.
2109///
2110/// Other variants must be explicitly opted in to.
2111/// Capabilities for different types of content in prompt requests.
2112///
2113/// Indicates which content types beyond the baseline (text and resource links)
2114/// the agent can process.
2115///
2116/// See protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)
2117#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2118#[serde(rename_all = "camelCase")]
2119#[non_exhaustive]
2120pub struct PromptCapabilities {
2121    /// Agent supports [`ContentBlock::Image`].
2122    #[serde(default)]
2123    pub image: bool,
2124    /// Agent supports [`ContentBlock::Audio`].
2125    #[serde(default)]
2126    pub audio: bool,
2127    /// Agent supports embedded context in `session/prompt` requests.
2128    ///
2129    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
2130    /// in prompt requests for pieces of context that are referenced in the message.
2131    #[serde(default)]
2132    pub embedded_context: bool,
2133    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2134    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2135    /// these keys.
2136    ///
2137    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2138    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2139    pub meta: Option<Meta>,
2140}
2141
2142impl PromptCapabilities {
2143    #[must_use]
2144    pub fn new() -> Self {
2145        Self::default()
2146    }
2147
2148    /// Agent supports [`ContentBlock::Image`].
2149    #[must_use]
2150    pub fn image(mut self, image: bool) -> Self {
2151        self.image = image;
2152        self
2153    }
2154
2155    /// Agent supports [`ContentBlock::Audio`].
2156    #[must_use]
2157    pub fn audio(mut self, audio: bool) -> Self {
2158        self.audio = audio;
2159        self
2160    }
2161
2162    /// Agent supports embedded context in `session/prompt` requests.
2163    ///
2164    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
2165    /// in prompt requests for pieces of context that are referenced in the message.
2166    #[must_use]
2167    pub fn embedded_context(mut self, embedded_context: bool) -> Self {
2168        self.embedded_context = embedded_context;
2169        self
2170    }
2171
2172    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2173    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2174    /// these keys.
2175    ///
2176    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2177    #[must_use]
2178    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2179        self.meta = meta.into_option();
2180        self
2181    }
2182}
2183
2184/// MCP capabilities supported by the agent
2185#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2186#[serde(rename_all = "camelCase")]
2187#[non_exhaustive]
2188pub struct McpCapabilities {
2189    /// Agent supports [`McpServer::Http`].
2190    #[serde(default)]
2191    pub http: bool,
2192    /// Agent supports [`McpServer::Sse`].
2193    #[serde(default)]
2194    pub sse: bool,
2195    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2196    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2197    /// these keys.
2198    ///
2199    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2200    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2201    pub meta: Option<Meta>,
2202}
2203
2204impl McpCapabilities {
2205    #[must_use]
2206    pub fn new() -> Self {
2207        Self::default()
2208    }
2209
2210    /// Agent supports [`McpServer::Http`].
2211    #[must_use]
2212    pub fn http(mut self, http: bool) -> Self {
2213        self.http = http;
2214        self
2215    }
2216
2217    /// Agent supports [`McpServer::Sse`].
2218    #[must_use]
2219    pub fn sse(mut self, sse: bool) -> Self {
2220        self.sse = sse;
2221        self
2222    }
2223
2224    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2225    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2226    /// these keys.
2227    ///
2228    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2229    #[must_use]
2230    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2231        self.meta = meta.into_option();
2232        self
2233    }
2234}
2235
2236// Method schema
2237
2238/// Names of all methods that agents handle.
2239///
2240/// Provides a centralized definition of method names used in the protocol.
2241#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2242#[non_exhaustive]
2243pub struct AgentMethodNames {
2244    /// Method for initializing the connection.
2245    pub initialize: &'static str,
2246    /// Method for authenticating with the agent.
2247    pub authenticate: &'static str,
2248    /// Method for creating a new session.
2249    pub session_new: &'static str,
2250    /// Method for loading an existing session.
2251    pub session_load: &'static str,
2252    /// Method for setting the mode for a session.
2253    pub session_set_mode: &'static str,
2254    /// Method for sending a prompt to the agent.
2255    pub session_prompt: &'static str,
2256    /// Notification for cancelling operations.
2257    pub session_cancel: &'static str,
2258    /// Method for selecting a model for a given session.
2259    #[cfg(feature = "unstable_session_model")]
2260    pub session_set_model: &'static str,
2261    /// Method for listing existing sessions.
2262    #[cfg(feature = "unstable_session_list")]
2263    pub session_list: &'static str,
2264    /// Method for forking an existing session.
2265    #[cfg(feature = "unstable_session_fork")]
2266    pub session_fork: &'static str,
2267    /// Method for resuming an existing session.
2268    #[cfg(feature = "unstable_session_resume")]
2269    pub session_resume: &'static str,
2270}
2271
2272/// Constant containing all agent method names.
2273pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
2274    initialize: INITIALIZE_METHOD_NAME,
2275    authenticate: AUTHENTICATE_METHOD_NAME,
2276    session_new: SESSION_NEW_METHOD_NAME,
2277    session_load: SESSION_LOAD_METHOD_NAME,
2278    session_set_mode: SESSION_SET_MODE_METHOD_NAME,
2279    session_prompt: SESSION_PROMPT_METHOD_NAME,
2280    session_cancel: SESSION_CANCEL_METHOD_NAME,
2281    #[cfg(feature = "unstable_session_model")]
2282    session_set_model: SESSION_SET_MODEL_METHOD_NAME,
2283    #[cfg(feature = "unstable_session_list")]
2284    session_list: SESSION_LIST_METHOD_NAME,
2285    #[cfg(feature = "unstable_session_fork")]
2286    session_fork: SESSION_FORK_METHOD_NAME,
2287    #[cfg(feature = "unstable_session_resume")]
2288    session_resume: SESSION_RESUME_METHOD_NAME,
2289};
2290
2291/// Method name for the initialize request.
2292pub(crate) const INITIALIZE_METHOD_NAME: &str = "initialize";
2293/// Method name for the authenticate request.
2294pub(crate) const AUTHENTICATE_METHOD_NAME: &str = "authenticate";
2295/// Method name for creating a new session.
2296pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
2297/// Method name for loading an existing session.
2298pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
2299/// Method name for setting the mode for a session.
2300pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
2301/// Method name for sending a prompt.
2302pub(crate) const SESSION_PROMPT_METHOD_NAME: &str = "session/prompt";
2303/// Method name for the cancel notification.
2304pub(crate) const SESSION_CANCEL_METHOD_NAME: &str = "session/cancel";
2305/// Method name for selecting a model for a given session.
2306#[cfg(feature = "unstable_session_model")]
2307pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
2308/// Method name for listing existing sessions.
2309#[cfg(feature = "unstable_session_list")]
2310pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list";
2311/// Method name for forking an existing session.
2312#[cfg(feature = "unstable_session_fork")]
2313pub(crate) const SESSION_FORK_METHOD_NAME: &str = "session/fork";
2314/// Method name for resuming an existing session.
2315#[cfg(feature = "unstable_session_resume")]
2316pub(crate) const SESSION_RESUME_METHOD_NAME: &str = "session/resume";
2317
2318/// All possible requests that a client can send to an agent.
2319///
2320/// This enum is used internally for routing RPC requests. You typically won't need
2321/// to use this directly - instead, use the methods on the [`Agent`] trait.
2322///
2323/// This enum encompasses all method calls from client to agent.
2324#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2325#[serde(untagged)]
2326#[schemars(inline)]
2327#[non_exhaustive]
2328pub enum ClientRequest {
2329    /// Establishes the connection with a client and negotiates protocol capabilities.
2330    ///
2331    /// This method is called once at the beginning of the connection to:
2332    /// - Negotiate the protocol version to use
2333    /// - Exchange capability information between client and agent
2334    /// - Determine available authentication methods
2335    ///
2336    /// The agent should respond with its supported protocol version and capabilities.
2337    ///
2338    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
2339    InitializeRequest(InitializeRequest),
2340    /// Authenticates the client using the specified authentication method.
2341    ///
2342    /// Called when the agent requires authentication before allowing session creation.
2343    /// The client provides the authentication method ID that was advertised during initialization.
2344    ///
2345    /// After successful authentication, the client can proceed to create sessions with
2346    /// `new_session` without receiving an `auth_required` error.
2347    ///
2348    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
2349    AuthenticateRequest(AuthenticateRequest),
2350    /// Creates a new conversation session with the agent.
2351    ///
2352    /// Sessions represent independent conversation contexts with their own history and state.
2353    ///
2354    /// The agent should:
2355    /// - Create a new session context
2356    /// - Connect to any specified MCP servers
2357    /// - Return a unique session ID for future requests
2358    ///
2359    /// May return an `auth_required` error if the agent requires authentication.
2360    ///
2361    /// See protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)
2362    NewSessionRequest(NewSessionRequest),
2363    /// Loads an existing session to resume a previous conversation.
2364    ///
2365    /// This method is only available if the agent advertises the `loadSession` capability.
2366    ///
2367    /// The agent should:
2368    /// - Restore the session context and conversation history
2369    /// - Connect to the specified MCP servers
2370    /// - Stream the entire conversation history back to the client via notifications
2371    ///
2372    /// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
2373    LoadSessionRequest(LoadSessionRequest),
2374    #[cfg(feature = "unstable_session_list")]
2375    /// **UNSTABLE**
2376    ///
2377    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2378    ///
2379    /// Lists existing sessions known to the agent.
2380    ///
2381    /// This method is only available if the agent advertises the `listSessions` capability.
2382    ///
2383    /// The agent should return metadata about sessions with optional filtering and pagination support.
2384    ListSessionsRequest(ListSessionsRequest),
2385    #[cfg(feature = "unstable_session_fork")]
2386    /// **UNSTABLE**
2387    ///
2388    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2389    ///
2390    /// Forks an existing session to create a new independent session.
2391    ///
2392    /// This method is only available if the agent advertises the `session.fork` capability.
2393    ///
2394    /// The agent should create a new session with the same conversation context as the
2395    /// original, allowing operations like generating summaries without affecting the
2396    /// original session's history.
2397    ForkSessionRequest(ForkSessionRequest),
2398    #[cfg(feature = "unstable_session_resume")]
2399    /// **UNSTABLE**
2400    ///
2401    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2402    ///
2403    /// Resumes an existing session without returning previous messages.
2404    ///
2405    /// This method is only available if the agent advertises the `session.resume` capability.
2406    ///
2407    /// The agent should resume the session context, allowing the conversation to continue
2408    /// without replaying the message history (unlike `session/load`).
2409    ResumeSessionRequest(ResumeSessionRequest),
2410    /// Sets the current mode for a session.
2411    ///
2412    /// Allows switching between different agent modes (e.g., "ask", "architect", "code")
2413    /// that affect system prompts, tool availability, and permission behaviors.
2414    ///
2415    /// The mode must be one of the modes advertised in `availableModes` during session
2416    /// creation or loading. Agents may also change modes autonomously and notify the
2417    /// client via `current_mode_update` notifications.
2418    ///
2419    /// This method can be called at any time during a session, whether the Agent is
2420    /// idle or actively generating a response.
2421    ///
2422    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
2423    SetSessionModeRequest(SetSessionModeRequest),
2424    /// Processes a user prompt within a session.
2425    ///
2426    /// This method handles the whole lifecycle of a prompt:
2427    /// - Receives user messages with optional context (files, images, etc.)
2428    /// - Processes the prompt using language models
2429    /// - Reports language model content and tool calls to the Clients
2430    /// - Requests permission to run tools
2431    /// - Executes any requested tool calls
2432    /// - Returns when the turn is complete with a stop reason
2433    ///
2434    /// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
2435    PromptRequest(PromptRequest),
2436    #[cfg(feature = "unstable_session_model")]
2437    /// **UNSTABLE**
2438    ///
2439    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2440    ///
2441    /// Select a model for a given session.
2442    SetSessionModelRequest(SetSessionModelRequest),
2443    /// Handles extension method requests from the client.
2444    ///
2445    /// Extension methods provide a way to add custom functionality while maintaining
2446    /// protocol compatibility.
2447    ///
2448    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2449    ExtMethodRequest(ExtRequest),
2450}
2451
2452impl ClientRequest {
2453    /// Returns the corresponding method name of the request.
2454    #[must_use]
2455    pub fn method(&self) -> &str {
2456        match self {
2457            Self::InitializeRequest(_) => AGENT_METHOD_NAMES.initialize,
2458            Self::AuthenticateRequest(_) => AGENT_METHOD_NAMES.authenticate,
2459            Self::NewSessionRequest(_) => AGENT_METHOD_NAMES.session_new,
2460            Self::LoadSessionRequest(_) => AGENT_METHOD_NAMES.session_load,
2461            #[cfg(feature = "unstable_session_list")]
2462            Self::ListSessionsRequest(_) => AGENT_METHOD_NAMES.session_list,
2463            #[cfg(feature = "unstable_session_fork")]
2464            Self::ForkSessionRequest(_) => AGENT_METHOD_NAMES.session_fork,
2465            #[cfg(feature = "unstable_session_resume")]
2466            Self::ResumeSessionRequest(_) => AGENT_METHOD_NAMES.session_resume,
2467            Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode,
2468            Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt,
2469            #[cfg(feature = "unstable_session_model")]
2470            Self::SetSessionModelRequest(_) => AGENT_METHOD_NAMES.session_set_model,
2471            Self::ExtMethodRequest(ext_request) => &ext_request.method,
2472        }
2473    }
2474}
2475
2476/// All possible responses that an agent can send to a client.
2477///
2478/// This enum is used internally for routing RPC responses. You typically won't need
2479/// to use this directly - the responses are handled automatically by the connection.
2480///
2481/// These are responses to the corresponding `ClientRequest` variants.
2482#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2483#[serde(untagged)]
2484#[schemars(inline)]
2485#[non_exhaustive]
2486#[expect(clippy::large_enum_variant)]
2487pub enum AgentResponse {
2488    InitializeResponse(InitializeResponse),
2489    AuthenticateResponse(#[serde(default)] AuthenticateResponse),
2490    NewSessionResponse(NewSessionResponse),
2491    LoadSessionResponse(#[serde(default)] LoadSessionResponse),
2492    #[cfg(feature = "unstable_session_list")]
2493    ListSessionsResponse(ListSessionsResponse),
2494    #[cfg(feature = "unstable_session_fork")]
2495    ForkSessionResponse(ForkSessionResponse),
2496    #[cfg(feature = "unstable_session_resume")]
2497    ResumeSessionResponse(#[serde(default)] ResumeSessionResponse),
2498    SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
2499    PromptResponse(PromptResponse),
2500    #[cfg(feature = "unstable_session_model")]
2501    SetSessionModelResponse(SetSessionModelResponse),
2502    ExtMethodResponse(ExtResponse),
2503}
2504
2505/// All possible notifications that a client can send to an agent.
2506///
2507/// This enum is used internally for routing RPC notifications. You typically won't need
2508/// to use this directly - use the notification methods on the [`Agent`] trait instead.
2509///
2510/// Notifications do not expect a response.
2511#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2512#[serde(untagged)]
2513#[schemars(inline)]
2514#[non_exhaustive]
2515pub enum ClientNotification {
2516    /// Cancels ongoing operations for a session.
2517    ///
2518    /// This is a notification sent by the client to cancel an ongoing prompt turn.
2519    ///
2520    /// Upon receiving this notification, the Agent SHOULD:
2521    /// - Stop all language model requests as soon as possible
2522    /// - Abort all tool call invocations in progress
2523    /// - Send any pending `session/update` notifications
2524    /// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
2525    ///
2526    /// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
2527    CancelNotification(CancelNotification),
2528    /// Handles extension notifications from the client.
2529    ///
2530    /// Extension notifications provide a way to send one-way messages for custom functionality
2531    /// while maintaining protocol compatibility.
2532    ///
2533    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2534    ExtNotification(ExtNotification),
2535}
2536
2537impl ClientNotification {
2538    /// Returns the corresponding method name of the notification.
2539    #[must_use]
2540    pub fn method(&self) -> &str {
2541        match self {
2542            Self::CancelNotification(_) => AGENT_METHOD_NAMES.session_cancel,
2543            Self::ExtNotification(ext_notification) => &ext_notification.method,
2544        }
2545    }
2546}
2547
2548/// Notification to cancel ongoing operations for a session.
2549///
2550/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
2551#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2552#[schemars(extend("x-side" = "agent", "x-method" = SESSION_CANCEL_METHOD_NAME))]
2553#[serde(rename_all = "camelCase")]
2554#[non_exhaustive]
2555pub struct CancelNotification {
2556    /// The ID of the session to cancel operations for.
2557    pub session_id: SessionId,
2558    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2559    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2560    /// these keys.
2561    ///
2562    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2563    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2564    pub meta: Option<Meta>,
2565}
2566
2567impl CancelNotification {
2568    #[must_use]
2569    pub fn new(session_id: impl Into<SessionId>) -> Self {
2570        Self {
2571            session_id: session_id.into(),
2572            meta: None,
2573        }
2574    }
2575
2576    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2577    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2578    /// these keys.
2579    ///
2580    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2581    #[must_use]
2582    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2583        self.meta = meta.into_option();
2584        self
2585    }
2586}
2587
2588#[cfg(test)]
2589mod test_serialization {
2590    use super::*;
2591    use serde_json::json;
2592
2593    #[test]
2594    fn test_mcp_server_stdio_serialization() {
2595        let server = McpServer::Stdio(
2596            McpServerStdio::new("test-server", "/usr/bin/server")
2597                .args(vec!["--port".to_string(), "3000".to_string()])
2598                .env(vec![EnvVariable::new("API_KEY", "secret123")]),
2599        );
2600
2601        let json = serde_json::to_value(&server).unwrap();
2602        assert_eq!(
2603            json,
2604            json!({
2605                "name": "test-server",
2606                "command": "/usr/bin/server",
2607                "args": ["--port", "3000"],
2608                "env": [
2609                    {
2610                        "name": "API_KEY",
2611                        "value": "secret123"
2612                    }
2613                ]
2614            })
2615        );
2616
2617        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2618        match deserialized {
2619            McpServer::Stdio(McpServerStdio {
2620                name,
2621                command,
2622                args,
2623                env,
2624                meta: _,
2625            }) => {
2626                assert_eq!(name, "test-server");
2627                assert_eq!(command, PathBuf::from("/usr/bin/server"));
2628                assert_eq!(args, vec!["--port", "3000"]);
2629                assert_eq!(env.len(), 1);
2630                assert_eq!(env[0].name, "API_KEY");
2631                assert_eq!(env[0].value, "secret123");
2632            }
2633            _ => panic!("Expected Stdio variant"),
2634        }
2635    }
2636
2637    #[test]
2638    fn test_mcp_server_http_serialization() {
2639        let server = McpServer::Http(
2640            McpServerHttp::new("http-server", "https://api.example.com").headers(vec![
2641                HttpHeader::new("Authorization", "Bearer token123"),
2642                HttpHeader::new("Content-Type", "application/json"),
2643            ]),
2644        );
2645
2646        let json = serde_json::to_value(&server).unwrap();
2647        assert_eq!(
2648            json,
2649            json!({
2650                "type": "http",
2651                "name": "http-server",
2652                "url": "https://api.example.com",
2653                "headers": [
2654                    {
2655                        "name": "Authorization",
2656                        "value": "Bearer token123"
2657                    },
2658                    {
2659                        "name": "Content-Type",
2660                        "value": "application/json"
2661                    }
2662                ]
2663            })
2664        );
2665
2666        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2667        match deserialized {
2668            McpServer::Http(McpServerHttp {
2669                name,
2670                url,
2671                headers,
2672                meta: _,
2673            }) => {
2674                assert_eq!(name, "http-server");
2675                assert_eq!(url, "https://api.example.com");
2676                assert_eq!(headers.len(), 2);
2677                assert_eq!(headers[0].name, "Authorization");
2678                assert_eq!(headers[0].value, "Bearer token123");
2679                assert_eq!(headers[1].name, "Content-Type");
2680                assert_eq!(headers[1].value, "application/json");
2681            }
2682            _ => panic!("Expected Http variant"),
2683        }
2684    }
2685
2686    #[test]
2687    fn test_mcp_server_sse_serialization() {
2688        let server = McpServer::Sse(
2689            McpServerSse::new("sse-server", "https://sse.example.com/events")
2690                .headers(vec![HttpHeader::new("X-API-Key", "apikey456")]),
2691        );
2692
2693        let json = serde_json::to_value(&server).unwrap();
2694        assert_eq!(
2695            json,
2696            json!({
2697                "type": "sse",
2698                "name": "sse-server",
2699                "url": "https://sse.example.com/events",
2700                "headers": [
2701                    {
2702                        "name": "X-API-Key",
2703                        "value": "apikey456"
2704                    }
2705                ]
2706            })
2707        );
2708
2709        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2710        match deserialized {
2711            McpServer::Sse(McpServerSse {
2712                name,
2713                url,
2714                headers,
2715                meta: _,
2716            }) => {
2717                assert_eq!(name, "sse-server");
2718                assert_eq!(url, "https://sse.example.com/events");
2719                assert_eq!(headers.len(), 1);
2720                assert_eq!(headers[0].name, "X-API-Key");
2721                assert_eq!(headers[0].value, "apikey456");
2722            }
2723            _ => panic!("Expected Sse variant"),
2724        }
2725    }
2726}