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, 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: Implementation) -> Self {
69        self.client_info = Some(client_info);
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: Meta) -> Self {
80        self.meta = Some(meta);
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: Implementation) -> Self {
149        self.agent_info = Some(agent_info);
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: Meta) -> Self {
160        self.meta = Some(meta);
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 Into<String>) -> Self {
208        self.title = Some(title.into());
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: Meta) -> Self {
219        self.meta = Some(meta);
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: Meta) -> Self {
257        self.meta = Some(meta);
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: Meta) -> Self {
285        self.meta = Some(meta);
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 Into<String>) -> Self {
335        self.description = Some(description.into());
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: Meta) -> Self {
346        self.meta = Some(meta);
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: Meta) -> Self {
397        self.meta = Some(meta);
398        self
399    }
400}
401
402/// Response from creating a new session.
403///
404/// See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)
405#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
406#[schemars(extend("x-side" = "agent", "x-method" = SESSION_NEW_METHOD_NAME))]
407#[serde(rename_all = "camelCase")]
408#[non_exhaustive]
409pub struct NewSessionResponse {
410    /// Unique identifier for the created session.
411    ///
412    /// Used in all subsequent requests for this conversation.
413    pub session_id: SessionId,
414    /// Initial mode state if supported by the Agent
415    ///
416    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
417    #[serde(skip_serializing_if = "Option::is_none")]
418    pub modes: Option<SessionModeState>,
419    /// **UNSTABLE**
420    ///
421    /// This capability is not part of the spec yet, and may be removed or changed at any point.
422    ///
423    /// Initial model state if supported by the Agent
424    #[cfg(feature = "unstable_session_model")]
425    #[serde(skip_serializing_if = "Option::is_none")]
426    pub models: Option<SessionModelState>,
427    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
428    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
429    /// these keys.
430    ///
431    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
432    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
433    pub meta: Option<Meta>,
434}
435
436impl NewSessionResponse {
437    #[must_use]
438    pub fn new(session_id: impl Into<SessionId>) -> Self {
439        Self {
440            session_id: session_id.into(),
441            modes: None,
442            #[cfg(feature = "unstable_session_model")]
443            models: None,
444            meta: None,
445        }
446    }
447
448    /// Initial mode state if supported by the Agent
449    ///
450    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
451    #[must_use]
452    pub fn modes(mut self, modes: SessionModeState) -> Self {
453        self.modes = Some(modes);
454        self
455    }
456
457    /// **UNSTABLE**
458    ///
459    /// This capability is not part of the spec yet, and may be removed or changed at any point.
460    ///
461    /// Initial model state if supported by the Agent
462    #[cfg(feature = "unstable_session_model")]
463    #[must_use]
464    pub fn models(mut self, models: SessionModelState) -> Self {
465        self.models = Some(models);
466        self
467    }
468
469    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
470    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
471    /// these keys.
472    ///
473    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
474    #[must_use]
475    pub fn meta(mut self, meta: Meta) -> Self {
476        self.meta = Some(meta);
477        self
478    }
479}
480
481// Load session
482
483/// Request parameters for loading an existing session.
484///
485/// Only available if the Agent supports the `loadSession` capability.
486///
487/// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
488#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
489#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
490#[serde(rename_all = "camelCase")]
491#[non_exhaustive]
492pub struct LoadSessionRequest {
493    /// List of MCP servers to connect to for this session.
494    pub mcp_servers: Vec<McpServer>,
495    /// The working directory for this session.
496    pub cwd: PathBuf,
497    /// The ID of the session to load.
498    pub session_id: SessionId,
499    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
500    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
501    /// these keys.
502    ///
503    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
504    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
505    pub meta: Option<Meta>,
506}
507
508impl LoadSessionRequest {
509    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
510        Self {
511            mcp_servers: vec![],
512            cwd: cwd.into(),
513            session_id: session_id.into(),
514            meta: None,
515        }
516    }
517
518    /// List of MCP servers to connect to for this session.
519    #[must_use]
520    pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
521        self.mcp_servers = mcp_servers;
522        self
523    }
524
525    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
526    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
527    /// these keys.
528    ///
529    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
530    #[must_use]
531    pub fn meta(mut self, meta: Meta) -> Self {
532        self.meta = Some(meta);
533        self
534    }
535}
536
537/// Response from loading an existing session.
538#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
539#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
540#[serde(rename_all = "camelCase")]
541#[non_exhaustive]
542pub struct LoadSessionResponse {
543    /// Initial mode state if supported by the Agent
544    ///
545    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
546    #[serde(default, skip_serializing_if = "Option::is_none")]
547    pub modes: Option<SessionModeState>,
548    /// **UNSTABLE**
549    ///
550    /// This capability is not part of the spec yet, and may be removed or changed at any point.
551    ///
552    /// Initial model state if supported by the Agent
553    #[cfg(feature = "unstable_session_model")]
554    #[serde(default, skip_serializing_if = "Option::is_none")]
555    pub models: Option<SessionModelState>,
556    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
557    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
558    /// these keys.
559    ///
560    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
561    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
562    pub meta: Option<Meta>,
563}
564
565impl LoadSessionResponse {
566    #[must_use]
567    pub fn new() -> Self {
568        Self::default()
569    }
570
571    /// Initial mode state if supported by the Agent
572    ///
573    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
574    #[must_use]
575    pub fn modes(mut self, modes: SessionModeState) -> Self {
576        self.modes = Some(modes);
577        self
578    }
579
580    /// **UNSTABLE**
581    ///
582    /// This capability is not part of the spec yet, and may be removed or changed at any point.
583    ///
584    /// Initial model state if supported by the Agent
585    #[cfg(feature = "unstable_session_model")]
586    #[must_use]
587    pub fn models(mut self, models: SessionModelState) -> Self {
588        self.models = Some(models);
589        self
590    }
591
592    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
593    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
594    /// these keys.
595    ///
596    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
597    #[must_use]
598    pub fn meta(mut self, meta: Meta) -> Self {
599        self.meta = Some(meta);
600        self
601    }
602}
603
604// List sessions
605
606/// **UNSTABLE**
607///
608/// This capability is not part of the spec yet, and may be removed or changed at any point.
609///
610/// Request parameters for listing existing sessions.
611///
612/// Only available if the Agent supports the `listSessions` capability.
613#[cfg(feature = "unstable_session_list")]
614#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
615#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
616#[serde(rename_all = "camelCase")]
617#[non_exhaustive]
618pub struct ListSessionsRequest {
619    /// Filter sessions by working directory. Must be an absolute path.
620    #[serde(skip_serializing_if = "Option::is_none")]
621    pub cwd: Option<PathBuf>,
622    /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
623    #[serde(skip_serializing_if = "Option::is_none")]
624    pub cursor: Option<String>,
625    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
626    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
627    /// these keys.
628    ///
629    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
630    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
631    pub meta: Option<Meta>,
632}
633
634#[cfg(feature = "unstable_session_list")]
635impl ListSessionsRequest {
636    #[must_use]
637    pub fn new() -> Self {
638        Self::default()
639    }
640
641    /// Filter sessions by working directory. Must be an absolute path.
642    #[must_use]
643    pub fn cwd(mut self, cwd: impl Into<PathBuf>) -> Self {
644        self.cwd = Some(cwd.into());
645        self
646    }
647
648    /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
649    #[must_use]
650    pub fn cursor(mut self, cursor: impl Into<String>) -> Self {
651        self.cursor = Some(cursor.into());
652        self
653    }
654
655    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
656    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
657    /// these keys.
658    ///
659    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
660    #[must_use]
661    pub fn meta(mut self, meta: Meta) -> Self {
662        self.meta = Some(meta);
663        self
664    }
665}
666
667/// **UNSTABLE**
668///
669/// This capability is not part of the spec yet, and may be removed or changed at any point.
670///
671/// Response from listing sessions.
672#[cfg(feature = "unstable_session_list")]
673#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
674#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
675#[serde(rename_all = "camelCase")]
676#[non_exhaustive]
677pub struct ListSessionsResponse {
678    /// Array of session information objects
679    pub sessions: Vec<SessionInfo>,
680    /// Opaque cursor token. If present, pass this in the next request's cursor parameter
681    /// to fetch the next page. If absent, there are no more results.
682    #[serde(skip_serializing_if = "Option::is_none")]
683    pub next_cursor: Option<String>,
684    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
685    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
686    /// these keys.
687    ///
688    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
689    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
690    pub meta: Option<Meta>,
691}
692
693#[cfg(feature = "unstable_session_list")]
694impl ListSessionsResponse {
695    #[must_use]
696    pub fn new(sessions: Vec<SessionInfo>) -> Self {
697        Self {
698            sessions,
699            next_cursor: None,
700            meta: None,
701        }
702    }
703
704    #[must_use]
705    pub fn next_cursor(mut self, next_cursor: impl Into<String>) -> Self {
706        self.next_cursor = Some(next_cursor.into());
707        self
708    }
709
710    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
711    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
712    /// these keys.
713    ///
714    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
715    #[must_use]
716    pub fn meta(mut self, meta: Meta) -> Self {
717        self.meta = Some(meta);
718        self
719    }
720}
721
722/// **UNSTABLE**
723///
724/// This capability is not part of the spec yet, and may be removed or changed at any point.
725///
726/// Information about a session returned by session/list
727#[cfg(feature = "unstable_session_list")]
728#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
729#[serde(rename_all = "camelCase")]
730#[non_exhaustive]
731pub struct SessionInfo {
732    /// Unique identifier for the session
733    pub session_id: SessionId,
734    /// The working directory for this session. Must be an absolute path.
735    pub cwd: PathBuf,
736    /// Human-readable title for the session
737    #[serde(skip_serializing_if = "Option::is_none")]
738    pub title: Option<String>,
739    /// ISO 8601 timestamp of last activity
740    #[serde(skip_serializing_if = "Option::is_none")]
741    pub updated_at: Option<String>,
742    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
743    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
744    /// these keys.
745    ///
746    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
747    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
748    pub meta: Option<Meta>,
749}
750
751#[cfg(feature = "unstable_session_list")]
752impl SessionInfo {
753    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
754        Self {
755            session_id: session_id.into(),
756            cwd: cwd.into(),
757            title: None,
758            updated_at: None,
759            meta: None,
760        }
761    }
762
763    /// Human-readable title for the session
764    #[must_use]
765    pub fn title(mut self, title: impl Into<String>) -> Self {
766        self.title = Some(title.into());
767        self
768    }
769
770    /// ISO 8601 timestamp of last activity
771    #[must_use]
772    pub fn updated_at(mut self, updated_at: impl Into<String>) -> Self {
773        self.updated_at = Some(updated_at.into());
774        self
775    }
776
777    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
778    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
779    /// these keys.
780    ///
781    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
782    #[must_use]
783    pub fn meta(mut self, meta: Meta) -> Self {
784        self.meta = Some(meta);
785        self
786    }
787}
788
789// Session modes
790
791/// The set of modes and the one currently active.
792#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
793#[serde(rename_all = "camelCase")]
794#[non_exhaustive]
795pub struct SessionModeState {
796    /// The current mode the Agent is in.
797    pub current_mode_id: SessionModeId,
798    /// The set of modes that the Agent can operate in
799    pub available_modes: Vec<SessionMode>,
800    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
801    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
802    /// these keys.
803    ///
804    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
805    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
806    pub meta: Option<Meta>,
807}
808
809impl SessionModeState {
810    #[must_use]
811    pub fn new(
812        current_mode_id: impl Into<SessionModeId>,
813        available_modes: Vec<SessionMode>,
814    ) -> Self {
815        Self {
816            current_mode_id: current_mode_id.into(),
817            available_modes,
818            meta: None,
819        }
820    }
821
822    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
823    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
824    /// these keys.
825    ///
826    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
827    #[must_use]
828    pub fn meta(mut self, meta: Meta) -> Self {
829        self.meta = Some(meta);
830        self
831    }
832}
833
834/// A mode the agent can operate in.
835///
836/// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
837#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
838#[serde(rename_all = "camelCase")]
839#[non_exhaustive]
840pub struct SessionMode {
841    pub id: SessionModeId,
842    pub name: String,
843    #[serde(default, skip_serializing_if = "Option::is_none")]
844    pub description: Option<String>,
845    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
846    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
847    /// these keys.
848    ///
849    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
850    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
851    pub meta: Option<Meta>,
852}
853
854impl SessionMode {
855    pub fn new(id: impl Into<SessionModeId>, name: impl Into<String>) -> Self {
856        Self {
857            id: id.into(),
858            name: name.into(),
859            description: None,
860            meta: None,
861        }
862    }
863
864    #[must_use]
865    pub fn description(mut self, description: impl Into<String>) -> Self {
866        self.description = Some(description.into());
867        self
868    }
869
870    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
871    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
872    /// these keys.
873    ///
874    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
875    #[must_use]
876    pub fn meta(mut self, meta: Meta) -> Self {
877        self.meta = Some(meta);
878        self
879    }
880}
881
882/// Unique identifier for a Session Mode.
883#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
884#[serde(transparent)]
885#[from(Arc<str>, String, &'static str)]
886#[non_exhaustive]
887pub struct SessionModeId(pub Arc<str>);
888
889impl SessionModeId {
890    pub fn new(id: impl Into<Arc<str>>) -> Self {
891        Self(id.into())
892    }
893}
894
895/// Request parameters for setting a session mode.
896#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
897#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
898#[serde(rename_all = "camelCase")]
899#[non_exhaustive]
900pub struct SetSessionModeRequest {
901    /// The ID of the session to set the mode for.
902    pub session_id: SessionId,
903    /// The ID of the mode to set.
904    pub mode_id: SessionModeId,
905    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
906    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
907    /// these keys.
908    ///
909    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
910    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
911    pub meta: Option<Meta>,
912}
913
914impl SetSessionModeRequest {
915    #[must_use]
916    pub fn new(session_id: impl Into<SessionId>, mode_id: impl Into<SessionModeId>) -> Self {
917        Self {
918            session_id: session_id.into(),
919            mode_id: mode_id.into(),
920            meta: None,
921        }
922    }
923
924    #[must_use]
925    pub fn meta(mut self, meta: Meta) -> Self {
926        self.meta = Some(meta);
927        self
928    }
929}
930
931/// Response to `session/set_mode` method.
932#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
933#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
934#[serde(rename_all = "camelCase")]
935#[non_exhaustive]
936pub struct SetSessionModeResponse {
937    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
938    pub meta: Option<Meta>,
939}
940
941impl SetSessionModeResponse {
942    #[must_use]
943    pub fn new() -> Self {
944        Self::default()
945    }
946
947    #[must_use]
948    pub fn meta(mut self, meta: Meta) -> Self {
949        self.meta = Some(meta);
950        self
951    }
952}
953
954// MCP
955
956/// Configuration for connecting to an MCP (Model Context Protocol) server.
957///
958/// MCP servers provide tools and context that the agent can use when
959/// processing prompts.
960///
961/// See protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)
962#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
963#[serde(tag = "type", rename_all = "snake_case")]
964#[schemars(extend("discriminator" = {"propertyName": "type"}))]
965#[non_exhaustive]
966pub enum McpServer {
967    /// HTTP transport configuration
968    ///
969    /// Only available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.
970    Http(McpServerHttp),
971    /// SSE transport configuration
972    ///
973    /// Only available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.
974    Sse(McpServerSse),
975    /// Stdio transport configuration
976    ///
977    /// All Agents MUST support this transport.
978    #[serde(untagged)]
979    Stdio(McpServerStdio),
980}
981
982/// HTTP transport configuration for MCP.
983#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
984#[serde(rename_all = "camelCase")]
985#[non_exhaustive]
986pub struct McpServerHttp {
987    /// Human-readable name identifying this MCP server.
988    pub name: String,
989    /// URL to the MCP server.
990    pub url: String,
991    /// HTTP headers to set when making requests to the MCP server.
992    pub headers: Vec<HttpHeader>,
993    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
994    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
995    /// these keys.
996    ///
997    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
998    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
999    pub meta: Option<Meta>,
1000}
1001
1002impl McpServerHttp {
1003    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1004        Self {
1005            name: name.into(),
1006            url: url.into(),
1007            headers: Vec::new(),
1008            meta: None,
1009        }
1010    }
1011
1012    /// HTTP headers to set when making requests to the MCP server.
1013    #[must_use]
1014    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1015        self.headers = headers;
1016        self
1017    }
1018
1019    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1020    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1021    /// these keys.
1022    ///
1023    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1024    #[must_use]
1025    pub fn meta(mut self, meta: Meta) -> Self {
1026        self.meta = Some(meta);
1027        self
1028    }
1029}
1030
1031/// SSE transport configuration for MCP.
1032#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1033#[serde(rename_all = "camelCase")]
1034#[non_exhaustive]
1035pub struct McpServerSse {
1036    /// Human-readable name identifying this MCP server.
1037    pub name: String,
1038    /// URL to the MCP server.
1039    pub url: String,
1040    /// HTTP headers to set when making requests to the MCP server.
1041    pub headers: Vec<HttpHeader>,
1042    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1043    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1044    /// these keys.
1045    ///
1046    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1047    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1048    pub meta: Option<Meta>,
1049}
1050
1051impl McpServerSse {
1052    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1053        Self {
1054            name: name.into(),
1055            url: url.into(),
1056            headers: Vec::new(),
1057            meta: None,
1058        }
1059    }
1060
1061    /// HTTP headers to set when making requests to the MCP server.
1062    #[must_use]
1063    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1064        self.headers = headers;
1065        self
1066    }
1067
1068    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1069    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1070    /// these keys.
1071    ///
1072    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1073    #[must_use]
1074    pub fn meta(mut self, meta: Meta) -> Self {
1075        self.meta = Some(meta);
1076        self
1077    }
1078}
1079
1080/// Stdio transport configuration for MCP.
1081#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1082#[serde(rename_all = "camelCase")]
1083#[non_exhaustive]
1084pub struct McpServerStdio {
1085    /// Human-readable name identifying this MCP server.
1086    pub name: String,
1087    /// Path to the MCP server executable.
1088    pub command: PathBuf,
1089    /// Command-line arguments to pass to the MCP server.
1090    pub args: Vec<String>,
1091    /// Environment variables to set when launching the MCP server.
1092    pub env: Vec<EnvVariable>,
1093    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1094    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1095    /// these keys.
1096    ///
1097    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1098    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1099    pub meta: Option<Meta>,
1100}
1101
1102impl McpServerStdio {
1103    pub fn new(name: impl Into<String>, command: impl Into<PathBuf>) -> Self {
1104        Self {
1105            name: name.into(),
1106            command: command.into(),
1107            args: Vec::new(),
1108            env: Vec::new(),
1109            meta: None,
1110        }
1111    }
1112
1113    /// Command-line arguments to pass to the MCP server.
1114    #[must_use]
1115    pub fn args(mut self, args: Vec<String>) -> Self {
1116        self.args = args;
1117        self
1118    }
1119
1120    /// Environment variables to set when launching the MCP server.
1121    #[must_use]
1122    pub fn env(mut self, env: Vec<EnvVariable>) -> Self {
1123        self.env = env;
1124        self
1125    }
1126
1127    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1128    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1129    /// these keys.
1130    ///
1131    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1132    #[must_use]
1133    pub fn meta(mut self, meta: Meta) -> Self {
1134        self.meta = Some(meta);
1135        self
1136    }
1137}
1138
1139/// An environment variable to set when launching an MCP server.
1140#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1141#[serde(rename_all = "camelCase")]
1142#[non_exhaustive]
1143pub struct EnvVariable {
1144    /// The name of the environment variable.
1145    pub name: String,
1146    /// The value to set for the environment variable.
1147    pub value: String,
1148    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1149    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1150    /// these keys.
1151    ///
1152    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1153    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1154    pub meta: Option<Meta>,
1155}
1156
1157impl EnvVariable {
1158    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1159        Self {
1160            name: name.into(),
1161            value: value.into(),
1162            meta: None,
1163        }
1164    }
1165
1166    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1167    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1168    /// these keys.
1169    ///
1170    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1171    #[must_use]
1172    pub fn meta(mut self, meta: Meta) -> Self {
1173        self.meta = Some(meta);
1174        self
1175    }
1176}
1177
1178/// An HTTP header to set when making requests to the MCP server.
1179#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1180#[serde(rename_all = "camelCase")]
1181#[non_exhaustive]
1182pub struct HttpHeader {
1183    /// The name of the HTTP header.
1184    pub name: String,
1185    /// The value to set for the HTTP header.
1186    pub value: String,
1187    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1188    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1189    /// these keys.
1190    ///
1191    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1192    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1193    pub meta: Option<Meta>,
1194}
1195
1196impl HttpHeader {
1197    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1198        Self {
1199            name: name.into(),
1200            value: value.into(),
1201            meta: None,
1202        }
1203    }
1204
1205    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1206    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1207    /// these keys.
1208    ///
1209    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1210    #[must_use]
1211    pub fn meta(mut self, meta: Meta) -> Self {
1212        self.meta = Some(meta);
1213        self
1214    }
1215}
1216
1217// Prompt
1218
1219/// Request parameters for sending a user prompt to the agent.
1220///
1221/// Contains the user's message and any additional context.
1222///
1223/// See protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)
1224#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
1225#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1226#[serde(rename_all = "camelCase")]
1227#[non_exhaustive]
1228pub struct PromptRequest {
1229    /// The ID of the session to send this user message to
1230    pub session_id: SessionId,
1231    /// The blocks of content that compose the user's message.
1232    ///
1233    /// As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],
1234    /// while other variants are optionally enabled via [`PromptCapabilities`].
1235    ///
1236    /// The Client MUST adapt its interface according to [`PromptCapabilities`].
1237    ///
1238    /// The client MAY include referenced pieces of context as either
1239    /// [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].
1240    ///
1241    /// When available, [`ContentBlock::Resource`] is preferred
1242    /// as it avoids extra round-trips and allows the message to include
1243    /// pieces of context from sources the agent may not have access to.
1244    pub prompt: Vec<ContentBlock>,
1245    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1246    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1247    /// these keys.
1248    ///
1249    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1250    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1251    pub meta: Option<Meta>,
1252}
1253
1254impl PromptRequest {
1255    #[must_use]
1256    pub fn new(session_id: impl Into<SessionId>, prompt: Vec<ContentBlock>) -> Self {
1257        Self {
1258            session_id: session_id.into(),
1259            prompt,
1260            meta: None,
1261        }
1262    }
1263
1264    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1265    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1266    /// these keys.
1267    ///
1268    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1269    #[must_use]
1270    pub fn meta(mut self, meta: Meta) -> Self {
1271        self.meta = Some(meta);
1272        self
1273    }
1274}
1275
1276/// Response from processing a user prompt.
1277///
1278/// See protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)
1279#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1280#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1281#[serde(rename_all = "camelCase")]
1282#[non_exhaustive]
1283pub struct PromptResponse {
1284    /// Indicates why the agent stopped processing the turn.
1285    pub stop_reason: StopReason,
1286    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1287    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1288    /// these keys.
1289    ///
1290    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1291    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1292    pub meta: Option<Meta>,
1293}
1294
1295impl PromptResponse {
1296    #[must_use]
1297    pub fn new(stop_reason: StopReason) -> Self {
1298        Self {
1299            stop_reason,
1300            meta: None,
1301        }
1302    }
1303
1304    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1305    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1306    /// these keys.
1307    ///
1308    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1309    #[must_use]
1310    pub fn meta(mut self, meta: Meta) -> Self {
1311        self.meta = Some(meta);
1312        self
1313    }
1314}
1315
1316/// Reasons why an agent stops processing a prompt turn.
1317///
1318/// See protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)
1319#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1320#[serde(rename_all = "snake_case")]
1321#[non_exhaustive]
1322pub enum StopReason {
1323    /// The turn ended successfully.
1324    EndTurn,
1325    /// The turn ended because the agent reached the maximum number of tokens.
1326    MaxTokens,
1327    /// The turn ended because the agent reached the maximum number of allowed
1328    /// agent requests between user turns.
1329    MaxTurnRequests,
1330    /// The turn ended because the agent refused to continue. The user prompt
1331    /// and everything that comes after it won't be included in the next
1332    /// prompt, so this should be reflected in the UI.
1333    Refusal,
1334    /// The turn was cancelled by the client via `session/cancel`.
1335    ///
1336    /// This stop reason MUST be returned when the client sends a `session/cancel`
1337    /// notification, even if the cancellation causes exceptions in underlying operations.
1338    /// Agents should catch these exceptions and return this semantically meaningful
1339    /// response to confirm successful cancellation.
1340    Cancelled,
1341}
1342
1343// Model
1344
1345/// **UNSTABLE**
1346///
1347/// This capability is not part of the spec yet, and may be removed or changed at any point.
1348///
1349/// The set of models and the one currently active.
1350#[cfg(feature = "unstable_session_model")]
1351#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1352#[serde(rename_all = "camelCase")]
1353#[non_exhaustive]
1354pub struct SessionModelState {
1355    /// The current model the Agent is in.
1356    pub current_model_id: ModelId,
1357    /// The set of models that the Agent can use
1358    pub available_models: Vec<ModelInfo>,
1359    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1360    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1361    /// these keys.
1362    ///
1363    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1364    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1365    pub meta: Option<Meta>,
1366}
1367
1368#[cfg(feature = "unstable_session_model")]
1369impl SessionModelState {
1370    #[must_use]
1371    pub fn new(current_model_id: impl Into<ModelId>, available_models: Vec<ModelInfo>) -> Self {
1372        Self {
1373            current_model_id: current_model_id.into(),
1374            available_models,
1375            meta: None,
1376        }
1377    }
1378
1379    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1380    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1381    /// these keys.
1382    ///
1383    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1384    #[must_use]
1385    pub fn meta(mut self, meta: Meta) -> Self {
1386        self.meta = Some(meta);
1387        self
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 unique identifier for a model.
1396#[cfg(feature = "unstable_session_model")]
1397#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
1398#[serde(transparent)]
1399#[from(Arc<str>, String, &'static str)]
1400#[non_exhaustive]
1401pub struct ModelId(pub Arc<str>);
1402
1403#[cfg(feature = "unstable_session_model")]
1404impl ModelId {
1405    pub fn new(id: impl Into<Arc<str>>) -> Self {
1406        Self(id.into())
1407    }
1408}
1409
1410/// **UNSTABLE**
1411///
1412/// This capability is not part of the spec yet, and may be removed or changed at any point.
1413///
1414/// Information about a selectable model.
1415#[cfg(feature = "unstable_session_model")]
1416#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1417#[serde(rename_all = "camelCase")]
1418#[non_exhaustive]
1419pub struct ModelInfo {
1420    /// Unique identifier for the model.
1421    pub model_id: ModelId,
1422    /// Human-readable name of the model.
1423    pub name: String,
1424    /// Optional description of the model.
1425    #[serde(default, skip_serializing_if = "Option::is_none")]
1426    pub description: Option<String>,
1427    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1428    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1429    /// these keys.
1430    ///
1431    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1432    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1433    pub meta: Option<Meta>,
1434}
1435
1436#[cfg(feature = "unstable_session_model")]
1437impl ModelInfo {
1438    pub fn new(model_id: impl Into<ModelId>, name: impl Into<String>) -> Self {
1439        Self {
1440            model_id: model_id.into(),
1441            name: name.into(),
1442            description: None,
1443            meta: None,
1444        }
1445    }
1446
1447    /// Optional description of the model.
1448    #[must_use]
1449    pub fn description(mut self, description: impl Into<String>) -> Self {
1450        self.description = Some(description.into());
1451        self
1452    }
1453
1454    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1455    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1456    /// these keys.
1457    ///
1458    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1459    #[must_use]
1460    pub fn meta(mut self, meta: Meta) -> Self {
1461        self.meta = Some(meta);
1462        self
1463    }
1464}
1465
1466/// **UNSTABLE**
1467///
1468/// This capability is not part of the spec yet, and may be removed or changed at any point.
1469///
1470/// Request parameters for setting a session model.
1471#[cfg(feature = "unstable_session_model")]
1472#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1473#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1474#[serde(rename_all = "camelCase")]
1475#[non_exhaustive]
1476pub struct SetSessionModelRequest {
1477    /// The ID of the session to set the model for.
1478    pub session_id: SessionId,
1479    /// The ID of the model to set.
1480    pub model_id: ModelId,
1481    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1482    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1483    /// these keys.
1484    ///
1485    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1486    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1487    pub meta: Option<Meta>,
1488}
1489
1490#[cfg(feature = "unstable_session_model")]
1491impl SetSessionModelRequest {
1492    #[must_use]
1493    pub fn new(session_id: impl Into<SessionId>, model_id: impl Into<ModelId>) -> Self {
1494        Self {
1495            session_id: session_id.into(),
1496            model_id: model_id.into(),
1497            meta: None,
1498        }
1499    }
1500
1501    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1502    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1503    /// these keys.
1504    ///
1505    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1506    #[must_use]
1507    pub fn meta(mut self, meta: Meta) -> Self {
1508        self.meta = Some(meta);
1509        self
1510    }
1511}
1512
1513/// **UNSTABLE**
1514///
1515/// This capability is not part of the spec yet, and may be removed or changed at any point.
1516///
1517/// Response to `session/set_model` method.
1518#[cfg(feature = "unstable_session_model")]
1519#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1520#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1521#[serde(rename_all = "camelCase")]
1522#[non_exhaustive]
1523pub struct SetSessionModelResponse {
1524    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1525    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1526    /// these keys.
1527    ///
1528    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1529    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1530    pub meta: Option<Meta>,
1531}
1532
1533#[cfg(feature = "unstable_session_model")]
1534impl SetSessionModelResponse {
1535    #[must_use]
1536    pub fn new() -> Self {
1537        Self::default()
1538    }
1539
1540    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1541    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1542    /// these keys.
1543    ///
1544    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1545    #[must_use]
1546    pub fn meta(mut self, meta: Meta) -> Self {
1547        self.meta = Some(meta);
1548        self
1549    }
1550}
1551
1552// Capabilities
1553
1554/// Capabilities supported by the agent.
1555///
1556/// Advertised during initialization to inform the client about
1557/// available features and content types.
1558///
1559/// See protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)
1560#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1561#[serde(rename_all = "camelCase")]
1562#[non_exhaustive]
1563pub struct AgentCapabilities {
1564    /// Whether the agent supports `session/load`.
1565    #[serde(default)]
1566    pub load_session: bool,
1567    /// Prompt capabilities supported by the agent.
1568    #[serde(default)]
1569    pub prompt_capabilities: PromptCapabilities,
1570    /// MCP capabilities supported by the agent.
1571    #[serde(default)]
1572    pub mcp_capabilities: McpCapabilities,
1573    #[serde(default)]
1574    pub session_capabilities: SessionCapabilities,
1575    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1576    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1577    /// these keys.
1578    ///
1579    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1580    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1581    pub meta: Option<Meta>,
1582}
1583
1584impl AgentCapabilities {
1585    #[must_use]
1586    pub fn new() -> Self {
1587        Self::default()
1588    }
1589
1590    /// Whether the agent supports `session/load`.
1591    #[must_use]
1592    pub fn load_session(mut self, load_session: bool) -> Self {
1593        self.load_session = load_session;
1594        self
1595    }
1596
1597    /// Prompt capabilities supported by the agent.
1598    #[must_use]
1599    pub fn prompt_capabilities(mut self, prompt_capabilities: PromptCapabilities) -> Self {
1600        self.prompt_capabilities = prompt_capabilities;
1601        self
1602    }
1603
1604    /// MCP capabilities supported by the agent.
1605    #[must_use]
1606    pub fn mcp_capabilities(mut self, mcp_capabilities: McpCapabilities) -> Self {
1607        self.mcp_capabilities = mcp_capabilities;
1608        self
1609    }
1610
1611    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1612    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1613    /// these keys.
1614    ///
1615    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1616    #[must_use]
1617    pub fn meta(mut self, meta: Meta) -> Self {
1618        self.meta = Some(meta);
1619        self
1620    }
1621}
1622
1623/// Session capabilities supported by the agent.
1624///
1625/// As a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.
1626///
1627/// Optionally, they **MAY** support other session methods and notifications by specifying additional capabilities.
1628///
1629/// Note: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.
1630///
1631/// See protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)
1632#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1633#[non_exhaustive]
1634pub struct SessionCapabilities {
1635    /// **UNSTABLE**
1636    ///
1637    /// This capability is not part of the spec yet, and may be removed or changed at any point.
1638    ///
1639    /// Whether the agent supports `session/list`.
1640    #[cfg(feature = "unstable_session_list")]
1641    #[serde(skip_serializing_if = "Option::is_none")]
1642    pub list: Option<SessionListCapabilities>,
1643    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1644    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1645    /// these keys.
1646    ///
1647    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1648    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1649    pub meta: Option<Meta>,
1650}
1651
1652impl SessionCapabilities {
1653    #[must_use]
1654    pub fn new() -> Self {
1655        Self::default()
1656    }
1657
1658    #[cfg(feature = "unstable_session_list")]
1659    /// Whether the agent supports `session/list`.
1660    #[must_use]
1661    pub fn list(mut self, list: SessionListCapabilities) -> Self {
1662        self.list = Some(list);
1663        self
1664    }
1665
1666    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1667    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1668    /// these keys.
1669    ///
1670    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1671    #[must_use]
1672    pub fn meta(mut self, meta: Meta) -> Self {
1673        self.meta = Some(meta);
1674        self
1675    }
1676}
1677
1678/// Capabilities for the `session/list` method.
1679///
1680/// By supplying `{}` it means that the agent supports listing of sessions.
1681///
1682/// Further capabilities can be added in the future for other means of filtering or searching the list.
1683#[cfg(feature = "unstable_session_list")]
1684#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1685#[non_exhaustive]
1686pub struct SessionListCapabilities {
1687    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1688    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1689    /// these keys.
1690    ///
1691    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1692    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1693    pub meta: Option<Meta>,
1694}
1695
1696#[cfg(feature = "unstable_session_list")]
1697impl SessionListCapabilities {
1698    #[must_use]
1699    pub fn new() -> Self {
1700        Self::default()
1701    }
1702    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1703    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1704    /// these keys.
1705    ///
1706    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1707    #[must_use]
1708    pub fn meta(mut self, meta: Meta) -> Self {
1709        self.meta = Some(meta);
1710        self
1711    }
1712}
1713
1714/// Prompt capabilities supported by the agent in `session/prompt` requests.
1715///
1716/// Baseline agent functionality requires support for [`ContentBlock::Text`]
1717/// and [`ContentBlock::ResourceLink`] in prompt requests.
1718///
1719/// Other variants must be explicitly opted in to.
1720/// Capabilities for different types of content in prompt requests.
1721///
1722/// Indicates which content types beyond the baseline (text and resource links)
1723/// the agent can process.
1724///
1725/// See protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)
1726#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1727#[serde(rename_all = "camelCase")]
1728#[non_exhaustive]
1729pub struct PromptCapabilities {
1730    /// Agent supports [`ContentBlock::Image`].
1731    #[serde(default)]
1732    pub image: bool,
1733    /// Agent supports [`ContentBlock::Audio`].
1734    #[serde(default)]
1735    pub audio: bool,
1736    /// Agent supports embedded context in `session/prompt` requests.
1737    ///
1738    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
1739    /// in prompt requests for pieces of context that are referenced in the message.
1740    #[serde(default)]
1741    pub embedded_context: bool,
1742    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1743    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1744    /// these keys.
1745    ///
1746    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1747    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1748    pub meta: Option<Meta>,
1749}
1750
1751impl PromptCapabilities {
1752    #[must_use]
1753    pub fn new() -> Self {
1754        Self::default()
1755    }
1756
1757    /// Agent supports [`ContentBlock::Image`].
1758    #[must_use]
1759    pub fn image(mut self, image: bool) -> Self {
1760        self.image = image;
1761        self
1762    }
1763
1764    /// Agent supports [`ContentBlock::Audio`].
1765    #[must_use]
1766    pub fn audio(mut self, audio: bool) -> Self {
1767        self.audio = audio;
1768        self
1769    }
1770
1771    /// Agent supports embedded context in `session/prompt` requests.
1772    ///
1773    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
1774    /// in prompt requests for pieces of context that are referenced in the message.
1775    #[must_use]
1776    pub fn embedded_context(mut self, embedded_context: bool) -> Self {
1777        self.embedded_context = embedded_context;
1778        self
1779    }
1780
1781    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1782    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1783    /// these keys.
1784    ///
1785    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1786    #[must_use]
1787    pub fn meta(mut self, meta: Meta) -> Self {
1788        self.meta = Some(meta);
1789        self
1790    }
1791}
1792
1793/// MCP capabilities supported by the agent
1794#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1795#[serde(rename_all = "camelCase")]
1796#[non_exhaustive]
1797pub struct McpCapabilities {
1798    /// Agent supports [`McpServer::Http`].
1799    #[serde(default)]
1800    pub http: bool,
1801    /// Agent supports [`McpServer::Sse`].
1802    #[serde(default)]
1803    pub sse: bool,
1804    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1805    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1806    /// these keys.
1807    ///
1808    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1809    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1810    pub meta: Option<Meta>,
1811}
1812
1813impl McpCapabilities {
1814    #[must_use]
1815    pub fn new() -> Self {
1816        Self::default()
1817    }
1818
1819    /// Agent supports [`McpServer::Http`].
1820    #[must_use]
1821    pub fn http(mut self, http: bool) -> Self {
1822        self.http = http;
1823        self
1824    }
1825
1826    /// Agent supports [`McpServer::Sse`].
1827    #[must_use]
1828    pub fn sse(mut self, sse: bool) -> Self {
1829        self.sse = sse;
1830        self
1831    }
1832
1833    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1834    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1835    /// these keys.
1836    ///
1837    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1838    #[must_use]
1839    pub fn meta(mut self, meta: Meta) -> Self {
1840        self.meta = Some(meta);
1841        self
1842    }
1843}
1844
1845// Method schema
1846
1847/// Names of all methods that agents handle.
1848///
1849/// Provides a centralized definition of method names used in the protocol.
1850#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1851#[non_exhaustive]
1852pub struct AgentMethodNames {
1853    /// Method for initializing the connection.
1854    pub initialize: &'static str,
1855    /// Method for authenticating with the agent.
1856    pub authenticate: &'static str,
1857    /// Method for creating a new session.
1858    pub session_new: &'static str,
1859    /// Method for loading an existing session.
1860    pub session_load: &'static str,
1861    /// Method for setting the mode for a session.
1862    pub session_set_mode: &'static str,
1863    /// Method for sending a prompt to the agent.
1864    pub session_prompt: &'static str,
1865    /// Notification for cancelling operations.
1866    pub session_cancel: &'static str,
1867    /// Method for selecting a model for a given session.
1868    #[cfg(feature = "unstable_session_model")]
1869    pub session_set_model: &'static str,
1870    /// Method for listing existing sessions.
1871    #[cfg(feature = "unstable_session_list")]
1872    pub session_list: &'static str,
1873}
1874
1875/// Constant containing all agent method names.
1876pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
1877    initialize: INITIALIZE_METHOD_NAME,
1878    authenticate: AUTHENTICATE_METHOD_NAME,
1879    session_new: SESSION_NEW_METHOD_NAME,
1880    session_load: SESSION_LOAD_METHOD_NAME,
1881    session_set_mode: SESSION_SET_MODE_METHOD_NAME,
1882    session_prompt: SESSION_PROMPT_METHOD_NAME,
1883    session_cancel: SESSION_CANCEL_METHOD_NAME,
1884    #[cfg(feature = "unstable_session_model")]
1885    session_set_model: SESSION_SET_MODEL_METHOD_NAME,
1886    #[cfg(feature = "unstable_session_list")]
1887    session_list: SESSION_LIST_METHOD_NAME,
1888};
1889
1890/// Method name for the initialize request.
1891pub(crate) const INITIALIZE_METHOD_NAME: &str = "initialize";
1892/// Method name for the authenticate request.
1893pub(crate) const AUTHENTICATE_METHOD_NAME: &str = "authenticate";
1894/// Method name for creating a new session.
1895pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
1896/// Method name for loading an existing session.
1897pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
1898/// Method name for setting the mode for a session.
1899pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
1900/// Method name for sending a prompt.
1901pub(crate) const SESSION_PROMPT_METHOD_NAME: &str = "session/prompt";
1902/// Method name for the cancel notification.
1903pub(crate) const SESSION_CANCEL_METHOD_NAME: &str = "session/cancel";
1904/// Method name for selecting a model for a given session.
1905#[cfg(feature = "unstable_session_model")]
1906pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
1907/// Method name for listing existing sessions.
1908#[cfg(feature = "unstable_session_list")]
1909pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list";
1910
1911/// All possible requests that a client can send to an agent.
1912///
1913/// This enum is used internally for routing RPC requests. You typically won't need
1914/// to use this directly - instead, use the methods on the [`Agent`] trait.
1915///
1916/// This enum encompasses all method calls from client to agent.
1917#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
1918#[serde(untagged)]
1919#[schemars(inline)]
1920#[non_exhaustive]
1921pub enum ClientRequest {
1922    /// Establishes the connection with a client and negotiates protocol capabilities.
1923    ///
1924    /// This method is called once at the beginning of the connection to:
1925    /// - Negotiate the protocol version to use
1926    /// - Exchange capability information between client and agent
1927    /// - Determine available authentication methods
1928    ///
1929    /// The agent should respond with its supported protocol version and capabilities.
1930    ///
1931    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
1932    InitializeRequest(InitializeRequest),
1933    /// Authenticates the client using the specified authentication method.
1934    ///
1935    /// Called when the agent requires authentication before allowing session creation.
1936    /// The client provides the authentication method ID that was advertised during initialization.
1937    ///
1938    /// After successful authentication, the client can proceed to create sessions with
1939    /// `new_session` without receiving an `auth_required` error.
1940    ///
1941    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
1942    AuthenticateRequest(AuthenticateRequest),
1943    /// Creates a new conversation session with the agent.
1944    ///
1945    /// Sessions represent independent conversation contexts with their own history and state.
1946    ///
1947    /// The agent should:
1948    /// - Create a new session context
1949    /// - Connect to any specified MCP servers
1950    /// - Return a unique session ID for future requests
1951    ///
1952    /// May return an `auth_required` error if the agent requires authentication.
1953    ///
1954    /// See protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)
1955    NewSessionRequest(NewSessionRequest),
1956    /// Loads an existing session to resume a previous conversation.
1957    ///
1958    /// This method is only available if the agent advertises the `loadSession` capability.
1959    ///
1960    /// The agent should:
1961    /// - Restore the session context and conversation history
1962    /// - Connect to the specified MCP servers
1963    /// - Stream the entire conversation history back to the client via notifications
1964    ///
1965    /// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
1966    LoadSessionRequest(LoadSessionRequest),
1967    #[cfg(feature = "unstable_session_list")]
1968    /// **UNSTABLE**
1969    ///
1970    /// This capability is not part of the spec yet, and may be removed or changed at any point.
1971    ///
1972    /// Lists existing sessions known to the agent.
1973    ///
1974    /// This method is only available if the agent advertises the `listSessions` capability.
1975    ///
1976    /// The agent should return metadata about sessions with optional filtering and pagination support.
1977    ListSessionsRequest(ListSessionsRequest),
1978    /// Sets the current mode for a session.
1979    ///
1980    /// Allows switching between different agent modes (e.g., "ask", "architect", "code")
1981    /// that affect system prompts, tool availability, and permission behaviors.
1982    ///
1983    /// The mode must be one of the modes advertised in `availableModes` during session
1984    /// creation or loading. Agents may also change modes autonomously and notify the
1985    /// client via `current_mode_update` notifications.
1986    ///
1987    /// This method can be called at any time during a session, whether the Agent is
1988    /// idle or actively generating a response.
1989    ///
1990    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
1991    SetSessionModeRequest(SetSessionModeRequest),
1992    /// Processes a user prompt within a session.
1993    ///
1994    /// This method handles the whole lifecycle of a prompt:
1995    /// - Receives user messages with optional context (files, images, etc.)
1996    /// - Processes the prompt using language models
1997    /// - Reports language model content and tool calls to the Clients
1998    /// - Requests permission to run tools
1999    /// - Executes any requested tool calls
2000    /// - Returns when the turn is complete with a stop reason
2001    ///
2002    /// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
2003    PromptRequest(PromptRequest),
2004    #[cfg(feature = "unstable_session_model")]
2005    /// **UNSTABLE**
2006    ///
2007    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2008    ///
2009    /// Select a model for a given session.
2010    SetSessionModelRequest(SetSessionModelRequest),
2011    /// Handles extension method requests from the client.
2012    ///
2013    /// Extension methods provide a way to add custom functionality while maintaining
2014    /// protocol compatibility.
2015    ///
2016    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2017    ExtMethodRequest(ExtRequest),
2018}
2019
2020impl ClientRequest {
2021    /// Returns the corresponding method name of the request.
2022    #[must_use]
2023    pub fn method(&self) -> &str {
2024        match self {
2025            Self::InitializeRequest(_) => AGENT_METHOD_NAMES.initialize,
2026            Self::AuthenticateRequest(_) => AGENT_METHOD_NAMES.authenticate,
2027            Self::NewSessionRequest(_) => AGENT_METHOD_NAMES.session_new,
2028            Self::LoadSessionRequest(_) => AGENT_METHOD_NAMES.session_load,
2029            #[cfg(feature = "unstable_session_list")]
2030            Self::ListSessionsRequest(_) => AGENT_METHOD_NAMES.session_list,
2031            Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode,
2032            Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt,
2033            #[cfg(feature = "unstable_session_model")]
2034            Self::SetSessionModelRequest(_) => AGENT_METHOD_NAMES.session_set_model,
2035            Self::ExtMethodRequest(ext_request) => &ext_request.method,
2036        }
2037    }
2038}
2039
2040/// All possible responses that an agent can send to a client.
2041///
2042/// This enum is used internally for routing RPC responses. You typically won't need
2043/// to use this directly - the responses are handled automatically by the connection.
2044///
2045/// These are responses to the corresponding `ClientRequest` variants.
2046#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2047#[serde(untagged)]
2048#[schemars(inline)]
2049#[non_exhaustive]
2050pub enum AgentResponse {
2051    InitializeResponse(InitializeResponse),
2052    AuthenticateResponse(#[serde(default)] AuthenticateResponse),
2053    NewSessionResponse(NewSessionResponse),
2054    LoadSessionResponse(#[serde(default)] LoadSessionResponse),
2055    #[cfg(feature = "unstable_session_list")]
2056    ListSessionsResponse(ListSessionsResponse),
2057    SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
2058    PromptResponse(PromptResponse),
2059    #[cfg(feature = "unstable_session_model")]
2060    SetSessionModelResponse(SetSessionModelResponse),
2061    ExtMethodResponse(ExtResponse),
2062}
2063
2064/// All possible notifications that a client can send to an agent.
2065///
2066/// This enum is used internally for routing RPC notifications. You typically won't need
2067/// to use this directly - use the notification methods on the [`Agent`] trait instead.
2068///
2069/// Notifications do not expect a response.
2070#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2071#[serde(untagged)]
2072#[schemars(inline)]
2073#[non_exhaustive]
2074pub enum ClientNotification {
2075    /// Cancels ongoing operations for a session.
2076    ///
2077    /// This is a notification sent by the client to cancel an ongoing prompt turn.
2078    ///
2079    /// Upon receiving this notification, the Agent SHOULD:
2080    /// - Stop all language model requests as soon as possible
2081    /// - Abort all tool call invocations in progress
2082    /// - Send any pending `session/update` notifications
2083    /// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
2084    ///
2085    /// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
2086    CancelNotification(CancelNotification),
2087    /// Handles extension notifications from the client.
2088    ///
2089    /// Extension notifications provide a way to send one-way messages for custom functionality
2090    /// while maintaining protocol compatibility.
2091    ///
2092    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2093    ExtNotification(ExtNotification),
2094}
2095
2096impl ClientNotification {
2097    /// Returns the corresponding method name of the notification.
2098    #[must_use]
2099    pub fn method(&self) -> &str {
2100        match self {
2101            Self::CancelNotification(_) => AGENT_METHOD_NAMES.session_cancel,
2102            Self::ExtNotification(ext_notification) => &ext_notification.method,
2103        }
2104    }
2105}
2106
2107/// Notification to cancel ongoing operations for a session.
2108///
2109/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
2110#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2111#[schemars(extend("x-side" = "agent", "x-method" = SESSION_CANCEL_METHOD_NAME))]
2112#[serde(rename_all = "camelCase")]
2113#[non_exhaustive]
2114pub struct CancelNotification {
2115    /// The ID of the session to cancel operations for.
2116    pub session_id: SessionId,
2117    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2118    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2119    /// these keys.
2120    ///
2121    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2122    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2123    pub meta: Option<Meta>,
2124}
2125
2126impl CancelNotification {
2127    #[must_use]
2128    pub fn new(session_id: impl Into<SessionId>) -> Self {
2129        Self {
2130            session_id: session_id.into(),
2131            meta: None,
2132        }
2133    }
2134
2135    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2136    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2137    /// these keys.
2138    ///
2139    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2140    #[must_use]
2141    pub fn meta(mut self, meta: Meta) -> Self {
2142        self.meta = Some(meta);
2143        self
2144    }
2145}
2146
2147#[cfg(test)]
2148mod test_serialization {
2149    use super::*;
2150    use serde_json::json;
2151
2152    #[test]
2153    fn test_mcp_server_stdio_serialization() {
2154        let server = McpServer::Stdio(
2155            McpServerStdio::new("test-server", "/usr/bin/server")
2156                .args(vec!["--port".to_string(), "3000".to_string()])
2157                .env(vec![EnvVariable::new("API_KEY", "secret123")]),
2158        );
2159
2160        let json = serde_json::to_value(&server).unwrap();
2161        assert_eq!(
2162            json,
2163            json!({
2164                "name": "test-server",
2165                "command": "/usr/bin/server",
2166                "args": ["--port", "3000"],
2167                "env": [
2168                    {
2169                        "name": "API_KEY",
2170                        "value": "secret123"
2171                    }
2172                ]
2173            })
2174        );
2175
2176        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2177        match deserialized {
2178            McpServer::Stdio(McpServerStdio {
2179                name,
2180                command,
2181                args,
2182                env,
2183                meta: _,
2184            }) => {
2185                assert_eq!(name, "test-server");
2186                assert_eq!(command, PathBuf::from("/usr/bin/server"));
2187                assert_eq!(args, vec!["--port", "3000"]);
2188                assert_eq!(env.len(), 1);
2189                assert_eq!(env[0].name, "API_KEY");
2190                assert_eq!(env[0].value, "secret123");
2191            }
2192            _ => panic!("Expected Stdio variant"),
2193        }
2194    }
2195
2196    #[test]
2197    fn test_mcp_server_http_serialization() {
2198        let server = McpServer::Http(
2199            McpServerHttp::new("http-server", "https://api.example.com").headers(vec![
2200                HttpHeader::new("Authorization", "Bearer token123"),
2201                HttpHeader::new("Content-Type", "application/json"),
2202            ]),
2203        );
2204
2205        let json = serde_json::to_value(&server).unwrap();
2206        assert_eq!(
2207            json,
2208            json!({
2209                "type": "http",
2210                "name": "http-server",
2211                "url": "https://api.example.com",
2212                "headers": [
2213                    {
2214                        "name": "Authorization",
2215                        "value": "Bearer token123"
2216                    },
2217                    {
2218                        "name": "Content-Type",
2219                        "value": "application/json"
2220                    }
2221                ]
2222            })
2223        );
2224
2225        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2226        match deserialized {
2227            McpServer::Http(McpServerHttp {
2228                name,
2229                url,
2230                headers,
2231                meta: _,
2232            }) => {
2233                assert_eq!(name, "http-server");
2234                assert_eq!(url, "https://api.example.com");
2235                assert_eq!(headers.len(), 2);
2236                assert_eq!(headers[0].name, "Authorization");
2237                assert_eq!(headers[0].value, "Bearer token123");
2238                assert_eq!(headers[1].name, "Content-Type");
2239                assert_eq!(headers[1].value, "application/json");
2240            }
2241            _ => panic!("Expected Http variant"),
2242        }
2243    }
2244
2245    #[test]
2246    fn test_mcp_server_sse_serialization() {
2247        let server = McpServer::Sse(
2248            McpServerSse::new("sse-server", "https://sse.example.com/events")
2249                .headers(vec![HttpHeader::new("X-API-Key", "apikey456")]),
2250        );
2251
2252        let json = serde_json::to_value(&server).unwrap();
2253        assert_eq!(
2254            json,
2255            json!({
2256                "type": "sse",
2257                "name": "sse-server",
2258                "url": "https://sse.example.com/events",
2259                "headers": [
2260                    {
2261                        "name": "X-API-Key",
2262                        "value": "apikey456"
2263                    }
2264                ]
2265            })
2266        );
2267
2268        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2269        match deserialized {
2270            McpServer::Sse(McpServerSse {
2271                name,
2272                url,
2273                headers,
2274                meta: _,
2275            }) => {
2276                assert_eq!(name, "sse-server");
2277                assert_eq!(url, "https://sse.example.com/events");
2278                assert_eq!(headers.len(), 1);
2279                assert_eq!(headers[0].name, "X-API-Key");
2280                assert_eq!(headers[0].value, "apikey456");
2281            }
2282            _ => panic!("Expected Sse variant"),
2283        }
2284    }
2285}