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#[non_exhaustive]
965pub enum McpServer {
966    /// HTTP transport configuration
967    ///
968    /// Only available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.
969    Http(McpServerHttp),
970    /// SSE transport configuration
971    ///
972    /// Only available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.
973    Sse(McpServerSse),
974    /// Stdio transport configuration
975    ///
976    /// All Agents MUST support this transport.
977    #[serde(untagged)]
978    Stdio(McpServerStdio),
979}
980
981/// HTTP transport configuration for MCP.
982#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
983#[serde(rename_all = "camelCase")]
984#[non_exhaustive]
985pub struct McpServerHttp {
986    /// Human-readable name identifying this MCP server.
987    pub name: String,
988    /// URL to the MCP server.
989    pub url: String,
990    /// HTTP headers to set when making requests to the MCP server.
991    pub headers: Vec<HttpHeader>,
992    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
993    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
994    /// these keys.
995    ///
996    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
997    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
998    pub meta: Option<Meta>,
999}
1000
1001impl McpServerHttp {
1002    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1003        Self {
1004            name: name.into(),
1005            url: url.into(),
1006            headers: Vec::new(),
1007            meta: None,
1008        }
1009    }
1010
1011    /// HTTP headers to set when making requests to the MCP server.
1012    #[must_use]
1013    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1014        self.headers = headers;
1015        self
1016    }
1017
1018    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1019    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1020    /// these keys.
1021    ///
1022    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1023    #[must_use]
1024    pub fn meta(mut self, meta: Meta) -> Self {
1025        self.meta = Some(meta);
1026        self
1027    }
1028}
1029
1030/// SSE transport configuration for MCP.
1031#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1032#[serde(rename_all = "camelCase")]
1033#[non_exhaustive]
1034pub struct McpServerSse {
1035    /// Human-readable name identifying this MCP server.
1036    pub name: String,
1037    /// URL to the MCP server.
1038    pub url: String,
1039    /// HTTP headers to set when making requests to the MCP server.
1040    pub headers: Vec<HttpHeader>,
1041    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1042    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1043    /// these keys.
1044    ///
1045    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1046    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1047    pub meta: Option<Meta>,
1048}
1049
1050impl McpServerSse {
1051    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1052        Self {
1053            name: name.into(),
1054            url: url.into(),
1055            headers: Vec::new(),
1056            meta: None,
1057        }
1058    }
1059
1060    /// HTTP headers to set when making requests to the MCP server.
1061    #[must_use]
1062    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1063        self.headers = headers;
1064        self
1065    }
1066
1067    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1068    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1069    /// these keys.
1070    ///
1071    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1072    #[must_use]
1073    pub fn meta(mut self, meta: Meta) -> Self {
1074        self.meta = Some(meta);
1075        self
1076    }
1077}
1078
1079/// Stdio transport configuration for MCP.
1080#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1081#[serde(rename_all = "camelCase")]
1082#[non_exhaustive]
1083pub struct McpServerStdio {
1084    /// Human-readable name identifying this MCP server.
1085    pub name: String,
1086    /// Path to the MCP server executable.
1087    pub command: PathBuf,
1088    /// Command-line arguments to pass to the MCP server.
1089    pub args: Vec<String>,
1090    /// Environment variables to set when launching the MCP server.
1091    pub env: Vec<EnvVariable>,
1092    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1093    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1094    /// these keys.
1095    ///
1096    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1097    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1098    pub meta: Option<Meta>,
1099}
1100
1101impl McpServerStdio {
1102    pub fn new(name: impl Into<String>, command: impl Into<PathBuf>) -> Self {
1103        Self {
1104            name: name.into(),
1105            command: command.into(),
1106            args: Vec::new(),
1107            env: Vec::new(),
1108            meta: None,
1109        }
1110    }
1111
1112    /// Command-line arguments to pass to the MCP server.
1113    #[must_use]
1114    pub fn args(mut self, args: Vec<String>) -> Self {
1115        self.args = args;
1116        self
1117    }
1118
1119    /// Environment variables to set when launching the MCP server.
1120    #[must_use]
1121    pub fn env(mut self, env: Vec<EnvVariable>) -> Self {
1122        self.env = env;
1123        self
1124    }
1125
1126    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1127    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1128    /// these keys.
1129    ///
1130    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1131    #[must_use]
1132    pub fn meta(mut self, meta: Meta) -> Self {
1133        self.meta = Some(meta);
1134        self
1135    }
1136}
1137
1138/// An environment variable to set when launching an MCP server.
1139#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1140#[serde(rename_all = "camelCase")]
1141#[non_exhaustive]
1142pub struct EnvVariable {
1143    /// The name of the environment variable.
1144    pub name: String,
1145    /// The value to set for the environment variable.
1146    pub value: String,
1147    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1148    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1149    /// these keys.
1150    ///
1151    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1152    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1153    pub meta: Option<Meta>,
1154}
1155
1156impl EnvVariable {
1157    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1158        Self {
1159            name: name.into(),
1160            value: value.into(),
1161            meta: None,
1162        }
1163    }
1164
1165    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1166    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1167    /// these keys.
1168    ///
1169    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1170    #[must_use]
1171    pub fn meta(mut self, meta: Meta) -> Self {
1172        self.meta = Some(meta);
1173        self
1174    }
1175}
1176
1177/// An HTTP header to set when making requests to the MCP server.
1178#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1179#[serde(rename_all = "camelCase")]
1180#[non_exhaustive]
1181pub struct HttpHeader {
1182    /// The name of the HTTP header.
1183    pub name: String,
1184    /// The value to set for the HTTP header.
1185    pub value: String,
1186    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1187    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1188    /// these keys.
1189    ///
1190    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1191    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1192    pub meta: Option<Meta>,
1193}
1194
1195impl HttpHeader {
1196    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1197        Self {
1198            name: name.into(),
1199            value: value.into(),
1200            meta: None,
1201        }
1202    }
1203
1204    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1205    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1206    /// these keys.
1207    ///
1208    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1209    #[must_use]
1210    pub fn meta(mut self, meta: Meta) -> Self {
1211        self.meta = Some(meta);
1212        self
1213    }
1214}
1215
1216// Prompt
1217
1218/// Request parameters for sending a user prompt to the agent.
1219///
1220/// Contains the user's message and any additional context.
1221///
1222/// See protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)
1223#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
1224#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1225#[serde(rename_all = "camelCase")]
1226#[non_exhaustive]
1227pub struct PromptRequest {
1228    /// The ID of the session to send this user message to
1229    pub session_id: SessionId,
1230    /// The blocks of content that compose the user's message.
1231    ///
1232    /// As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],
1233    /// while other variants are optionally enabled via [`PromptCapabilities`].
1234    ///
1235    /// The Client MUST adapt its interface according to [`PromptCapabilities`].
1236    ///
1237    /// The client MAY include referenced pieces of context as either
1238    /// [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].
1239    ///
1240    /// When available, [`ContentBlock::Resource`] is preferred
1241    /// as it avoids extra round-trips and allows the message to include
1242    /// pieces of context from sources the agent may not have access to.
1243    pub prompt: Vec<ContentBlock>,
1244    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1245    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1246    /// these keys.
1247    ///
1248    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1249    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1250    pub meta: Option<Meta>,
1251}
1252
1253impl PromptRequest {
1254    #[must_use]
1255    pub fn new(session_id: impl Into<SessionId>, prompt: Vec<ContentBlock>) -> Self {
1256        Self {
1257            session_id: session_id.into(),
1258            prompt,
1259            meta: None,
1260        }
1261    }
1262
1263    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1264    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1265    /// these keys.
1266    ///
1267    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1268    #[must_use]
1269    pub fn meta(mut self, meta: Meta) -> Self {
1270        self.meta = Some(meta);
1271        self
1272    }
1273}
1274
1275/// Response from processing a user prompt.
1276///
1277/// See protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)
1278#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1279#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1280#[serde(rename_all = "camelCase")]
1281#[non_exhaustive]
1282pub struct PromptResponse {
1283    /// Indicates why the agent stopped processing the turn.
1284    pub stop_reason: StopReason,
1285    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1286    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1287    /// these keys.
1288    ///
1289    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1290    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1291    pub meta: Option<Meta>,
1292}
1293
1294impl PromptResponse {
1295    #[must_use]
1296    pub fn new(stop_reason: StopReason) -> Self {
1297        Self {
1298            stop_reason,
1299            meta: None,
1300        }
1301    }
1302
1303    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1304    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1305    /// these keys.
1306    ///
1307    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1308    #[must_use]
1309    pub fn meta(mut self, meta: Meta) -> Self {
1310        self.meta = Some(meta);
1311        self
1312    }
1313}
1314
1315/// Reasons why an agent stops processing a prompt turn.
1316///
1317/// See protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)
1318#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1319#[serde(rename_all = "snake_case")]
1320#[non_exhaustive]
1321pub enum StopReason {
1322    /// The turn ended successfully.
1323    EndTurn,
1324    /// The turn ended because the agent reached the maximum number of tokens.
1325    MaxTokens,
1326    /// The turn ended because the agent reached the maximum number of allowed
1327    /// agent requests between user turns.
1328    MaxTurnRequests,
1329    /// The turn ended because the agent refused to continue. The user prompt
1330    /// and everything that comes after it won't be included in the next
1331    /// prompt, so this should be reflected in the UI.
1332    Refusal,
1333    /// The turn was cancelled by the client via `session/cancel`.
1334    ///
1335    /// This stop reason MUST be returned when the client sends a `session/cancel`
1336    /// notification, even if the cancellation causes exceptions in underlying operations.
1337    /// Agents should catch these exceptions and return this semantically meaningful
1338    /// response to confirm successful cancellation.
1339    Cancelled,
1340}
1341
1342// Model
1343
1344/// **UNSTABLE**
1345///
1346/// This capability is not part of the spec yet, and may be removed or changed at any point.
1347///
1348/// The set of models and the one currently active.
1349#[cfg(feature = "unstable_session_model")]
1350#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1351#[serde(rename_all = "camelCase")]
1352#[non_exhaustive]
1353pub struct SessionModelState {
1354    /// The current model the Agent is in.
1355    pub current_model_id: ModelId,
1356    /// The set of models that the Agent can use
1357    pub available_models: Vec<ModelInfo>,
1358    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1359    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1360    /// these keys.
1361    ///
1362    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1363    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1364    pub meta: Option<Meta>,
1365}
1366
1367#[cfg(feature = "unstable_session_model")]
1368impl SessionModelState {
1369    #[must_use]
1370    pub fn new(current_model_id: impl Into<ModelId>, available_models: Vec<ModelInfo>) -> Self {
1371        Self {
1372            current_model_id: current_model_id.into(),
1373            available_models,
1374            meta: None,
1375        }
1376    }
1377
1378    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1379    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1380    /// these keys.
1381    ///
1382    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1383    #[must_use]
1384    pub fn meta(mut self, meta: Meta) -> Self {
1385        self.meta = Some(meta);
1386        self
1387    }
1388}
1389
1390/// **UNSTABLE**
1391///
1392/// This capability is not part of the spec yet, and may be removed or changed at any point.
1393///
1394/// A unique identifier for a model.
1395#[cfg(feature = "unstable_session_model")]
1396#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
1397#[serde(transparent)]
1398#[from(Arc<str>, String, &'static str)]
1399#[non_exhaustive]
1400pub struct ModelId(pub Arc<str>);
1401
1402#[cfg(feature = "unstable_session_model")]
1403impl ModelId {
1404    pub fn new(id: impl Into<Arc<str>>) -> Self {
1405        Self(id.into())
1406    }
1407}
1408
1409/// **UNSTABLE**
1410///
1411/// This capability is not part of the spec yet, and may be removed or changed at any point.
1412///
1413/// Information about a selectable model.
1414#[cfg(feature = "unstable_session_model")]
1415#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1416#[serde(rename_all = "camelCase")]
1417#[non_exhaustive]
1418pub struct ModelInfo {
1419    /// Unique identifier for the model.
1420    pub model_id: ModelId,
1421    /// Human-readable name of the model.
1422    pub name: String,
1423    /// Optional description of the model.
1424    #[serde(default, skip_serializing_if = "Option::is_none")]
1425    pub description: Option<String>,
1426    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1427    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1428    /// these keys.
1429    ///
1430    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1431    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1432    pub meta: Option<Meta>,
1433}
1434
1435#[cfg(feature = "unstable_session_model")]
1436impl ModelInfo {
1437    pub fn new(model_id: impl Into<ModelId>, name: impl Into<String>) -> Self {
1438        Self {
1439            model_id: model_id.into(),
1440            name: name.into(),
1441            description: None,
1442            meta: None,
1443        }
1444    }
1445
1446    /// Optional description of the model.
1447    #[must_use]
1448    pub fn description(mut self, description: impl Into<String>) -> Self {
1449        self.description = Some(description.into());
1450        self
1451    }
1452
1453    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1454    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1455    /// these keys.
1456    ///
1457    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1458    #[must_use]
1459    pub fn meta(mut self, meta: Meta) -> Self {
1460        self.meta = Some(meta);
1461        self
1462    }
1463}
1464
1465/// **UNSTABLE**
1466///
1467/// This capability is not part of the spec yet, and may be removed or changed at any point.
1468///
1469/// Request parameters for setting a session model.
1470#[cfg(feature = "unstable_session_model")]
1471#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1472#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1473#[serde(rename_all = "camelCase")]
1474#[non_exhaustive]
1475pub struct SetSessionModelRequest {
1476    /// The ID of the session to set the model for.
1477    pub session_id: SessionId,
1478    /// The ID of the model to set.
1479    pub model_id: ModelId,
1480    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1481    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1482    /// these keys.
1483    ///
1484    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1485    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1486    pub meta: Option<Meta>,
1487}
1488
1489#[cfg(feature = "unstable_session_model")]
1490impl SetSessionModelRequest {
1491    #[must_use]
1492    pub fn new(session_id: impl Into<SessionId>, model_id: impl Into<ModelId>) -> Self {
1493        Self {
1494            session_id: session_id.into(),
1495            model_id: model_id.into(),
1496            meta: None,
1497        }
1498    }
1499
1500    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1501    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1502    /// these keys.
1503    ///
1504    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1505    #[must_use]
1506    pub fn meta(mut self, meta: Meta) -> Self {
1507        self.meta = Some(meta);
1508        self
1509    }
1510}
1511
1512/// **UNSTABLE**
1513///
1514/// This capability is not part of the spec yet, and may be removed or changed at any point.
1515///
1516/// Response to `session/set_model` method.
1517#[cfg(feature = "unstable_session_model")]
1518#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1519#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1520#[serde(rename_all = "camelCase")]
1521#[non_exhaustive]
1522pub struct SetSessionModelResponse {
1523    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1524    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1525    /// these keys.
1526    ///
1527    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1528    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1529    pub meta: Option<Meta>,
1530}
1531
1532#[cfg(feature = "unstable_session_model")]
1533impl SetSessionModelResponse {
1534    #[must_use]
1535    pub fn new() -> Self {
1536        Self::default()
1537    }
1538
1539    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1540    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1541    /// these keys.
1542    ///
1543    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1544    #[must_use]
1545    pub fn meta(mut self, meta: Meta) -> Self {
1546        self.meta = Some(meta);
1547        self
1548    }
1549}
1550
1551// Capabilities
1552
1553/// Capabilities supported by the agent.
1554///
1555/// Advertised during initialization to inform the client about
1556/// available features and content types.
1557///
1558/// See protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)
1559#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1560#[serde(rename_all = "camelCase")]
1561#[non_exhaustive]
1562pub struct AgentCapabilities {
1563    /// Whether the agent supports `session/load`.
1564    #[serde(default)]
1565    pub load_session: bool,
1566    /// Prompt capabilities supported by the agent.
1567    #[serde(default)]
1568    pub prompt_capabilities: PromptCapabilities,
1569    /// MCP capabilities supported by the agent.
1570    #[serde(default)]
1571    pub mcp_capabilities: McpCapabilities,
1572    #[serde(default)]
1573    pub session_capabilities: SessionCapabilities,
1574    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1575    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1576    /// these keys.
1577    ///
1578    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1579    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1580    pub meta: Option<Meta>,
1581}
1582
1583impl AgentCapabilities {
1584    #[must_use]
1585    pub fn new() -> Self {
1586        Self::default()
1587    }
1588
1589    /// Whether the agent supports `session/load`.
1590    #[must_use]
1591    pub fn load_session(mut self, load_session: bool) -> Self {
1592        self.load_session = load_session;
1593        self
1594    }
1595
1596    /// Prompt capabilities supported by the agent.
1597    #[must_use]
1598    pub fn prompt_capabilities(mut self, prompt_capabilities: PromptCapabilities) -> Self {
1599        self.prompt_capabilities = prompt_capabilities;
1600        self
1601    }
1602
1603    /// MCP capabilities supported by the agent.
1604    #[must_use]
1605    pub fn mcp_capabilities(mut self, mcp_capabilities: McpCapabilities) -> Self {
1606        self.mcp_capabilities = mcp_capabilities;
1607        self
1608    }
1609
1610    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1611    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1612    /// these keys.
1613    ///
1614    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1615    #[must_use]
1616    pub fn meta(mut self, meta: Meta) -> Self {
1617        self.meta = Some(meta);
1618        self
1619    }
1620}
1621
1622/// Session capabilities supported by the agent.
1623///
1624/// As a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.
1625///
1626/// Optionally, they **MAY** support other session methods and notifications by specifying additional capabilities.
1627///
1628/// Note: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.
1629///
1630/// See protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)
1631#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1632#[non_exhaustive]
1633pub struct SessionCapabilities {
1634    /// **UNSTABLE**
1635    ///
1636    /// This capability is not part of the spec yet, and may be removed or changed at any point.
1637    ///
1638    /// Whether the agent supports `session/list`.
1639    #[cfg(feature = "unstable_session_list")]
1640    #[serde(skip_serializing_if = "Option::is_none")]
1641    pub list: Option<SessionListCapabilities>,
1642    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1643    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1644    /// these keys.
1645    ///
1646    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1647    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1648    pub meta: Option<Meta>,
1649}
1650
1651impl SessionCapabilities {
1652    #[must_use]
1653    pub fn new() -> Self {
1654        Self::default()
1655    }
1656
1657    #[cfg(feature = "unstable_session_list")]
1658    /// Whether the agent supports `session/list`.
1659    #[must_use]
1660    pub fn list(mut self, list: SessionListCapabilities) -> Self {
1661        self.list = Some(list);
1662        self
1663    }
1664
1665    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1666    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1667    /// these keys.
1668    ///
1669    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1670    #[must_use]
1671    pub fn meta(mut self, meta: Meta) -> Self {
1672        self.meta = Some(meta);
1673        self
1674    }
1675}
1676
1677/// Capabilities for the `session/list` method.
1678///
1679/// By supplying `{}` it means that the agent supports listing of sessions.
1680///
1681/// Further capabilities can be added in the future for other means of filtering or searching the list.
1682#[cfg(feature = "unstable_session_list")]
1683#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1684#[non_exhaustive]
1685pub struct SessionListCapabilities {
1686    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1687    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1688    /// these keys.
1689    ///
1690    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1691    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1692    pub meta: Option<Meta>,
1693}
1694
1695#[cfg(feature = "unstable_session_list")]
1696impl SessionListCapabilities {
1697    #[must_use]
1698    pub fn new() -> Self {
1699        Self::default()
1700    }
1701    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1702    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1703    /// these keys.
1704    ///
1705    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1706    #[must_use]
1707    pub fn meta(mut self, meta: Meta) -> Self {
1708        self.meta = Some(meta);
1709        self
1710    }
1711}
1712
1713/// Prompt capabilities supported by the agent in `session/prompt` requests.
1714///
1715/// Baseline agent functionality requires support for [`ContentBlock::Text`]
1716/// and [`ContentBlock::ResourceLink`] in prompt requests.
1717///
1718/// Other variants must be explicitly opted in to.
1719/// Capabilities for different types of content in prompt requests.
1720///
1721/// Indicates which content types beyond the baseline (text and resource links)
1722/// the agent can process.
1723///
1724/// See protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)
1725#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1726#[serde(rename_all = "camelCase")]
1727#[non_exhaustive]
1728pub struct PromptCapabilities {
1729    /// Agent supports [`ContentBlock::Image`].
1730    #[serde(default)]
1731    pub image: bool,
1732    /// Agent supports [`ContentBlock::Audio`].
1733    #[serde(default)]
1734    pub audio: bool,
1735    /// Agent supports embedded context in `session/prompt` requests.
1736    ///
1737    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
1738    /// in prompt requests for pieces of context that are referenced in the message.
1739    #[serde(default)]
1740    pub embedded_context: bool,
1741    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1742    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1743    /// these keys.
1744    ///
1745    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1746    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1747    pub meta: Option<Meta>,
1748}
1749
1750impl PromptCapabilities {
1751    #[must_use]
1752    pub fn new() -> Self {
1753        Self::default()
1754    }
1755
1756    /// Agent supports [`ContentBlock::Image`].
1757    #[must_use]
1758    pub fn image(mut self, image: bool) -> Self {
1759        self.image = image;
1760        self
1761    }
1762
1763    /// Agent supports [`ContentBlock::Audio`].
1764    #[must_use]
1765    pub fn audio(mut self, audio: bool) -> Self {
1766        self.audio = audio;
1767        self
1768    }
1769
1770    /// Agent supports embedded context in `session/prompt` requests.
1771    ///
1772    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
1773    /// in prompt requests for pieces of context that are referenced in the message.
1774    #[must_use]
1775    pub fn embedded_context(mut self, embedded_context: bool) -> Self {
1776        self.embedded_context = embedded_context;
1777        self
1778    }
1779
1780    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1781    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1782    /// these keys.
1783    ///
1784    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1785    #[must_use]
1786    pub fn meta(mut self, meta: Meta) -> Self {
1787        self.meta = Some(meta);
1788        self
1789    }
1790}
1791
1792/// MCP capabilities supported by the agent
1793#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1794#[serde(rename_all = "camelCase")]
1795#[non_exhaustive]
1796pub struct McpCapabilities {
1797    /// Agent supports [`McpServer::Http`].
1798    #[serde(default)]
1799    pub http: bool,
1800    /// Agent supports [`McpServer::Sse`].
1801    #[serde(default)]
1802    pub sse: bool,
1803    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1804    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1805    /// these keys.
1806    ///
1807    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1808    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1809    pub meta: Option<Meta>,
1810}
1811
1812impl McpCapabilities {
1813    #[must_use]
1814    pub fn new() -> Self {
1815        Self::default()
1816    }
1817
1818    /// Agent supports [`McpServer::Http`].
1819    #[must_use]
1820    pub fn http(mut self, http: bool) -> Self {
1821        self.http = http;
1822        self
1823    }
1824
1825    /// Agent supports [`McpServer::Sse`].
1826    #[must_use]
1827    pub fn sse(mut self, sse: bool) -> Self {
1828        self.sse = sse;
1829        self
1830    }
1831
1832    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1833    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1834    /// these keys.
1835    ///
1836    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1837    #[must_use]
1838    pub fn meta(mut self, meta: Meta) -> Self {
1839        self.meta = Some(meta);
1840        self
1841    }
1842}
1843
1844// Method schema
1845
1846/// Names of all methods that agents handle.
1847///
1848/// Provides a centralized definition of method names used in the protocol.
1849#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1850#[non_exhaustive]
1851pub struct AgentMethodNames {
1852    /// Method for initializing the connection.
1853    pub initialize: &'static str,
1854    /// Method for authenticating with the agent.
1855    pub authenticate: &'static str,
1856    /// Method for creating a new session.
1857    pub session_new: &'static str,
1858    /// Method for loading an existing session.
1859    pub session_load: &'static str,
1860    /// Method for setting the mode for a session.
1861    pub session_set_mode: &'static str,
1862    /// Method for sending a prompt to the agent.
1863    pub session_prompt: &'static str,
1864    /// Notification for cancelling operations.
1865    pub session_cancel: &'static str,
1866    /// Method for selecting a model for a given session.
1867    #[cfg(feature = "unstable_session_model")]
1868    pub session_set_model: &'static str,
1869    /// Method for listing existing sessions.
1870    #[cfg(feature = "unstable_session_list")]
1871    pub session_list: &'static str,
1872}
1873
1874/// Constant containing all agent method names.
1875pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
1876    initialize: INITIALIZE_METHOD_NAME,
1877    authenticate: AUTHENTICATE_METHOD_NAME,
1878    session_new: SESSION_NEW_METHOD_NAME,
1879    session_load: SESSION_LOAD_METHOD_NAME,
1880    session_set_mode: SESSION_SET_MODE_METHOD_NAME,
1881    session_prompt: SESSION_PROMPT_METHOD_NAME,
1882    session_cancel: SESSION_CANCEL_METHOD_NAME,
1883    #[cfg(feature = "unstable_session_model")]
1884    session_set_model: SESSION_SET_MODEL_METHOD_NAME,
1885    #[cfg(feature = "unstable_session_list")]
1886    session_list: SESSION_LIST_METHOD_NAME,
1887};
1888
1889/// Method name for the initialize request.
1890pub(crate) const INITIALIZE_METHOD_NAME: &str = "initialize";
1891/// Method name for the authenticate request.
1892pub(crate) const AUTHENTICATE_METHOD_NAME: &str = "authenticate";
1893/// Method name for creating a new session.
1894pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
1895/// Method name for loading an existing session.
1896pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
1897/// Method name for setting the mode for a session.
1898pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
1899/// Method name for sending a prompt.
1900pub(crate) const SESSION_PROMPT_METHOD_NAME: &str = "session/prompt";
1901/// Method name for the cancel notification.
1902pub(crate) const SESSION_CANCEL_METHOD_NAME: &str = "session/cancel";
1903/// Method name for selecting a model for a given session.
1904#[cfg(feature = "unstable_session_model")]
1905pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
1906/// Method name for listing existing sessions.
1907#[cfg(feature = "unstable_session_list")]
1908pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list";
1909
1910/// All possible requests that a client can send to an agent.
1911///
1912/// This enum is used internally for routing RPC requests. You typically won't need
1913/// to use this directly - instead, use the methods on the [`Agent`] trait.
1914///
1915/// This enum encompasses all method calls from client to agent.
1916#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
1917#[serde(untagged)]
1918#[schemars(inline)]
1919#[non_exhaustive]
1920pub enum ClientRequest {
1921    /// Establishes the connection with a client and negotiates protocol capabilities.
1922    ///
1923    /// This method is called once at the beginning of the connection to:
1924    /// - Negotiate the protocol version to use
1925    /// - Exchange capability information between client and agent
1926    /// - Determine available authentication methods
1927    ///
1928    /// The agent should respond with its supported protocol version and capabilities.
1929    ///
1930    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
1931    InitializeRequest(InitializeRequest),
1932    /// Authenticates the client using the specified authentication method.
1933    ///
1934    /// Called when the agent requires authentication before allowing session creation.
1935    /// The client provides the authentication method ID that was advertised during initialization.
1936    ///
1937    /// After successful authentication, the client can proceed to create sessions with
1938    /// `new_session` without receiving an `auth_required` error.
1939    ///
1940    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
1941    AuthenticateRequest(AuthenticateRequest),
1942    /// Creates a new conversation session with the agent.
1943    ///
1944    /// Sessions represent independent conversation contexts with their own history and state.
1945    ///
1946    /// The agent should:
1947    /// - Create a new session context
1948    /// - Connect to any specified MCP servers
1949    /// - Return a unique session ID for future requests
1950    ///
1951    /// May return an `auth_required` error if the agent requires authentication.
1952    ///
1953    /// See protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)
1954    NewSessionRequest(NewSessionRequest),
1955    /// Loads an existing session to resume a previous conversation.
1956    ///
1957    /// This method is only available if the agent advertises the `loadSession` capability.
1958    ///
1959    /// The agent should:
1960    /// - Restore the session context and conversation history
1961    /// - Connect to the specified MCP servers
1962    /// - Stream the entire conversation history back to the client via notifications
1963    ///
1964    /// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
1965    LoadSessionRequest(LoadSessionRequest),
1966    #[cfg(feature = "unstable_session_list")]
1967    /// **UNSTABLE**
1968    ///
1969    /// This capability is not part of the spec yet, and may be removed or changed at any point.
1970    ///
1971    /// Lists existing sessions known to the agent.
1972    ///
1973    /// This method is only available if the agent advertises the `listSessions` capability.
1974    ///
1975    /// The agent should return metadata about sessions with optional filtering and pagination support.
1976    ListSessionsRequest(ListSessionsRequest),
1977    /// Sets the current mode for a session.
1978    ///
1979    /// Allows switching between different agent modes (e.g., "ask", "architect", "code")
1980    /// that affect system prompts, tool availability, and permission behaviors.
1981    ///
1982    /// The mode must be one of the modes advertised in `availableModes` during session
1983    /// creation or loading. Agents may also change modes autonomously and notify the
1984    /// client via `current_mode_update` notifications.
1985    ///
1986    /// This method can be called at any time during a session, whether the Agent is
1987    /// idle or actively generating a response.
1988    ///
1989    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
1990    SetSessionModeRequest(SetSessionModeRequest),
1991    /// Processes a user prompt within a session.
1992    ///
1993    /// This method handles the whole lifecycle of a prompt:
1994    /// - Receives user messages with optional context (files, images, etc.)
1995    /// - Processes the prompt using language models
1996    /// - Reports language model content and tool calls to the Clients
1997    /// - Requests permission to run tools
1998    /// - Executes any requested tool calls
1999    /// - Returns when the turn is complete with a stop reason
2000    ///
2001    /// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
2002    PromptRequest(PromptRequest),
2003    #[cfg(feature = "unstable_session_model")]
2004    /// **UNSTABLE**
2005    ///
2006    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2007    ///
2008    /// Select a model for a given session.
2009    SetSessionModelRequest(SetSessionModelRequest),
2010    /// Handles extension method requests from the client.
2011    ///
2012    /// Extension methods provide a way to add custom functionality while maintaining
2013    /// protocol compatibility.
2014    ///
2015    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2016    ExtMethodRequest(ExtRequest),
2017}
2018
2019impl ClientRequest {
2020    /// Returns the corresponding method name of the request.
2021    #[must_use]
2022    pub fn method(&self) -> &str {
2023        match self {
2024            Self::InitializeRequest(_) => AGENT_METHOD_NAMES.initialize,
2025            Self::AuthenticateRequest(_) => AGENT_METHOD_NAMES.authenticate,
2026            Self::NewSessionRequest(_) => AGENT_METHOD_NAMES.session_new,
2027            Self::LoadSessionRequest(_) => AGENT_METHOD_NAMES.session_load,
2028            #[cfg(feature = "unstable_session_list")]
2029            Self::ListSessionsRequest(_) => AGENT_METHOD_NAMES.session_list,
2030            Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode,
2031            Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt,
2032            #[cfg(feature = "unstable_session_model")]
2033            Self::SetSessionModelRequest(_) => AGENT_METHOD_NAMES.session_set_model,
2034            Self::ExtMethodRequest(ext_request) => &ext_request.method,
2035        }
2036    }
2037}
2038
2039/// All possible responses that an agent can send to a client.
2040///
2041/// This enum is used internally for routing RPC responses. You typically won't need
2042/// to use this directly - the responses are handled automatically by the connection.
2043///
2044/// These are responses to the corresponding `ClientRequest` variants.
2045#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2046#[serde(untagged)]
2047#[schemars(inline)]
2048#[non_exhaustive]
2049pub enum AgentResponse {
2050    InitializeResponse(InitializeResponse),
2051    AuthenticateResponse(#[serde(default)] AuthenticateResponse),
2052    NewSessionResponse(NewSessionResponse),
2053    LoadSessionResponse(#[serde(default)] LoadSessionResponse),
2054    #[cfg(feature = "unstable_session_list")]
2055    ListSessionsResponse(ListSessionsResponse),
2056    SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
2057    PromptResponse(PromptResponse),
2058    #[cfg(feature = "unstable_session_model")]
2059    SetSessionModelResponse(SetSessionModelResponse),
2060    ExtMethodResponse(ExtResponse),
2061}
2062
2063/// All possible notifications that a client can send to an agent.
2064///
2065/// This enum is used internally for routing RPC notifications. You typically won't need
2066/// to use this directly - use the notification methods on the [`Agent`] trait instead.
2067///
2068/// Notifications do not expect a response.
2069#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2070#[serde(untagged)]
2071#[schemars(inline)]
2072#[non_exhaustive]
2073pub enum ClientNotification {
2074    /// Cancels ongoing operations for a session.
2075    ///
2076    /// This is a notification sent by the client to cancel an ongoing prompt turn.
2077    ///
2078    /// Upon receiving this notification, the Agent SHOULD:
2079    /// - Stop all language model requests as soon as possible
2080    /// - Abort all tool call invocations in progress
2081    /// - Send any pending `session/update` notifications
2082    /// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
2083    ///
2084    /// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
2085    CancelNotification(CancelNotification),
2086    /// Handles extension notifications from the client.
2087    ///
2088    /// Extension notifications provide a way to send one-way messages for custom functionality
2089    /// while maintaining protocol compatibility.
2090    ///
2091    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2092    ExtNotification(ExtNotification),
2093}
2094
2095impl ClientNotification {
2096    /// Returns the corresponding method name of the notification.
2097    #[must_use]
2098    pub fn method(&self) -> &str {
2099        match self {
2100            Self::CancelNotification(_) => AGENT_METHOD_NAMES.session_cancel,
2101            Self::ExtNotification(ext_notification) => &ext_notification.method,
2102        }
2103    }
2104}
2105
2106/// Notification to cancel ongoing operations for a session.
2107///
2108/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
2109#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2110#[schemars(extend("x-side" = "agent", "x-method" = SESSION_CANCEL_METHOD_NAME))]
2111#[serde(rename_all = "camelCase")]
2112#[non_exhaustive]
2113pub struct CancelNotification {
2114    /// The ID of the session to cancel operations for.
2115    pub session_id: SessionId,
2116    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2117    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2118    /// these keys.
2119    ///
2120    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2121    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2122    pub meta: Option<Meta>,
2123}
2124
2125impl CancelNotification {
2126    #[must_use]
2127    pub fn new(session_id: impl Into<SessionId>) -> Self {
2128        Self {
2129            session_id: session_id.into(),
2130            meta: None,
2131        }
2132    }
2133
2134    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2135    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2136    /// these keys.
2137    ///
2138    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2139    #[must_use]
2140    pub fn meta(mut self, meta: Meta) -> Self {
2141        self.meta = Some(meta);
2142        self
2143    }
2144}
2145
2146#[cfg(test)]
2147mod test_serialization {
2148    use super::*;
2149    use serde_json::json;
2150
2151    #[test]
2152    fn test_mcp_server_stdio_serialization() {
2153        let server = McpServer::Stdio(
2154            McpServerStdio::new("test-server", "/usr/bin/server")
2155                .args(vec!["--port".to_string(), "3000".to_string()])
2156                .env(vec![EnvVariable::new("API_KEY", "secret123")]),
2157        );
2158
2159        let json = serde_json::to_value(&server).unwrap();
2160        assert_eq!(
2161            json,
2162            json!({
2163                "name": "test-server",
2164                "command": "/usr/bin/server",
2165                "args": ["--port", "3000"],
2166                "env": [
2167                    {
2168                        "name": "API_KEY",
2169                        "value": "secret123"
2170                    }
2171                ]
2172            })
2173        );
2174
2175        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2176        match deserialized {
2177            McpServer::Stdio(McpServerStdio {
2178                name,
2179                command,
2180                args,
2181                env,
2182                meta: _,
2183            }) => {
2184                assert_eq!(name, "test-server");
2185                assert_eq!(command, PathBuf::from("/usr/bin/server"));
2186                assert_eq!(args, vec!["--port", "3000"]);
2187                assert_eq!(env.len(), 1);
2188                assert_eq!(env[0].name, "API_KEY");
2189                assert_eq!(env[0].value, "secret123");
2190            }
2191            _ => panic!("Expected Stdio variant"),
2192        }
2193    }
2194
2195    #[test]
2196    fn test_mcp_server_http_serialization() {
2197        let server = McpServer::Http(
2198            McpServerHttp::new("http-server", "https://api.example.com").headers(vec![
2199                HttpHeader::new("Authorization", "Bearer token123"),
2200                HttpHeader::new("Content-Type", "application/json"),
2201            ]),
2202        );
2203
2204        let json = serde_json::to_value(&server).unwrap();
2205        assert_eq!(
2206            json,
2207            json!({
2208                "type": "http",
2209                "name": "http-server",
2210                "url": "https://api.example.com",
2211                "headers": [
2212                    {
2213                        "name": "Authorization",
2214                        "value": "Bearer token123"
2215                    },
2216                    {
2217                        "name": "Content-Type",
2218                        "value": "application/json"
2219                    }
2220                ]
2221            })
2222        );
2223
2224        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2225        match deserialized {
2226            McpServer::Http(McpServerHttp {
2227                name,
2228                url,
2229                headers,
2230                meta: _,
2231            }) => {
2232                assert_eq!(name, "http-server");
2233                assert_eq!(url, "https://api.example.com");
2234                assert_eq!(headers.len(), 2);
2235                assert_eq!(headers[0].name, "Authorization");
2236                assert_eq!(headers[0].value, "Bearer token123");
2237                assert_eq!(headers[1].name, "Content-Type");
2238                assert_eq!(headers[1].value, "application/json");
2239            }
2240            _ => panic!("Expected Http variant"),
2241        }
2242    }
2243
2244    #[test]
2245    fn test_mcp_server_sse_serialization() {
2246        let server = McpServer::Sse(
2247            McpServerSse::new("sse-server", "https://sse.example.com/events")
2248                .headers(vec![HttpHeader::new("X-API-Key", "apikey456")]),
2249        );
2250
2251        let json = serde_json::to_value(&server).unwrap();
2252        assert_eq!(
2253            json,
2254            json!({
2255                "type": "sse",
2256                "name": "sse-server",
2257                "url": "https://sse.example.com/events",
2258                "headers": [
2259                    {
2260                        "name": "X-API-Key",
2261                        "value": "apikey456"
2262                    }
2263                ]
2264            })
2265        );
2266
2267        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2268        match deserialized {
2269            McpServer::Sse(McpServerSse {
2270                name,
2271                url,
2272                headers,
2273                meta: _,
2274            }) => {
2275                assert_eq!(name, "sse-server");
2276                assert_eq!(url, "https://sse.example.com/events");
2277                assert_eq!(headers.len(), 1);
2278                assert_eq!(headers[0].name, "X-API-Key");
2279                assert_eq!(headers[0].value, "apikey456");
2280            }
2281            _ => panic!("Expected Sse variant"),
2282        }
2283    }
2284}