agent_client_protocol_schema/
agent.rs

1//! Methods and notifications the agent handles/receives.
2//!
3//! This module defines the Agent trait and all associated types for implementing
4//! an AI coding agent that follows the Agent Client Protocol (ACP).
5
6use std::{path::PathBuf, sync::Arc};
7
8use derive_more::{Display, From};
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11
12use crate::{
13    ClientCapabilities, ContentBlock, ExtNotification, ExtRequest, ExtResponse, IntoOption, Meta,
14    ProtocolVersion, SessionId,
15};
16
17// Initialize
18
19/// Request parameters for the initialize method.
20///
21/// Sent by the client to establish connection and negotiate capabilities.
22///
23/// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
24#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
25#[schemars(extend("x-side" = "agent", "x-method" = INITIALIZE_METHOD_NAME))]
26#[serde(rename_all = "camelCase")]
27#[non_exhaustive]
28pub struct InitializeRequest {
29    /// The latest protocol version supported by the client.
30    pub protocol_version: ProtocolVersion,
31    /// Capabilities supported by the client.
32    #[serde(default)]
33    pub client_capabilities: ClientCapabilities,
34    /// Information about the Client name and version sent to the Agent.
35    ///
36    /// Note: in future versions of the protocol, this will be required.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub client_info: Option<Implementation>,
39    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
40    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
41    /// these keys.
42    ///
43    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
44    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
45    pub meta: Option<Meta>,
46}
47
48impl InitializeRequest {
49    #[must_use]
50    pub fn new(protocol_version: ProtocolVersion) -> Self {
51        Self {
52            protocol_version,
53            client_capabilities: ClientCapabilities::default(),
54            client_info: None,
55            meta: None,
56        }
57    }
58
59    /// Capabilities supported by the client.
60    #[must_use]
61    pub fn client_capabilities(mut self, client_capabilities: ClientCapabilities) -> Self {
62        self.client_capabilities = client_capabilities;
63        self
64    }
65
66    /// Information about the Client name and version sent to the Agent.
67    #[must_use]
68    pub fn client_info(mut self, client_info: impl IntoOption<Implementation>) -> Self {
69        self.client_info = client_info.into_option();
70        self
71    }
72
73    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
74    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
75    /// these keys.
76    ///
77    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
78    #[must_use]
79    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
80        self.meta = meta.into_option();
81        self
82    }
83}
84
85/// Response to the `initialize` method.
86///
87/// Contains the negotiated protocol version and agent capabilities.
88///
89/// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
90#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
91#[schemars(extend("x-side" = "agent", "x-method" = INITIALIZE_METHOD_NAME))]
92#[serde(rename_all = "camelCase")]
93#[non_exhaustive]
94pub struct InitializeResponse {
95    /// The protocol version the client specified if supported by the agent,
96    /// or the latest protocol version supported by the agent.
97    ///
98    /// The client should disconnect, if it doesn't support this version.
99    pub protocol_version: ProtocolVersion,
100    /// Capabilities supported by the agent.
101    #[serde(default)]
102    pub agent_capabilities: AgentCapabilities,
103    /// Authentication methods supported by the agent.
104    #[serde(default)]
105    pub auth_methods: Vec<AuthMethod>,
106    /// Information about the Agent name and version sent to the Client.
107    ///
108    /// Note: in future versions of the protocol, this will be required.
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub agent_info: Option<Implementation>,
111    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
112    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
113    /// these keys.
114    ///
115    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
116    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
117    pub meta: Option<Meta>,
118}
119
120impl InitializeResponse {
121    #[must_use]
122    pub fn new(protocol_version: ProtocolVersion) -> Self {
123        Self {
124            protocol_version,
125            agent_capabilities: AgentCapabilities::default(),
126            auth_methods: vec![],
127            agent_info: None,
128            meta: None,
129        }
130    }
131
132    /// Capabilities supported by the agent.
133    #[must_use]
134    pub fn agent_capabilities(mut self, agent_capabilities: AgentCapabilities) -> Self {
135        self.agent_capabilities = agent_capabilities;
136        self
137    }
138
139    /// Authentication methods supported by the agent.
140    #[must_use]
141    pub fn auth_methods(mut self, auth_methods: Vec<AuthMethod>) -> Self {
142        self.auth_methods = auth_methods;
143        self
144    }
145
146    /// Information about the Agent name and version sent to the Client.
147    #[must_use]
148    pub fn agent_info(mut self, agent_info: impl IntoOption<Implementation>) -> Self {
149        self.agent_info = agent_info.into_option();
150        self
151    }
152
153    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
154    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
155    /// these keys.
156    ///
157    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
158    #[must_use]
159    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
160        self.meta = meta.into_option();
161        self
162    }
163}
164
165/// Metadata about the implementation of the client or agent.
166/// Describes the name and version of an MCP implementation, with an optional
167/// title for UI representation.
168#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
169#[serde(rename_all = "camelCase")]
170#[non_exhaustive]
171pub struct Implementation {
172    /// Intended for programmatic or logical use, but can be used as a display
173    /// name fallback if title isn’t present.
174    pub name: String,
175    /// Intended for UI and end-user contexts — optimized to be human-readable
176    /// and easily understood.
177    ///
178    /// If not provided, the name should be used for display.
179    pub title: Option<String>,
180    /// Version of the implementation. Can be displayed to the user or used
181    /// for debugging or metrics purposes. (e.g. "1.0.0").
182    pub version: String,
183    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
184    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
185    /// these keys.
186    ///
187    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
188    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
189    pub meta: Option<Meta>,
190}
191
192impl Implementation {
193    pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
194        Self {
195            name: name.into(),
196            title: None,
197            version: version.into(),
198            meta: None,
199        }
200    }
201
202    /// Intended for UI and end-user contexts — optimized to be human-readable
203    /// and easily understood.
204    ///
205    /// If not provided, the name should be used for display.
206    #[must_use]
207    pub fn title(mut self, title: impl IntoOption<String>) -> Self {
208        self.title = title.into_option();
209        self
210    }
211
212    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
213    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
214    /// these keys.
215    ///
216    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
217    #[must_use]
218    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
219        self.meta = meta.into_option();
220        self
221    }
222}
223
224// Authentication
225
226/// Request parameters for the authenticate method.
227///
228/// Specifies which authentication method to use.
229#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
230#[schemars(extend("x-side" = "agent", "x-method" = AUTHENTICATE_METHOD_NAME))]
231#[serde(rename_all = "camelCase")]
232#[non_exhaustive]
233pub struct AuthenticateRequest {
234    /// The ID of the authentication method to use.
235    /// Must be one of the methods advertised in the initialize response.
236    pub method_id: AuthMethodId,
237    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
238    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
239    /// these keys.
240    ///
241    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
242    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
243    pub meta: Option<Meta>,
244}
245
246impl AuthenticateRequest {
247    #[must_use]
248    pub fn new(method_id: impl Into<AuthMethodId>) -> Self {
249        Self {
250            method_id: method_id.into(),
251            meta: None,
252        }
253    }
254
255    #[must_use]
256    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
257        self.meta = meta.into_option();
258        self
259    }
260}
261
262/// Response to the `authenticate` method.
263#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
264#[serde(rename_all = "camelCase")]
265#[schemars(extend("x-side" = "agent", "x-method" = AUTHENTICATE_METHOD_NAME))]
266#[non_exhaustive]
267pub struct AuthenticateResponse {
268    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
269    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
270    /// these keys.
271    ///
272    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
273    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
274    pub meta: Option<Meta>,
275}
276
277impl AuthenticateResponse {
278    #[must_use]
279    pub fn new() -> Self {
280        Self::default()
281    }
282
283    #[must_use]
284    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
285        self.meta = meta.into_option();
286        self
287    }
288}
289
290#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
291#[serde(transparent)]
292#[from(Arc<str>, String, &'static str)]
293#[non_exhaustive]
294pub struct AuthMethodId(pub Arc<str>);
295
296impl AuthMethodId {
297    pub fn new(id: impl Into<Arc<str>>) -> Self {
298        Self(id.into())
299    }
300}
301
302/// Describes an available authentication method.
303#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
304#[serde(rename_all = "camelCase")]
305#[non_exhaustive]
306pub struct AuthMethod {
307    /// Unique identifier for this authentication method.
308    pub id: AuthMethodId,
309    /// Human-readable name of the authentication method.
310    pub name: String,
311    /// Optional description providing more details about this authentication method.
312    pub description: Option<String>,
313    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
314    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
315    /// these keys.
316    ///
317    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
318    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
319    pub meta: Option<Meta>,
320}
321
322impl AuthMethod {
323    pub fn new(id: impl Into<AuthMethodId>, name: impl Into<String>) -> Self {
324        Self {
325            id: id.into(),
326            name: name.into(),
327            description: None,
328            meta: None,
329        }
330    }
331
332    /// Optional description providing more details about this authentication method.
333    #[must_use]
334    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
335        self.description = description.into_option();
336        self
337    }
338
339    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
340    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
341    /// these keys.
342    ///
343    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
344    #[must_use]
345    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
346        self.meta = meta.into_option();
347        self
348    }
349}
350
351// New session
352
353/// Request parameters for creating a new session.
354///
355/// See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)
356#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
357#[schemars(extend("x-side" = "agent", "x-method" = SESSION_NEW_METHOD_NAME))]
358#[serde(rename_all = "camelCase")]
359#[non_exhaustive]
360pub struct NewSessionRequest {
361    /// The working directory for this session. Must be an absolute path.
362    pub cwd: PathBuf,
363    /// List of MCP (Model Context Protocol) servers the agent should connect to.
364    pub mcp_servers: Vec<McpServer>,
365    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
366    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
367    /// these keys.
368    ///
369    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
370    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
371    pub meta: Option<Meta>,
372}
373
374impl NewSessionRequest {
375    pub fn new(cwd: impl Into<PathBuf>) -> Self {
376        Self {
377            cwd: cwd.into(),
378            mcp_servers: vec![],
379            meta: None,
380        }
381    }
382
383    /// List of MCP (Model Context Protocol) servers the agent should connect to.
384    #[must_use]
385    pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
386        self.mcp_servers = mcp_servers;
387        self
388    }
389
390    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
391    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
392    /// these keys.
393    ///
394    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
395    #[must_use]
396    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
397        self.meta = meta.into_option();
398        self
399    }
400}
401
402/// Response from creating a new session.
403///
404/// See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)
405#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
406#[schemars(extend("x-side" = "agent", "x-method" = SESSION_NEW_METHOD_NAME))]
407#[serde(rename_all = "camelCase")]
408#[non_exhaustive]
409pub struct NewSessionResponse {
410    /// Unique identifier for the created session.
411    ///
412    /// Used in all subsequent requests for this conversation.
413    pub session_id: SessionId,
414    /// Initial mode state if supported by the Agent
415    ///
416    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
417    #[serde(skip_serializing_if = "Option::is_none")]
418    pub modes: Option<SessionModeState>,
419    /// **UNSTABLE**
420    ///
421    /// This capability is not part of the spec yet, and may be removed or changed at any point.
422    ///
423    /// Initial model state if supported by the Agent
424    #[cfg(feature = "unstable_session_model")]
425    #[serde(skip_serializing_if = "Option::is_none")]
426    pub models: Option<SessionModelState>,
427    /// 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: impl IntoOption<SessionModeState>) -> Self {
453        self.modes = modes.into_option();
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: impl IntoOption<SessionModelState>) -> Self {
465        self.models = models.into_option();
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: impl IntoOption<Meta>) -> Self {
476        self.meta = meta.into_option();
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: impl IntoOption<Meta>) -> Self {
532        self.meta = meta.into_option();
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: impl IntoOption<SessionModeState>) -> Self {
576        self.modes = modes.into_option();
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: impl IntoOption<SessionModelState>) -> Self {
588        self.models = models.into_option();
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: impl IntoOption<Meta>) -> Self {
599        self.meta = meta.into_option();
600        self
601    }
602}
603
604// Fork session
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 forking an existing session.
611///
612/// Creates a new session based on the context of an existing one, allowing
613/// operations like generating summaries without affecting the original session's history.
614///
615/// Only available if the Agent supports the `session.fork` capability.
616#[cfg(feature = "unstable_session_fork")]
617#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
618#[schemars(extend("x-side" = "agent", "x-method" = SESSION_FORK_METHOD_NAME))]
619#[serde(rename_all = "camelCase")]
620#[non_exhaustive]
621pub struct ForkSessionRequest {
622    /// The ID of the session to fork.
623    pub session_id: SessionId,
624    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
625    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
626    /// these keys.
627    ///
628    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
629    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
630    pub meta: Option<Meta>,
631}
632
633#[cfg(feature = "unstable_session_fork")]
634impl ForkSessionRequest {
635    pub fn new(session_id: impl Into<SessionId>) -> Self {
636        Self {
637            session_id: session_id.into(),
638            meta: None,
639        }
640    }
641
642    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
643    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
644    /// these keys.
645    ///
646    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
647    #[must_use]
648    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
649        self.meta = meta.into_option();
650        self
651    }
652}
653
654/// **UNSTABLE**
655///
656/// This capability is not part of the spec yet, and may be removed or changed at any point.
657///
658/// Response from forking an existing session.
659#[cfg(feature = "unstable_session_fork")]
660#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
661#[schemars(extend("x-side" = "agent", "x-method" = SESSION_FORK_METHOD_NAME))]
662#[serde(rename_all = "camelCase")]
663#[non_exhaustive]
664pub struct ForkSessionResponse {
665    /// Unique identifier for the newly created forked session.
666    pub session_id: SessionId,
667    /// Initial mode state if supported by the Agent
668    ///
669    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
670    #[serde(skip_serializing_if = "Option::is_none")]
671    pub modes: Option<SessionModeState>,
672    /// **UNSTABLE**
673    ///
674    /// This capability is not part of the spec yet, and may be removed or changed at any point.
675    ///
676    /// Initial model state if supported by the Agent
677    #[cfg(feature = "unstable_session_model")]
678    #[serde(skip_serializing_if = "Option::is_none")]
679    pub models: Option<SessionModelState>,
680    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
681    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
682    /// these keys.
683    ///
684    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
685    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
686    pub meta: Option<Meta>,
687}
688
689#[cfg(feature = "unstable_session_fork")]
690impl ForkSessionResponse {
691    #[must_use]
692    pub fn new(session_id: impl Into<SessionId>) -> Self {
693        Self {
694            session_id: session_id.into(),
695            modes: None,
696            #[cfg(feature = "unstable_session_model")]
697            models: None,
698            meta: None,
699        }
700    }
701
702    /// Initial mode state if supported by the Agent
703    ///
704    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
705    #[must_use]
706    pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
707        self.modes = modes.into_option();
708        self
709    }
710
711    /// **UNSTABLE**
712    ///
713    /// This capability is not part of the spec yet, and may be removed or changed at any point.
714    ///
715    /// Initial model state if supported by the Agent
716    #[cfg(feature = "unstable_session_model")]
717    #[must_use]
718    pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
719        self.models = models.into_option();
720        self
721    }
722
723    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
724    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
725    /// these keys.
726    ///
727    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
728    #[must_use]
729    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
730        self.meta = meta.into_option();
731        self
732    }
733}
734
735// List sessions
736
737/// **UNSTABLE**
738///
739/// This capability is not part of the spec yet, and may be removed or changed at any point.
740///
741/// Request parameters for listing existing sessions.
742///
743/// Only available if the Agent supports the `listSessions` capability.
744#[cfg(feature = "unstable_session_list")]
745#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
746#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
747#[serde(rename_all = "camelCase")]
748#[non_exhaustive]
749pub struct ListSessionsRequest {
750    /// Filter sessions by working directory. Must be an absolute path.
751    #[serde(skip_serializing_if = "Option::is_none")]
752    pub cwd: Option<PathBuf>,
753    /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
754    #[serde(skip_serializing_if = "Option::is_none")]
755    pub cursor: Option<String>,
756    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
757    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
758    /// these keys.
759    ///
760    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
761    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
762    pub meta: Option<Meta>,
763}
764
765#[cfg(feature = "unstable_session_list")]
766impl ListSessionsRequest {
767    #[must_use]
768    pub fn new() -> Self {
769        Self::default()
770    }
771
772    /// Filter sessions by working directory. Must be an absolute path.
773    #[must_use]
774    pub fn cwd(mut self, cwd: impl IntoOption<PathBuf>) -> Self {
775        self.cwd = cwd.into_option();
776        self
777    }
778
779    /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
780    #[must_use]
781    pub fn cursor(mut self, cursor: impl IntoOption<String>) -> Self {
782        self.cursor = cursor.into_option();
783        self
784    }
785
786    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
787    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
788    /// these keys.
789    ///
790    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
791    #[must_use]
792    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
793        self.meta = meta.into_option();
794        self
795    }
796}
797
798/// **UNSTABLE**
799///
800/// This capability is not part of the spec yet, and may be removed or changed at any point.
801///
802/// Response from listing sessions.
803#[cfg(feature = "unstable_session_list")]
804#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
805#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
806#[serde(rename_all = "camelCase")]
807#[non_exhaustive]
808pub struct ListSessionsResponse {
809    /// Array of session information objects
810    pub sessions: Vec<SessionInfo>,
811    /// Opaque cursor token. If present, pass this in the next request's cursor parameter
812    /// to fetch the next page. If absent, there are no more results.
813    #[serde(skip_serializing_if = "Option::is_none")]
814    pub next_cursor: Option<String>,
815    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
816    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
817    /// these keys.
818    ///
819    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
820    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
821    pub meta: Option<Meta>,
822}
823
824#[cfg(feature = "unstable_session_list")]
825impl ListSessionsResponse {
826    #[must_use]
827    pub fn new(sessions: Vec<SessionInfo>) -> Self {
828        Self {
829            sessions,
830            next_cursor: None,
831            meta: None,
832        }
833    }
834
835    #[must_use]
836    pub fn next_cursor(mut self, next_cursor: impl IntoOption<String>) -> Self {
837        self.next_cursor = next_cursor.into_option();
838        self
839    }
840
841    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
842    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
843    /// these keys.
844    ///
845    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
846    #[must_use]
847    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
848        self.meta = meta.into_option();
849        self
850    }
851}
852
853/// **UNSTABLE**
854///
855/// This capability is not part of the spec yet, and may be removed or changed at any point.
856///
857/// Information about a session returned by session/list
858#[cfg(feature = "unstable_session_list")]
859#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
860#[serde(rename_all = "camelCase")]
861#[non_exhaustive]
862pub struct SessionInfo {
863    /// Unique identifier for the session
864    pub session_id: SessionId,
865    /// The working directory for this session. Must be an absolute path.
866    pub cwd: PathBuf,
867    /// Human-readable title for the session
868    #[serde(skip_serializing_if = "Option::is_none")]
869    pub title: Option<String>,
870    /// ISO 8601 timestamp of last activity
871    #[serde(skip_serializing_if = "Option::is_none")]
872    pub updated_at: Option<String>,
873    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
874    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
875    /// these keys.
876    ///
877    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
878    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
879    pub meta: Option<Meta>,
880}
881
882#[cfg(feature = "unstable_session_list")]
883impl SessionInfo {
884    pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
885        Self {
886            session_id: session_id.into(),
887            cwd: cwd.into(),
888            title: None,
889            updated_at: None,
890            meta: None,
891        }
892    }
893
894    /// Human-readable title for the session
895    #[must_use]
896    pub fn title(mut self, title: impl IntoOption<String>) -> Self {
897        self.title = title.into_option();
898        self
899    }
900
901    /// ISO 8601 timestamp of last activity
902    #[must_use]
903    pub fn updated_at(mut self, updated_at: impl IntoOption<String>) -> Self {
904        self.updated_at = updated_at.into_option();
905        self
906    }
907
908    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
909    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
910    /// these keys.
911    ///
912    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
913    #[must_use]
914    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
915        self.meta = meta.into_option();
916        self
917    }
918}
919
920// Session modes
921
922/// The set of modes and the one currently active.
923#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
924#[serde(rename_all = "camelCase")]
925#[non_exhaustive]
926pub struct SessionModeState {
927    /// The current mode the Agent is in.
928    pub current_mode_id: SessionModeId,
929    /// The set of modes that the Agent can operate in
930    pub available_modes: Vec<SessionMode>,
931    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
932    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
933    /// these keys.
934    ///
935    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
936    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
937    pub meta: Option<Meta>,
938}
939
940impl SessionModeState {
941    #[must_use]
942    pub fn new(
943        current_mode_id: impl Into<SessionModeId>,
944        available_modes: Vec<SessionMode>,
945    ) -> Self {
946        Self {
947            current_mode_id: current_mode_id.into(),
948            available_modes,
949            meta: None,
950        }
951    }
952
953    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
954    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
955    /// these keys.
956    ///
957    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
958    #[must_use]
959    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
960        self.meta = meta.into_option();
961        self
962    }
963}
964
965/// A mode the agent can operate in.
966///
967/// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
968#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
969#[serde(rename_all = "camelCase")]
970#[non_exhaustive]
971pub struct SessionMode {
972    pub id: SessionModeId,
973    pub name: String,
974    #[serde(default, skip_serializing_if = "Option::is_none")]
975    pub description: Option<String>,
976    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
977    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
978    /// these keys.
979    ///
980    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
981    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
982    pub meta: Option<Meta>,
983}
984
985impl SessionMode {
986    pub fn new(id: impl Into<SessionModeId>, name: impl Into<String>) -> Self {
987        Self {
988            id: id.into(),
989            name: name.into(),
990            description: None,
991            meta: None,
992        }
993    }
994
995    #[must_use]
996    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
997        self.description = description.into_option();
998        self
999    }
1000
1001    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1002    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1003    /// these keys.
1004    ///
1005    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1006    #[must_use]
1007    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1008        self.meta = meta.into_option();
1009        self
1010    }
1011}
1012
1013/// Unique identifier for a Session Mode.
1014#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1015#[serde(transparent)]
1016#[from(Arc<str>, String, &'static str)]
1017#[non_exhaustive]
1018pub struct SessionModeId(pub Arc<str>);
1019
1020impl SessionModeId {
1021    pub fn new(id: impl Into<Arc<str>>) -> Self {
1022        Self(id.into())
1023    }
1024}
1025
1026/// Request parameters for setting a session mode.
1027#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1028#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
1029#[serde(rename_all = "camelCase")]
1030#[non_exhaustive]
1031pub struct SetSessionModeRequest {
1032    /// The ID of the session to set the mode for.
1033    pub session_id: SessionId,
1034    /// The ID of the mode to set.
1035    pub mode_id: SessionModeId,
1036    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1037    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1038    /// these keys.
1039    ///
1040    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1041    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1042    pub meta: Option<Meta>,
1043}
1044
1045impl SetSessionModeRequest {
1046    #[must_use]
1047    pub fn new(session_id: impl Into<SessionId>, mode_id: impl Into<SessionModeId>) -> Self {
1048        Self {
1049            session_id: session_id.into(),
1050            mode_id: mode_id.into(),
1051            meta: None,
1052        }
1053    }
1054
1055    #[must_use]
1056    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1057        self.meta = meta.into_option();
1058        self
1059    }
1060}
1061
1062/// Response to `session/set_mode` method.
1063#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1064#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
1065#[serde(rename_all = "camelCase")]
1066#[non_exhaustive]
1067pub struct SetSessionModeResponse {
1068    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1069    pub meta: Option<Meta>,
1070}
1071
1072impl SetSessionModeResponse {
1073    #[must_use]
1074    pub fn new() -> Self {
1075        Self::default()
1076    }
1077
1078    #[must_use]
1079    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1080        self.meta = meta.into_option();
1081        self
1082    }
1083}
1084
1085// MCP
1086
1087/// Configuration for connecting to an MCP (Model Context Protocol) server.
1088///
1089/// MCP servers provide tools and context that the agent can use when
1090/// processing prompts.
1091///
1092/// See protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)
1093#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1094#[serde(tag = "type", rename_all = "snake_case")]
1095#[non_exhaustive]
1096pub enum McpServer {
1097    /// HTTP transport configuration
1098    ///
1099    /// Only available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.
1100    Http(McpServerHttp),
1101    /// SSE transport configuration
1102    ///
1103    /// Only available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.
1104    Sse(McpServerSse),
1105    /// Stdio transport configuration
1106    ///
1107    /// All Agents MUST support this transport.
1108    #[serde(untagged)]
1109    Stdio(McpServerStdio),
1110}
1111
1112/// HTTP transport configuration for MCP.
1113#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1114#[serde(rename_all = "camelCase")]
1115#[non_exhaustive]
1116pub struct McpServerHttp {
1117    /// Human-readable name identifying this MCP server.
1118    pub name: String,
1119    /// URL to the MCP server.
1120    pub url: String,
1121    /// HTTP headers to set when making requests to the MCP server.
1122    pub headers: Vec<HttpHeader>,
1123    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1124    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1125    /// these keys.
1126    ///
1127    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1128    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1129    pub meta: Option<Meta>,
1130}
1131
1132impl McpServerHttp {
1133    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1134        Self {
1135            name: name.into(),
1136            url: url.into(),
1137            headers: Vec::new(),
1138            meta: None,
1139        }
1140    }
1141
1142    /// HTTP headers to set when making requests to the MCP server.
1143    #[must_use]
1144    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1145        self.headers = headers;
1146        self
1147    }
1148
1149    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1150    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1151    /// these keys.
1152    ///
1153    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1154    #[must_use]
1155    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1156        self.meta = meta.into_option();
1157        self
1158    }
1159}
1160
1161/// SSE transport configuration for MCP.
1162#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1163#[serde(rename_all = "camelCase")]
1164#[non_exhaustive]
1165pub struct McpServerSse {
1166    /// Human-readable name identifying this MCP server.
1167    pub name: String,
1168    /// URL to the MCP server.
1169    pub url: String,
1170    /// HTTP headers to set when making requests to the MCP server.
1171    pub headers: Vec<HttpHeader>,
1172    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1173    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1174    /// these keys.
1175    ///
1176    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1177    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1178    pub meta: Option<Meta>,
1179}
1180
1181impl McpServerSse {
1182    pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1183        Self {
1184            name: name.into(),
1185            url: url.into(),
1186            headers: Vec::new(),
1187            meta: None,
1188        }
1189    }
1190
1191    /// HTTP headers to set when making requests to the MCP server.
1192    #[must_use]
1193    pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1194        self.headers = headers;
1195        self
1196    }
1197
1198    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1199    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1200    /// these keys.
1201    ///
1202    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1203    #[must_use]
1204    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1205        self.meta = meta.into_option();
1206        self
1207    }
1208}
1209
1210/// Stdio transport configuration for MCP.
1211#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1212#[serde(rename_all = "camelCase")]
1213#[non_exhaustive]
1214pub struct McpServerStdio {
1215    /// Human-readable name identifying this MCP server.
1216    pub name: String,
1217    /// Path to the MCP server executable.
1218    pub command: PathBuf,
1219    /// Command-line arguments to pass to the MCP server.
1220    pub args: Vec<String>,
1221    /// Environment variables to set when launching the MCP server.
1222    pub env: Vec<EnvVariable>,
1223    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1224    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1225    /// these keys.
1226    ///
1227    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1228    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1229    pub meta: Option<Meta>,
1230}
1231
1232impl McpServerStdio {
1233    pub fn new(name: impl Into<String>, command: impl Into<PathBuf>) -> Self {
1234        Self {
1235            name: name.into(),
1236            command: command.into(),
1237            args: Vec::new(),
1238            env: Vec::new(),
1239            meta: None,
1240        }
1241    }
1242
1243    /// Command-line arguments to pass to the MCP server.
1244    #[must_use]
1245    pub fn args(mut self, args: Vec<String>) -> Self {
1246        self.args = args;
1247        self
1248    }
1249
1250    /// Environment variables to set when launching the MCP server.
1251    #[must_use]
1252    pub fn env(mut self, env: Vec<EnvVariable>) -> Self {
1253        self.env = env;
1254        self
1255    }
1256
1257    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1258    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1259    /// these keys.
1260    ///
1261    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1262    #[must_use]
1263    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1264        self.meta = meta.into_option();
1265        self
1266    }
1267}
1268
1269/// An environment variable to set when launching an MCP server.
1270#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1271#[serde(rename_all = "camelCase")]
1272#[non_exhaustive]
1273pub struct EnvVariable {
1274    /// The name of the environment variable.
1275    pub name: String,
1276    /// The value to set for the environment variable.
1277    pub value: String,
1278    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1279    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1280    /// these keys.
1281    ///
1282    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1283    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1284    pub meta: Option<Meta>,
1285}
1286
1287impl EnvVariable {
1288    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1289        Self {
1290            name: name.into(),
1291            value: value.into(),
1292            meta: None,
1293        }
1294    }
1295
1296    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1297    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1298    /// these keys.
1299    ///
1300    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1301    #[must_use]
1302    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1303        self.meta = meta.into_option();
1304        self
1305    }
1306}
1307
1308/// An HTTP header to set when making requests to the MCP server.
1309#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1310#[serde(rename_all = "camelCase")]
1311#[non_exhaustive]
1312pub struct HttpHeader {
1313    /// The name of the HTTP header.
1314    pub name: String,
1315    /// The value to set for the HTTP header.
1316    pub value: String,
1317    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1318    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1319    /// these keys.
1320    ///
1321    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1322    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1323    pub meta: Option<Meta>,
1324}
1325
1326impl HttpHeader {
1327    pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1328        Self {
1329            name: name.into(),
1330            value: value.into(),
1331            meta: None,
1332        }
1333    }
1334
1335    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1336    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1337    /// these keys.
1338    ///
1339    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1340    #[must_use]
1341    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1342        self.meta = meta.into_option();
1343        self
1344    }
1345}
1346
1347// Prompt
1348
1349/// Request parameters for sending a user prompt to the agent.
1350///
1351/// Contains the user's message and any additional context.
1352///
1353/// See protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)
1354#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
1355#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1356#[serde(rename_all = "camelCase")]
1357#[non_exhaustive]
1358pub struct PromptRequest {
1359    /// The ID of the session to send this user message to
1360    pub session_id: SessionId,
1361    /// The blocks of content that compose the user's message.
1362    ///
1363    /// As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],
1364    /// while other variants are optionally enabled via [`PromptCapabilities`].
1365    ///
1366    /// The Client MUST adapt its interface according to [`PromptCapabilities`].
1367    ///
1368    /// The client MAY include referenced pieces of context as either
1369    /// [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].
1370    ///
1371    /// When available, [`ContentBlock::Resource`] is preferred
1372    /// as it avoids extra round-trips and allows the message to include
1373    /// pieces of context from sources the agent may not have access to.
1374    pub prompt: Vec<ContentBlock>,
1375    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1376    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1377    /// these keys.
1378    ///
1379    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1380    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1381    pub meta: Option<Meta>,
1382}
1383
1384impl PromptRequest {
1385    #[must_use]
1386    pub fn new(session_id: impl Into<SessionId>, prompt: Vec<ContentBlock>) -> Self {
1387        Self {
1388            session_id: session_id.into(),
1389            prompt,
1390            meta: None,
1391        }
1392    }
1393
1394    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1395    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1396    /// these keys.
1397    ///
1398    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1399    #[must_use]
1400    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1401        self.meta = meta.into_option();
1402        self
1403    }
1404}
1405
1406/// Response from processing a user prompt.
1407///
1408/// See protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)
1409#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1410#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1411#[serde(rename_all = "camelCase")]
1412#[non_exhaustive]
1413pub struct PromptResponse {
1414    /// Indicates why the agent stopped processing the turn.
1415    pub stop_reason: StopReason,
1416    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1417    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1418    /// these keys.
1419    ///
1420    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1421    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1422    pub meta: Option<Meta>,
1423}
1424
1425impl PromptResponse {
1426    #[must_use]
1427    pub fn new(stop_reason: StopReason) -> Self {
1428        Self {
1429            stop_reason,
1430            meta: None,
1431        }
1432    }
1433
1434    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1435    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1436    /// these keys.
1437    ///
1438    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1439    #[must_use]
1440    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1441        self.meta = meta.into_option();
1442        self
1443    }
1444}
1445
1446/// Reasons why an agent stops processing a prompt turn.
1447///
1448/// See protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)
1449#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1450#[serde(rename_all = "snake_case")]
1451#[non_exhaustive]
1452pub enum StopReason {
1453    /// The turn ended successfully.
1454    EndTurn,
1455    /// The turn ended because the agent reached the maximum number of tokens.
1456    MaxTokens,
1457    /// The turn ended because the agent reached the maximum number of allowed
1458    /// agent requests between user turns.
1459    MaxTurnRequests,
1460    /// The turn ended because the agent refused to continue. The user prompt
1461    /// and everything that comes after it won't be included in the next
1462    /// prompt, so this should be reflected in the UI.
1463    Refusal,
1464    /// The turn was cancelled by the client via `session/cancel`.
1465    ///
1466    /// This stop reason MUST be returned when the client sends a `session/cancel`
1467    /// notification, even if the cancellation causes exceptions in underlying operations.
1468    /// Agents should catch these exceptions and return this semantically meaningful
1469    /// response to confirm successful cancellation.
1470    Cancelled,
1471}
1472
1473// Model
1474
1475/// **UNSTABLE**
1476///
1477/// This capability is not part of the spec yet, and may be removed or changed at any point.
1478///
1479/// The set of models and the one currently active.
1480#[cfg(feature = "unstable_session_model")]
1481#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1482#[serde(rename_all = "camelCase")]
1483#[non_exhaustive]
1484pub struct SessionModelState {
1485    /// The current model the Agent is in.
1486    pub current_model_id: ModelId,
1487    /// The set of models that the Agent can use
1488    pub available_models: Vec<ModelInfo>,
1489    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1490    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1491    /// these keys.
1492    ///
1493    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1494    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1495    pub meta: Option<Meta>,
1496}
1497
1498#[cfg(feature = "unstable_session_model")]
1499impl SessionModelState {
1500    #[must_use]
1501    pub fn new(current_model_id: impl Into<ModelId>, available_models: Vec<ModelInfo>) -> Self {
1502        Self {
1503            current_model_id: current_model_id.into(),
1504            available_models,
1505            meta: None,
1506        }
1507    }
1508
1509    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1510    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1511    /// these keys.
1512    ///
1513    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1514    #[must_use]
1515    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1516        self.meta = meta.into_option();
1517        self
1518    }
1519}
1520
1521/// **UNSTABLE**
1522///
1523/// This capability is not part of the spec yet, and may be removed or changed at any point.
1524///
1525/// A unique identifier for a model.
1526#[cfg(feature = "unstable_session_model")]
1527#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
1528#[serde(transparent)]
1529#[from(Arc<str>, String, &'static str)]
1530#[non_exhaustive]
1531pub struct ModelId(pub Arc<str>);
1532
1533#[cfg(feature = "unstable_session_model")]
1534impl ModelId {
1535    pub fn new(id: impl Into<Arc<str>>) -> Self {
1536        Self(id.into())
1537    }
1538}
1539
1540/// **UNSTABLE**
1541///
1542/// This capability is not part of the spec yet, and may be removed or changed at any point.
1543///
1544/// Information about a selectable model.
1545#[cfg(feature = "unstable_session_model")]
1546#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1547#[serde(rename_all = "camelCase")]
1548#[non_exhaustive]
1549pub struct ModelInfo {
1550    /// Unique identifier for the model.
1551    pub model_id: ModelId,
1552    /// Human-readable name of the model.
1553    pub name: String,
1554    /// Optional description of the model.
1555    #[serde(default, skip_serializing_if = "Option::is_none")]
1556    pub description: Option<String>,
1557    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1558    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1559    /// these keys.
1560    ///
1561    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1562    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1563    pub meta: Option<Meta>,
1564}
1565
1566#[cfg(feature = "unstable_session_model")]
1567impl ModelInfo {
1568    pub fn new(model_id: impl Into<ModelId>, name: impl Into<String>) -> Self {
1569        Self {
1570            model_id: model_id.into(),
1571            name: name.into(),
1572            description: None,
1573            meta: None,
1574        }
1575    }
1576
1577    /// Optional description of the model.
1578    #[must_use]
1579    pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1580        self.description = description.into_option();
1581        self
1582    }
1583
1584    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1585    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1586    /// these keys.
1587    ///
1588    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1589    #[must_use]
1590    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1591        self.meta = meta.into_option();
1592        self
1593    }
1594}
1595
1596/// **UNSTABLE**
1597///
1598/// This capability is not part of the spec yet, and may be removed or changed at any point.
1599///
1600/// Request parameters for setting a session model.
1601#[cfg(feature = "unstable_session_model")]
1602#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1603#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1604#[serde(rename_all = "camelCase")]
1605#[non_exhaustive]
1606pub struct SetSessionModelRequest {
1607    /// The ID of the session to set the model for.
1608    pub session_id: SessionId,
1609    /// The ID of the model to set.
1610    pub model_id: ModelId,
1611    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1612    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1613    /// these keys.
1614    ///
1615    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1616    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1617    pub meta: Option<Meta>,
1618}
1619
1620#[cfg(feature = "unstable_session_model")]
1621impl SetSessionModelRequest {
1622    #[must_use]
1623    pub fn new(session_id: impl Into<SessionId>, model_id: impl Into<ModelId>) -> Self {
1624        Self {
1625            session_id: session_id.into(),
1626            model_id: model_id.into(),
1627            meta: None,
1628        }
1629    }
1630
1631    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1632    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1633    /// these keys.
1634    ///
1635    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1636    #[must_use]
1637    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1638        self.meta = meta.into_option();
1639        self
1640    }
1641}
1642
1643/// **UNSTABLE**
1644///
1645/// This capability is not part of the spec yet, and may be removed or changed at any point.
1646///
1647/// Response to `session/set_model` method.
1648#[cfg(feature = "unstable_session_model")]
1649#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1650#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1651#[serde(rename_all = "camelCase")]
1652#[non_exhaustive]
1653pub struct SetSessionModelResponse {
1654    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1655    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1656    /// these keys.
1657    ///
1658    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1659    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1660    pub meta: Option<Meta>,
1661}
1662
1663#[cfg(feature = "unstable_session_model")]
1664impl SetSessionModelResponse {
1665    #[must_use]
1666    pub fn new() -> Self {
1667        Self::default()
1668    }
1669
1670    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1671    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1672    /// these keys.
1673    ///
1674    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1675    #[must_use]
1676    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1677        self.meta = meta.into_option();
1678        self
1679    }
1680}
1681
1682// Capabilities
1683
1684/// Capabilities supported by the agent.
1685///
1686/// Advertised during initialization to inform the client about
1687/// available features and content types.
1688///
1689/// See protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)
1690#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1691#[serde(rename_all = "camelCase")]
1692#[non_exhaustive]
1693pub struct AgentCapabilities {
1694    /// Whether the agent supports `session/load`.
1695    #[serde(default)]
1696    pub load_session: bool,
1697    /// Prompt capabilities supported by the agent.
1698    #[serde(default)]
1699    pub prompt_capabilities: PromptCapabilities,
1700    /// MCP capabilities supported by the agent.
1701    #[serde(default)]
1702    pub mcp_capabilities: McpCapabilities,
1703    #[serde(default)]
1704    pub session_capabilities: SessionCapabilities,
1705    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1706    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1707    /// these keys.
1708    ///
1709    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1710    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1711    pub meta: Option<Meta>,
1712}
1713
1714impl AgentCapabilities {
1715    #[must_use]
1716    pub fn new() -> Self {
1717        Self::default()
1718    }
1719
1720    /// Whether the agent supports `session/load`.
1721    #[must_use]
1722    pub fn load_session(mut self, load_session: bool) -> Self {
1723        self.load_session = load_session;
1724        self
1725    }
1726
1727    /// Prompt capabilities supported by the agent.
1728    #[must_use]
1729    pub fn prompt_capabilities(mut self, prompt_capabilities: PromptCapabilities) -> Self {
1730        self.prompt_capabilities = prompt_capabilities;
1731        self
1732    }
1733
1734    /// MCP capabilities supported by the agent.
1735    #[must_use]
1736    pub fn mcp_capabilities(mut self, mcp_capabilities: McpCapabilities) -> Self {
1737        self.mcp_capabilities = mcp_capabilities;
1738        self
1739    }
1740
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    #[must_use]
1747    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1748        self.meta = meta.into_option();
1749        self
1750    }
1751}
1752
1753/// Session capabilities supported by the agent.
1754///
1755/// As a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.
1756///
1757/// Optionally, they **MAY** support other session methods and notifications by specifying additional capabilities.
1758///
1759/// Note: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.
1760///
1761/// See protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)
1762#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1763#[non_exhaustive]
1764pub struct SessionCapabilities {
1765    /// **UNSTABLE**
1766    ///
1767    /// This capability is not part of the spec yet, and may be removed or changed at any point.
1768    ///
1769    /// Whether the agent supports `session/list`.
1770    #[cfg(feature = "unstable_session_list")]
1771    #[serde(skip_serializing_if = "Option::is_none")]
1772    pub list: Option<SessionListCapabilities>,
1773    /// **UNSTABLE**
1774    ///
1775    /// This capability is not part of the spec yet, and may be removed or changed at any point.
1776    ///
1777    /// Whether the agent supports `session/fork`.
1778    #[cfg(feature = "unstable_session_fork")]
1779    #[serde(skip_serializing_if = "Option::is_none")]
1780    pub fork: Option<SessionForkCapabilities>,
1781    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1782    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1783    /// these keys.
1784    ///
1785    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1786    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1787    pub meta: Option<Meta>,
1788}
1789
1790impl SessionCapabilities {
1791    #[must_use]
1792    pub fn new() -> Self {
1793        Self::default()
1794    }
1795
1796    #[cfg(feature = "unstable_session_list")]
1797    /// Whether the agent supports `session/list`.
1798    #[must_use]
1799    pub fn list(mut self, list: impl IntoOption<SessionListCapabilities>) -> Self {
1800        self.list = list.into_option();
1801        self
1802    }
1803
1804    #[cfg(feature = "unstable_session_fork")]
1805    /// Whether the agent supports `session/fork`.
1806    #[must_use]
1807    pub fn fork(mut self, fork: impl IntoOption<SessionForkCapabilities>) -> Self {
1808        self.fork = fork.into_option();
1809        self
1810    }
1811
1812    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1813    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1814    /// these keys.
1815    ///
1816    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1817    #[must_use]
1818    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1819        self.meta = meta.into_option();
1820        self
1821    }
1822}
1823
1824/// Capabilities for the `session/list` method.
1825///
1826/// By supplying `{}` it means that the agent supports listing of sessions.
1827///
1828/// Further capabilities can be added in the future for other means of filtering or searching the list.
1829#[cfg(feature = "unstable_session_list")]
1830#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1831#[non_exhaustive]
1832pub struct SessionListCapabilities {
1833    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1834    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1835    /// these keys.
1836    ///
1837    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1838    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1839    pub meta: Option<Meta>,
1840}
1841
1842#[cfg(feature = "unstable_session_list")]
1843impl SessionListCapabilities {
1844    #[must_use]
1845    pub fn new() -> Self {
1846        Self::default()
1847    }
1848    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1849    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1850    /// these keys.
1851    ///
1852    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1853    #[must_use]
1854    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1855        self.meta = meta.into_option();
1856        self
1857    }
1858}
1859
1860/// **UNSTABLE**
1861///
1862/// This capability is not part of the spec yet, and may be removed or changed at any point.
1863///
1864/// Capabilities for the `session/fork` method.
1865///
1866/// By supplying `{}` it means that the agent supports forking of sessions.
1867#[cfg(feature = "unstable_session_fork")]
1868#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1869#[non_exhaustive]
1870pub struct SessionForkCapabilities {
1871    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1872    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1873    /// these keys.
1874    ///
1875    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1876    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1877    pub meta: Option<Meta>,
1878}
1879
1880#[cfg(feature = "unstable_session_fork")]
1881impl SessionForkCapabilities {
1882    #[must_use]
1883    pub fn new() -> Self {
1884        Self::default()
1885    }
1886
1887    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1888    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1889    /// these keys.
1890    ///
1891    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1892    #[must_use]
1893    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1894        self.meta = meta.into_option();
1895        self
1896    }
1897}
1898
1899/// Prompt capabilities supported by the agent in `session/prompt` requests.
1900///
1901/// Baseline agent functionality requires support for [`ContentBlock::Text`]
1902/// and [`ContentBlock::ResourceLink`] in prompt requests.
1903///
1904/// Other variants must be explicitly opted in to.
1905/// Capabilities for different types of content in prompt requests.
1906///
1907/// Indicates which content types beyond the baseline (text and resource links)
1908/// the agent can process.
1909///
1910/// See protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)
1911#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1912#[serde(rename_all = "camelCase")]
1913#[non_exhaustive]
1914pub struct PromptCapabilities {
1915    /// Agent supports [`ContentBlock::Image`].
1916    #[serde(default)]
1917    pub image: bool,
1918    /// Agent supports [`ContentBlock::Audio`].
1919    #[serde(default)]
1920    pub audio: bool,
1921    /// Agent supports embedded context in `session/prompt` requests.
1922    ///
1923    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
1924    /// in prompt requests for pieces of context that are referenced in the message.
1925    #[serde(default)]
1926    pub embedded_context: bool,
1927    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1928    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1929    /// these keys.
1930    ///
1931    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1932    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1933    pub meta: Option<Meta>,
1934}
1935
1936impl PromptCapabilities {
1937    #[must_use]
1938    pub fn new() -> Self {
1939        Self::default()
1940    }
1941
1942    /// Agent supports [`ContentBlock::Image`].
1943    #[must_use]
1944    pub fn image(mut self, image: bool) -> Self {
1945        self.image = image;
1946        self
1947    }
1948
1949    /// Agent supports [`ContentBlock::Audio`].
1950    #[must_use]
1951    pub fn audio(mut self, audio: bool) -> Self {
1952        self.audio = audio;
1953        self
1954    }
1955
1956    /// Agent supports embedded context in `session/prompt` requests.
1957    ///
1958    /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
1959    /// in prompt requests for pieces of context that are referenced in the message.
1960    #[must_use]
1961    pub fn embedded_context(mut self, embedded_context: bool) -> Self {
1962        self.embedded_context = embedded_context;
1963        self
1964    }
1965
1966    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1967    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1968    /// these keys.
1969    ///
1970    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1971    #[must_use]
1972    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1973        self.meta = meta.into_option();
1974        self
1975    }
1976}
1977
1978/// MCP capabilities supported by the agent
1979#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1980#[serde(rename_all = "camelCase")]
1981#[non_exhaustive]
1982pub struct McpCapabilities {
1983    /// Agent supports [`McpServer::Http`].
1984    #[serde(default)]
1985    pub http: bool,
1986    /// Agent supports [`McpServer::Sse`].
1987    #[serde(default)]
1988    pub sse: bool,
1989    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1990    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1991    /// these keys.
1992    ///
1993    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1994    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1995    pub meta: Option<Meta>,
1996}
1997
1998impl McpCapabilities {
1999    #[must_use]
2000    pub fn new() -> Self {
2001        Self::default()
2002    }
2003
2004    /// Agent supports [`McpServer::Http`].
2005    #[must_use]
2006    pub fn http(mut self, http: bool) -> Self {
2007        self.http = http;
2008        self
2009    }
2010
2011    /// Agent supports [`McpServer::Sse`].
2012    #[must_use]
2013    pub fn sse(mut self, sse: bool) -> Self {
2014        self.sse = sse;
2015        self
2016    }
2017
2018    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2019    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2020    /// these keys.
2021    ///
2022    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2023    #[must_use]
2024    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2025        self.meta = meta.into_option();
2026        self
2027    }
2028}
2029
2030// Method schema
2031
2032/// Names of all methods that agents handle.
2033///
2034/// Provides a centralized definition of method names used in the protocol.
2035#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2036#[non_exhaustive]
2037pub struct AgentMethodNames {
2038    /// Method for initializing the connection.
2039    pub initialize: &'static str,
2040    /// Method for authenticating with the agent.
2041    pub authenticate: &'static str,
2042    /// Method for creating a new session.
2043    pub session_new: &'static str,
2044    /// Method for loading an existing session.
2045    pub session_load: &'static str,
2046    /// Method for setting the mode for a session.
2047    pub session_set_mode: &'static str,
2048    /// Method for sending a prompt to the agent.
2049    pub session_prompt: &'static str,
2050    /// Notification for cancelling operations.
2051    pub session_cancel: &'static str,
2052    /// Method for selecting a model for a given session.
2053    #[cfg(feature = "unstable_session_model")]
2054    pub session_set_model: &'static str,
2055    /// Method for listing existing sessions.
2056    #[cfg(feature = "unstable_session_list")]
2057    pub session_list: &'static str,
2058    /// Method for forking an existing session.
2059    #[cfg(feature = "unstable_session_fork")]
2060    pub session_fork: &'static str,
2061}
2062
2063/// Constant containing all agent method names.
2064pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
2065    initialize: INITIALIZE_METHOD_NAME,
2066    authenticate: AUTHENTICATE_METHOD_NAME,
2067    session_new: SESSION_NEW_METHOD_NAME,
2068    session_load: SESSION_LOAD_METHOD_NAME,
2069    session_set_mode: SESSION_SET_MODE_METHOD_NAME,
2070    session_prompt: SESSION_PROMPT_METHOD_NAME,
2071    session_cancel: SESSION_CANCEL_METHOD_NAME,
2072    #[cfg(feature = "unstable_session_model")]
2073    session_set_model: SESSION_SET_MODEL_METHOD_NAME,
2074    #[cfg(feature = "unstable_session_list")]
2075    session_list: SESSION_LIST_METHOD_NAME,
2076    #[cfg(feature = "unstable_session_fork")]
2077    session_fork: SESSION_FORK_METHOD_NAME,
2078};
2079
2080/// Method name for the initialize request.
2081pub(crate) const INITIALIZE_METHOD_NAME: &str = "initialize";
2082/// Method name for the authenticate request.
2083pub(crate) const AUTHENTICATE_METHOD_NAME: &str = "authenticate";
2084/// Method name for creating a new session.
2085pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
2086/// Method name for loading an existing session.
2087pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
2088/// Method name for setting the mode for a session.
2089pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
2090/// Method name for sending a prompt.
2091pub(crate) const SESSION_PROMPT_METHOD_NAME: &str = "session/prompt";
2092/// Method name for the cancel notification.
2093pub(crate) const SESSION_CANCEL_METHOD_NAME: &str = "session/cancel";
2094/// Method name for selecting a model for a given session.
2095#[cfg(feature = "unstable_session_model")]
2096pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
2097/// Method name for listing existing sessions.
2098#[cfg(feature = "unstable_session_list")]
2099pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list";
2100/// Method name for forking an existing session.
2101#[cfg(feature = "unstable_session_fork")]
2102pub(crate) const SESSION_FORK_METHOD_NAME: &str = "session/fork";
2103
2104/// All possible requests that a client can send to an agent.
2105///
2106/// This enum is used internally for routing RPC requests. You typically won't need
2107/// to use this directly - instead, use the methods on the [`Agent`] trait.
2108///
2109/// This enum encompasses all method calls from client to agent.
2110#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2111#[serde(untagged)]
2112#[schemars(inline)]
2113#[non_exhaustive]
2114pub enum ClientRequest {
2115    /// Establishes the connection with a client and negotiates protocol capabilities.
2116    ///
2117    /// This method is called once at the beginning of the connection to:
2118    /// - Negotiate the protocol version to use
2119    /// - Exchange capability information between client and agent
2120    /// - Determine available authentication methods
2121    ///
2122    /// The agent should respond with its supported protocol version and capabilities.
2123    ///
2124    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
2125    InitializeRequest(InitializeRequest),
2126    /// Authenticates the client using the specified authentication method.
2127    ///
2128    /// Called when the agent requires authentication before allowing session creation.
2129    /// The client provides the authentication method ID that was advertised during initialization.
2130    ///
2131    /// After successful authentication, the client can proceed to create sessions with
2132    /// `new_session` without receiving an `auth_required` error.
2133    ///
2134    /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
2135    AuthenticateRequest(AuthenticateRequest),
2136    /// Creates a new conversation session with the agent.
2137    ///
2138    /// Sessions represent independent conversation contexts with their own history and state.
2139    ///
2140    /// The agent should:
2141    /// - Create a new session context
2142    /// - Connect to any specified MCP servers
2143    /// - Return a unique session ID for future requests
2144    ///
2145    /// May return an `auth_required` error if the agent requires authentication.
2146    ///
2147    /// See protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)
2148    NewSessionRequest(NewSessionRequest),
2149    /// Loads an existing session to resume a previous conversation.
2150    ///
2151    /// This method is only available if the agent advertises the `loadSession` capability.
2152    ///
2153    /// The agent should:
2154    /// - Restore the session context and conversation history
2155    /// - Connect to the specified MCP servers
2156    /// - Stream the entire conversation history back to the client via notifications
2157    ///
2158    /// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
2159    LoadSessionRequest(LoadSessionRequest),
2160    #[cfg(feature = "unstable_session_list")]
2161    /// **UNSTABLE**
2162    ///
2163    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2164    ///
2165    /// Lists existing sessions known to the agent.
2166    ///
2167    /// This method is only available if the agent advertises the `listSessions` capability.
2168    ///
2169    /// The agent should return metadata about sessions with optional filtering and pagination support.
2170    ListSessionsRequest(ListSessionsRequest),
2171    #[cfg(feature = "unstable_session_fork")]
2172    /// **UNSTABLE**
2173    ///
2174    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2175    ///
2176    /// Forks an existing session to create a new independent session.
2177    ///
2178    /// This method is only available if the agent advertises the `session.fork` capability.
2179    ///
2180    /// The agent should create a new session with the same conversation context as the
2181    /// original, allowing operations like generating summaries without affecting the
2182    /// original session's history.
2183    ForkSessionRequest(ForkSessionRequest),
2184    /// Sets the current mode for a session.
2185    ///
2186    /// Allows switching between different agent modes (e.g., "ask", "architect", "code")
2187    /// that affect system prompts, tool availability, and permission behaviors.
2188    ///
2189    /// The mode must be one of the modes advertised in `availableModes` during session
2190    /// creation or loading. Agents may also change modes autonomously and notify the
2191    /// client via `current_mode_update` notifications.
2192    ///
2193    /// This method can be called at any time during a session, whether the Agent is
2194    /// idle or actively generating a response.
2195    ///
2196    /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
2197    SetSessionModeRequest(SetSessionModeRequest),
2198    /// Processes a user prompt within a session.
2199    ///
2200    /// This method handles the whole lifecycle of a prompt:
2201    /// - Receives user messages with optional context (files, images, etc.)
2202    /// - Processes the prompt using language models
2203    /// - Reports language model content and tool calls to the Clients
2204    /// - Requests permission to run tools
2205    /// - Executes any requested tool calls
2206    /// - Returns when the turn is complete with a stop reason
2207    ///
2208    /// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
2209    PromptRequest(PromptRequest),
2210    #[cfg(feature = "unstable_session_model")]
2211    /// **UNSTABLE**
2212    ///
2213    /// This capability is not part of the spec yet, and may be removed or changed at any point.
2214    ///
2215    /// Select a model for a given session.
2216    SetSessionModelRequest(SetSessionModelRequest),
2217    /// Handles extension method requests from the client.
2218    ///
2219    /// Extension methods provide a way to add custom functionality while maintaining
2220    /// protocol compatibility.
2221    ///
2222    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2223    ExtMethodRequest(ExtRequest),
2224}
2225
2226impl ClientRequest {
2227    /// Returns the corresponding method name of the request.
2228    #[must_use]
2229    pub fn method(&self) -> &str {
2230        match self {
2231            Self::InitializeRequest(_) => AGENT_METHOD_NAMES.initialize,
2232            Self::AuthenticateRequest(_) => AGENT_METHOD_NAMES.authenticate,
2233            Self::NewSessionRequest(_) => AGENT_METHOD_NAMES.session_new,
2234            Self::LoadSessionRequest(_) => AGENT_METHOD_NAMES.session_load,
2235            #[cfg(feature = "unstable_session_list")]
2236            Self::ListSessionsRequest(_) => AGENT_METHOD_NAMES.session_list,
2237            #[cfg(feature = "unstable_session_fork")]
2238            Self::ForkSessionRequest(_) => AGENT_METHOD_NAMES.session_fork,
2239            Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode,
2240            Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt,
2241            #[cfg(feature = "unstable_session_model")]
2242            Self::SetSessionModelRequest(_) => AGENT_METHOD_NAMES.session_set_model,
2243            Self::ExtMethodRequest(ext_request) => &ext_request.method,
2244        }
2245    }
2246}
2247
2248/// All possible responses that an agent can send to a client.
2249///
2250/// This enum is used internally for routing RPC responses. You typically won't need
2251/// to use this directly - the responses are handled automatically by the connection.
2252///
2253/// These are responses to the corresponding `ClientRequest` variants.
2254#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2255#[serde(untagged)]
2256#[schemars(inline)]
2257#[non_exhaustive]
2258pub enum AgentResponse {
2259    InitializeResponse(InitializeResponse),
2260    AuthenticateResponse(#[serde(default)] AuthenticateResponse),
2261    NewSessionResponse(NewSessionResponse),
2262    LoadSessionResponse(#[serde(default)] LoadSessionResponse),
2263    #[cfg(feature = "unstable_session_list")]
2264    ListSessionsResponse(ListSessionsResponse),
2265    #[cfg(feature = "unstable_session_fork")]
2266    ForkSessionResponse(ForkSessionResponse),
2267    SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
2268    PromptResponse(PromptResponse),
2269    #[cfg(feature = "unstable_session_model")]
2270    SetSessionModelResponse(SetSessionModelResponse),
2271    ExtMethodResponse(ExtResponse),
2272}
2273
2274/// All possible notifications that a client can send to an agent.
2275///
2276/// This enum is used internally for routing RPC notifications. You typically won't need
2277/// to use this directly - use the notification methods on the [`Agent`] trait instead.
2278///
2279/// Notifications do not expect a response.
2280#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2281#[serde(untagged)]
2282#[schemars(inline)]
2283#[non_exhaustive]
2284pub enum ClientNotification {
2285    /// Cancels ongoing operations for a session.
2286    ///
2287    /// This is a notification sent by the client to cancel an ongoing prompt turn.
2288    ///
2289    /// Upon receiving this notification, the Agent SHOULD:
2290    /// - Stop all language model requests as soon as possible
2291    /// - Abort all tool call invocations in progress
2292    /// - Send any pending `session/update` notifications
2293    /// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
2294    ///
2295    /// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
2296    CancelNotification(CancelNotification),
2297    /// Handles extension notifications from the client.
2298    ///
2299    /// Extension notifications provide a way to send one-way messages for custom functionality
2300    /// while maintaining protocol compatibility.
2301    ///
2302    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2303    ExtNotification(ExtNotification),
2304}
2305
2306impl ClientNotification {
2307    /// Returns the corresponding method name of the notification.
2308    #[must_use]
2309    pub fn method(&self) -> &str {
2310        match self {
2311            Self::CancelNotification(_) => AGENT_METHOD_NAMES.session_cancel,
2312            Self::ExtNotification(ext_notification) => &ext_notification.method,
2313        }
2314    }
2315}
2316
2317/// Notification to cancel ongoing operations for a session.
2318///
2319/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
2320#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2321#[schemars(extend("x-side" = "agent", "x-method" = SESSION_CANCEL_METHOD_NAME))]
2322#[serde(rename_all = "camelCase")]
2323#[non_exhaustive]
2324pub struct CancelNotification {
2325    /// The ID of the session to cancel operations for.
2326    pub session_id: SessionId,
2327    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2328    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2329    /// these keys.
2330    ///
2331    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2332    #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2333    pub meta: Option<Meta>,
2334}
2335
2336impl CancelNotification {
2337    #[must_use]
2338    pub fn new(session_id: impl Into<SessionId>) -> Self {
2339        Self {
2340            session_id: session_id.into(),
2341            meta: None,
2342        }
2343    }
2344
2345    /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2346    /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2347    /// these keys.
2348    ///
2349    /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2350    #[must_use]
2351    pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2352        self.meta = meta.into_option();
2353        self
2354    }
2355}
2356
2357#[cfg(test)]
2358mod test_serialization {
2359    use super::*;
2360    use serde_json::json;
2361
2362    #[test]
2363    fn test_mcp_server_stdio_serialization() {
2364        let server = McpServer::Stdio(
2365            McpServerStdio::new("test-server", "/usr/bin/server")
2366                .args(vec!["--port".to_string(), "3000".to_string()])
2367                .env(vec![EnvVariable::new("API_KEY", "secret123")]),
2368        );
2369
2370        let json = serde_json::to_value(&server).unwrap();
2371        assert_eq!(
2372            json,
2373            json!({
2374                "name": "test-server",
2375                "command": "/usr/bin/server",
2376                "args": ["--port", "3000"],
2377                "env": [
2378                    {
2379                        "name": "API_KEY",
2380                        "value": "secret123"
2381                    }
2382                ]
2383            })
2384        );
2385
2386        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2387        match deserialized {
2388            McpServer::Stdio(McpServerStdio {
2389                name,
2390                command,
2391                args,
2392                env,
2393                meta: _,
2394            }) => {
2395                assert_eq!(name, "test-server");
2396                assert_eq!(command, PathBuf::from("/usr/bin/server"));
2397                assert_eq!(args, vec!["--port", "3000"]);
2398                assert_eq!(env.len(), 1);
2399                assert_eq!(env[0].name, "API_KEY");
2400                assert_eq!(env[0].value, "secret123");
2401            }
2402            _ => panic!("Expected Stdio variant"),
2403        }
2404    }
2405
2406    #[test]
2407    fn test_mcp_server_http_serialization() {
2408        let server = McpServer::Http(
2409            McpServerHttp::new("http-server", "https://api.example.com").headers(vec![
2410                HttpHeader::new("Authorization", "Bearer token123"),
2411                HttpHeader::new("Content-Type", "application/json"),
2412            ]),
2413        );
2414
2415        let json = serde_json::to_value(&server).unwrap();
2416        assert_eq!(
2417            json,
2418            json!({
2419                "type": "http",
2420                "name": "http-server",
2421                "url": "https://api.example.com",
2422                "headers": [
2423                    {
2424                        "name": "Authorization",
2425                        "value": "Bearer token123"
2426                    },
2427                    {
2428                        "name": "Content-Type",
2429                        "value": "application/json"
2430                    }
2431                ]
2432            })
2433        );
2434
2435        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2436        match deserialized {
2437            McpServer::Http(McpServerHttp {
2438                name,
2439                url,
2440                headers,
2441                meta: _,
2442            }) => {
2443                assert_eq!(name, "http-server");
2444                assert_eq!(url, "https://api.example.com");
2445                assert_eq!(headers.len(), 2);
2446                assert_eq!(headers[0].name, "Authorization");
2447                assert_eq!(headers[0].value, "Bearer token123");
2448                assert_eq!(headers[1].name, "Content-Type");
2449                assert_eq!(headers[1].value, "application/json");
2450            }
2451            _ => panic!("Expected Http variant"),
2452        }
2453    }
2454
2455    #[test]
2456    fn test_mcp_server_sse_serialization() {
2457        let server = McpServer::Sse(
2458            McpServerSse::new("sse-server", "https://sse.example.com/events")
2459                .headers(vec![HttpHeader::new("X-API-Key", "apikey456")]),
2460        );
2461
2462        let json = serde_json::to_value(&server).unwrap();
2463        assert_eq!(
2464            json,
2465            json!({
2466                "type": "sse",
2467                "name": "sse-server",
2468                "url": "https://sse.example.com/events",
2469                "headers": [
2470                    {
2471                        "name": "X-API-Key",
2472                        "value": "apikey456"
2473                    }
2474                ]
2475            })
2476        );
2477
2478        let deserialized: McpServer = serde_json::from_value(json).unwrap();
2479        match deserialized {
2480            McpServer::Sse(McpServerSse {
2481                name,
2482                url,
2483                headers,
2484                meta: _,
2485            }) => {
2486                assert_eq!(name, "sse-server");
2487                assert_eq!(url, "https://sse.example.com/events");
2488                assert_eq!(headers.len(), 1);
2489                assert_eq!(headers[0].name, "X-API-Key");
2490                assert_eq!(headers[0].value, "apikey456");
2491            }
2492            _ => panic!("Expected Sse variant"),
2493        }
2494    }
2495}