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    /// **UNSTABLE**
428    ///
429    /// This capability is not part of the spec yet, and may be removed or changed at any point.
430    ///
431    /// Initial session configuration options if supported by the Agent.
432    #[cfg(feature = "unstable_session_config_options")]
433    #[serde(skip_serializing_if = "Option::is_none")]
434    pub config_options: Option<Vec<SessionConfigOption>>,
435    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
436    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
437    /// these keys.
438    ///
439    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
440    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
441    pub meta: Option<Meta>,
442}
443
444impl NewSessionResponse {
445    #[must_use]
446    pub fn new(session_id: impl Into<SessionId>) -> Self {
447        Self {
448            session_id: session_id.into(),
449            modes: None,
450            #[cfg(feature = "unstable_session_model")]
451            models: None,
452            #[cfg(feature = "unstable_session_config_options")]
453            config_options: None,
454            meta: None,
455        }
456    }
457
458    /// Initial mode state if supported by the Agent
459    ///
460    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
461    #[must_use]
462    pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
463        self.modes = modes.into_option();
464        self
465    }
466
467    /// **UNSTABLE**
468    ///
469    /// This capability is not part of the spec yet, and may be removed or changed at any point.
470    ///
471    /// Initial model state if supported by the Agent
472    #[cfg(feature = "unstable_session_model")]
473    #[must_use]
474    pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
475        self.models = models.into_option();
476        self
477    }
478
479    /// **UNSTABLE**
480    ///
481    /// This capability is not part of the spec yet, and may be removed or changed at any point.
482    ///
483    /// Initial session configuration options if supported by the Agent.
484    #[cfg(feature = "unstable_session_config_options")]
485    #[must_use]
486    pub fn config_options(
487        mut self,
488        config_options: impl IntoOption<Vec<SessionConfigOption>>,
489    ) -> Self {
490        self.config_options = config_options.into_option();
491        self
492    }
493
494    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
495    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
496    /// these keys.
497    ///
498    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
499    #[must_use]
500    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
501        self.meta = meta.into_option();
502        self
503    }
504}
505
506// Load session
507
508/// Request parameters for loading an existing session.
509///
510/// Only available if the Agent supports the `loadSession` capability.
511///
512/// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
513#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
514#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
515#[serde(rename_all = "camelCase")]
516#[non_exhaustive]
517pub struct LoadSessionRequest {
518    /// List of MCP servers to connect to for this session.
519    pub mcp_servers: Vec<McpServer>,
520    /// The working directory for this session.
521    pub cwd: PathBuf,
522    /// The ID of the session to load.
523    pub session_id: SessionId,
524    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
525    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
526    /// these keys.
527    ///
528    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
529    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
530    pub meta: Option<Meta>,
531}
532
533impl LoadSessionRequest {
534    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
535        Self {
536            mcp_servers: vec![],
537            cwd: cwd.into(),
538            session_id: session_id.into(),
539            meta: None,
540        }
541    }
542
543    /// List of MCP servers to connect to for this session.
544    #[must_use]
545    pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
546        self.mcp_servers = mcp_servers;
547        self
548    }
549
550    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
551    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
552    /// these keys.
553    ///
554    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
555    #[must_use]
556    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
557        self.meta = meta.into_option();
558        self
559    }
560}
561
562/// Response from loading an existing session.
563#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
564#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
565#[serde(rename_all = "camelCase")]
566#[non_exhaustive]
567pub struct LoadSessionResponse {
568    /// Initial mode state if supported by the Agent
569    ///
570    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
571    #[serde(default, skip_serializing_if = "Option::is_none")]
572    pub modes: Option<SessionModeState>,
573    /// **UNSTABLE**
574    ///
575    /// This capability is not part of the spec yet, and may be removed or changed at any point.
576    ///
577    /// Initial model state if supported by the Agent
578    #[cfg(feature = "unstable_session_model")]
579    #[serde(default, skip_serializing_if = "Option::is_none")]
580    pub models: Option<SessionModelState>,
581    /// **UNSTABLE**
582    ///
583    /// This capability is not part of the spec yet, and may be removed or changed at any point.
584    ///
585    /// Initial session configuration options if supported by the Agent.
586    #[cfg(feature = "unstable_session_config_options")]
587    #[serde(default, skip_serializing_if = "Option::is_none")]
588    pub config_options: Option<Vec<SessionConfigOption>>,
589    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
590    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
591    /// these keys.
592    ///
593    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
594    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
595    pub meta: Option<Meta>,
596}
597
598impl LoadSessionResponse {
599    #[must_use]
600    pub fn new() -> Self {
601        Self::default()
602    }
603
604    /// Initial mode state if supported by the Agent
605    ///
606    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
607    #[must_use]
608    pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
609        self.modes = modes.into_option();
610        self
611    }
612
613    /// **UNSTABLE**
614    ///
615    /// This capability is not part of the spec yet, and may be removed or changed at any point.
616    ///
617    /// Initial model state if supported by the Agent
618    #[cfg(feature = "unstable_session_model")]
619    #[must_use]
620    pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
621        self.models = models.into_option();
622        self
623    }
624
625    /// **UNSTABLE**
626    ///
627    /// This capability is not part of the spec yet, and may be removed or changed at any point.
628    ///
629    /// Initial session configuration options if supported by the Agent.
630    #[cfg(feature = "unstable_session_config_options")]
631    #[must_use]
632    pub fn config_options(
633        mut self,
634        config_options: impl IntoOption<Vec<SessionConfigOption>>,
635    ) -> Self {
636        self.config_options = config_options.into_option();
637        self
638    }
639
640    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
641    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
642    /// these keys.
643    ///
644    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
645    #[must_use]
646    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
647        self.meta = meta.into_option();
648        self
649    }
650}
651
652// Fork session
653
654/// **UNSTABLE**
655///
656/// This capability is not part of the spec yet, and may be removed or changed at any point.
657///
658/// Request parameters for forking an existing session.
659///
660/// Creates a new session based on the context of an existing one, allowing
661/// operations like generating summaries without affecting the original session's history.
662///
663/// Only available if the Agent supports the `session.fork` capability.
664#[cfg(feature = "unstable_session_fork")]
665#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
666#[schemars(extend("x-side" = "agent", "x-method" = SESSION_FORK_METHOD_NAME))]
667#[serde(rename_all = "camelCase")]
668#[non_exhaustive]
669pub struct ForkSessionRequest {
670    /// The ID of the session to fork.
671    pub session_id: SessionId,
672    /// The working directory for this session.
673    pub cwd: PathBuf,
674    /// List of MCP servers to connect to for this session.
675    #[serde(default, skip_serializing_if = "Vec::is_empty")]
676    pub mcp_servers: Vec<McpServer>,
677    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
678    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
679    /// these keys.
680    ///
681    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
682    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
683    pub meta: Option<Meta>,
684}
685
686#[cfg(feature = "unstable_session_fork")]
687impl ForkSessionRequest {
688    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
689        Self {
690            session_id: session_id.into(),
691            cwd: cwd.into(),
692            mcp_servers: vec![],
693            meta: None,
694        }
695    }
696
697    /// List of MCP servers to connect to for this session.
698    #[must_use]
699    pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
700        self.mcp_servers = mcp_servers;
701        self
702    }
703
704    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
705    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
706    /// these keys.
707    ///
708    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
709    #[must_use]
710    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
711        self.meta = meta.into_option();
712        self
713    }
714}
715
716/// **UNSTABLE**
717///
718/// This capability is not part of the spec yet, and may be removed or changed at any point.
719///
720/// Response from forking an existing session.
721#[cfg(feature = "unstable_session_fork")]
722#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
723#[schemars(extend("x-side" = "agent", "x-method" = SESSION_FORK_METHOD_NAME))]
724#[serde(rename_all = "camelCase")]
725#[non_exhaustive]
726pub struct ForkSessionResponse {
727    /// Unique identifier for the newly created forked session.
728    pub session_id: SessionId,
729    /// Initial mode state if supported by the Agent
730    ///
731    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
732    #[serde(skip_serializing_if = "Option::is_none")]
733    pub modes: Option<SessionModeState>,
734    /// **UNSTABLE**
735    ///
736    /// This capability is not part of the spec yet, and may be removed or changed at any point.
737    ///
738    /// Initial model state if supported by the Agent
739    #[cfg(feature = "unstable_session_model")]
740    #[serde(skip_serializing_if = "Option::is_none")]
741    pub models: Option<SessionModelState>,
742    /// **UNSTABLE**
743    ///
744    /// This capability is not part of the spec yet, and may be removed or changed at any point.
745    ///
746    /// Initial session configuration options if supported by the Agent.
747    #[cfg(feature = "unstable_session_config_options")]
748    #[serde(skip_serializing_if = "Option::is_none")]
749    pub config_options: Option<Vec<SessionConfigOption>>,
750    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
751    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
752    /// these keys.
753    ///
754    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
755    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
756    pub meta: Option<Meta>,
757}
758
759#[cfg(feature = "unstable_session_fork")]
760impl ForkSessionResponse {
761    #[must_use]
762    pub fn new(session_id: impl Into<SessionId>) -> Self {
763        Self {
764            session_id: session_id.into(),
765            modes: None,
766            #[cfg(feature = "unstable_session_model")]
767            models: None,
768            #[cfg(feature = "unstable_session_config_options")]
769            config_options: None,
770            meta: None,
771        }
772    }
773
774    /// Initial mode state if supported by the Agent
775    ///
776    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
777    #[must_use]
778    pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
779        self.modes = modes.into_option();
780        self
781    }
782
783    /// **UNSTABLE**
784    ///
785    /// This capability is not part of the spec yet, and may be removed or changed at any point.
786    ///
787    /// Initial model state if supported by the Agent
788    #[cfg(feature = "unstable_session_model")]
789    #[must_use]
790    pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
791        self.models = models.into_option();
792        self
793    }
794
795    /// **UNSTABLE**
796    ///
797    /// This capability is not part of the spec yet, and may be removed or changed at any point.
798    ///
799    /// Initial session configuration options if supported by the Agent.
800    #[cfg(feature = "unstable_session_config_options")]
801    #[must_use]
802    pub fn config_options(
803        mut self,
804        config_options: impl IntoOption<Vec<SessionConfigOption>>,
805    ) -> Self {
806        self.config_options = config_options.into_option();
807        self
808    }
809
810    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
811    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
812    /// these keys.
813    ///
814    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
815    #[must_use]
816    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
817        self.meta = meta.into_option();
818        self
819    }
820}
821
822// Resume session
823
824/// **UNSTABLE**
825///
826/// This capability is not part of the spec yet, and may be removed or changed at any point.
827///
828/// Request parameters for resuming an existing session.
829///
830/// Resumes an existing session without returning previous messages (unlike `session/load`).
831/// This is useful for agents that can resume sessions but don't implement full session loading.
832///
833/// Only available if the Agent supports the `session.resume` capability.
834#[cfg(feature = "unstable_session_resume")]
835#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
836#[schemars(extend("x-side" = "agent", "x-method" = SESSION_RESUME_METHOD_NAME))]
837#[serde(rename_all = "camelCase")]
838#[non_exhaustive]
839pub struct ResumeSessionRequest {
840    /// The ID of the session to resume.
841    pub session_id: SessionId,
842    /// The working directory for this session.
843    pub cwd: PathBuf,
844    /// List of MCP servers to connect to for this session.
845    #[serde(default, skip_serializing_if = "Vec::is_empty")]
846    pub mcp_servers: Vec<McpServer>,
847    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
848    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
849    /// these keys.
850    ///
851    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
852    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
853    pub meta: Option<Meta>,
854}
855
856#[cfg(feature = "unstable_session_resume")]
857impl ResumeSessionRequest {
858    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
859        Self {
860            session_id: session_id.into(),
861            cwd: cwd.into(),
862            mcp_servers: vec![],
863            meta: None,
864        }
865    }
866
867    /// List of MCP servers to connect to for this session.
868    #[must_use]
869    pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
870        self.mcp_servers = mcp_servers;
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/// **UNSTABLE**
887///
888/// This capability is not part of the spec yet, and may be removed or changed at any point.
889///
890/// Response from resuming an existing session.
891#[cfg(feature = "unstable_session_resume")]
892#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
893#[schemars(extend("x-side" = "agent", "x-method" = SESSION_RESUME_METHOD_NAME))]
894#[serde(rename_all = "camelCase")]
895#[non_exhaustive]
896pub struct ResumeSessionResponse {
897    /// Initial mode state if supported by the Agent
898    ///
899    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
900    #[serde(default, skip_serializing_if = "Option::is_none")]
901    pub modes: Option<SessionModeState>,
902    /// **UNSTABLE**
903    ///
904    /// This capability is not part of the spec yet, and may be removed or changed at any point.
905    ///
906    /// Initial model state if supported by the Agent
907    #[cfg(feature = "unstable_session_model")]
908    #[serde(default, skip_serializing_if = "Option::is_none")]
909    pub models: Option<SessionModelState>,
910    /// **UNSTABLE**
911    ///
912    /// This capability is not part of the spec yet, and may be removed or changed at any point.
913    ///
914    /// Initial session configuration options if supported by the Agent.
915    #[cfg(feature = "unstable_session_config_options")]
916    #[serde(default, skip_serializing_if = "Option::is_none")]
917    pub config_options: Option<Vec<SessionConfigOption>>,
918    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
919    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
920    /// these keys.
921    ///
922    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
923    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
924    pub meta: Option<Meta>,
925}
926
927#[cfg(feature = "unstable_session_resume")]
928impl ResumeSessionResponse {
929    #[must_use]
930    pub fn new() -> Self {
931        Self::default()
932    }
933
934    /// Initial mode state if supported by the Agent
935    ///
936    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
937    #[must_use]
938    pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
939        self.modes = modes.into_option();
940        self
941    }
942
943    /// **UNSTABLE**
944    ///
945    /// This capability is not part of the spec yet, and may be removed or changed at any point.
946    ///
947    /// Initial model state if supported by the Agent
948    #[cfg(feature = "unstable_session_model")]
949    #[must_use]
950    pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
951        self.models = models.into_option();
952        self
953    }
954
955    /// **UNSTABLE**
956    ///
957    /// This capability is not part of the spec yet, and may be removed or changed at any point.
958    ///
959    /// Initial session configuration options if supported by the Agent.
960    #[cfg(feature = "unstable_session_config_options")]
961    #[must_use]
962    pub fn config_options(
963        mut self,
964        config_options: impl IntoOption<Vec<SessionConfigOption>>,
965    ) -> Self {
966        self.config_options = config_options.into_option();
967        self
968    }
969
970    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
971    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
972    /// these keys.
973    ///
974    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
975    #[must_use]
976    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
977        self.meta = meta.into_option();
978        self
979    }
980}
981
982// List sessions
983
984/// **UNSTABLE**
985///
986/// This capability is not part of the spec yet, and may be removed or changed at any point.
987///
988/// Request parameters for listing existing sessions.
989///
990/// Only available if the Agent supports the `listSessions` capability.
991#[cfg(feature = "unstable_session_list")]
992#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
993#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
994#[serde(rename_all = "camelCase")]
995#[non_exhaustive]
996pub struct ListSessionsRequest {
997    /// Filter sessions by working directory. Must be an absolute path.
998    #[serde(skip_serializing_if = "Option::is_none")]
999    pub cwd: Option<PathBuf>,
1000    /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
1001    #[serde(skip_serializing_if = "Option::is_none")]
1002    pub cursor: Option<String>,
1003    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1004    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1005    /// these keys.
1006    ///
1007    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1008    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1009    pub meta: Option<Meta>,
1010}
1011
1012#[cfg(feature = "unstable_session_list")]
1013impl ListSessionsRequest {
1014    #[must_use]
1015    pub fn new() -> Self {
1016        Self::default()
1017    }
1018
1019    /// Filter sessions by working directory. Must be an absolute path.
1020    #[must_use]
1021    pub fn cwd(mut self, cwd: impl IntoOption<PathBuf>) -> Self {
1022        self.cwd = cwd.into_option();
1023        self
1024    }
1025
1026    /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
1027    #[must_use]
1028    pub fn cursor(mut self, cursor: impl IntoOption<String>) -> Self {
1029        self.cursor = cursor.into_option();
1030        self
1031    }
1032
1033    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1034    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1035    /// these keys.
1036    ///
1037    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1038    #[must_use]
1039    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1040        self.meta = meta.into_option();
1041        self
1042    }
1043}
1044
1045/// **UNSTABLE**
1046///
1047/// This capability is not part of the spec yet, and may be removed or changed at any point.
1048///
1049/// Response from listing sessions.
1050#[cfg(feature = "unstable_session_list")]
1051#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1052#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
1053#[serde(rename_all = "camelCase")]
1054#[non_exhaustive]
1055pub struct ListSessionsResponse {
1056    /// Array of session information objects
1057    pub sessions: Vec<SessionInfo>,
1058    /// Opaque cursor token. If present, pass this in the next request's cursor parameter
1059    /// to fetch the next page. If absent, there are no more results.
1060    #[serde(skip_serializing_if = "Option::is_none")]
1061    pub next_cursor: Option<String>,
1062    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1063    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1064    /// these keys.
1065    ///
1066    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1067    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1068    pub meta: Option<Meta>,
1069}
1070
1071#[cfg(feature = "unstable_session_list")]
1072impl ListSessionsResponse {
1073    #[must_use]
1074    pub fn new(sessions: Vec<SessionInfo>) -> Self {
1075        Self {
1076            sessions,
1077            next_cursor: None,
1078            meta: None,
1079        }
1080    }
1081
1082    #[must_use]
1083    pub fn next_cursor(mut self, next_cursor: impl IntoOption<String>) -> Self {
1084        self.next_cursor = next_cursor.into_option();
1085        self
1086    }
1087
1088    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1089    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1090    /// these keys.
1091    ///
1092    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1093    #[must_use]
1094    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1095        self.meta = meta.into_option();
1096        self
1097    }
1098}
1099
1100/// **UNSTABLE**
1101///
1102/// This capability is not part of the spec yet, and may be removed or changed at any point.
1103///
1104/// Information about a session returned by session/list
1105#[cfg(feature = "unstable_session_list")]
1106#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1107#[serde(rename_all = "camelCase")]
1108#[non_exhaustive]
1109pub struct SessionInfo {
1110    /// Unique identifier for the session
1111    pub session_id: SessionId,
1112    /// The working directory for this session. Must be an absolute path.
1113    pub cwd: PathBuf,
1114    /// Human-readable title for the session
1115    #[serde(skip_serializing_if = "Option::is_none")]
1116    pub title: Option<String>,
1117    /// ISO 8601 timestamp of last activity
1118    #[serde(skip_serializing_if = "Option::is_none")]
1119    pub updated_at: Option<String>,
1120    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1121    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1122    /// these keys.
1123    ///
1124    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1125    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1126    pub meta: Option<Meta>,
1127}
1128
1129#[cfg(feature = "unstable_session_list")]
1130impl SessionInfo {
1131    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
1132        Self {
1133            session_id: session_id.into(),
1134            cwd: cwd.into(),
1135            title: None,
1136            updated_at: None,
1137            meta: None,
1138        }
1139    }
1140
1141    /// Human-readable title for the session
1142    #[must_use]
1143    pub fn title(mut self, title: impl IntoOption<String>) -> Self {
1144        self.title = title.into_option();
1145        self
1146    }
1147
1148    /// ISO 8601 timestamp of last activity
1149    #[must_use]
1150    pub fn updated_at(mut self, updated_at: impl IntoOption<String>) -> Self {
1151        self.updated_at = updated_at.into_option();
1152        self
1153    }
1154
1155    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1156    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1157    /// these keys.
1158    ///
1159    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1160    #[must_use]
1161    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1162        self.meta = meta.into_option();
1163        self
1164    }
1165}
1166
1167// Session modes
1168
1169/// The set of modes and the one currently active.
1170#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1171#[serde(rename_all = "camelCase")]
1172#[non_exhaustive]
1173pub struct SessionModeState {
1174    /// The current mode the Agent is in.
1175    pub current_mode_id: SessionModeId,
1176    /// The set of modes that the Agent can operate in
1177    pub available_modes: Vec<SessionMode>,
1178    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1179    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1180    /// these keys.
1181    ///
1182    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1183    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1184    pub meta: Option<Meta>,
1185}
1186
1187impl SessionModeState {
1188    #[must_use]
1189    pub fn new(
1190        current_mode_id: impl Into<SessionModeId>,
1191        available_modes: Vec<SessionMode>,
1192    ) -> Self {
1193        Self {
1194            current_mode_id: current_mode_id.into(),
1195            available_modes,
1196            meta: None,
1197        }
1198    }
1199
1200    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1201    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1202    /// these keys.
1203    ///
1204    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1205    #[must_use]
1206    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1207        self.meta = meta.into_option();
1208        self
1209    }
1210}
1211
1212/// A mode the agent can operate in.
1213///
1214/// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
1215#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1216#[serde(rename_all = "camelCase")]
1217#[non_exhaustive]
1218pub struct SessionMode {
1219    pub id: SessionModeId,
1220    pub name: String,
1221    #[serde(default, skip_serializing_if = "Option::is_none")]
1222    pub description: Option<String>,
1223    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1224    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1225    /// these keys.
1226    ///
1227    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1228    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1229    pub meta: Option<Meta>,
1230}
1231
1232impl SessionMode {
1233    pub fn new(id: impl Into<SessionModeId>, name: impl Into<String>) -> Self {
1234        Self {
1235            id: id.into(),
1236            name: name.into(),
1237            description: None,
1238            meta: None,
1239        }
1240    }
1241
1242    #[must_use]
1243    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1244        self.description = description.into_option();
1245        self
1246    }
1247
1248    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1249    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1250    /// these keys.
1251    ///
1252    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1253    #[must_use]
1254    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1255        self.meta = meta.into_option();
1256        self
1257    }
1258}
1259
1260/// Unique identifier for a Session Mode.
1261#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1262#[serde(transparent)]
1263#[from(Arc<str>, String, &'static str)]
1264#[non_exhaustive]
1265pub struct SessionModeId(pub Arc<str>);
1266
1267impl SessionModeId {
1268    pub fn new(id: impl Into<Arc<str>>) -> Self {
1269        Self(id.into())
1270    }
1271}
1272
1273/// Request parameters for setting a session mode.
1274#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1275#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
1276#[serde(rename_all = "camelCase")]
1277#[non_exhaustive]
1278pub struct SetSessionModeRequest {
1279    /// The ID of the session to set the mode for.
1280    pub session_id: SessionId,
1281    /// The ID of the mode to set.
1282    pub mode_id: SessionModeId,
1283    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1284    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1285    /// these keys.
1286    ///
1287    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1288    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1289    pub meta: Option<Meta>,
1290}
1291
1292impl SetSessionModeRequest {
1293    #[must_use]
1294    pub fn new(session_id: impl Into<SessionId>, mode_id: impl Into<SessionModeId>) -> Self {
1295        Self {
1296            session_id: session_id.into(),
1297            mode_id: mode_id.into(),
1298            meta: None,
1299        }
1300    }
1301
1302    #[must_use]
1303    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1304        self.meta = meta.into_option();
1305        self
1306    }
1307}
1308
1309/// Response to `session/set_mode` method.
1310#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1311#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
1312#[serde(rename_all = "camelCase")]
1313#[non_exhaustive]
1314pub struct SetSessionModeResponse {
1315    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1316    pub meta: Option<Meta>,
1317}
1318
1319impl SetSessionModeResponse {
1320    #[must_use]
1321    pub fn new() -> Self {
1322        Self::default()
1323    }
1324
1325    #[must_use]
1326    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1327        self.meta = meta.into_option();
1328        self
1329    }
1330}
1331
1332// Session config options
1333
1334/// **UNSTABLE**
1335///
1336/// This capability is not part of the spec yet, and may be removed or changed at any point.
1337///
1338/// Unique identifier for a session configuration option.
1339#[cfg(feature = "unstable_session_config_options")]
1340#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1341#[serde(transparent)]
1342#[from(Arc<str>, String, &'static str)]
1343#[non_exhaustive]
1344pub struct SessionConfigId(pub Arc<str>);
1345
1346#[cfg(feature = "unstable_session_config_options")]
1347impl SessionConfigId {
1348    pub fn new(id: impl Into<Arc<str>>) -> Self {
1349        Self(id.into())
1350    }
1351}
1352
1353/// **UNSTABLE**
1354///
1355/// This capability is not part of the spec yet, and may be removed or changed at any point.
1356///
1357/// Unique identifier for a session configuration option value.
1358#[cfg(feature = "unstable_session_config_options")]
1359#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1360#[serde(transparent)]
1361#[from(Arc<str>, String, &'static str)]
1362#[non_exhaustive]
1363pub struct SessionConfigValueId(pub Arc<str>);
1364
1365#[cfg(feature = "unstable_session_config_options")]
1366impl SessionConfigValueId {
1367    pub fn new(id: impl Into<Arc<str>>) -> Self {
1368        Self(id.into())
1369    }
1370}
1371
1372/// **UNSTABLE**
1373///
1374/// This capability is not part of the spec yet, and may be removed or changed at any point.
1375///
1376/// Unique identifier for a session configuration option value group.
1377#[cfg(feature = "unstable_session_config_options")]
1378#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1379#[serde(transparent)]
1380#[from(Arc<str>, String, &'static str)]
1381#[non_exhaustive]
1382pub struct SessionConfigGroupId(pub Arc<str>);
1383
1384#[cfg(feature = "unstable_session_config_options")]
1385impl SessionConfigGroupId {
1386    pub fn new(id: impl Into<Arc<str>>) -> Self {
1387        Self(id.into())
1388    }
1389}
1390
1391/// **UNSTABLE**
1392///
1393/// This capability is not part of the spec yet, and may be removed or changed at any point.
1394///
1395/// A possible value for a session configuration option.
1396#[cfg(feature = "unstable_session_config_options")]
1397#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1398#[serde(rename_all = "camelCase")]
1399#[non_exhaustive]
1400pub struct SessionConfigSelectOption {
1401    /// Unique identifier for this option value.
1402    pub value: SessionConfigValueId,
1403    /// Human-readable label for this option value.
1404    pub name: String,
1405    /// Optional description for this option value.
1406    #[serde(default, skip_serializing_if = "Option::is_none")]
1407    pub description: Option<String>,
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    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1414    pub meta: Option<Meta>,
1415}
1416
1417#[cfg(feature = "unstable_session_config_options")]
1418impl SessionConfigSelectOption {
1419    #[must_use]
1420    pub fn new(value: impl Into<SessionConfigValueId>, name: impl Into<String>) -> Self {
1421        Self {
1422            value: value.into(),
1423            name: name.into(),
1424            description: None,
1425            meta: None,
1426        }
1427    }
1428
1429    #[must_use]
1430    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1431        self.description = description.into_option();
1432        self
1433    }
1434
1435    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1436    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1437    /// these keys.
1438    ///
1439    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1440    #[must_use]
1441    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1442        self.meta = meta.into_option();
1443        self
1444    }
1445}
1446
1447/// **UNSTABLE**
1448///
1449/// This capability is not part of the spec yet, and may be removed or changed at any point.
1450///
1451/// A group of possible values for a session configuration option.
1452#[cfg(feature = "unstable_session_config_options")]
1453#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1454#[serde(rename_all = "camelCase")]
1455#[non_exhaustive]
1456pub struct SessionConfigSelectGroup {
1457    /// Unique identifier for this group.
1458    pub group: SessionConfigGroupId,
1459    /// Human-readable label for this group.
1460    pub name: String,
1461    /// The set of option values in this group.
1462    pub options: Vec<SessionConfigSelectOption>,
1463    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1464    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1465    /// these keys.
1466    ///
1467    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1468    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1469    pub meta: Option<Meta>,
1470}
1471
1472#[cfg(feature = "unstable_session_config_options")]
1473impl SessionConfigSelectGroup {
1474    #[must_use]
1475    pub fn new(
1476        group: impl Into<SessionConfigGroupId>,
1477        name: impl Into<String>,
1478        options: Vec<SessionConfigSelectOption>,
1479    ) -> Self {
1480        Self {
1481            group: group.into(),
1482            name: name.into(),
1483            options,
1484            meta: None,
1485        }
1486    }
1487
1488    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1489    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1490    /// these keys.
1491    ///
1492    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1493    #[must_use]
1494    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1495        self.meta = meta.into_option();
1496        self
1497    }
1498}
1499
1500/// **UNSTABLE**
1501///
1502/// This capability is not part of the spec yet, and may be removed or changed at any point.
1503///
1504/// Possible values for a session configuration option.
1505#[cfg(feature = "unstable_session_config_options")]
1506#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1507#[serde(untagged)]
1508#[non_exhaustive]
1509pub enum SessionConfigSelectOptions {
1510    /// A flat list of options with no grouping.
1511    Ungrouped(Vec<SessionConfigSelectOption>),
1512    /// A list of options grouped under headers.
1513    Grouped(Vec<SessionConfigSelectGroup>),
1514}
1515
1516#[cfg(feature = "unstable_session_config_options")]
1517impl From<Vec<SessionConfigSelectOption>> for SessionConfigSelectOptions {
1518    fn from(options: Vec<SessionConfigSelectOption>) -> Self {
1519        SessionConfigSelectOptions::Ungrouped(options)
1520    }
1521}
1522
1523#[cfg(feature = "unstable_session_config_options")]
1524impl From<Vec<SessionConfigSelectGroup>> for SessionConfigSelectOptions {
1525    fn from(groups: Vec<SessionConfigSelectGroup>) -> Self {
1526        SessionConfigSelectOptions::Grouped(groups)
1527    }
1528}
1529
1530/// **UNSTABLE**
1531///
1532/// This capability is not part of the spec yet, and may be removed or changed at any point.
1533///
1534/// A single-value selector (dropdown) session configuration option payload.
1535#[cfg(feature = "unstable_session_config_options")]
1536#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1537#[serde(rename_all = "camelCase")]
1538#[non_exhaustive]
1539pub struct SessionConfigSelect {
1540    /// The currently selected value.
1541    pub current_value: SessionConfigValueId,
1542    /// The set of selectable options.
1543    pub options: SessionConfigSelectOptions,
1544}
1545
1546#[cfg(feature = "unstable_session_config_options")]
1547impl SessionConfigSelect {
1548    #[must_use]
1549    pub fn new(
1550        current_value: impl Into<SessionConfigValueId>,
1551        options: impl Into<SessionConfigSelectOptions>,
1552    ) -> Self {
1553        Self {
1554            current_value: current_value.into(),
1555            options: options.into(),
1556        }
1557    }
1558}
1559
1560/// **UNSTABLE**
1561///
1562/// This capability is not part of the spec yet, and may be removed or changed at any point.
1563///
1564/// Semantic category for a session configuration option.
1565///
1566/// This is intended to help Clients distinguish broadly common selectors (e.g. model selector vs
1567/// session mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,
1568/// placement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown
1569/// categories gracefully.
1570///
1571/// Category names beginning with `_` are free for custom use, like other ACP extension methods.
1572/// Category names that do not begin with `_` are reserved for the ACP spec.
1573#[cfg(feature = "unstable_session_config_options")]
1574#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1575#[serde(rename_all = "snake_case")]
1576#[non_exhaustive]
1577pub enum SessionConfigOptionCategory {
1578    /// Session mode selector.
1579    Mode,
1580    /// Model selector.
1581    Model,
1582    /// Thought/reasoning level selector.
1583    ThoughtLevel,
1584    /// Unknown / uncategorized selector.
1585    #[serde(untagged)]
1586    Other(String),
1587}
1588
1589/// **UNSTABLE**
1590///
1591/// This capability is not part of the spec yet, and may be removed or changed at any point.
1592///
1593/// Type-specific session configuration option payload.
1594#[cfg(feature = "unstable_session_config_options")]
1595#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1596#[serde(tag = "type", rename_all = "snake_case")]
1597#[schemars(extend("discriminator" = {"propertyName": "type"}))]
1598#[non_exhaustive]
1599pub enum SessionConfigKind {
1600    /// Single-value selector (dropdown).
1601    Select(SessionConfigSelect),
1602}
1603
1604/// **UNSTABLE**
1605///
1606/// This capability is not part of the spec yet, and may be removed or changed at any point.
1607///
1608/// A session configuration option selector and its current state.
1609#[cfg(feature = "unstable_session_config_options")]
1610#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1611#[serde(rename_all = "camelCase")]
1612#[non_exhaustive]
1613pub struct SessionConfigOption {
1614    /// Unique identifier for the configuration option.
1615    pub id: SessionConfigId,
1616    /// Human-readable label for the option.
1617    pub name: String,
1618    /// Optional description for the Client to display to the user.
1619    #[serde(default, skip_serializing_if = "Option::is_none")]
1620    pub description: Option<String>,
1621    /// Optional semantic category for this option (UX only).
1622    #[serde(default, skip_serializing_if = "Option::is_none")]
1623    pub category: Option<SessionConfigOptionCategory>,
1624    /// Type-specific fields for this configuration option.
1625    #[serde(flatten)]
1626    pub kind: SessionConfigKind,
1627    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1628    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1629    /// these keys.
1630    ///
1631    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1632    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1633    pub meta: Option<Meta>,
1634}
1635
1636#[cfg(feature = "unstable_session_config_options")]
1637impl SessionConfigOption {
1638    #[must_use]
1639    pub fn new(
1640        id: impl Into<SessionConfigId>,
1641        name: impl Into<String>,
1642        kind: SessionConfigKind,
1643    ) -> Self {
1644        Self {
1645            id: id.into(),
1646            name: name.into(),
1647            description: None,
1648            category: None,
1649            kind,
1650            meta: None,
1651        }
1652    }
1653
1654    #[must_use]
1655    pub fn select(
1656        id: impl Into<SessionConfigId>,
1657        name: impl Into<String>,
1658        current_value: impl Into<SessionConfigValueId>,
1659        options: impl Into<SessionConfigSelectOptions>,
1660    ) -> Self {
1661        Self::new(
1662            id,
1663            name,
1664            SessionConfigKind::Select(SessionConfigSelect::new(current_value, options)),
1665        )
1666    }
1667
1668    #[must_use]
1669    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1670        self.description = description.into_option();
1671        self
1672    }
1673
1674    #[must_use]
1675    pub fn category(mut self, category: impl IntoOption<SessionConfigOptionCategory>) -> Self {
1676        self.category = category.into_option();
1677        self
1678    }
1679
1680    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1681    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1682    /// these keys.
1683    ///
1684    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1685    #[must_use]
1686    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1687        self.meta = meta.into_option();
1688        self
1689    }
1690}
1691
1692/// **UNSTABLE**
1693///
1694/// This capability is not part of the spec yet, and may be removed or changed at any point.
1695///
1696/// Request parameters for setting a session configuration option.
1697#[cfg(feature = "unstable_session_config_options")]
1698#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1699#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_CONFIG_OPTION_METHOD_NAME))]
1700#[serde(rename_all = "camelCase")]
1701#[non_exhaustive]
1702pub struct SetSessionConfigOptionRequest {
1703    /// The ID of the session to set the configuration option for.
1704    pub session_id: SessionId,
1705    /// The ID of the configuration option to set.
1706    pub config_id: SessionConfigId,
1707    /// The ID of the configuration option value to set.
1708    pub value: SessionConfigValueId,
1709    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1710    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1711    /// these keys.
1712    ///
1713    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1714    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1715    pub meta: Option<Meta>,
1716}
1717
1718#[cfg(feature = "unstable_session_config_options")]
1719impl SetSessionConfigOptionRequest {
1720    #[must_use]
1721    pub fn new(
1722        session_id: impl Into<SessionId>,
1723        config_id: impl Into<SessionConfigId>,
1724        value: impl Into<SessionConfigValueId>,
1725    ) -> Self {
1726        Self {
1727            session_id: session_id.into(),
1728            config_id: config_id.into(),
1729            value: value.into(),
1730            meta: None,
1731        }
1732    }
1733
1734    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1735    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1736    /// these keys.
1737    ///
1738    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1739    #[must_use]
1740    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1741        self.meta = meta.into_option();
1742        self
1743    }
1744}
1745
1746/// **UNSTABLE**
1747///
1748/// This capability is not part of the spec yet, and may be removed or changed at any point.
1749///
1750/// Response to `session/set_config_option` method.
1751#[cfg(feature = "unstable_session_config_options")]
1752#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1753#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_CONFIG_OPTION_METHOD_NAME))]
1754#[serde(rename_all = "camelCase")]
1755#[non_exhaustive]
1756pub struct SetSessionConfigOptionResponse {
1757    /// The full set of configuration options and their current values.
1758    pub config_options: Vec<SessionConfigOption>,
1759    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1760    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1761    /// these keys.
1762    ///
1763    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1764    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1765    pub meta: Option<Meta>,
1766}
1767
1768#[cfg(feature = "unstable_session_config_options")]
1769impl SetSessionConfigOptionResponse {
1770    #[must_use]
1771    pub fn new(config_options: Vec<SessionConfigOption>) -> Self {
1772        Self {
1773            config_options,
1774            meta: None,
1775        }
1776    }
1777
1778    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1779    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1780    /// these keys.
1781    ///
1782    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1783    #[must_use]
1784    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1785        self.meta = meta.into_option();
1786        self
1787    }
1788}
1789
1790// MCP
1791
1792/// Configuration for connecting to an MCP (Model Context Protocol) server.
1793///
1794/// MCP servers provide tools and context that the agent can use when
1795/// processing prompts.
1796///
1797/// See protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)
1798#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1799#[serde(tag = "type", rename_all = "snake_case")]
1800#[non_exhaustive]
1801pub enum McpServer {
1802    /// HTTP transport configuration
1803    ///
1804    /// Only available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.
1805    Http(McpServerHttp),
1806    /// SSE transport configuration
1807    ///
1808    /// Only available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.
1809    Sse(McpServerSse),
1810    /// Stdio transport configuration
1811    ///
1812    /// All Agents MUST support this transport.
1813    #[serde(untagged)]
1814    Stdio(McpServerStdio),
1815}
1816
1817/// HTTP transport configuration for MCP.
1818#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1819#[serde(rename_all = "camelCase")]
1820#[non_exhaustive]
1821pub struct McpServerHttp {
1822    /// Human-readable name identifying this MCP server.
1823    pub name: String,
1824    /// URL to the MCP server.
1825    pub url: String,
1826    /// HTTP headers to set when making requests to the MCP server.
1827    pub headers: Vec<HttpHeader>,
1828    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1829    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1830    /// these keys.
1831    ///
1832    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1833    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1834    pub meta: Option<Meta>,
1835}
1836
1837impl McpServerHttp {
1838    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1839        Self {
1840            name: name.into(),
1841            url: url.into(),
1842            headers: Vec::new(),
1843            meta: None,
1844        }
1845    }
1846
1847    /// HTTP headers to set when making requests to the MCP server.
1848    #[must_use]
1849    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1850        self.headers = headers;
1851        self
1852    }
1853
1854    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1855    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1856    /// these keys.
1857    ///
1858    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1859    #[must_use]
1860    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1861        self.meta = meta.into_option();
1862        self
1863    }
1864}
1865
1866/// SSE transport configuration for MCP.
1867#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1868#[serde(rename_all = "camelCase")]
1869#[non_exhaustive]
1870pub struct McpServerSse {
1871    /// Human-readable name identifying this MCP server.
1872    pub name: String,
1873    /// URL to the MCP server.
1874    pub url: String,
1875    /// HTTP headers to set when making requests to the MCP server.
1876    pub headers: Vec<HttpHeader>,
1877    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1878    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1879    /// these keys.
1880    ///
1881    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1882    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1883    pub meta: Option<Meta>,
1884}
1885
1886impl McpServerSse {
1887    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1888        Self {
1889            name: name.into(),
1890            url: url.into(),
1891            headers: Vec::new(),
1892            meta: None,
1893        }
1894    }
1895
1896    /// HTTP headers to set when making requests to the MCP server.
1897    #[must_use]
1898    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1899        self.headers = headers;
1900        self
1901    }
1902
1903    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1904    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1905    /// these keys.
1906    ///
1907    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1908    #[must_use]
1909    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1910        self.meta = meta.into_option();
1911        self
1912    }
1913}
1914
1915/// Stdio transport configuration for MCP.
1916#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1917#[serde(rename_all = "camelCase")]
1918#[non_exhaustive]
1919pub struct McpServerStdio {
1920    /// Human-readable name identifying this MCP server.
1921    pub name: String,
1922    /// Path to the MCP server executable.
1923    pub command: PathBuf,
1924    /// Command-line arguments to pass to the MCP server.
1925    pub args: Vec<String>,
1926    /// Environment variables to set when launching the MCP server.
1927    pub env: Vec<EnvVariable>,
1928    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1929    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1930    /// these keys.
1931    ///
1932    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1933    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1934    pub meta: Option<Meta>,
1935}
1936
1937impl McpServerStdio {
1938    pub fn new(name: impl Into<String>, command: impl Into<PathBuf>) -> Self {
1939        Self {
1940            name: name.into(),
1941            command: command.into(),
1942            args: Vec::new(),
1943            env: Vec::new(),
1944            meta: None,
1945        }
1946    }
1947
1948    /// Command-line arguments to pass to the MCP server.
1949    #[must_use]
1950    pub fn args(mut self, args: Vec<String>) -> Self {
1951        self.args = args;
1952        self
1953    }
1954
1955    /// Environment variables to set when launching the MCP server.
1956    #[must_use]
1957    pub fn env(mut self, env: Vec<EnvVariable>) -> Self {
1958        self.env = env;
1959        self
1960    }
1961
1962    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1963    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1964    /// these keys.
1965    ///
1966    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1967    #[must_use]
1968    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1969        self.meta = meta.into_option();
1970        self
1971    }
1972}
1973
1974/// An environment variable to set when launching an MCP server.
1975#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1976#[serde(rename_all = "camelCase")]
1977#[non_exhaustive]
1978pub struct EnvVariable {
1979    /// The name of the environment variable.
1980    pub name: String,
1981    /// The value to set for the environment variable.
1982    pub value: String,
1983    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1984    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1985    /// these keys.
1986    ///
1987    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1988    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1989    pub meta: Option<Meta>,
1990}
1991
1992impl EnvVariable {
1993    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1994        Self {
1995            name: name.into(),
1996            value: value.into(),
1997            meta: None,
1998        }
1999    }
2000
2001    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2002    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2003    /// these keys.
2004    ///
2005    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2006    #[must_use]
2007    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2008        self.meta = meta.into_option();
2009        self
2010    }
2011}
2012
2013/// An HTTP header to set when making requests to the MCP server.
2014#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2015#[serde(rename_all = "camelCase")]
2016#[non_exhaustive]
2017pub struct HttpHeader {
2018    /// The name of the HTTP header.
2019    pub name: String,
2020    /// The value to set for the HTTP header.
2021    pub value: String,
2022    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2023    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2024    /// these keys.
2025    ///
2026    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2027    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2028    pub meta: Option<Meta>,
2029}
2030
2031impl HttpHeader {
2032    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
2033        Self {
2034            name: name.into(),
2035            value: value.into(),
2036            meta: None,
2037        }
2038    }
2039
2040    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2041    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2042    /// these keys.
2043    ///
2044    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2045    #[must_use]
2046    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2047        self.meta = meta.into_option();
2048        self
2049    }
2050}
2051
2052// Prompt
2053
2054/// Request parameters for sending a user prompt to the agent.
2055///
2056/// Contains the user's message and any additional context.
2057///
2058/// See protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)
2059#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
2060#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
2061#[serde(rename_all = "camelCase")]
2062#[non_exhaustive]
2063pub struct PromptRequest {
2064    /// The ID of the session to send this user message to
2065    pub session_id: SessionId,
2066    /// The blocks of content that compose the user's message.
2067    ///
2068    /// As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],
2069    /// while other variants are optionally enabled via [`PromptCapabilities`].
2070    ///
2071    /// The Client MUST adapt its interface according to [`PromptCapabilities`].
2072    ///
2073    /// The client MAY include referenced pieces of context as either
2074    /// [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].
2075    ///
2076    /// When available, [`ContentBlock::Resource`] is preferred
2077    /// as it avoids extra round-trips and allows the message to include
2078    /// pieces of context from sources the agent may not have access to.
2079    pub prompt: Vec<ContentBlock>,
2080    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2081    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2082    /// these keys.
2083    ///
2084    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2085    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2086    pub meta: Option<Meta>,
2087}
2088
2089impl PromptRequest {
2090    #[must_use]
2091    pub fn new(session_id: impl Into<SessionId>, prompt: Vec<ContentBlock>) -> Self {
2092        Self {
2093            session_id: session_id.into(),
2094            prompt,
2095            meta: None,
2096        }
2097    }
2098
2099    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2100    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2101    /// these keys.
2102    ///
2103    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2104    #[must_use]
2105    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2106        self.meta = meta.into_option();
2107        self
2108    }
2109}
2110
2111/// Response from processing a user prompt.
2112///
2113/// See protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)
2114#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2115#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
2116#[serde(rename_all = "camelCase")]
2117#[non_exhaustive]
2118pub struct PromptResponse {
2119    /// Indicates why the agent stopped processing the turn.
2120    pub stop_reason: StopReason,
2121    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2122    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2123    /// these keys.
2124    ///
2125    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2126    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2127    pub meta: Option<Meta>,
2128}
2129
2130impl PromptResponse {
2131    #[must_use]
2132    pub fn new(stop_reason: StopReason) -> Self {
2133        Self {
2134            stop_reason,
2135            meta: None,
2136        }
2137    }
2138
2139    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2140    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2141    /// these keys.
2142    ///
2143    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2144    #[must_use]
2145    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2146        self.meta = meta.into_option();
2147        self
2148    }
2149}
2150
2151/// Reasons why an agent stops processing a prompt turn.
2152///
2153/// See protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)
2154#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
2155#[serde(rename_all = "snake_case")]
2156#[non_exhaustive]
2157pub enum StopReason {
2158    /// The turn ended successfully.
2159    EndTurn,
2160    /// The turn ended because the agent reached the maximum number of tokens.
2161    MaxTokens,
2162    /// The turn ended because the agent reached the maximum number of allowed
2163    /// agent requests between user turns.
2164    MaxTurnRequests,
2165    /// The turn ended because the agent refused to continue. The user prompt
2166    /// and everything that comes after it won't be included in the next
2167    /// prompt, so this should be reflected in the UI.
2168    Refusal,
2169    /// The turn was cancelled by the client via `session/cancel`.
2170    ///
2171    /// This stop reason MUST be returned when the client sends a `session/cancel`
2172    /// notification, even if the cancellation causes exceptions in underlying operations.
2173    /// Agents should catch these exceptions and return this semantically meaningful
2174    /// response to confirm successful cancellation.
2175    Cancelled,
2176}
2177
2178// Model
2179
2180/// **UNSTABLE**
2181///
2182/// This capability is not part of the spec yet, and may be removed or changed at any point.
2183///
2184/// The set of models and the one currently active.
2185#[cfg(feature = "unstable_session_model")]
2186#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2187#[serde(rename_all = "camelCase")]
2188#[non_exhaustive]
2189pub struct SessionModelState {
2190    /// The current model the Agent is in.
2191    pub current_model_id: ModelId,
2192    /// The set of models that the Agent can use
2193    pub available_models: Vec<ModelInfo>,
2194    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2195    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2196    /// these keys.
2197    ///
2198    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2199    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2200    pub meta: Option<Meta>,
2201}
2202
2203#[cfg(feature = "unstable_session_model")]
2204impl SessionModelState {
2205    #[must_use]
2206    pub fn new(current_model_id: impl Into<ModelId>, available_models: Vec<ModelInfo>) -> Self {
2207        Self {
2208            current_model_id: current_model_id.into(),
2209            available_models,
2210            meta: None,
2211        }
2212    }
2213
2214    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2215    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2216    /// these keys.
2217    ///
2218    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2219    #[must_use]
2220    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2221        self.meta = meta.into_option();
2222        self
2223    }
2224}
2225
2226/// **UNSTABLE**
2227///
2228/// This capability is not part of the spec yet, and may be removed or changed at any point.
2229///
2230/// A unique identifier for a model.
2231#[cfg(feature = "unstable_session_model")]
2232#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
2233#[serde(transparent)]
2234#[from(Arc<str>, String, &'static str)]
2235#[non_exhaustive]
2236pub struct ModelId(pub Arc<str>);
2237
2238#[cfg(feature = "unstable_session_model")]
2239impl ModelId {
2240    pub fn new(id: impl Into<Arc<str>>) -> Self {
2241        Self(id.into())
2242    }
2243}
2244
2245/// **UNSTABLE**
2246///
2247/// This capability is not part of the spec yet, and may be removed or changed at any point.
2248///
2249/// Information about a selectable model.
2250#[cfg(feature = "unstable_session_model")]
2251#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2252#[serde(rename_all = "camelCase")]
2253#[non_exhaustive]
2254pub struct ModelInfo {
2255    /// Unique identifier for the model.
2256    pub model_id: ModelId,
2257    /// Human-readable name of the model.
2258    pub name: String,
2259    /// Optional description of the model.
2260    #[serde(default, skip_serializing_if = "Option::is_none")]
2261    pub description: Option<String>,
2262    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2263    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2264    /// these keys.
2265    ///
2266    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2267    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2268    pub meta: Option<Meta>,
2269}
2270
2271#[cfg(feature = "unstable_session_model")]
2272impl ModelInfo {
2273    pub fn new(model_id: impl Into<ModelId>, name: impl Into<String>) -> Self {
2274        Self {
2275            model_id: model_id.into(),
2276            name: name.into(),
2277            description: None,
2278            meta: None,
2279        }
2280    }
2281
2282    /// Optional description of the model.
2283    #[must_use]
2284    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
2285        self.description = description.into_option();
2286        self
2287    }
2288
2289    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2290    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2291    /// these keys.
2292    ///
2293    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2294    #[must_use]
2295    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2296        self.meta = meta.into_option();
2297        self
2298    }
2299}
2300
2301/// **UNSTABLE**
2302///
2303/// This capability is not part of the spec yet, and may be removed or changed at any point.
2304///
2305/// Request parameters for setting a session model.
2306#[cfg(feature = "unstable_session_model")]
2307#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2308#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
2309#[serde(rename_all = "camelCase")]
2310#[non_exhaustive]
2311pub struct SetSessionModelRequest {
2312    /// The ID of the session to set the model for.
2313    pub session_id: SessionId,
2314    /// The ID of the model to set.
2315    pub model_id: ModelId,
2316    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2317    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2318    /// these keys.
2319    ///
2320    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2321    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2322    pub meta: Option<Meta>,
2323}
2324
2325#[cfg(feature = "unstable_session_model")]
2326impl SetSessionModelRequest {
2327    #[must_use]
2328    pub fn new(session_id: impl Into<SessionId>, model_id: impl Into<ModelId>) -> Self {
2329        Self {
2330            session_id: session_id.into(),
2331            model_id: model_id.into(),
2332            meta: None,
2333        }
2334    }
2335
2336    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2337    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2338    /// these keys.
2339    ///
2340    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2341    #[must_use]
2342    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2343        self.meta = meta.into_option();
2344        self
2345    }
2346}
2347
2348/// **UNSTABLE**
2349///
2350/// This capability is not part of the spec yet, and may be removed or changed at any point.
2351///
2352/// Response to `session/set_model` method.
2353#[cfg(feature = "unstable_session_model")]
2354#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2355#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
2356#[serde(rename_all = "camelCase")]
2357#[non_exhaustive]
2358pub struct SetSessionModelResponse {
2359    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2360    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2361    /// these keys.
2362    ///
2363    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2364    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2365    pub meta: Option<Meta>,
2366}
2367
2368#[cfg(feature = "unstable_session_model")]
2369impl SetSessionModelResponse {
2370    #[must_use]
2371    pub fn new() -> Self {
2372        Self::default()
2373    }
2374
2375    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2376    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2377    /// these keys.
2378    ///
2379    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2380    #[must_use]
2381    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2382        self.meta = meta.into_option();
2383        self
2384    }
2385}
2386
2387// Capabilities
2388
2389/// Capabilities supported by the agent.
2390///
2391/// Advertised during initialization to inform the client about
2392/// available features and content types.
2393///
2394/// See protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)
2395#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2396#[serde(rename_all = "camelCase")]
2397#[non_exhaustive]
2398pub struct AgentCapabilities {
2399    /// Whether the agent supports `session/load`.
2400    #[serde(default)]
2401    pub load_session: bool,
2402    /// Prompt capabilities supported by the agent.
2403    #[serde(default)]
2404    pub prompt_capabilities: PromptCapabilities,
2405    /// MCP capabilities supported by the agent.
2406    #[serde(default)]
2407    pub mcp_capabilities: McpCapabilities,
2408    #[serde(default)]
2409    pub session_capabilities: SessionCapabilities,
2410    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2411    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2412    /// these keys.
2413    ///
2414    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2415    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2416    pub meta: Option<Meta>,
2417}
2418
2419impl AgentCapabilities {
2420    #[must_use]
2421    pub fn new() -> Self {
2422        Self::default()
2423    }
2424
2425    /// Whether the agent supports `session/load`.
2426    #[must_use]
2427    pub fn load_session(mut self, load_session: bool) -> Self {
2428        self.load_session = load_session;
2429        self
2430    }
2431
2432    /// Prompt capabilities supported by the agent.
2433    #[must_use]
2434    pub fn prompt_capabilities(mut self, prompt_capabilities: PromptCapabilities) -> Self {
2435        self.prompt_capabilities = prompt_capabilities;
2436        self
2437    }
2438
2439    /// MCP capabilities supported by the agent.
2440    #[must_use]
2441    pub fn mcp_capabilities(mut self, mcp_capabilities: McpCapabilities) -> Self {
2442        self.mcp_capabilities = mcp_capabilities;
2443        self
2444    }
2445
2446    /// Session capabilities supported by the agent.
2447    #[must_use]
2448    pub fn session_capabilities(mut self, session_capabilities: SessionCapabilities) -> Self {
2449        self.session_capabilities = session_capabilities;
2450        self
2451    }
2452
2453    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2454    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2455    /// these keys.
2456    ///
2457    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2458    #[must_use]
2459    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2460        self.meta = meta.into_option();
2461        self
2462    }
2463}
2464
2465/// Session capabilities supported by the agent.
2466///
2467/// As a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.
2468///
2469/// Optionally, they **MAY** support other session methods and notifications by specifying additional capabilities.
2470///
2471/// Note: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.
2472///
2473/// See protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)
2474#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2475#[non_exhaustive]
2476pub struct SessionCapabilities {
2477    /// **UNSTABLE**
2478    ///
2479    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2480    ///
2481    /// Whether the agent supports `session/list`.
2482    #[cfg(feature = "unstable_session_list")]
2483    #[serde(skip_serializing_if = "Option::is_none")]
2484    pub list: Option<SessionListCapabilities>,
2485    /// **UNSTABLE**
2486    ///
2487    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2488    ///
2489    /// Whether the agent supports `session/fork`.
2490    #[cfg(feature = "unstable_session_fork")]
2491    #[serde(skip_serializing_if = "Option::is_none")]
2492    pub fork: Option<SessionForkCapabilities>,
2493    /// **UNSTABLE**
2494    ///
2495    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2496    ///
2497    /// Whether the agent supports `session/resume`.
2498    #[cfg(feature = "unstable_session_resume")]
2499    #[serde(skip_serializing_if = "Option::is_none")]
2500    pub resume: Option<SessionResumeCapabilities>,
2501    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2502    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2503    /// these keys.
2504    ///
2505    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2506    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2507    pub meta: Option<Meta>,
2508}
2509
2510impl SessionCapabilities {
2511    #[must_use]
2512    pub fn new() -> Self {
2513        Self::default()
2514    }
2515
2516    #[cfg(feature = "unstable_session_list")]
2517    /// Whether the agent supports `session/list`.
2518    #[must_use]
2519    pub fn list(mut self, list: impl IntoOption<SessionListCapabilities>) -> Self {
2520        self.list = list.into_option();
2521        self
2522    }
2523
2524    #[cfg(feature = "unstable_session_fork")]
2525    /// Whether the agent supports `session/fork`.
2526    #[must_use]
2527    pub fn fork(mut self, fork: impl IntoOption<SessionForkCapabilities>) -> Self {
2528        self.fork = fork.into_option();
2529        self
2530    }
2531
2532    #[cfg(feature = "unstable_session_resume")]
2533    /// Whether the agent supports `session/resume`.
2534    #[must_use]
2535    pub fn resume(mut self, resume: impl IntoOption<SessionResumeCapabilities>) -> Self {
2536        self.resume = resume.into_option();
2537        self
2538    }
2539
2540    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2541    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2542    /// these keys.
2543    ///
2544    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2545    #[must_use]
2546    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2547        self.meta = meta.into_option();
2548        self
2549    }
2550}
2551
2552/// Capabilities for the `session/list` method.
2553///
2554/// By supplying `{}` it means that the agent supports listing of sessions.
2555///
2556/// Further capabilities can be added in the future for other means of filtering or searching the list.
2557#[cfg(feature = "unstable_session_list")]
2558#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2559#[non_exhaustive]
2560pub struct SessionListCapabilities {
2561    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2562    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2563    /// these keys.
2564    ///
2565    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2566    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2567    pub meta: Option<Meta>,
2568}
2569
2570#[cfg(feature = "unstable_session_list")]
2571impl SessionListCapabilities {
2572    #[must_use]
2573    pub fn new() -> Self {
2574        Self::default()
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/// **UNSTABLE**
2589///
2590/// This capability is not part of the spec yet, and may be removed or changed at any point.
2591///
2592/// Capabilities for the `session/fork` method.
2593///
2594/// By supplying `{}` it means that the agent supports forking of sessions.
2595#[cfg(feature = "unstable_session_fork")]
2596#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2597#[non_exhaustive]
2598pub struct SessionForkCapabilities {
2599    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2600    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2601    /// these keys.
2602    ///
2603    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2604    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2605    pub meta: Option<Meta>,
2606}
2607
2608#[cfg(feature = "unstable_session_fork")]
2609impl SessionForkCapabilities {
2610    #[must_use]
2611    pub fn new() -> Self {
2612        Self::default()
2613    }
2614
2615    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2616    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2617    /// these keys.
2618    ///
2619    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2620    #[must_use]
2621    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2622        self.meta = meta.into_option();
2623        self
2624    }
2625}
2626
2627/// **UNSTABLE**
2628///
2629/// This capability is not part of the spec yet, and may be removed or changed at any point.
2630///
2631/// Capabilities for the `session/resume` method.
2632///
2633/// By supplying `{}` it means that the agent supports resuming of sessions.
2634#[cfg(feature = "unstable_session_resume")]
2635#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2636#[non_exhaustive]
2637pub struct SessionResumeCapabilities {
2638    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2639    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2640    /// these keys.
2641    ///
2642    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2643    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2644    pub meta: Option<Meta>,
2645}
2646
2647#[cfg(feature = "unstable_session_resume")]
2648impl SessionResumeCapabilities {
2649    #[must_use]
2650    pub fn new() -> Self {
2651        Self::default()
2652    }
2653
2654    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2655    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2656    /// these keys.
2657    ///
2658    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2659    #[must_use]
2660    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2661        self.meta = meta.into_option();
2662        self
2663    }
2664}
2665
2666/// Prompt capabilities supported by the agent in `session/prompt` requests.
2667///
2668/// Baseline agent functionality requires support for [`ContentBlock::Text`]
2669/// and [`ContentBlock::ResourceLink`] in prompt requests.
2670///
2671/// Other variants must be explicitly opted in to.
2672/// Capabilities for different types of content in prompt requests.
2673///
2674/// Indicates which content types beyond the baseline (text and resource links)
2675/// the agent can process.
2676///
2677/// See protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)
2678#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2679#[serde(rename_all = "camelCase")]
2680#[non_exhaustive]
2681pub struct PromptCapabilities {
2682    /// Agent supports [`ContentBlock::Image`].
2683    #[serde(default)]
2684    pub image: bool,
2685    /// Agent supports [`ContentBlock::Audio`].
2686    #[serde(default)]
2687    pub audio: bool,
2688    /// Agent supports embedded context in `session/prompt` requests.
2689    ///
2690    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
2691    /// in prompt requests for pieces of context that are referenced in the message.
2692    #[serde(default)]
2693    pub embedded_context: bool,
2694    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2695    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2696    /// these keys.
2697    ///
2698    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2699    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2700    pub meta: Option<Meta>,
2701}
2702
2703impl PromptCapabilities {
2704    #[must_use]
2705    pub fn new() -> Self {
2706        Self::default()
2707    }
2708
2709    /// Agent supports [`ContentBlock::Image`].
2710    #[must_use]
2711    pub fn image(mut self, image: bool) -> Self {
2712        self.image = image;
2713        self
2714    }
2715
2716    /// Agent supports [`ContentBlock::Audio`].
2717    #[must_use]
2718    pub fn audio(mut self, audio: bool) -> Self {
2719        self.audio = audio;
2720        self
2721    }
2722
2723    /// Agent supports embedded context in `session/prompt` requests.
2724    ///
2725    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
2726    /// in prompt requests for pieces of context that are referenced in the message.
2727    #[must_use]
2728    pub fn embedded_context(mut self, embedded_context: bool) -> Self {
2729        self.embedded_context = embedded_context;
2730        self
2731    }
2732
2733    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2734    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2735    /// these keys.
2736    ///
2737    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2738    #[must_use]
2739    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2740        self.meta = meta.into_option();
2741        self
2742    }
2743}
2744
2745/// MCP capabilities supported by the agent
2746#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2747#[serde(rename_all = "camelCase")]
2748#[non_exhaustive]
2749pub struct McpCapabilities {
2750    /// Agent supports [`McpServer::Http`].
2751    #[serde(default)]
2752    pub http: bool,
2753    /// Agent supports [`McpServer::Sse`].
2754    #[serde(default)]
2755    pub sse: bool,
2756    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2757    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2758    /// these keys.
2759    ///
2760    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2761    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2762    pub meta: Option<Meta>,
2763}
2764
2765impl McpCapabilities {
2766    #[must_use]
2767    pub fn new() -> Self {
2768        Self::default()
2769    }
2770
2771    /// Agent supports [`McpServer::Http`].
2772    #[must_use]
2773    pub fn http(mut self, http: bool) -> Self {
2774        self.http = http;
2775        self
2776    }
2777
2778    /// Agent supports [`McpServer::Sse`].
2779    #[must_use]
2780    pub fn sse(mut self, sse: bool) -> Self {
2781        self.sse = sse;
2782        self
2783    }
2784
2785    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2786    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2787    /// these keys.
2788    ///
2789    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2790    #[must_use]
2791    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2792        self.meta = meta.into_option();
2793        self
2794    }
2795}
2796
2797// Method schema
2798
2799/// Names of all methods that agents handle.
2800///
2801/// Provides a centralized definition of method names used in the protocol.
2802#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2803#[non_exhaustive]
2804pub struct AgentMethodNames {
2805    /// Method for initializing the connection.
2806    pub initialize: &'static str,
2807    /// Method for authenticating with the agent.
2808    pub authenticate: &'static str,
2809    /// Method for creating a new session.
2810    pub session_new: &'static str,
2811    /// Method for loading an existing session.
2812    pub session_load: &'static str,
2813    /// Method for setting the mode for a session.
2814    pub session_set_mode: &'static str,
2815    /// Method for setting a configuration option for a session.
2816    #[cfg(feature = "unstable_session_config_options")]
2817    pub session_set_config_option: &'static str,
2818    /// Method for sending a prompt to the agent.
2819    pub session_prompt: &'static str,
2820    /// Notification for cancelling operations.
2821    pub session_cancel: &'static str,
2822    /// Method for selecting a model for a given session.
2823    #[cfg(feature = "unstable_session_model")]
2824    pub session_set_model: &'static str,
2825    /// Method for listing existing sessions.
2826    #[cfg(feature = "unstable_session_list")]
2827    pub session_list: &'static str,
2828    /// Method for forking an existing session.
2829    #[cfg(feature = "unstable_session_fork")]
2830    pub session_fork: &'static str,
2831    /// Method for resuming an existing session.
2832    #[cfg(feature = "unstable_session_resume")]
2833    pub session_resume: &'static str,
2834}
2835
2836/// Constant containing all agent method names.
2837pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
2838    initialize: INITIALIZE_METHOD_NAME,
2839    authenticate: AUTHENTICATE_METHOD_NAME,
2840    session_new: SESSION_NEW_METHOD_NAME,
2841    session_load: SESSION_LOAD_METHOD_NAME,
2842    session_set_mode: SESSION_SET_MODE_METHOD_NAME,
2843    #[cfg(feature = "unstable_session_config_options")]
2844    session_set_config_option: SESSION_SET_CONFIG_OPTION_METHOD_NAME,
2845    session_prompt: SESSION_PROMPT_METHOD_NAME,
2846    session_cancel: SESSION_CANCEL_METHOD_NAME,
2847    #[cfg(feature = "unstable_session_model")]
2848    session_set_model: SESSION_SET_MODEL_METHOD_NAME,
2849    #[cfg(feature = "unstable_session_list")]
2850    session_list: SESSION_LIST_METHOD_NAME,
2851    #[cfg(feature = "unstable_session_fork")]
2852    session_fork: SESSION_FORK_METHOD_NAME,
2853    #[cfg(feature = "unstable_session_resume")]
2854    session_resume: SESSION_RESUME_METHOD_NAME,
2855};
2856
2857/// Method name for the initialize request.
2858pub(crate) const INITIALIZE_METHOD_NAME: &str = "initialize";
2859/// Method name for the authenticate request.
2860pub(crate) const AUTHENTICATE_METHOD_NAME: &str = "authenticate";
2861/// Method name for creating a new session.
2862pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
2863/// Method name for loading an existing session.
2864pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
2865/// Method name for setting the mode for a session.
2866pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
2867/// Method name for setting a configuration option for a session.
2868#[cfg(feature = "unstable_session_config_options")]
2869pub(crate) const SESSION_SET_CONFIG_OPTION_METHOD_NAME: &str = "session/set_config_option";
2870/// Method name for sending a prompt.
2871pub(crate) const SESSION_PROMPT_METHOD_NAME: &str = "session/prompt";
2872/// Method name for the cancel notification.
2873pub(crate) const SESSION_CANCEL_METHOD_NAME: &str = "session/cancel";
2874/// Method name for selecting a model for a given session.
2875#[cfg(feature = "unstable_session_model")]
2876pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
2877/// Method name for listing existing sessions.
2878#[cfg(feature = "unstable_session_list")]
2879pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list";
2880/// Method name for forking an existing session.
2881#[cfg(feature = "unstable_session_fork")]
2882pub(crate) const SESSION_FORK_METHOD_NAME: &str = "session/fork";
2883/// Method name for resuming an existing session.
2884#[cfg(feature = "unstable_session_resume")]
2885pub(crate) const SESSION_RESUME_METHOD_NAME: &str = "session/resume";
2886
2887/// All possible requests that a client can send to an agent.
2888///
2889/// This enum is used internally for routing RPC requests. You typically won't need
2890/// to use this directly - instead, use the methods on the [`Agent`] trait.
2891///
2892/// This enum encompasses all method calls from client to agent.
2893#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2894#[serde(untagged)]
2895#[schemars(inline)]
2896#[non_exhaustive]
2897pub enum ClientRequest {
2898    /// Establishes the connection with a client and negotiates protocol capabilities.
2899    ///
2900    /// This method is called once at the beginning of the connection to:
2901    /// - Negotiate the protocol version to use
2902    /// - Exchange capability information between client and agent
2903    /// - Determine available authentication methods
2904    ///
2905    /// The agent should respond with its supported protocol version and capabilities.
2906    ///
2907    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
2908    InitializeRequest(InitializeRequest),
2909    /// Authenticates the client using the specified authentication method.
2910    ///
2911    /// Called when the agent requires authentication before allowing session creation.
2912    /// The client provides the authentication method ID that was advertised during initialization.
2913    ///
2914    /// After successful authentication, the client can proceed to create sessions with
2915    /// `new_session` without receiving an `auth_required` error.
2916    ///
2917    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
2918    AuthenticateRequest(AuthenticateRequest),
2919    /// Creates a new conversation session with the agent.
2920    ///
2921    /// Sessions represent independent conversation contexts with their own history and state.
2922    ///
2923    /// The agent should:
2924    /// - Create a new session context
2925    /// - Connect to any specified MCP servers
2926    /// - Return a unique session ID for future requests
2927    ///
2928    /// May return an `auth_required` error if the agent requires authentication.
2929    ///
2930    /// See protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)
2931    NewSessionRequest(NewSessionRequest),
2932    /// Loads an existing session to resume a previous conversation.
2933    ///
2934    /// This method is only available if the agent advertises the `loadSession` capability.
2935    ///
2936    /// The agent should:
2937    /// - Restore the session context and conversation history
2938    /// - Connect to the specified MCP servers
2939    /// - Stream the entire conversation history back to the client via notifications
2940    ///
2941    /// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
2942    LoadSessionRequest(LoadSessionRequest),
2943    #[cfg(feature = "unstable_session_list")]
2944    /// **UNSTABLE**
2945    ///
2946    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2947    ///
2948    /// Lists existing sessions known to the agent.
2949    ///
2950    /// This method is only available if the agent advertises the `listSessions` capability.
2951    ///
2952    /// The agent should return metadata about sessions with optional filtering and pagination support.
2953    ListSessionsRequest(ListSessionsRequest),
2954    #[cfg(feature = "unstable_session_fork")]
2955    /// **UNSTABLE**
2956    ///
2957    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2958    ///
2959    /// Forks an existing session to create a new independent session.
2960    ///
2961    /// This method is only available if the agent advertises the `session.fork` capability.
2962    ///
2963    /// The agent should create a new session with the same conversation context as the
2964    /// original, allowing operations like generating summaries without affecting the
2965    /// original session's history.
2966    ForkSessionRequest(ForkSessionRequest),
2967    #[cfg(feature = "unstable_session_resume")]
2968    /// **UNSTABLE**
2969    ///
2970    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2971    ///
2972    /// Resumes an existing session without returning previous messages.
2973    ///
2974    /// This method is only available if the agent advertises the `session.resume` capability.
2975    ///
2976    /// The agent should resume the session context, allowing the conversation to continue
2977    /// without replaying the message history (unlike `session/load`).
2978    ResumeSessionRequest(ResumeSessionRequest),
2979    /// Sets the current mode for a session.
2980    ///
2981    /// Allows switching between different agent modes (e.g., "ask", "architect", "code")
2982    /// that affect system prompts, tool availability, and permission behaviors.
2983    ///
2984    /// The mode must be one of the modes advertised in `availableModes` during session
2985    /// creation or loading. Agents may also change modes autonomously and notify the
2986    /// client via `current_mode_update` notifications.
2987    ///
2988    /// This method can be called at any time during a session, whether the Agent is
2989    /// idle or actively generating a response.
2990    ///
2991    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
2992    SetSessionModeRequest(SetSessionModeRequest),
2993    #[cfg(feature = "unstable_session_config_options")]
2994    /// **UNSTABLE**
2995    ///
2996    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2997    ///
2998    /// Sets the current value for a session configuration option.
2999    SetSessionConfigOptionRequest(SetSessionConfigOptionRequest),
3000    /// Processes a user prompt within a session.
3001    ///
3002    /// This method handles the whole lifecycle of a prompt:
3003    /// - Receives user messages with optional context (files, images, etc.)
3004    /// - Processes the prompt using language models
3005    /// - Reports language model content and tool calls to the Clients
3006    /// - Requests permission to run tools
3007    /// - Executes any requested tool calls
3008    /// - Returns when the turn is complete with a stop reason
3009    ///
3010    /// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
3011    PromptRequest(PromptRequest),
3012    #[cfg(feature = "unstable_session_model")]
3013    /// **UNSTABLE**
3014    ///
3015    /// This capability is not part of the spec yet, and may be removed or changed at any point.
3016    ///
3017    /// Select a model for a given session.
3018    SetSessionModelRequest(SetSessionModelRequest),
3019    /// Handles extension method requests from the client.
3020    ///
3021    /// Extension methods provide a way to add custom functionality while maintaining
3022    /// protocol compatibility.
3023    ///
3024    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3025    ExtMethodRequest(ExtRequest),
3026}
3027
3028impl ClientRequest {
3029    /// Returns the corresponding method name of the request.
3030    #[must_use]
3031    pub fn method(&self) -> &str {
3032        match self {
3033            Self::InitializeRequest(_) => AGENT_METHOD_NAMES.initialize,
3034            Self::AuthenticateRequest(_) => AGENT_METHOD_NAMES.authenticate,
3035            Self::NewSessionRequest(_) => AGENT_METHOD_NAMES.session_new,
3036            Self::LoadSessionRequest(_) => AGENT_METHOD_NAMES.session_load,
3037            #[cfg(feature = "unstable_session_list")]
3038            Self::ListSessionsRequest(_) => AGENT_METHOD_NAMES.session_list,
3039            #[cfg(feature = "unstable_session_fork")]
3040            Self::ForkSessionRequest(_) => AGENT_METHOD_NAMES.session_fork,
3041            #[cfg(feature = "unstable_session_resume")]
3042            Self::ResumeSessionRequest(_) => AGENT_METHOD_NAMES.session_resume,
3043            Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode,
3044            #[cfg(feature = "unstable_session_config_options")]
3045            Self::SetSessionConfigOptionRequest(_) => AGENT_METHOD_NAMES.session_set_config_option,
3046            Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt,
3047            #[cfg(feature = "unstable_session_model")]
3048            Self::SetSessionModelRequest(_) => AGENT_METHOD_NAMES.session_set_model,
3049            Self::ExtMethodRequest(ext_request) => &ext_request.method,
3050        }
3051    }
3052}
3053
3054/// All possible responses that an agent can send to a client.
3055///
3056/// This enum is used internally for routing RPC responses. You typically won't need
3057/// to use this directly - the responses are handled automatically by the connection.
3058///
3059/// These are responses to the corresponding `ClientRequest` variants.
3060#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
3061#[serde(untagged)]
3062#[schemars(inline)]
3063#[non_exhaustive]
3064pub enum AgentResponse {
3065    InitializeResponse(InitializeResponse),
3066    AuthenticateResponse(#[serde(default)] AuthenticateResponse),
3067    NewSessionResponse(NewSessionResponse),
3068    LoadSessionResponse(#[serde(default)] LoadSessionResponse),
3069    #[cfg(feature = "unstable_session_list")]
3070    ListSessionsResponse(ListSessionsResponse),
3071    #[cfg(feature = "unstable_session_fork")]
3072    ForkSessionResponse(ForkSessionResponse),
3073    #[cfg(feature = "unstable_session_resume")]
3074    ResumeSessionResponse(#[serde(default)] ResumeSessionResponse),
3075    SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
3076    #[cfg(feature = "unstable_session_config_options")]
3077    SetSessionConfigOptionResponse(SetSessionConfigOptionResponse),
3078    PromptResponse(PromptResponse),
3079    #[cfg(feature = "unstable_session_model")]
3080    SetSessionModelResponse(SetSessionModelResponse),
3081    ExtMethodResponse(ExtResponse),
3082}
3083
3084/// All possible notifications that a client can send to an agent.
3085///
3086/// This enum is used internally for routing RPC notifications. You typically won't need
3087/// to use this directly - use the notification methods on the [`Agent`] trait instead.
3088///
3089/// Notifications do not expect a response.
3090#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
3091#[serde(untagged)]
3092#[schemars(inline)]
3093#[non_exhaustive]
3094pub enum ClientNotification {
3095    /// Cancels ongoing operations for a session.
3096    ///
3097    /// This is a notification sent by the client to cancel an ongoing prompt turn.
3098    ///
3099    /// Upon receiving this notification, the Agent SHOULD:
3100    /// - Stop all language model requests as soon as possible
3101    /// - Abort all tool call invocations in progress
3102    /// - Send any pending `session/update` notifications
3103    /// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
3104    ///
3105    /// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
3106    CancelNotification(CancelNotification),
3107    /// Handles extension notifications from the client.
3108    ///
3109    /// Extension notifications provide a way to send one-way messages for custom functionality
3110    /// while maintaining protocol compatibility.
3111    ///
3112    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3113    ExtNotification(ExtNotification),
3114}
3115
3116impl ClientNotification {
3117    /// Returns the corresponding method name of the notification.
3118    #[must_use]
3119    pub fn method(&self) -> &str {
3120        match self {
3121            Self::CancelNotification(_) => AGENT_METHOD_NAMES.session_cancel,
3122            Self::ExtNotification(ext_notification) => &ext_notification.method,
3123        }
3124    }
3125}
3126
3127/// Notification to cancel ongoing operations for a session.
3128///
3129/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
3130#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
3131#[schemars(extend("x-side" = "agent", "x-method" = SESSION_CANCEL_METHOD_NAME))]
3132#[serde(rename_all = "camelCase")]
3133#[non_exhaustive]
3134pub struct CancelNotification {
3135    /// The ID of the session to cancel operations for.
3136    pub session_id: SessionId,
3137    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3138    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3139    /// these keys.
3140    ///
3141    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3142    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3143    pub meta: Option<Meta>,
3144}
3145
3146impl CancelNotification {
3147    #[must_use]
3148    pub fn new(session_id: impl Into<SessionId>) -> Self {
3149        Self {
3150            session_id: session_id.into(),
3151            meta: None,
3152        }
3153    }
3154
3155    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3156    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3157    /// these keys.
3158    ///
3159    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3160    #[must_use]
3161    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3162        self.meta = meta.into_option();
3163        self
3164    }
3165}
3166
3167#[cfg(test)]
3168mod test_serialization {
3169    use super::*;
3170    use serde_json::json;
3171
3172    #[test]
3173    fn test_mcp_server_stdio_serialization() {
3174        let server = McpServer::Stdio(
3175            McpServerStdio::new("test-server", "/usr/bin/server")
3176                .args(vec!["--port".to_string(), "3000".to_string()])
3177                .env(vec![EnvVariable::new("API_KEY", "secret123")]),
3178        );
3179
3180        let json = serde_json::to_value(&server).unwrap();
3181        assert_eq!(
3182            json,
3183            json!({
3184                "name": "test-server",
3185                "command": "/usr/bin/server",
3186                "args": ["--port", "3000"],
3187                "env": [
3188                    {
3189                        "name": "API_KEY",
3190                        "value": "secret123"
3191                    }
3192                ]
3193            })
3194        );
3195
3196        let deserialized: McpServer = serde_json::from_value(json).unwrap();
3197        match deserialized {
3198            McpServer::Stdio(McpServerStdio {
3199                name,
3200                command,
3201                args,
3202                env,
3203                meta: _,
3204            }) => {
3205                assert_eq!(name, "test-server");
3206                assert_eq!(command, PathBuf::from("/usr/bin/server"));
3207                assert_eq!(args, vec!["--port", "3000"]);
3208                assert_eq!(env.len(), 1);
3209                assert_eq!(env[0].name, "API_KEY");
3210                assert_eq!(env[0].value, "secret123");
3211            }
3212            _ => panic!("Expected Stdio variant"),
3213        }
3214    }
3215
3216    #[test]
3217    fn test_mcp_server_http_serialization() {
3218        let server = McpServer::Http(
3219            McpServerHttp::new("http-server", "https://api.example.com").headers(vec![
3220                HttpHeader::new("Authorization", "Bearer token123"),
3221                HttpHeader::new("Content-Type", "application/json"),
3222            ]),
3223        );
3224
3225        let json = serde_json::to_value(&server).unwrap();
3226        assert_eq!(
3227            json,
3228            json!({
3229                "type": "http",
3230                "name": "http-server",
3231                "url": "https://api.example.com",
3232                "headers": [
3233                    {
3234                        "name": "Authorization",
3235                        "value": "Bearer token123"
3236                    },
3237                    {
3238                        "name": "Content-Type",
3239                        "value": "application/json"
3240                    }
3241                ]
3242            })
3243        );
3244
3245        let deserialized: McpServer = serde_json::from_value(json).unwrap();
3246        match deserialized {
3247            McpServer::Http(McpServerHttp {
3248                name,
3249                url,
3250                headers,
3251                meta: _,
3252            }) => {
3253                assert_eq!(name, "http-server");
3254                assert_eq!(url, "https://api.example.com");
3255                assert_eq!(headers.len(), 2);
3256                assert_eq!(headers[0].name, "Authorization");
3257                assert_eq!(headers[0].value, "Bearer token123");
3258                assert_eq!(headers[1].name, "Content-Type");
3259                assert_eq!(headers[1].value, "application/json");
3260            }
3261            _ => panic!("Expected Http variant"),
3262        }
3263    }
3264
3265    #[test]
3266    fn test_mcp_server_sse_serialization() {
3267        let server = McpServer::Sse(
3268            McpServerSse::new("sse-server", "https://sse.example.com/events")
3269                .headers(vec![HttpHeader::new("X-API-Key", "apikey456")]),
3270        );
3271
3272        let json = serde_json::to_value(&server).unwrap();
3273        assert_eq!(
3274            json,
3275            json!({
3276                "type": "sse",
3277                "name": "sse-server",
3278                "url": "https://sse.example.com/events",
3279                "headers": [
3280                    {
3281                        "name": "X-API-Key",
3282                        "value": "apikey456"
3283                    }
3284                ]
3285            })
3286        );
3287
3288        let deserialized: McpServer = serde_json::from_value(json).unwrap();
3289        match deserialized {
3290            McpServer::Sse(McpServerSse {
3291                name,
3292                url,
3293                headers,
3294                meta: _,
3295            }) => {
3296                assert_eq!(name, "sse-server");
3297                assert_eq!(url, "https://sse.example.com/events");
3298                assert_eq!(headers.len(), 1);
3299                assert_eq!(headers[0].name, "X-API-Key");
3300                assert_eq!(headers[0].value, "apikey456");
3301            }
3302            _ => panic!("Expected Sse variant"),
3303        }
3304    }
3305
3306    #[test]
3307    #[cfg(feature = "unstable_session_config_options")]
3308    fn test_session_config_option_category_known_variants() {
3309        // Test serialization of known variants
3310        assert_eq!(
3311            serde_json::to_value(&SessionConfigOptionCategory::Mode).unwrap(),
3312            json!("mode")
3313        );
3314        assert_eq!(
3315            serde_json::to_value(&SessionConfigOptionCategory::Model).unwrap(),
3316            json!("model")
3317        );
3318        assert_eq!(
3319            serde_json::to_value(&SessionConfigOptionCategory::ThoughtLevel).unwrap(),
3320            json!("thought_level")
3321        );
3322
3323        // Test deserialization of known variants
3324        assert_eq!(
3325            serde_json::from_str::<SessionConfigOptionCategory>("\"mode\"").unwrap(),
3326            SessionConfigOptionCategory::Mode
3327        );
3328        assert_eq!(
3329            serde_json::from_str::<SessionConfigOptionCategory>("\"model\"").unwrap(),
3330            SessionConfigOptionCategory::Model
3331        );
3332        assert_eq!(
3333            serde_json::from_str::<SessionConfigOptionCategory>("\"thought_level\"").unwrap(),
3334            SessionConfigOptionCategory::ThoughtLevel
3335        );
3336    }
3337
3338    #[test]
3339    #[cfg(feature = "unstable_session_config_options")]
3340    fn test_session_config_option_category_unknown_variants() {
3341        // Test that unknown strings are captured in Other variant
3342        let unknown: SessionConfigOptionCategory =
3343            serde_json::from_str("\"some_future_category\"").unwrap();
3344        assert_eq!(
3345            unknown,
3346            SessionConfigOptionCategory::Other("some_future_category".to_string())
3347        );
3348
3349        // Test round-trip of unknown category
3350        let json = serde_json::to_value(&unknown).unwrap();
3351        assert_eq!(json, json!("some_future_category"));
3352    }
3353
3354    #[test]
3355    #[cfg(feature = "unstable_session_config_options")]
3356    fn test_session_config_option_category_custom_categories() {
3357        // Category names beginning with `_` are free for custom use
3358        let custom: SessionConfigOptionCategory =
3359            serde_json::from_str("\"_my_custom_category\"").unwrap();
3360        assert_eq!(
3361            custom,
3362            SessionConfigOptionCategory::Other("_my_custom_category".to_string())
3363        );
3364
3365        // Test round-trip preserves the custom category name
3366        let json = serde_json::to_value(&custom).unwrap();
3367        assert_eq!(json, json!("_my_custom_category"));
3368
3369        // Deserialize back and verify
3370        let deserialized: SessionConfigOptionCategory = serde_json::from_value(json).unwrap();
3371        assert_eq!(
3372            deserialized,
3373            SessionConfigOptionCategory::Other("_my_custom_category".to_string())
3374        );
3375    }
3376}