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}