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/// Type-specific session configuration option payload.
1565#[cfg(feature = "unstable_session_config_options")]
1566#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1567#[serde(tag = "type", rename_all = "snake_case")]
1568#[schemars(extend("discriminator" = {"propertyName": "type"}))]
1569#[non_exhaustive]
1570pub enum SessionConfigKind {
1571    /// Single-value selector (dropdown).
1572    Select(SessionConfigSelect),
1573}
1574
1575/// **UNSTABLE**
1576///
1577/// This capability is not part of the spec yet, and may be removed or changed at any point.
1578///
1579/// A session configuration option selector and its current state.
1580#[cfg(feature = "unstable_session_config_options")]
1581#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1582#[serde(rename_all = "camelCase")]
1583#[non_exhaustive]
1584pub struct SessionConfigOption {
1585    /// Unique identifier for the configuration option.
1586    pub id: SessionConfigId,
1587    /// Human-readable label for the option.
1588    pub name: String,
1589    /// Optional description for the Client to display to the user.
1590    #[serde(default, skip_serializing_if = "Option::is_none")]
1591    pub description: Option<String>,
1592    /// Type-specific fields for this configuration option.
1593    #[serde(flatten)]
1594    pub kind: SessionConfigKind,
1595    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1596    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1597    /// these keys.
1598    ///
1599    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1600    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1601    pub meta: Option<Meta>,
1602}
1603
1604#[cfg(feature = "unstable_session_config_options")]
1605impl SessionConfigOption {
1606    #[must_use]
1607    pub fn new(
1608        id: impl Into<SessionConfigId>,
1609        name: impl Into<String>,
1610        kind: SessionConfigKind,
1611    ) -> Self {
1612        Self {
1613            id: id.into(),
1614            name: name.into(),
1615            description: None,
1616            kind,
1617            meta: None,
1618        }
1619    }
1620
1621    #[must_use]
1622    pub fn select(
1623        id: impl Into<SessionConfigId>,
1624        name: impl Into<String>,
1625        current_value: impl Into<SessionConfigValueId>,
1626        options: impl Into<SessionConfigSelectOptions>,
1627    ) -> Self {
1628        Self::new(
1629            id,
1630            name,
1631            SessionConfigKind::Select(SessionConfigSelect::new(current_value, options)),
1632        )
1633    }
1634
1635    #[must_use]
1636    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1637        self.description = description.into_option();
1638        self
1639    }
1640
1641    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1642    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1643    /// these keys.
1644    ///
1645    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1646    #[must_use]
1647    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1648        self.meta = meta.into_option();
1649        self
1650    }
1651}
1652
1653/// **UNSTABLE**
1654///
1655/// This capability is not part of the spec yet, and may be removed or changed at any point.
1656///
1657/// Request parameters for setting a session configuration option.
1658#[cfg(feature = "unstable_session_config_options")]
1659#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1660#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_CONFIG_OPTION_METHOD_NAME))]
1661#[serde(rename_all = "camelCase")]
1662#[non_exhaustive]
1663pub struct SetSessionConfigOptionRequest {
1664    /// The ID of the session to set the configuration option for.
1665    pub session_id: SessionId,
1666    /// The ID of the configuration option to set.
1667    pub config_id: SessionConfigId,
1668    /// The ID of the configuration option value to set.
1669    pub value: SessionConfigValueId,
1670    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1671    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1672    /// these keys.
1673    ///
1674    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1675    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1676    pub meta: Option<Meta>,
1677}
1678
1679#[cfg(feature = "unstable_session_config_options")]
1680impl SetSessionConfigOptionRequest {
1681    #[must_use]
1682    pub fn new(
1683        session_id: impl Into<SessionId>,
1684        config_id: impl Into<SessionConfigId>,
1685        value: impl Into<SessionConfigValueId>,
1686    ) -> Self {
1687        Self {
1688            session_id: session_id.into(),
1689            config_id: config_id.into(),
1690            value: value.into(),
1691            meta: None,
1692        }
1693    }
1694
1695    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1696    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1697    /// these keys.
1698    ///
1699    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1700    #[must_use]
1701    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1702        self.meta = meta.into_option();
1703        self
1704    }
1705}
1706
1707/// **UNSTABLE**
1708///
1709/// This capability is not part of the spec yet, and may be removed or changed at any point.
1710///
1711/// Response to `session/set_config_option` method.
1712#[cfg(feature = "unstable_session_config_options")]
1713#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1714#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_CONFIG_OPTION_METHOD_NAME))]
1715#[serde(rename_all = "camelCase")]
1716#[non_exhaustive]
1717pub struct SetSessionConfigOptionResponse {
1718    /// The full set of configuration options and their current values.
1719    pub config_options: Vec<SessionConfigOption>,
1720    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1721    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1722    /// these keys.
1723    ///
1724    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1725    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1726    pub meta: Option<Meta>,
1727}
1728
1729#[cfg(feature = "unstable_session_config_options")]
1730impl SetSessionConfigOptionResponse {
1731    #[must_use]
1732    pub fn new(config_options: Vec<SessionConfigOption>) -> Self {
1733        Self {
1734            config_options,
1735            meta: None,
1736        }
1737    }
1738
1739    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1740    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1741    /// these keys.
1742    ///
1743    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1744    #[must_use]
1745    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1746        self.meta = meta.into_option();
1747        self
1748    }
1749}
1750
1751// MCP
1752
1753/// Configuration for connecting to an MCP (Model Context Protocol) server.
1754///
1755/// MCP servers provide tools and context that the agent can use when
1756/// processing prompts.
1757///
1758/// See protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)
1759#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1760#[serde(tag = "type", rename_all = "snake_case")]
1761#[non_exhaustive]
1762pub enum McpServer {
1763    /// HTTP transport configuration
1764    ///
1765    /// Only available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.
1766    Http(McpServerHttp),
1767    /// SSE transport configuration
1768    ///
1769    /// Only available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.
1770    Sse(McpServerSse),
1771    /// Stdio transport configuration
1772    ///
1773    /// All Agents MUST support this transport.
1774    #[serde(untagged)]
1775    Stdio(McpServerStdio),
1776}
1777
1778/// HTTP transport configuration for MCP.
1779#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1780#[serde(rename_all = "camelCase")]
1781#[non_exhaustive]
1782pub struct McpServerHttp {
1783    /// Human-readable name identifying this MCP server.
1784    pub name: String,
1785    /// URL to the MCP server.
1786    pub url: String,
1787    /// HTTP headers to set when making requests to the MCP server.
1788    pub headers: Vec<HttpHeader>,
1789    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1790    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1791    /// these keys.
1792    ///
1793    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1794    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1795    pub meta: Option<Meta>,
1796}
1797
1798impl McpServerHttp {
1799    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1800        Self {
1801            name: name.into(),
1802            url: url.into(),
1803            headers: Vec::new(),
1804            meta: None,
1805        }
1806    }
1807
1808    /// HTTP headers to set when making requests to the MCP server.
1809    #[must_use]
1810    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1811        self.headers = headers;
1812        self
1813    }
1814
1815    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1816    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1817    /// these keys.
1818    ///
1819    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1820    #[must_use]
1821    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1822        self.meta = meta.into_option();
1823        self
1824    }
1825}
1826
1827/// SSE transport configuration for MCP.
1828#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1829#[serde(rename_all = "camelCase")]
1830#[non_exhaustive]
1831pub struct McpServerSse {
1832    /// Human-readable name identifying this MCP server.
1833    pub name: String,
1834    /// URL to the MCP server.
1835    pub url: String,
1836    /// HTTP headers to set when making requests to the MCP server.
1837    pub headers: Vec<HttpHeader>,
1838    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1839    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1840    /// these keys.
1841    ///
1842    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1843    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1844    pub meta: Option<Meta>,
1845}
1846
1847impl McpServerSse {
1848    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1849        Self {
1850            name: name.into(),
1851            url: url.into(),
1852            headers: Vec::new(),
1853            meta: None,
1854        }
1855    }
1856
1857    /// HTTP headers to set when making requests to the MCP server.
1858    #[must_use]
1859    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1860        self.headers = headers;
1861        self
1862    }
1863
1864    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1865    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1866    /// these keys.
1867    ///
1868    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1869    #[must_use]
1870    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1871        self.meta = meta.into_option();
1872        self
1873    }
1874}
1875
1876/// Stdio transport configuration for MCP.
1877#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1878#[serde(rename_all = "camelCase")]
1879#[non_exhaustive]
1880pub struct McpServerStdio {
1881    /// Human-readable name identifying this MCP server.
1882    pub name: String,
1883    /// Path to the MCP server executable.
1884    pub command: PathBuf,
1885    /// Command-line arguments to pass to the MCP server.
1886    pub args: Vec<String>,
1887    /// Environment variables to set when launching the MCP server.
1888    pub env: Vec<EnvVariable>,
1889    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1890    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1891    /// these keys.
1892    ///
1893    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1894    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1895    pub meta: Option<Meta>,
1896}
1897
1898impl McpServerStdio {
1899    pub fn new(name: impl Into<String>, command: impl Into<PathBuf>) -> Self {
1900        Self {
1901            name: name.into(),
1902            command: command.into(),
1903            args: Vec::new(),
1904            env: Vec::new(),
1905            meta: None,
1906        }
1907    }
1908
1909    /// Command-line arguments to pass to the MCP server.
1910    #[must_use]
1911    pub fn args(mut self, args: Vec<String>) -> Self {
1912        self.args = args;
1913        self
1914    }
1915
1916    /// Environment variables to set when launching the MCP server.
1917    #[must_use]
1918    pub fn env(mut self, env: Vec<EnvVariable>) -> Self {
1919        self.env = env;
1920        self
1921    }
1922
1923    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1924    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1925    /// these keys.
1926    ///
1927    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1928    #[must_use]
1929    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1930        self.meta = meta.into_option();
1931        self
1932    }
1933}
1934
1935/// An environment variable to set when launching an MCP server.
1936#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1937#[serde(rename_all = "camelCase")]
1938#[non_exhaustive]
1939pub struct EnvVariable {
1940    /// The name of the environment variable.
1941    pub name: String,
1942    /// The value to set for the environment variable.
1943    pub value: String,
1944    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1945    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1946    /// these keys.
1947    ///
1948    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1949    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1950    pub meta: Option<Meta>,
1951}
1952
1953impl EnvVariable {
1954    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1955        Self {
1956            name: name.into(),
1957            value: value.into(),
1958            meta: None,
1959        }
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 HTTP header to set when making requests to the MCP server.
1975#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1976#[serde(rename_all = "camelCase")]
1977#[non_exhaustive]
1978pub struct HttpHeader {
1979    /// The name of the HTTP header.
1980    pub name: String,
1981    /// The value to set for the HTTP header.
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 HttpHeader {
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// Prompt
2014
2015/// Request parameters for sending a user prompt to the agent.
2016///
2017/// Contains the user's message and any additional context.
2018///
2019/// See protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)
2020#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
2021#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
2022#[serde(rename_all = "camelCase")]
2023#[non_exhaustive]
2024pub struct PromptRequest {
2025    /// The ID of the session to send this user message to
2026    pub session_id: SessionId,
2027    /// The blocks of content that compose the user's message.
2028    ///
2029    /// As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],
2030    /// while other variants are optionally enabled via [`PromptCapabilities`].
2031    ///
2032    /// The Client MUST adapt its interface according to [`PromptCapabilities`].
2033    ///
2034    /// The client MAY include referenced pieces of context as either
2035    /// [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].
2036    ///
2037    /// When available, [`ContentBlock::Resource`] is preferred
2038    /// as it avoids extra round-trips and allows the message to include
2039    /// pieces of context from sources the agent may not have access to.
2040    pub prompt: Vec<ContentBlock>,
2041    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2042    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2043    /// these keys.
2044    ///
2045    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2046    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2047    pub meta: Option<Meta>,
2048}
2049
2050impl PromptRequest {
2051    #[must_use]
2052    pub fn new(session_id: impl Into<SessionId>, prompt: Vec<ContentBlock>) -> Self {
2053        Self {
2054            session_id: session_id.into(),
2055            prompt,
2056            meta: None,
2057        }
2058    }
2059
2060    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2061    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2062    /// these keys.
2063    ///
2064    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2065    #[must_use]
2066    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2067        self.meta = meta.into_option();
2068        self
2069    }
2070}
2071
2072/// Response from processing a user prompt.
2073///
2074/// See protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)
2075#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2076#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
2077#[serde(rename_all = "camelCase")]
2078#[non_exhaustive]
2079pub struct PromptResponse {
2080    /// Indicates why the agent stopped processing the turn.
2081    pub stop_reason: StopReason,
2082    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2083    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2084    /// these keys.
2085    ///
2086    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2087    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2088    pub meta: Option<Meta>,
2089}
2090
2091impl PromptResponse {
2092    #[must_use]
2093    pub fn new(stop_reason: StopReason) -> Self {
2094        Self {
2095            stop_reason,
2096            meta: None,
2097        }
2098    }
2099
2100    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2101    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2102    /// these keys.
2103    ///
2104    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2105    #[must_use]
2106    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2107        self.meta = meta.into_option();
2108        self
2109    }
2110}
2111
2112/// Reasons why an agent stops processing a prompt turn.
2113///
2114/// See protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)
2115#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
2116#[serde(rename_all = "snake_case")]
2117#[non_exhaustive]
2118pub enum StopReason {
2119    /// The turn ended successfully.
2120    EndTurn,
2121    /// The turn ended because the agent reached the maximum number of tokens.
2122    MaxTokens,
2123    /// The turn ended because the agent reached the maximum number of allowed
2124    /// agent requests between user turns.
2125    MaxTurnRequests,
2126    /// The turn ended because the agent refused to continue. The user prompt
2127    /// and everything that comes after it won't be included in the next
2128    /// prompt, so this should be reflected in the UI.
2129    Refusal,
2130    /// The turn was cancelled by the client via `session/cancel`.
2131    ///
2132    /// This stop reason MUST be returned when the client sends a `session/cancel`
2133    /// notification, even if the cancellation causes exceptions in underlying operations.
2134    /// Agents should catch these exceptions and return this semantically meaningful
2135    /// response to confirm successful cancellation.
2136    Cancelled,
2137}
2138
2139// Model
2140
2141/// **UNSTABLE**
2142///
2143/// This capability is not part of the spec yet, and may be removed or changed at any point.
2144///
2145/// The set of models and the one currently active.
2146#[cfg(feature = "unstable_session_model")]
2147#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2148#[serde(rename_all = "camelCase")]
2149#[non_exhaustive]
2150pub struct SessionModelState {
2151    /// The current model the Agent is in.
2152    pub current_model_id: ModelId,
2153    /// The set of models that the Agent can use
2154    pub available_models: Vec<ModelInfo>,
2155    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2156    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2157    /// these keys.
2158    ///
2159    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2160    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2161    pub meta: Option<Meta>,
2162}
2163
2164#[cfg(feature = "unstable_session_model")]
2165impl SessionModelState {
2166    #[must_use]
2167    pub fn new(current_model_id: impl Into<ModelId>, available_models: Vec<ModelInfo>) -> Self {
2168        Self {
2169            current_model_id: current_model_id.into(),
2170            available_models,
2171            meta: None,
2172        }
2173    }
2174
2175    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2176    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2177    /// these keys.
2178    ///
2179    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2180    #[must_use]
2181    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2182        self.meta = meta.into_option();
2183        self
2184    }
2185}
2186
2187/// **UNSTABLE**
2188///
2189/// This capability is not part of the spec yet, and may be removed or changed at any point.
2190///
2191/// A unique identifier for a model.
2192#[cfg(feature = "unstable_session_model")]
2193#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
2194#[serde(transparent)]
2195#[from(Arc<str>, String, &'static str)]
2196#[non_exhaustive]
2197pub struct ModelId(pub Arc<str>);
2198
2199#[cfg(feature = "unstable_session_model")]
2200impl ModelId {
2201    pub fn new(id: impl Into<Arc<str>>) -> Self {
2202        Self(id.into())
2203    }
2204}
2205
2206/// **UNSTABLE**
2207///
2208/// This capability is not part of the spec yet, and may be removed or changed at any point.
2209///
2210/// Information about a selectable model.
2211#[cfg(feature = "unstable_session_model")]
2212#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2213#[serde(rename_all = "camelCase")]
2214#[non_exhaustive]
2215pub struct ModelInfo {
2216    /// Unique identifier for the model.
2217    pub model_id: ModelId,
2218    /// Human-readable name of the model.
2219    pub name: String,
2220    /// Optional description of the model.
2221    #[serde(default, skip_serializing_if = "Option::is_none")]
2222    pub description: Option<String>,
2223    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2224    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2225    /// these keys.
2226    ///
2227    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2228    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2229    pub meta: Option<Meta>,
2230}
2231
2232#[cfg(feature = "unstable_session_model")]
2233impl ModelInfo {
2234    pub fn new(model_id: impl Into<ModelId>, name: impl Into<String>) -> Self {
2235        Self {
2236            model_id: model_id.into(),
2237            name: name.into(),
2238            description: None,
2239            meta: None,
2240        }
2241    }
2242
2243    /// Optional description of the model.
2244    #[must_use]
2245    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
2246        self.description = description.into_option();
2247        self
2248    }
2249
2250    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2251    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2252    /// these keys.
2253    ///
2254    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2255    #[must_use]
2256    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2257        self.meta = meta.into_option();
2258        self
2259    }
2260}
2261
2262/// **UNSTABLE**
2263///
2264/// This capability is not part of the spec yet, and may be removed or changed at any point.
2265///
2266/// Request parameters for setting a session model.
2267#[cfg(feature = "unstable_session_model")]
2268#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2269#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
2270#[serde(rename_all = "camelCase")]
2271#[non_exhaustive]
2272pub struct SetSessionModelRequest {
2273    /// The ID of the session to set the model for.
2274    pub session_id: SessionId,
2275    /// The ID of the model to set.
2276    pub model_id: ModelId,
2277    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2278    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2279    /// these keys.
2280    ///
2281    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2282    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2283    pub meta: Option<Meta>,
2284}
2285
2286#[cfg(feature = "unstable_session_model")]
2287impl SetSessionModelRequest {
2288    #[must_use]
2289    pub fn new(session_id: impl Into<SessionId>, model_id: impl Into<ModelId>) -> Self {
2290        Self {
2291            session_id: session_id.into(),
2292            model_id: model_id.into(),
2293            meta: None,
2294        }
2295    }
2296
2297    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2298    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2299    /// these keys.
2300    ///
2301    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2302    #[must_use]
2303    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2304        self.meta = meta.into_option();
2305        self
2306    }
2307}
2308
2309/// **UNSTABLE**
2310///
2311/// This capability is not part of the spec yet, and may be removed or changed at any point.
2312///
2313/// Response to `session/set_model` method.
2314#[cfg(feature = "unstable_session_model")]
2315#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2316#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
2317#[serde(rename_all = "camelCase")]
2318#[non_exhaustive]
2319pub struct SetSessionModelResponse {
2320    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2321    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2322    /// these keys.
2323    ///
2324    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2325    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2326    pub meta: Option<Meta>,
2327}
2328
2329#[cfg(feature = "unstable_session_model")]
2330impl SetSessionModelResponse {
2331    #[must_use]
2332    pub fn new() -> Self {
2333        Self::default()
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// Capabilities
2349
2350/// Capabilities supported by the agent.
2351///
2352/// Advertised during initialization to inform the client about
2353/// available features and content types.
2354///
2355/// See protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)
2356#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2357#[serde(rename_all = "camelCase")]
2358#[non_exhaustive]
2359pub struct AgentCapabilities {
2360    /// Whether the agent supports `session/load`.
2361    #[serde(default)]
2362    pub load_session: bool,
2363    /// Prompt capabilities supported by the agent.
2364    #[serde(default)]
2365    pub prompt_capabilities: PromptCapabilities,
2366    /// MCP capabilities supported by the agent.
2367    #[serde(default)]
2368    pub mcp_capabilities: McpCapabilities,
2369    #[serde(default)]
2370    pub session_capabilities: SessionCapabilities,
2371    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2372    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2373    /// these keys.
2374    ///
2375    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2376    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2377    pub meta: Option<Meta>,
2378}
2379
2380impl AgentCapabilities {
2381    #[must_use]
2382    pub fn new() -> Self {
2383        Self::default()
2384    }
2385
2386    /// Whether the agent supports `session/load`.
2387    #[must_use]
2388    pub fn load_session(mut self, load_session: bool) -> Self {
2389        self.load_session = load_session;
2390        self
2391    }
2392
2393    /// Prompt capabilities supported by the agent.
2394    #[must_use]
2395    pub fn prompt_capabilities(mut self, prompt_capabilities: PromptCapabilities) -> Self {
2396        self.prompt_capabilities = prompt_capabilities;
2397        self
2398    }
2399
2400    /// MCP capabilities supported by the agent.
2401    #[must_use]
2402    pub fn mcp_capabilities(mut self, mcp_capabilities: McpCapabilities) -> Self {
2403        self.mcp_capabilities = mcp_capabilities;
2404        self
2405    }
2406
2407    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2408    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2409    /// these keys.
2410    ///
2411    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2412    #[must_use]
2413    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2414        self.meta = meta.into_option();
2415        self
2416    }
2417}
2418
2419/// Session capabilities supported by the agent.
2420///
2421/// As a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.
2422///
2423/// Optionally, they **MAY** support other session methods and notifications by specifying additional capabilities.
2424///
2425/// Note: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.
2426///
2427/// See protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)
2428#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2429#[non_exhaustive]
2430pub struct SessionCapabilities {
2431    /// **UNSTABLE**
2432    ///
2433    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2434    ///
2435    /// Whether the agent supports `session/list`.
2436    #[cfg(feature = "unstable_session_list")]
2437    #[serde(skip_serializing_if = "Option::is_none")]
2438    pub list: Option<SessionListCapabilities>,
2439    /// **UNSTABLE**
2440    ///
2441    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2442    ///
2443    /// Whether the agent supports `session/fork`.
2444    #[cfg(feature = "unstable_session_fork")]
2445    #[serde(skip_serializing_if = "Option::is_none")]
2446    pub fork: Option<SessionForkCapabilities>,
2447    /// **UNSTABLE**
2448    ///
2449    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2450    ///
2451    /// Whether the agent supports `session/resume`.
2452    #[cfg(feature = "unstable_session_resume")]
2453    #[serde(skip_serializing_if = "Option::is_none")]
2454    pub resume: Option<SessionResumeCapabilities>,
2455    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2456    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2457    /// these keys.
2458    ///
2459    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2460    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2461    pub meta: Option<Meta>,
2462}
2463
2464impl SessionCapabilities {
2465    #[must_use]
2466    pub fn new() -> Self {
2467        Self::default()
2468    }
2469
2470    #[cfg(feature = "unstable_session_list")]
2471    /// Whether the agent supports `session/list`.
2472    #[must_use]
2473    pub fn list(mut self, list: impl IntoOption<SessionListCapabilities>) -> Self {
2474        self.list = list.into_option();
2475        self
2476    }
2477
2478    #[cfg(feature = "unstable_session_fork")]
2479    /// Whether the agent supports `session/fork`.
2480    #[must_use]
2481    pub fn fork(mut self, fork: impl IntoOption<SessionForkCapabilities>) -> Self {
2482        self.fork = fork.into_option();
2483        self
2484    }
2485
2486    #[cfg(feature = "unstable_session_resume")]
2487    /// Whether the agent supports `session/resume`.
2488    #[must_use]
2489    pub fn resume(mut self, resume: impl IntoOption<SessionResumeCapabilities>) -> Self {
2490        self.resume = resume.into_option();
2491        self
2492    }
2493
2494    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2495    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2496    /// these keys.
2497    ///
2498    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2499    #[must_use]
2500    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2501        self.meta = meta.into_option();
2502        self
2503    }
2504}
2505
2506/// Capabilities for the `session/list` method.
2507///
2508/// By supplying `{}` it means that the agent supports listing of sessions.
2509///
2510/// Further capabilities can be added in the future for other means of filtering or searching the list.
2511#[cfg(feature = "unstable_session_list")]
2512#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2513#[non_exhaustive]
2514pub struct SessionListCapabilities {
2515    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2516    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2517    /// these keys.
2518    ///
2519    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2520    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2521    pub meta: Option<Meta>,
2522}
2523
2524#[cfg(feature = "unstable_session_list")]
2525impl SessionListCapabilities {
2526    #[must_use]
2527    pub fn new() -> Self {
2528        Self::default()
2529    }
2530    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2531    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2532    /// these keys.
2533    ///
2534    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2535    #[must_use]
2536    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2537        self.meta = meta.into_option();
2538        self
2539    }
2540}
2541
2542/// **UNSTABLE**
2543///
2544/// This capability is not part of the spec yet, and may be removed or changed at any point.
2545///
2546/// Capabilities for the `session/fork` method.
2547///
2548/// By supplying `{}` it means that the agent supports forking of sessions.
2549#[cfg(feature = "unstable_session_fork")]
2550#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2551#[non_exhaustive]
2552pub struct SessionForkCapabilities {
2553    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2554    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2555    /// these keys.
2556    ///
2557    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2558    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2559    pub meta: Option<Meta>,
2560}
2561
2562#[cfg(feature = "unstable_session_fork")]
2563impl SessionForkCapabilities {
2564    #[must_use]
2565    pub fn new() -> Self {
2566        Self::default()
2567    }
2568
2569    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2570    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2571    /// these keys.
2572    ///
2573    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2574    #[must_use]
2575    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2576        self.meta = meta.into_option();
2577        self
2578    }
2579}
2580
2581/// **UNSTABLE**
2582///
2583/// This capability is not part of the spec yet, and may be removed or changed at any point.
2584///
2585/// Capabilities for the `session/resume` method.
2586///
2587/// By supplying `{}` it means that the agent supports resuming of sessions.
2588#[cfg(feature = "unstable_session_resume")]
2589#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2590#[non_exhaustive]
2591pub struct SessionResumeCapabilities {
2592    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2593    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2594    /// these keys.
2595    ///
2596    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2597    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2598    pub meta: Option<Meta>,
2599}
2600
2601#[cfg(feature = "unstable_session_resume")]
2602impl SessionResumeCapabilities {
2603    #[must_use]
2604    pub fn new() -> Self {
2605        Self::default()
2606    }
2607
2608    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2609    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2610    /// these keys.
2611    ///
2612    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2613    #[must_use]
2614    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2615        self.meta = meta.into_option();
2616        self
2617    }
2618}
2619
2620/// Prompt capabilities supported by the agent in `session/prompt` requests.
2621///
2622/// Baseline agent functionality requires support for [`ContentBlock::Text`]
2623/// and [`ContentBlock::ResourceLink`] in prompt requests.
2624///
2625/// Other variants must be explicitly opted in to.
2626/// Capabilities for different types of content in prompt requests.
2627///
2628/// Indicates which content types beyond the baseline (text and resource links)
2629/// the agent can process.
2630///
2631/// See protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)
2632#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2633#[serde(rename_all = "camelCase")]
2634#[non_exhaustive]
2635pub struct PromptCapabilities {
2636    /// Agent supports [`ContentBlock::Image`].
2637    #[serde(default)]
2638    pub image: bool,
2639    /// Agent supports [`ContentBlock::Audio`].
2640    #[serde(default)]
2641    pub audio: bool,
2642    /// Agent supports embedded context in `session/prompt` requests.
2643    ///
2644    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
2645    /// in prompt requests for pieces of context that are referenced in the message.
2646    #[serde(default)]
2647    pub embedded_context: bool,
2648    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2649    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2650    /// these keys.
2651    ///
2652    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2653    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2654    pub meta: Option<Meta>,
2655}
2656
2657impl PromptCapabilities {
2658    #[must_use]
2659    pub fn new() -> Self {
2660        Self::default()
2661    }
2662
2663    /// Agent supports [`ContentBlock::Image`].
2664    #[must_use]
2665    pub fn image(mut self, image: bool) -> Self {
2666        self.image = image;
2667        self
2668    }
2669
2670    /// Agent supports [`ContentBlock::Audio`].
2671    #[must_use]
2672    pub fn audio(mut self, audio: bool) -> Self {
2673        self.audio = audio;
2674        self
2675    }
2676
2677    /// Agent supports embedded context in `session/prompt` requests.
2678    ///
2679    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
2680    /// in prompt requests for pieces of context that are referenced in the message.
2681    #[must_use]
2682    pub fn embedded_context(mut self, embedded_context: bool) -> Self {
2683        self.embedded_context = embedded_context;
2684        self
2685    }
2686
2687    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2688    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2689    /// these keys.
2690    ///
2691    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2692    #[must_use]
2693    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2694        self.meta = meta.into_option();
2695        self
2696    }
2697}
2698
2699/// MCP capabilities supported by the agent
2700#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2701#[serde(rename_all = "camelCase")]
2702#[non_exhaustive]
2703pub struct McpCapabilities {
2704    /// Agent supports [`McpServer::Http`].
2705    #[serde(default)]
2706    pub http: bool,
2707    /// Agent supports [`McpServer::Sse`].
2708    #[serde(default)]
2709    pub sse: bool,
2710    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2711    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2712    /// these keys.
2713    ///
2714    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2715    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2716    pub meta: Option<Meta>,
2717}
2718
2719impl McpCapabilities {
2720    #[must_use]
2721    pub fn new() -> Self {
2722        Self::default()
2723    }
2724
2725    /// Agent supports [`McpServer::Http`].
2726    #[must_use]
2727    pub fn http(mut self, http: bool) -> Self {
2728        self.http = http;
2729        self
2730    }
2731
2732    /// Agent supports [`McpServer::Sse`].
2733    #[must_use]
2734    pub fn sse(mut self, sse: bool) -> Self {
2735        self.sse = sse;
2736        self
2737    }
2738
2739    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2740    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2741    /// these keys.
2742    ///
2743    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2744    #[must_use]
2745    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2746        self.meta = meta.into_option();
2747        self
2748    }
2749}
2750
2751// Method schema
2752
2753/// Names of all methods that agents handle.
2754///
2755/// Provides a centralized definition of method names used in the protocol.
2756#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2757#[non_exhaustive]
2758pub struct AgentMethodNames {
2759    /// Method for initializing the connection.
2760    pub initialize: &'static str,
2761    /// Method for authenticating with the agent.
2762    pub authenticate: &'static str,
2763    /// Method for creating a new session.
2764    pub session_new: &'static str,
2765    /// Method for loading an existing session.
2766    pub session_load: &'static str,
2767    /// Method for setting the mode for a session.
2768    pub session_set_mode: &'static str,
2769    /// Method for setting a configuration option for a session.
2770    #[cfg(feature = "unstable_session_config_options")]
2771    pub session_set_config_option: &'static str,
2772    /// Method for sending a prompt to the agent.
2773    pub session_prompt: &'static str,
2774    /// Notification for cancelling operations.
2775    pub session_cancel: &'static str,
2776    /// Method for selecting a model for a given session.
2777    #[cfg(feature = "unstable_session_model")]
2778    pub session_set_model: &'static str,
2779    /// Method for listing existing sessions.
2780    #[cfg(feature = "unstable_session_list")]
2781    pub session_list: &'static str,
2782    /// Method for forking an existing session.
2783    #[cfg(feature = "unstable_session_fork")]
2784    pub session_fork: &'static str,
2785    /// Method for resuming an existing session.
2786    #[cfg(feature = "unstable_session_resume")]
2787    pub session_resume: &'static str,
2788}
2789
2790/// Constant containing all agent method names.
2791pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
2792    initialize: INITIALIZE_METHOD_NAME,
2793    authenticate: AUTHENTICATE_METHOD_NAME,
2794    session_new: SESSION_NEW_METHOD_NAME,
2795    session_load: SESSION_LOAD_METHOD_NAME,
2796    session_set_mode: SESSION_SET_MODE_METHOD_NAME,
2797    #[cfg(feature = "unstable_session_config_options")]
2798    session_set_config_option: SESSION_SET_CONFIG_OPTION_METHOD_NAME,
2799    session_prompt: SESSION_PROMPT_METHOD_NAME,
2800    session_cancel: SESSION_CANCEL_METHOD_NAME,
2801    #[cfg(feature = "unstable_session_model")]
2802    session_set_model: SESSION_SET_MODEL_METHOD_NAME,
2803    #[cfg(feature = "unstable_session_list")]
2804    session_list: SESSION_LIST_METHOD_NAME,
2805    #[cfg(feature = "unstable_session_fork")]
2806    session_fork: SESSION_FORK_METHOD_NAME,
2807    #[cfg(feature = "unstable_session_resume")]
2808    session_resume: SESSION_RESUME_METHOD_NAME,
2809};
2810
2811/// Method name for the initialize request.
2812pub(crate) const INITIALIZE_METHOD_NAME: &str = "initialize";
2813/// Method name for the authenticate request.
2814pub(crate) const AUTHENTICATE_METHOD_NAME: &str = "authenticate";
2815/// Method name for creating a new session.
2816pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
2817/// Method name for loading an existing session.
2818pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
2819/// Method name for setting the mode for a session.
2820pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
2821/// Method name for setting a configuration option for a session.
2822#[cfg(feature = "unstable_session_config_options")]
2823pub(crate) const SESSION_SET_CONFIG_OPTION_METHOD_NAME: &str = "session/set_config_option";
2824/// Method name for sending a prompt.
2825pub(crate) const SESSION_PROMPT_METHOD_NAME: &str = "session/prompt";
2826/// Method name for the cancel notification.
2827pub(crate) const SESSION_CANCEL_METHOD_NAME: &str = "session/cancel";
2828/// Method name for selecting a model for a given session.
2829#[cfg(feature = "unstable_session_model")]
2830pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
2831/// Method name for listing existing sessions.
2832#[cfg(feature = "unstable_session_list")]
2833pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list";
2834/// Method name for forking an existing session.
2835#[cfg(feature = "unstable_session_fork")]
2836pub(crate) const SESSION_FORK_METHOD_NAME: &str = "session/fork";
2837/// Method name for resuming an existing session.
2838#[cfg(feature = "unstable_session_resume")]
2839pub(crate) const SESSION_RESUME_METHOD_NAME: &str = "session/resume";
2840
2841/// All possible requests that a client can send to an agent.
2842///
2843/// This enum is used internally for routing RPC requests. You typically won't need
2844/// to use this directly - instead, use the methods on the [`Agent`] trait.
2845///
2846/// This enum encompasses all method calls from client to agent.
2847#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2848#[serde(untagged)]
2849#[schemars(inline)]
2850#[non_exhaustive]
2851pub enum ClientRequest {
2852    /// Establishes the connection with a client and negotiates protocol capabilities.
2853    ///
2854    /// This method is called once at the beginning of the connection to:
2855    /// - Negotiate the protocol version to use
2856    /// - Exchange capability information between client and agent
2857    /// - Determine available authentication methods
2858    ///
2859    /// The agent should respond with its supported protocol version and capabilities.
2860    ///
2861    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
2862    InitializeRequest(InitializeRequest),
2863    /// Authenticates the client using the specified authentication method.
2864    ///
2865    /// Called when the agent requires authentication before allowing session creation.
2866    /// The client provides the authentication method ID that was advertised during initialization.
2867    ///
2868    /// After successful authentication, the client can proceed to create sessions with
2869    /// `new_session` without receiving an `auth_required` error.
2870    ///
2871    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
2872    AuthenticateRequest(AuthenticateRequest),
2873    /// Creates a new conversation session with the agent.
2874    ///
2875    /// Sessions represent independent conversation contexts with their own history and state.
2876    ///
2877    /// The agent should:
2878    /// - Create a new session context
2879    /// - Connect to any specified MCP servers
2880    /// - Return a unique session ID for future requests
2881    ///
2882    /// May return an `auth_required` error if the agent requires authentication.
2883    ///
2884    /// See protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)
2885    NewSessionRequest(NewSessionRequest),
2886    /// Loads an existing session to resume a previous conversation.
2887    ///
2888    /// This method is only available if the agent advertises the `loadSession` capability.
2889    ///
2890    /// The agent should:
2891    /// - Restore the session context and conversation history
2892    /// - Connect to the specified MCP servers
2893    /// - Stream the entire conversation history back to the client via notifications
2894    ///
2895    /// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
2896    LoadSessionRequest(LoadSessionRequest),
2897    #[cfg(feature = "unstable_session_list")]
2898    /// **UNSTABLE**
2899    ///
2900    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2901    ///
2902    /// Lists existing sessions known to the agent.
2903    ///
2904    /// This method is only available if the agent advertises the `listSessions` capability.
2905    ///
2906    /// The agent should return metadata about sessions with optional filtering and pagination support.
2907    ListSessionsRequest(ListSessionsRequest),
2908    #[cfg(feature = "unstable_session_fork")]
2909    /// **UNSTABLE**
2910    ///
2911    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2912    ///
2913    /// Forks an existing session to create a new independent session.
2914    ///
2915    /// This method is only available if the agent advertises the `session.fork` capability.
2916    ///
2917    /// The agent should create a new session with the same conversation context as the
2918    /// original, allowing operations like generating summaries without affecting the
2919    /// original session's history.
2920    ForkSessionRequest(ForkSessionRequest),
2921    #[cfg(feature = "unstable_session_resume")]
2922    /// **UNSTABLE**
2923    ///
2924    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2925    ///
2926    /// Resumes an existing session without returning previous messages.
2927    ///
2928    /// This method is only available if the agent advertises the `session.resume` capability.
2929    ///
2930    /// The agent should resume the session context, allowing the conversation to continue
2931    /// without replaying the message history (unlike `session/load`).
2932    ResumeSessionRequest(ResumeSessionRequest),
2933    /// Sets the current mode for a session.
2934    ///
2935    /// Allows switching between different agent modes (e.g., "ask", "architect", "code")
2936    /// that affect system prompts, tool availability, and permission behaviors.
2937    ///
2938    /// The mode must be one of the modes advertised in `availableModes` during session
2939    /// creation or loading. Agents may also change modes autonomously and notify the
2940    /// client via `current_mode_update` notifications.
2941    ///
2942    /// This method can be called at any time during a session, whether the Agent is
2943    /// idle or actively generating a response.
2944    ///
2945    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
2946    SetSessionModeRequest(SetSessionModeRequest),
2947    #[cfg(feature = "unstable_session_config_options")]
2948    /// **UNSTABLE**
2949    ///
2950    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2951    ///
2952    /// Sets the current value for a session configuration option.
2953    SetSessionConfigOptionRequest(SetSessionConfigOptionRequest),
2954    /// Processes a user prompt within a session.
2955    ///
2956    /// This method handles the whole lifecycle of a prompt:
2957    /// - Receives user messages with optional context (files, images, etc.)
2958    /// - Processes the prompt using language models
2959    /// - Reports language model content and tool calls to the Clients
2960    /// - Requests permission to run tools
2961    /// - Executes any requested tool calls
2962    /// - Returns when the turn is complete with a stop reason
2963    ///
2964    /// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
2965    PromptRequest(PromptRequest),
2966    #[cfg(feature = "unstable_session_model")]
2967    /// **UNSTABLE**
2968    ///
2969    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2970    ///
2971    /// Select a model for a given session.
2972    SetSessionModelRequest(SetSessionModelRequest),
2973    /// Handles extension method requests from the client.
2974    ///
2975    /// Extension methods provide a way to add custom functionality while maintaining
2976    /// protocol compatibility.
2977    ///
2978    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2979    ExtMethodRequest(ExtRequest),
2980}
2981
2982impl ClientRequest {
2983    /// Returns the corresponding method name of the request.
2984    #[must_use]
2985    pub fn method(&self) -> &str {
2986        match self {
2987            Self::InitializeRequest(_) => AGENT_METHOD_NAMES.initialize,
2988            Self::AuthenticateRequest(_) => AGENT_METHOD_NAMES.authenticate,
2989            Self::NewSessionRequest(_) => AGENT_METHOD_NAMES.session_new,
2990            Self::LoadSessionRequest(_) => AGENT_METHOD_NAMES.session_load,
2991            #[cfg(feature = "unstable_session_list")]
2992            Self::ListSessionsRequest(_) => AGENT_METHOD_NAMES.session_list,
2993            #[cfg(feature = "unstable_session_fork")]
2994            Self::ForkSessionRequest(_) => AGENT_METHOD_NAMES.session_fork,
2995            #[cfg(feature = "unstable_session_resume")]
2996            Self::ResumeSessionRequest(_) => AGENT_METHOD_NAMES.session_resume,
2997            Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode,
2998            #[cfg(feature = "unstable_session_config_options")]
2999            Self::SetSessionConfigOptionRequest(_) => AGENT_METHOD_NAMES.session_set_config_option,
3000            Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt,
3001            #[cfg(feature = "unstable_session_model")]
3002            Self::SetSessionModelRequest(_) => AGENT_METHOD_NAMES.session_set_model,
3003            Self::ExtMethodRequest(ext_request) => &ext_request.method,
3004        }
3005    }
3006}
3007
3008/// All possible responses that an agent can send to a client.
3009///
3010/// This enum is used internally for routing RPC responses. You typically won't need
3011/// to use this directly - the responses are handled automatically by the connection.
3012///
3013/// These are responses to the corresponding `ClientRequest` variants.
3014#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
3015#[serde(untagged)]
3016#[schemars(inline)]
3017#[non_exhaustive]
3018pub enum AgentResponse {
3019    InitializeResponse(InitializeResponse),
3020    AuthenticateResponse(#[serde(default)] AuthenticateResponse),
3021    NewSessionResponse(NewSessionResponse),
3022    LoadSessionResponse(#[serde(default)] LoadSessionResponse),
3023    #[cfg(feature = "unstable_session_list")]
3024    ListSessionsResponse(ListSessionsResponse),
3025    #[cfg(feature = "unstable_session_fork")]
3026    ForkSessionResponse(ForkSessionResponse),
3027    #[cfg(feature = "unstable_session_resume")]
3028    ResumeSessionResponse(#[serde(default)] ResumeSessionResponse),
3029    SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
3030    #[cfg(feature = "unstable_session_config_options")]
3031    SetSessionConfigOptionResponse(SetSessionConfigOptionResponse),
3032    PromptResponse(PromptResponse),
3033    #[cfg(feature = "unstable_session_model")]
3034    SetSessionModelResponse(SetSessionModelResponse),
3035    ExtMethodResponse(ExtResponse),
3036}
3037
3038/// All possible notifications that a client can send to an agent.
3039///
3040/// This enum is used internally for routing RPC notifications. You typically won't need
3041/// to use this directly - use the notification methods on the [`Agent`] trait instead.
3042///
3043/// Notifications do not expect a response.
3044#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
3045#[serde(untagged)]
3046#[schemars(inline)]
3047#[non_exhaustive]
3048pub enum ClientNotification {
3049    /// Cancels ongoing operations for a session.
3050    ///
3051    /// This is a notification sent by the client to cancel an ongoing prompt turn.
3052    ///
3053    /// Upon receiving this notification, the Agent SHOULD:
3054    /// - Stop all language model requests as soon as possible
3055    /// - Abort all tool call invocations in progress
3056    /// - Send any pending `session/update` notifications
3057    /// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
3058    ///
3059    /// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
3060    CancelNotification(CancelNotification),
3061    /// Handles extension notifications from the client.
3062    ///
3063    /// Extension notifications provide a way to send one-way messages for custom functionality
3064    /// while maintaining protocol compatibility.
3065    ///
3066    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3067    ExtNotification(ExtNotification),
3068}
3069
3070impl ClientNotification {
3071    /// Returns the corresponding method name of the notification.
3072    #[must_use]
3073    pub fn method(&self) -> &str {
3074        match self {
3075            Self::CancelNotification(_) => AGENT_METHOD_NAMES.session_cancel,
3076            Self::ExtNotification(ext_notification) => &ext_notification.method,
3077        }
3078    }
3079}
3080
3081/// Notification to cancel ongoing operations for a session.
3082///
3083/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
3084#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
3085#[schemars(extend("x-side" = "agent", "x-method" = SESSION_CANCEL_METHOD_NAME))]
3086#[serde(rename_all = "camelCase")]
3087#[non_exhaustive]
3088pub struct CancelNotification {
3089    /// The ID of the session to cancel operations for.
3090    pub session_id: SessionId,
3091    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3092    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3093    /// these keys.
3094    ///
3095    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3096    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3097    pub meta: Option<Meta>,
3098}
3099
3100impl CancelNotification {
3101    #[must_use]
3102    pub fn new(session_id: impl Into<SessionId>) -> Self {
3103        Self {
3104            session_id: session_id.into(),
3105            meta: None,
3106        }
3107    }
3108
3109    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3110    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3111    /// these keys.
3112    ///
3113    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3114    #[must_use]
3115    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3116        self.meta = meta.into_option();
3117        self
3118    }
3119}
3120
3121#[cfg(test)]
3122mod test_serialization {
3123    use super::*;
3124    use serde_json::json;
3125
3126    #[test]
3127    fn test_mcp_server_stdio_serialization() {
3128        let server = McpServer::Stdio(
3129            McpServerStdio::new("test-server", "/usr/bin/server")
3130                .args(vec!["--port".to_string(), "3000".to_string()])
3131                .env(vec![EnvVariable::new("API_KEY", "secret123")]),
3132        );
3133
3134        let json = serde_json::to_value(&server).unwrap();
3135        assert_eq!(
3136            json,
3137            json!({
3138                "name": "test-server",
3139                "command": "/usr/bin/server",
3140                "args": ["--port", "3000"],
3141                "env": [
3142                    {
3143                        "name": "API_KEY",
3144                        "value": "secret123"
3145                    }
3146                ]
3147            })
3148        );
3149
3150        let deserialized: McpServer = serde_json::from_value(json).unwrap();
3151        match deserialized {
3152            McpServer::Stdio(McpServerStdio {
3153                name,
3154                command,
3155                args,
3156                env,
3157                meta: _,
3158            }) => {
3159                assert_eq!(name, "test-server");
3160                assert_eq!(command, PathBuf::from("/usr/bin/server"));
3161                assert_eq!(args, vec!["--port", "3000"]);
3162                assert_eq!(env.len(), 1);
3163                assert_eq!(env[0].name, "API_KEY");
3164                assert_eq!(env[0].value, "secret123");
3165            }
3166            _ => panic!("Expected Stdio variant"),
3167        }
3168    }
3169
3170    #[test]
3171    fn test_mcp_server_http_serialization() {
3172        let server = McpServer::Http(
3173            McpServerHttp::new("http-server", "https://api.example.com").headers(vec![
3174                HttpHeader::new("Authorization", "Bearer token123"),
3175                HttpHeader::new("Content-Type", "application/json"),
3176            ]),
3177        );
3178
3179        let json = serde_json::to_value(&server).unwrap();
3180        assert_eq!(
3181            json,
3182            json!({
3183                "type": "http",
3184                "name": "http-server",
3185                "url": "https://api.example.com",
3186                "headers": [
3187                    {
3188                        "name": "Authorization",
3189                        "value": "Bearer token123"
3190                    },
3191                    {
3192                        "name": "Content-Type",
3193                        "value": "application/json"
3194                    }
3195                ]
3196            })
3197        );
3198
3199        let deserialized: McpServer = serde_json::from_value(json).unwrap();
3200        match deserialized {
3201            McpServer::Http(McpServerHttp {
3202                name,
3203                url,
3204                headers,
3205                meta: _,
3206            }) => {
3207                assert_eq!(name, "http-server");
3208                assert_eq!(url, "https://api.example.com");
3209                assert_eq!(headers.len(), 2);
3210                assert_eq!(headers[0].name, "Authorization");
3211                assert_eq!(headers[0].value, "Bearer token123");
3212                assert_eq!(headers[1].name, "Content-Type");
3213                assert_eq!(headers[1].value, "application/json");
3214            }
3215            _ => panic!("Expected Http variant"),
3216        }
3217    }
3218
3219    #[test]
3220    fn test_mcp_server_sse_serialization() {
3221        let server = McpServer::Sse(
3222            McpServerSse::new("sse-server", "https://sse.example.com/events")
3223                .headers(vec![HttpHeader::new("X-API-Key", "apikey456")]),
3224        );
3225
3226        let json = serde_json::to_value(&server).unwrap();
3227        assert_eq!(
3228            json,
3229            json!({
3230                "type": "sse",
3231                "name": "sse-server",
3232                "url": "https://sse.example.com/events",
3233                "headers": [
3234                    {
3235                        "name": "X-API-Key",
3236                        "value": "apikey456"
3237                    }
3238                ]
3239            })
3240        );
3241
3242        let deserialized: McpServer = serde_json::from_value(json).unwrap();
3243        match deserialized {
3244            McpServer::Sse(McpServerSse {
3245                name,
3246                url,
3247                headers,
3248                meta: _,
3249            }) => {
3250                assert_eq!(name, "sse-server");
3251                assert_eq!(url, "https://sse.example.com/events");
3252                assert_eq!(headers.len(), 1);
3253                assert_eq!(headers[0].name, "X-API-Key");
3254                assert_eq!(headers[0].value, "apikey456");
3255            }
3256            _ => panic!("Expected Sse variant"),
3257        }
3258    }
3259}