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