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 /// Initial session configuration options if supported by the Agent.
428 #[serde(skip_serializing_if = "Option::is_none")]
429 pub config_options: Option<Vec<SessionConfigOption>>,
430 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
431 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
432 /// these keys.
433 ///
434 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
435 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
436 pub meta: Option<Meta>,
437}
438
439impl NewSessionResponse {
440 #[must_use]
441 pub fn new(session_id: impl Into<SessionId>) -> Self {
442 Self {
443 session_id: session_id.into(),
444 modes: None,
445 #[cfg(feature = "unstable_session_model")]
446 models: None,
447 config_options: None,
448 meta: None,
449 }
450 }
451
452 /// Initial mode state if supported by the Agent
453 ///
454 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
455 #[must_use]
456 pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
457 self.modes = modes.into_option();
458 self
459 }
460
461 /// **UNSTABLE**
462 ///
463 /// This capability is not part of the spec yet, and may be removed or changed at any point.
464 ///
465 /// Initial model state if supported by the Agent
466 #[cfg(feature = "unstable_session_model")]
467 #[must_use]
468 pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
469 self.models = models.into_option();
470 self
471 }
472
473 /// Initial session configuration options if supported by the Agent.
474 #[must_use]
475 pub fn config_options(
476 mut self,
477 config_options: impl IntoOption<Vec<SessionConfigOption>>,
478 ) -> Self {
479 self.config_options = config_options.into_option();
480 self
481 }
482
483 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
484 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
485 /// these keys.
486 ///
487 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
488 #[must_use]
489 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
490 self.meta = meta.into_option();
491 self
492 }
493}
494
495// Load session
496
497/// Request parameters for loading an existing session.
498///
499/// Only available if the Agent supports the `loadSession` capability.
500///
501/// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
502#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
503#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
504#[serde(rename_all = "camelCase")]
505#[non_exhaustive]
506pub struct LoadSessionRequest {
507 /// List of MCP servers to connect to for this session.
508 pub mcp_servers: Vec<McpServer>,
509 /// The working directory for this session.
510 pub cwd: PathBuf,
511 /// The ID of the session to load.
512 pub session_id: SessionId,
513 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
514 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
515 /// these keys.
516 ///
517 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
518 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
519 pub meta: Option<Meta>,
520}
521
522impl LoadSessionRequest {
523 pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
524 Self {
525 mcp_servers: vec![],
526 cwd: cwd.into(),
527 session_id: session_id.into(),
528 meta: None,
529 }
530 }
531
532 /// List of MCP servers to connect to for this session.
533 #[must_use]
534 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
535 self.mcp_servers = mcp_servers;
536 self
537 }
538
539 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
540 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
541 /// these keys.
542 ///
543 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
544 #[must_use]
545 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
546 self.meta = meta.into_option();
547 self
548 }
549}
550
551/// Response from loading an existing session.
552#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
553#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
554#[serde(rename_all = "camelCase")]
555#[non_exhaustive]
556pub struct LoadSessionResponse {
557 /// Initial mode state if supported by the Agent
558 ///
559 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
560 #[serde(default, skip_serializing_if = "Option::is_none")]
561 pub modes: Option<SessionModeState>,
562 /// **UNSTABLE**
563 ///
564 /// This capability is not part of the spec yet, and may be removed or changed at any point.
565 ///
566 /// Initial model state if supported by the Agent
567 #[cfg(feature = "unstable_session_model")]
568 #[serde(default, skip_serializing_if = "Option::is_none")]
569 pub models: Option<SessionModelState>,
570 /// Initial session configuration options if supported by the Agent.
571 #[serde(default, skip_serializing_if = "Option::is_none")]
572 pub config_options: Option<Vec<SessionConfigOption>>,
573 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
574 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
575 /// these keys.
576 ///
577 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
578 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
579 pub meta: Option<Meta>,
580}
581
582impl LoadSessionResponse {
583 #[must_use]
584 pub fn new() -> Self {
585 Self::default()
586 }
587
588 /// Initial mode state if supported by the Agent
589 ///
590 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
591 #[must_use]
592 pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
593 self.modes = modes.into_option();
594 self
595 }
596
597 /// **UNSTABLE**
598 ///
599 /// This capability is not part of the spec yet, and may be removed or changed at any point.
600 ///
601 /// Initial model state if supported by the Agent
602 #[cfg(feature = "unstable_session_model")]
603 #[must_use]
604 pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
605 self.models = models.into_option();
606 self
607 }
608
609 /// Initial session configuration options if supported by the Agent.
610 #[must_use]
611 pub fn config_options(
612 mut self,
613 config_options: impl IntoOption<Vec<SessionConfigOption>>,
614 ) -> Self {
615 self.config_options = config_options.into_option();
616 self
617 }
618
619 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
620 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
621 /// these keys.
622 ///
623 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
624 #[must_use]
625 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
626 self.meta = meta.into_option();
627 self
628 }
629}
630
631// Fork session
632
633/// **UNSTABLE**
634///
635/// This capability is not part of the spec yet, and may be removed or changed at any point.
636///
637/// Request parameters for forking an existing session.
638///
639/// Creates a new session based on the context of an existing one, allowing
640/// operations like generating summaries without affecting the original session's history.
641///
642/// Only available if the Agent supports the `session.fork` capability.
643#[cfg(feature = "unstable_session_fork")]
644#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
645#[schemars(extend("x-side" = "agent", "x-method" = SESSION_FORK_METHOD_NAME))]
646#[serde(rename_all = "camelCase")]
647#[non_exhaustive]
648pub struct ForkSessionRequest {
649 /// The ID of the session to fork.
650 pub session_id: SessionId,
651 /// The working directory for this session.
652 pub cwd: PathBuf,
653 /// List of MCP servers to connect to for this session.
654 #[serde(default, skip_serializing_if = "Vec::is_empty")]
655 pub mcp_servers: Vec<McpServer>,
656 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
657 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
658 /// these keys.
659 ///
660 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
661 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
662 pub meta: Option<Meta>,
663}
664
665#[cfg(feature = "unstable_session_fork")]
666impl ForkSessionRequest {
667 pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
668 Self {
669 session_id: session_id.into(),
670 cwd: cwd.into(),
671 mcp_servers: vec![],
672 meta: None,
673 }
674 }
675
676 /// List of MCP servers to connect to for this session.
677 #[must_use]
678 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
679 self.mcp_servers = mcp_servers;
680 self
681 }
682
683 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
684 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
685 /// these keys.
686 ///
687 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
688 #[must_use]
689 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
690 self.meta = meta.into_option();
691 self
692 }
693}
694
695/// **UNSTABLE**
696///
697/// This capability is not part of the spec yet, and may be removed or changed at any point.
698///
699/// Response from forking an existing session.
700#[cfg(feature = "unstable_session_fork")]
701#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
702#[schemars(extend("x-side" = "agent", "x-method" = SESSION_FORK_METHOD_NAME))]
703#[serde(rename_all = "camelCase")]
704#[non_exhaustive]
705pub struct ForkSessionResponse {
706 /// Unique identifier for the newly created forked session.
707 pub session_id: SessionId,
708 /// Initial mode state if supported by the Agent
709 ///
710 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
711 #[serde(skip_serializing_if = "Option::is_none")]
712 pub modes: Option<SessionModeState>,
713 /// **UNSTABLE**
714 ///
715 /// This capability is not part of the spec yet, and may be removed or changed at any point.
716 ///
717 /// Initial model state if supported by the Agent
718 #[cfg(feature = "unstable_session_model")]
719 #[serde(skip_serializing_if = "Option::is_none")]
720 pub models: Option<SessionModelState>,
721 /// Initial session configuration options if supported by the Agent.
722 #[serde(skip_serializing_if = "Option::is_none")]
723 pub config_options: Option<Vec<SessionConfigOption>>,
724 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
725 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
726 /// these keys.
727 ///
728 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
729 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
730 pub meta: Option<Meta>,
731}
732
733#[cfg(feature = "unstable_session_fork")]
734impl ForkSessionResponse {
735 #[must_use]
736 pub fn new(session_id: impl Into<SessionId>) -> Self {
737 Self {
738 session_id: session_id.into(),
739 modes: None,
740 #[cfg(feature = "unstable_session_model")]
741 models: None,
742 config_options: None,
743 meta: None,
744 }
745 }
746
747 /// Initial mode state if supported by the Agent
748 ///
749 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
750 #[must_use]
751 pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
752 self.modes = modes.into_option();
753 self
754 }
755
756 /// **UNSTABLE**
757 ///
758 /// This capability is not part of the spec yet, and may be removed or changed at any point.
759 ///
760 /// Initial model state if supported by the Agent
761 #[cfg(feature = "unstable_session_model")]
762 #[must_use]
763 pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
764 self.models = models.into_option();
765 self
766 }
767
768 /// Initial session configuration options if supported by the Agent.
769 #[must_use]
770 pub fn config_options(
771 mut self,
772 config_options: impl IntoOption<Vec<SessionConfigOption>>,
773 ) -> Self {
774 self.config_options = config_options.into_option();
775 self
776 }
777
778 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
779 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
780 /// these keys.
781 ///
782 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
783 #[must_use]
784 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
785 self.meta = meta.into_option();
786 self
787 }
788}
789
790// Resume session
791
792/// **UNSTABLE**
793///
794/// This capability is not part of the spec yet, and may be removed or changed at any point.
795///
796/// Request parameters for resuming an existing session.
797///
798/// Resumes an existing session without returning previous messages (unlike `session/load`).
799/// This is useful for agents that can resume sessions but don't implement full session loading.
800///
801/// Only available if the Agent supports the `session.resume` capability.
802#[cfg(feature = "unstable_session_resume")]
803#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
804#[schemars(extend("x-side" = "agent", "x-method" = SESSION_RESUME_METHOD_NAME))]
805#[serde(rename_all = "camelCase")]
806#[non_exhaustive]
807pub struct ResumeSessionRequest {
808 /// The ID of the session to resume.
809 pub session_id: SessionId,
810 /// The working directory for this session.
811 pub cwd: PathBuf,
812 /// List of MCP servers to connect to for this session.
813 #[serde(default, skip_serializing_if = "Vec::is_empty")]
814 pub mcp_servers: Vec<McpServer>,
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_resume")]
825impl ResumeSessionRequest {
826 pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
827 Self {
828 session_id: session_id.into(),
829 cwd: cwd.into(),
830 mcp_servers: vec![],
831 meta: None,
832 }
833 }
834
835 /// List of MCP servers to connect to for this session.
836 #[must_use]
837 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
838 self.mcp_servers = mcp_servers;
839 self
840 }
841
842 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
843 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
844 /// these keys.
845 ///
846 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
847 #[must_use]
848 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
849 self.meta = meta.into_option();
850 self
851 }
852}
853
854/// **UNSTABLE**
855///
856/// This capability is not part of the spec yet, and may be removed or changed at any point.
857///
858/// Response from resuming an existing session.
859#[cfg(feature = "unstable_session_resume")]
860#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
861#[schemars(extend("x-side" = "agent", "x-method" = SESSION_RESUME_METHOD_NAME))]
862#[serde(rename_all = "camelCase")]
863#[non_exhaustive]
864pub struct ResumeSessionResponse {
865 /// Initial mode state if supported by the Agent
866 ///
867 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
868 #[serde(default, skip_serializing_if = "Option::is_none")]
869 pub modes: Option<SessionModeState>,
870 /// **UNSTABLE**
871 ///
872 /// This capability is not part of the spec yet, and may be removed or changed at any point.
873 ///
874 /// Initial model state if supported by the Agent
875 #[cfg(feature = "unstable_session_model")]
876 #[serde(default, skip_serializing_if = "Option::is_none")]
877 pub models: Option<SessionModelState>,
878 /// Initial session configuration options if supported by the Agent.
879 #[serde(default, skip_serializing_if = "Option::is_none")]
880 pub config_options: Option<Vec<SessionConfigOption>>,
881 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
882 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
883 /// these keys.
884 ///
885 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
886 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
887 pub meta: Option<Meta>,
888}
889
890#[cfg(feature = "unstable_session_resume")]
891impl ResumeSessionResponse {
892 #[must_use]
893 pub fn new() -> Self {
894 Self::default()
895 }
896
897 /// Initial mode state if supported by the Agent
898 ///
899 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
900 #[must_use]
901 pub fn modes(mut self, modes: impl IntoOption<SessionModeState>) -> Self {
902 self.modes = modes.into_option();
903 self
904 }
905
906 /// **UNSTABLE**
907 ///
908 /// This capability is not part of the spec yet, and may be removed or changed at any point.
909 ///
910 /// Initial model state if supported by the Agent
911 #[cfg(feature = "unstable_session_model")]
912 #[must_use]
913 pub fn models(mut self, models: impl IntoOption<SessionModelState>) -> Self {
914 self.models = models.into_option();
915 self
916 }
917
918 /// Initial session configuration options if supported by the Agent.
919 #[must_use]
920 pub fn config_options(
921 mut self,
922 config_options: impl IntoOption<Vec<SessionConfigOption>>,
923 ) -> Self {
924 self.config_options = config_options.into_option();
925 self
926 }
927
928 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
929 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
930 /// these keys.
931 ///
932 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
933 #[must_use]
934 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
935 self.meta = meta.into_option();
936 self
937 }
938}
939
940// List sessions
941
942/// **UNSTABLE**
943///
944/// This capability is not part of the spec yet, and may be removed or changed at any point.
945///
946/// Request parameters for listing existing sessions.
947///
948/// Only available if the Agent supports the `listSessions` capability.
949#[cfg(feature = "unstable_session_list")]
950#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
951#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
952#[serde(rename_all = "camelCase")]
953#[non_exhaustive]
954pub struct ListSessionsRequest {
955 /// Filter sessions by working directory. Must be an absolute path.
956 #[serde(skip_serializing_if = "Option::is_none")]
957 pub cwd: Option<PathBuf>,
958 /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
959 #[serde(skip_serializing_if = "Option::is_none")]
960 pub cursor: Option<String>,
961 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
962 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
963 /// these keys.
964 ///
965 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
966 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
967 pub meta: Option<Meta>,
968}
969
970#[cfg(feature = "unstable_session_list")]
971impl ListSessionsRequest {
972 #[must_use]
973 pub fn new() -> Self {
974 Self::default()
975 }
976
977 /// Filter sessions by working directory. Must be an absolute path.
978 #[must_use]
979 pub fn cwd(mut self, cwd: impl IntoOption<PathBuf>) -> Self {
980 self.cwd = cwd.into_option();
981 self
982 }
983
984 /// Opaque cursor token from a previous response's nextCursor field for cursor-based pagination
985 #[must_use]
986 pub fn cursor(mut self, cursor: impl IntoOption<String>) -> Self {
987 self.cursor = cursor.into_option();
988 self
989 }
990
991 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
992 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
993 /// these keys.
994 ///
995 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
996 #[must_use]
997 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
998 self.meta = meta.into_option();
999 self
1000 }
1001}
1002
1003/// **UNSTABLE**
1004///
1005/// This capability is not part of the spec yet, and may be removed or changed at any point.
1006///
1007/// Response from listing sessions.
1008#[cfg(feature = "unstable_session_list")]
1009#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1010#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
1011#[serde(rename_all = "camelCase")]
1012#[non_exhaustive]
1013pub struct ListSessionsResponse {
1014 /// Array of session information objects
1015 pub sessions: Vec<SessionInfo>,
1016 /// Opaque cursor token. If present, pass this in the next request's cursor parameter
1017 /// to fetch the next page. If absent, there are no more results.
1018 #[serde(skip_serializing_if = "Option::is_none")]
1019 pub next_cursor: Option<String>,
1020 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1021 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1022 /// these keys.
1023 ///
1024 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1025 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1026 pub meta: Option<Meta>,
1027}
1028
1029#[cfg(feature = "unstable_session_list")]
1030impl ListSessionsResponse {
1031 #[must_use]
1032 pub fn new(sessions: Vec<SessionInfo>) -> Self {
1033 Self {
1034 sessions,
1035 next_cursor: None,
1036 meta: None,
1037 }
1038 }
1039
1040 #[must_use]
1041 pub fn next_cursor(mut self, next_cursor: impl IntoOption<String>) -> Self {
1042 self.next_cursor = next_cursor.into_option();
1043 self
1044 }
1045
1046 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1047 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1048 /// these keys.
1049 ///
1050 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1051 #[must_use]
1052 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1053 self.meta = meta.into_option();
1054 self
1055 }
1056}
1057
1058/// **UNSTABLE**
1059///
1060/// This capability is not part of the spec yet, and may be removed or changed at any point.
1061///
1062/// Information about a session returned by session/list
1063#[cfg(feature = "unstable_session_list")]
1064#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1065#[serde(rename_all = "camelCase")]
1066#[non_exhaustive]
1067pub struct SessionInfo {
1068 /// Unique identifier for the session
1069 pub session_id: SessionId,
1070 /// The working directory for this session. Must be an absolute path.
1071 pub cwd: PathBuf,
1072 /// Human-readable title for the session
1073 #[serde(skip_serializing_if = "Option::is_none")]
1074 pub title: Option<String>,
1075 /// ISO 8601 timestamp of last activity
1076 #[serde(skip_serializing_if = "Option::is_none")]
1077 pub updated_at: Option<String>,
1078 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1079 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1080 /// these keys.
1081 ///
1082 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1083 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1084 pub meta: Option<Meta>,
1085}
1086
1087#[cfg(feature = "unstable_session_list")]
1088impl SessionInfo {
1089 pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
1090 Self {
1091 session_id: session_id.into(),
1092 cwd: cwd.into(),
1093 title: None,
1094 updated_at: None,
1095 meta: None,
1096 }
1097 }
1098
1099 /// Human-readable title for the session
1100 #[must_use]
1101 pub fn title(mut self, title: impl IntoOption<String>) -> Self {
1102 self.title = title.into_option();
1103 self
1104 }
1105
1106 /// ISO 8601 timestamp of last activity
1107 #[must_use]
1108 pub fn updated_at(mut self, updated_at: impl IntoOption<String>) -> Self {
1109 self.updated_at = updated_at.into_option();
1110 self
1111 }
1112
1113 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1114 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1115 /// these keys.
1116 ///
1117 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1118 #[must_use]
1119 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1120 self.meta = meta.into_option();
1121 self
1122 }
1123}
1124
1125// Session modes
1126
1127/// The set of modes and the one currently active.
1128#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1129#[serde(rename_all = "camelCase")]
1130#[non_exhaustive]
1131pub struct SessionModeState {
1132 /// The current mode the Agent is in.
1133 pub current_mode_id: SessionModeId,
1134 /// The set of modes that the Agent can operate in
1135 pub available_modes: Vec<SessionMode>,
1136 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1137 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1138 /// these keys.
1139 ///
1140 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1141 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1142 pub meta: Option<Meta>,
1143}
1144
1145impl SessionModeState {
1146 #[must_use]
1147 pub fn new(
1148 current_mode_id: impl Into<SessionModeId>,
1149 available_modes: Vec<SessionMode>,
1150 ) -> Self {
1151 Self {
1152 current_mode_id: current_mode_id.into(),
1153 available_modes,
1154 meta: None,
1155 }
1156 }
1157
1158 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1159 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1160 /// these keys.
1161 ///
1162 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1163 #[must_use]
1164 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1165 self.meta = meta.into_option();
1166 self
1167 }
1168}
1169
1170/// A mode the agent can operate in.
1171///
1172/// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
1173#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1174#[serde(rename_all = "camelCase")]
1175#[non_exhaustive]
1176pub struct SessionMode {
1177 pub id: SessionModeId,
1178 pub name: String,
1179 #[serde(default, skip_serializing_if = "Option::is_none")]
1180 pub description: Option<String>,
1181 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1182 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1183 /// these keys.
1184 ///
1185 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1186 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1187 pub meta: Option<Meta>,
1188}
1189
1190impl SessionMode {
1191 pub fn new(id: impl Into<SessionModeId>, name: impl Into<String>) -> Self {
1192 Self {
1193 id: id.into(),
1194 name: name.into(),
1195 description: None,
1196 meta: None,
1197 }
1198 }
1199
1200 #[must_use]
1201 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1202 self.description = description.into_option();
1203 self
1204 }
1205
1206 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1207 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1208 /// these keys.
1209 ///
1210 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1211 #[must_use]
1212 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1213 self.meta = meta.into_option();
1214 self
1215 }
1216}
1217
1218/// Unique identifier for a Session Mode.
1219#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1220#[serde(transparent)]
1221#[from(Arc<str>, String, &'static str)]
1222#[non_exhaustive]
1223pub struct SessionModeId(pub Arc<str>);
1224
1225impl SessionModeId {
1226 pub fn new(id: impl Into<Arc<str>>) -> Self {
1227 Self(id.into())
1228 }
1229}
1230
1231/// Request parameters for setting a session mode.
1232#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1233#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
1234#[serde(rename_all = "camelCase")]
1235#[non_exhaustive]
1236pub struct SetSessionModeRequest {
1237 /// The ID of the session to set the mode for.
1238 pub session_id: SessionId,
1239 /// The ID of the mode to set.
1240 pub mode_id: SessionModeId,
1241 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1242 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1243 /// these keys.
1244 ///
1245 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1246 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1247 pub meta: Option<Meta>,
1248}
1249
1250impl SetSessionModeRequest {
1251 #[must_use]
1252 pub fn new(session_id: impl Into<SessionId>, mode_id: impl Into<SessionModeId>) -> Self {
1253 Self {
1254 session_id: session_id.into(),
1255 mode_id: mode_id.into(),
1256 meta: None,
1257 }
1258 }
1259
1260 #[must_use]
1261 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1262 self.meta = meta.into_option();
1263 self
1264 }
1265}
1266
1267/// Response to `session/set_mode` method.
1268#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1269#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
1270#[serde(rename_all = "camelCase")]
1271#[non_exhaustive]
1272pub struct SetSessionModeResponse {
1273 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1274 pub meta: Option<Meta>,
1275}
1276
1277impl SetSessionModeResponse {
1278 #[must_use]
1279 pub fn new() -> Self {
1280 Self::default()
1281 }
1282
1283 #[must_use]
1284 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1285 self.meta = meta.into_option();
1286 self
1287 }
1288}
1289
1290// Session config options
1291
1292/// Unique identifier for a session configuration option.
1293#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1294#[serde(transparent)]
1295#[from(Arc<str>, String, &'static str)]
1296#[non_exhaustive]
1297pub struct SessionConfigId(pub Arc<str>);
1298
1299impl SessionConfigId {
1300 pub fn new(id: impl Into<Arc<str>>) -> Self {
1301 Self(id.into())
1302 }
1303}
1304
1305/// Unique identifier for a session configuration option value.
1306#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1307#[serde(transparent)]
1308#[from(Arc<str>, String, &'static str)]
1309#[non_exhaustive]
1310pub struct SessionConfigValueId(pub Arc<str>);
1311
1312impl SessionConfigValueId {
1313 pub fn new(id: impl Into<Arc<str>>) -> Self {
1314 Self(id.into())
1315 }
1316}
1317
1318/// Unique identifier for a session configuration option value group.
1319#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
1320#[serde(transparent)]
1321#[from(Arc<str>, String, &'static str)]
1322#[non_exhaustive]
1323pub struct SessionConfigGroupId(pub Arc<str>);
1324
1325impl SessionConfigGroupId {
1326 pub fn new(id: impl Into<Arc<str>>) -> Self {
1327 Self(id.into())
1328 }
1329}
1330
1331/// A possible value for a session configuration option.
1332#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1333#[serde(rename_all = "camelCase")]
1334#[non_exhaustive]
1335pub struct SessionConfigSelectOption {
1336 /// Unique identifier for this option value.
1337 pub value: SessionConfigValueId,
1338 /// Human-readable label for this option value.
1339 pub name: String,
1340 /// Optional description for this option value.
1341 #[serde(default, skip_serializing_if = "Option::is_none")]
1342 pub description: Option<String>,
1343 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1344 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1345 /// these keys.
1346 ///
1347 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1348 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1349 pub meta: Option<Meta>,
1350}
1351
1352impl SessionConfigSelectOption {
1353 #[must_use]
1354 pub fn new(value: impl Into<SessionConfigValueId>, name: impl Into<String>) -> Self {
1355 Self {
1356 value: value.into(),
1357 name: name.into(),
1358 description: None,
1359 meta: None,
1360 }
1361 }
1362
1363 #[must_use]
1364 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1365 self.description = description.into_option();
1366 self
1367 }
1368
1369 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1370 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1371 /// these keys.
1372 ///
1373 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1374 #[must_use]
1375 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1376 self.meta = meta.into_option();
1377 self
1378 }
1379}
1380
1381/// A group of possible values for a session configuration option.
1382#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1383#[serde(rename_all = "camelCase")]
1384#[non_exhaustive]
1385pub struct SessionConfigSelectGroup {
1386 /// Unique identifier for this group.
1387 pub group: SessionConfigGroupId,
1388 /// Human-readable label for this group.
1389 pub name: String,
1390 /// The set of option values in this group.
1391 pub options: Vec<SessionConfigSelectOption>,
1392 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1393 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1394 /// these keys.
1395 ///
1396 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1397 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1398 pub meta: Option<Meta>,
1399}
1400
1401impl SessionConfigSelectGroup {
1402 #[must_use]
1403 pub fn new(
1404 group: impl Into<SessionConfigGroupId>,
1405 name: impl Into<String>,
1406 options: Vec<SessionConfigSelectOption>,
1407 ) -> Self {
1408 Self {
1409 group: group.into(),
1410 name: name.into(),
1411 options,
1412 meta: None,
1413 }
1414 }
1415
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 #[must_use]
1422 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1423 self.meta = meta.into_option();
1424 self
1425 }
1426}
1427
1428/// Possible values for a session configuration option.
1429#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1430#[serde(untagged)]
1431#[non_exhaustive]
1432pub enum SessionConfigSelectOptions {
1433 /// A flat list of options with no grouping.
1434 Ungrouped(Vec<SessionConfigSelectOption>),
1435 /// A list of options grouped under headers.
1436 Grouped(Vec<SessionConfigSelectGroup>),
1437}
1438
1439impl From<Vec<SessionConfigSelectOption>> for SessionConfigSelectOptions {
1440 fn from(options: Vec<SessionConfigSelectOption>) -> Self {
1441 SessionConfigSelectOptions::Ungrouped(options)
1442 }
1443}
1444
1445impl From<Vec<SessionConfigSelectGroup>> for SessionConfigSelectOptions {
1446 fn from(groups: Vec<SessionConfigSelectGroup>) -> Self {
1447 SessionConfigSelectOptions::Grouped(groups)
1448 }
1449}
1450
1451/// A single-value selector (dropdown) session configuration option payload.
1452#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1453#[serde(rename_all = "camelCase")]
1454#[non_exhaustive]
1455pub struct SessionConfigSelect {
1456 /// The currently selected value.
1457 pub current_value: SessionConfigValueId,
1458 /// The set of selectable options.
1459 pub options: SessionConfigSelectOptions,
1460}
1461
1462impl SessionConfigSelect {
1463 #[must_use]
1464 pub fn new(
1465 current_value: impl Into<SessionConfigValueId>,
1466 options: impl Into<SessionConfigSelectOptions>,
1467 ) -> Self {
1468 Self {
1469 current_value: current_value.into(),
1470 options: options.into(),
1471 }
1472 }
1473}
1474
1475/// Semantic category for a session configuration option.
1476///
1477/// This is intended to help Clients distinguish broadly common selectors (e.g. model selector vs
1478/// session mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,
1479/// placement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown
1480/// categories gracefully.
1481///
1482/// Category names beginning with `_` are free for custom use, like other ACP extension methods.
1483/// Category names that do not begin with `_` are reserved for the ACP spec.
1484#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1485#[serde(rename_all = "snake_case")]
1486#[non_exhaustive]
1487pub enum SessionConfigOptionCategory {
1488 /// Session mode selector.
1489 Mode,
1490 /// Model selector.
1491 Model,
1492 /// Thought/reasoning level selector.
1493 ThoughtLevel,
1494 /// Unknown / uncategorized selector.
1495 #[serde(untagged)]
1496 Other(String),
1497}
1498
1499/// Type-specific session configuration option payload.
1500#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1501#[serde(tag = "type", rename_all = "snake_case")]
1502#[schemars(extend("discriminator" = {"propertyName": "type"}))]
1503#[non_exhaustive]
1504pub enum SessionConfigKind {
1505 /// Single-value selector (dropdown).
1506 Select(SessionConfigSelect),
1507}
1508
1509/// A session configuration option selector and its current state.
1510#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1511#[serde(rename_all = "camelCase")]
1512#[non_exhaustive]
1513pub struct SessionConfigOption {
1514 /// Unique identifier for the configuration option.
1515 pub id: SessionConfigId,
1516 /// Human-readable label for the option.
1517 pub name: String,
1518 /// Optional description for the Client to display to the user.
1519 #[serde(default, skip_serializing_if = "Option::is_none")]
1520 pub description: Option<String>,
1521 /// Optional semantic category for this option (UX only).
1522 #[serde(default, skip_serializing_if = "Option::is_none")]
1523 pub category: Option<SessionConfigOptionCategory>,
1524 /// Type-specific fields for this configuration option.
1525 #[serde(flatten)]
1526 pub kind: SessionConfigKind,
1527 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1528 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1529 /// these keys.
1530 ///
1531 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1532 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1533 pub meta: Option<Meta>,
1534}
1535
1536impl SessionConfigOption {
1537 #[must_use]
1538 pub fn new(
1539 id: impl Into<SessionConfigId>,
1540 name: impl Into<String>,
1541 kind: SessionConfigKind,
1542 ) -> Self {
1543 Self {
1544 id: id.into(),
1545 name: name.into(),
1546 description: None,
1547 category: None,
1548 kind,
1549 meta: None,
1550 }
1551 }
1552
1553 #[must_use]
1554 pub fn select(
1555 id: impl Into<SessionConfigId>,
1556 name: impl Into<String>,
1557 current_value: impl Into<SessionConfigValueId>,
1558 options: impl Into<SessionConfigSelectOptions>,
1559 ) -> Self {
1560 Self::new(
1561 id,
1562 name,
1563 SessionConfigKind::Select(SessionConfigSelect::new(current_value, options)),
1564 )
1565 }
1566
1567 #[must_use]
1568 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
1569 self.description = description.into_option();
1570 self
1571 }
1572
1573 #[must_use]
1574 pub fn category(mut self, category: impl IntoOption<SessionConfigOptionCategory>) -> Self {
1575 self.category = category.into_option();
1576 self
1577 }
1578
1579 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1580 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1581 /// these keys.
1582 ///
1583 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1584 #[must_use]
1585 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1586 self.meta = meta.into_option();
1587 self
1588 }
1589}
1590
1591/// Request parameters for setting a session configuration option.
1592#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1593#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_CONFIG_OPTION_METHOD_NAME))]
1594#[serde(rename_all = "camelCase")]
1595#[non_exhaustive]
1596pub struct SetSessionConfigOptionRequest {
1597 /// The ID of the session to set the configuration option for.
1598 pub session_id: SessionId,
1599 /// The ID of the configuration option to set.
1600 pub config_id: SessionConfigId,
1601 /// The ID of the configuration option value to set.
1602 pub value: SessionConfigValueId,
1603 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1604 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1605 /// these keys.
1606 ///
1607 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1608 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1609 pub meta: Option<Meta>,
1610}
1611
1612impl SetSessionConfigOptionRequest {
1613 #[must_use]
1614 pub fn new(
1615 session_id: impl Into<SessionId>,
1616 config_id: impl Into<SessionConfigId>,
1617 value: impl Into<SessionConfigValueId>,
1618 ) -> Self {
1619 Self {
1620 session_id: session_id.into(),
1621 config_id: config_id.into(),
1622 value: value.into(),
1623 meta: None,
1624 }
1625 }
1626
1627 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1628 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1629 /// these keys.
1630 ///
1631 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1632 #[must_use]
1633 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1634 self.meta = meta.into_option();
1635 self
1636 }
1637}
1638
1639/// Response to `session/set_config_option` method.
1640#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1641#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_CONFIG_OPTION_METHOD_NAME))]
1642#[serde(rename_all = "camelCase")]
1643#[non_exhaustive]
1644pub struct SetSessionConfigOptionResponse {
1645 /// The full set of configuration options and their current values.
1646 pub config_options: Vec<SessionConfigOption>,
1647 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1648 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1649 /// these keys.
1650 ///
1651 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1652 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1653 pub meta: Option<Meta>,
1654}
1655
1656impl SetSessionConfigOptionResponse {
1657 #[must_use]
1658 pub fn new(config_options: Vec<SessionConfigOption>) -> Self {
1659 Self {
1660 config_options,
1661 meta: None,
1662 }
1663 }
1664
1665 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1666 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1667 /// these keys.
1668 ///
1669 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1670 #[must_use]
1671 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1672 self.meta = meta.into_option();
1673 self
1674 }
1675}
1676
1677// MCP
1678
1679/// Configuration for connecting to an MCP (Model Context Protocol) server.
1680///
1681/// MCP servers provide tools and context that the agent can use when
1682/// processing prompts.
1683///
1684/// See protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)
1685#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1686#[serde(tag = "type", rename_all = "snake_case")]
1687#[non_exhaustive]
1688pub enum McpServer {
1689 /// HTTP transport configuration
1690 ///
1691 /// Only available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.
1692 Http(McpServerHttp),
1693 /// SSE transport configuration
1694 ///
1695 /// Only available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.
1696 Sse(McpServerSse),
1697 /// Stdio transport configuration
1698 ///
1699 /// All Agents MUST support this transport.
1700 #[serde(untagged)]
1701 Stdio(McpServerStdio),
1702}
1703
1704/// HTTP transport configuration for MCP.
1705#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1706#[serde(rename_all = "camelCase")]
1707#[non_exhaustive]
1708pub struct McpServerHttp {
1709 /// Human-readable name identifying this MCP server.
1710 pub name: String,
1711 /// URL to the MCP server.
1712 pub url: String,
1713 /// HTTP headers to set when making requests to the MCP server.
1714 pub headers: Vec<HttpHeader>,
1715 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1716 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1717 /// these keys.
1718 ///
1719 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1720 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1721 pub meta: Option<Meta>,
1722}
1723
1724impl McpServerHttp {
1725 pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1726 Self {
1727 name: name.into(),
1728 url: url.into(),
1729 headers: Vec::new(),
1730 meta: None,
1731 }
1732 }
1733
1734 /// HTTP headers to set when making requests to the MCP server.
1735 #[must_use]
1736 pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1737 self.headers = headers;
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/// SSE transport configuration for MCP.
1754#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1755#[serde(rename_all = "camelCase")]
1756#[non_exhaustive]
1757pub struct McpServerSse {
1758 /// Human-readable name identifying this MCP server.
1759 pub name: String,
1760 /// URL to the MCP server.
1761 pub url: String,
1762 /// HTTP headers to set when making requests to the MCP server.
1763 pub headers: Vec<HttpHeader>,
1764 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1765 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1766 /// these keys.
1767 ///
1768 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1769 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1770 pub meta: Option<Meta>,
1771}
1772
1773impl McpServerSse {
1774 pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
1775 Self {
1776 name: name.into(),
1777 url: url.into(),
1778 headers: Vec::new(),
1779 meta: None,
1780 }
1781 }
1782
1783 /// HTTP headers to set when making requests to the MCP server.
1784 #[must_use]
1785 pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
1786 self.headers = headers;
1787 self
1788 }
1789
1790 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1791 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1792 /// these keys.
1793 ///
1794 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1795 #[must_use]
1796 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1797 self.meta = meta.into_option();
1798 self
1799 }
1800}
1801
1802/// Stdio transport configuration for MCP.
1803#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1804#[serde(rename_all = "camelCase")]
1805#[non_exhaustive]
1806pub struct McpServerStdio {
1807 /// Human-readable name identifying this MCP server.
1808 pub name: String,
1809 /// Path to the MCP server executable.
1810 pub command: PathBuf,
1811 /// Command-line arguments to pass to the MCP server.
1812 pub args: Vec<String>,
1813 /// Environment variables to set when launching the MCP server.
1814 pub env: Vec<EnvVariable>,
1815 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1816 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1817 /// these keys.
1818 ///
1819 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1820 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1821 pub meta: Option<Meta>,
1822}
1823
1824impl McpServerStdio {
1825 pub fn new(name: impl Into<String>, command: impl Into<PathBuf>) -> Self {
1826 Self {
1827 name: name.into(),
1828 command: command.into(),
1829 args: Vec::new(),
1830 env: Vec::new(),
1831 meta: None,
1832 }
1833 }
1834
1835 /// Command-line arguments to pass to the MCP server.
1836 #[must_use]
1837 pub fn args(mut self, args: Vec<String>) -> Self {
1838 self.args = args;
1839 self
1840 }
1841
1842 /// Environment variables to set when launching the MCP server.
1843 #[must_use]
1844 pub fn env(mut self, env: Vec<EnvVariable>) -> Self {
1845 self.env = env;
1846 self
1847 }
1848
1849 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1850 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1851 /// these keys.
1852 ///
1853 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1854 #[must_use]
1855 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1856 self.meta = meta.into_option();
1857 self
1858 }
1859}
1860
1861/// An environment variable to set when launching an MCP server.
1862#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1863#[serde(rename_all = "camelCase")]
1864#[non_exhaustive]
1865pub struct EnvVariable {
1866 /// The name of the environment variable.
1867 pub name: String,
1868 /// The value to set for the environment variable.
1869 pub value: String,
1870 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1871 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1872 /// these keys.
1873 ///
1874 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1875 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1876 pub meta: Option<Meta>,
1877}
1878
1879impl EnvVariable {
1880 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1881 Self {
1882 name: name.into(),
1883 value: value.into(),
1884 meta: None,
1885 }
1886 }
1887
1888 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1889 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1890 /// these keys.
1891 ///
1892 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1893 #[must_use]
1894 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1895 self.meta = meta.into_option();
1896 self
1897 }
1898}
1899
1900/// An HTTP header to set when making requests to the MCP server.
1901#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1902#[serde(rename_all = "camelCase")]
1903#[non_exhaustive]
1904pub struct HttpHeader {
1905 /// The name of the HTTP header.
1906 pub name: String,
1907 /// The value to set for the HTTP header.
1908 pub value: String,
1909 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1910 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1911 /// these keys.
1912 ///
1913 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1914 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1915 pub meta: Option<Meta>,
1916}
1917
1918impl HttpHeader {
1919 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1920 Self {
1921 name: name.into(),
1922 value: value.into(),
1923 meta: None,
1924 }
1925 }
1926
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 #[must_use]
1933 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1934 self.meta = meta.into_option();
1935 self
1936 }
1937}
1938
1939// Prompt
1940
1941/// Request parameters for sending a user prompt to the agent.
1942///
1943/// Contains the user's message and any additional context.
1944///
1945/// See protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)
1946#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
1947#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1948#[serde(rename_all = "camelCase")]
1949#[non_exhaustive]
1950pub struct PromptRequest {
1951 /// The ID of the session to send this user message to
1952 pub session_id: SessionId,
1953 /// The blocks of content that compose the user's message.
1954 ///
1955 /// As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],
1956 /// while other variants are optionally enabled via [`PromptCapabilities`].
1957 ///
1958 /// The Client MUST adapt its interface according to [`PromptCapabilities`].
1959 ///
1960 /// The client MAY include referenced pieces of context as either
1961 /// [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].
1962 ///
1963 /// When available, [`ContentBlock::Resource`] is preferred
1964 /// as it avoids extra round-trips and allows the message to include
1965 /// pieces of context from sources the agent may not have access to.
1966 pub prompt: Vec<ContentBlock>,
1967 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1968 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1969 /// these keys.
1970 ///
1971 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1972 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1973 pub meta: Option<Meta>,
1974}
1975
1976impl PromptRequest {
1977 #[must_use]
1978 pub fn new(session_id: impl Into<SessionId>, prompt: Vec<ContentBlock>) -> Self {
1979 Self {
1980 session_id: session_id.into(),
1981 prompt,
1982 meta: None,
1983 }
1984 }
1985
1986 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
1987 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
1988 /// these keys.
1989 ///
1990 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
1991 #[must_use]
1992 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1993 self.meta = meta.into_option();
1994 self
1995 }
1996}
1997
1998/// Response from processing a user prompt.
1999///
2000/// See protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)
2001#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2002#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
2003#[serde(rename_all = "camelCase")]
2004#[non_exhaustive]
2005pub struct PromptResponse {
2006 /// Indicates why the agent stopped processing the turn.
2007 pub stop_reason: StopReason,
2008 /// **UNSTABLE**
2009 ///
2010 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2011 ///
2012 /// Token usage for this turn (optional).
2013 #[cfg(feature = "unstable_session_usage")]
2014 #[serde(skip_serializing_if = "Option::is_none")]
2015 pub usage: Option<Usage>,
2016 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2017 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2018 /// these keys.
2019 ///
2020 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2021 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2022 pub meta: Option<Meta>,
2023}
2024
2025impl PromptResponse {
2026 #[must_use]
2027 pub fn new(stop_reason: StopReason) -> Self {
2028 Self {
2029 stop_reason,
2030 #[cfg(feature = "unstable_session_usage")]
2031 usage: None,
2032 meta: None,
2033 }
2034 }
2035
2036 /// **UNSTABLE**
2037 ///
2038 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2039 ///
2040 /// Token usage for this turn.
2041 #[cfg(feature = "unstable_session_usage")]
2042 #[must_use]
2043 pub fn usage(mut self, usage: impl IntoOption<Usage>) -> Self {
2044 self.usage = usage.into_option();
2045 self
2046 }
2047
2048 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2049 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2050 /// these keys.
2051 ///
2052 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2053 #[must_use]
2054 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2055 self.meta = meta.into_option();
2056 self
2057 }
2058}
2059
2060/// Reasons why an agent stops processing a prompt turn.
2061///
2062/// See protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)
2063#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
2064#[serde(rename_all = "snake_case")]
2065#[non_exhaustive]
2066pub enum StopReason {
2067 /// The turn ended successfully.
2068 EndTurn,
2069 /// The turn ended because the agent reached the maximum number of tokens.
2070 MaxTokens,
2071 /// The turn ended because the agent reached the maximum number of allowed
2072 /// agent requests between user turns.
2073 MaxTurnRequests,
2074 /// The turn ended because the agent refused to continue. The user prompt
2075 /// and everything that comes after it won't be included in the next
2076 /// prompt, so this should be reflected in the UI.
2077 Refusal,
2078 /// The turn was cancelled by the client via `session/cancel`.
2079 ///
2080 /// This stop reason MUST be returned when the client sends a `session/cancel`
2081 /// notification, even if the cancellation causes exceptions in underlying operations.
2082 /// Agents should catch these exceptions and return this semantically meaningful
2083 /// response to confirm successful cancellation.
2084 Cancelled,
2085}
2086
2087/// **UNSTABLE**
2088///
2089/// This capability is not part of the spec yet, and may be removed or changed at any point.
2090///
2091/// Token usage information for a prompt turn.
2092#[cfg(feature = "unstable_session_usage")]
2093#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2094#[serde(rename_all = "camelCase")]
2095#[non_exhaustive]
2096pub struct Usage {
2097 /// Sum of all token types across session.
2098 pub total_tokens: u64,
2099 /// Total input tokens across all turns.
2100 pub input_tokens: u64,
2101 /// Total output tokens across all turns.
2102 pub output_tokens: u64,
2103 /// Total thought/reasoning tokens
2104 #[serde(skip_serializing_if = "Option::is_none")]
2105 pub thought_tokens: Option<u64>,
2106 /// Total cache read tokens.
2107 #[serde(skip_serializing_if = "Option::is_none")]
2108 pub cached_read_tokens: Option<u64>,
2109 /// Total cache write tokens.
2110 #[serde(skip_serializing_if = "Option::is_none")]
2111 pub cached_write_tokens: Option<u64>,
2112}
2113
2114#[cfg(feature = "unstable_session_usage")]
2115impl Usage {
2116 #[must_use]
2117 pub fn new(total_tokens: u64, input_tokens: u64, output_tokens: u64) -> Self {
2118 Self {
2119 total_tokens,
2120 input_tokens,
2121 output_tokens,
2122 thought_tokens: None,
2123 cached_read_tokens: None,
2124 cached_write_tokens: None,
2125 }
2126 }
2127
2128 /// Total thought/reasoning tokens
2129 #[must_use]
2130 pub fn thought_tokens(mut self, thought_tokens: impl IntoOption<u64>) -> Self {
2131 self.thought_tokens = thought_tokens.into_option();
2132 self
2133 }
2134
2135 /// Total cache read tokens.
2136 #[must_use]
2137 pub fn cached_read_tokens(mut self, cached_read_tokens: impl IntoOption<u64>) -> Self {
2138 self.cached_read_tokens = cached_read_tokens.into_option();
2139 self
2140 }
2141
2142 /// Total cache write tokens.
2143 #[must_use]
2144 pub fn cached_write_tokens(mut self, cached_write_tokens: impl IntoOption<u64>) -> Self {
2145 self.cached_write_tokens = cached_write_tokens.into_option();
2146 self
2147 }
2148}
2149
2150// Model
2151
2152/// **UNSTABLE**
2153///
2154/// This capability is not part of the spec yet, and may be removed or changed at any point.
2155///
2156/// The set of models and the one currently active.
2157#[cfg(feature = "unstable_session_model")]
2158#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2159#[serde(rename_all = "camelCase")]
2160#[non_exhaustive]
2161pub struct SessionModelState {
2162 /// The current model the Agent is in.
2163 pub current_model_id: ModelId,
2164 /// The set of models that the Agent can use
2165 pub available_models: Vec<ModelInfo>,
2166 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2167 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2168 /// these keys.
2169 ///
2170 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2171 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2172 pub meta: Option<Meta>,
2173}
2174
2175#[cfg(feature = "unstable_session_model")]
2176impl SessionModelState {
2177 #[must_use]
2178 pub fn new(current_model_id: impl Into<ModelId>, available_models: Vec<ModelInfo>) -> Self {
2179 Self {
2180 current_model_id: current_model_id.into(),
2181 available_models,
2182 meta: None,
2183 }
2184 }
2185
2186 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2187 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2188 /// these keys.
2189 ///
2190 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2191 #[must_use]
2192 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2193 self.meta = meta.into_option();
2194 self
2195 }
2196}
2197
2198/// **UNSTABLE**
2199///
2200/// This capability is not part of the spec yet, and may be removed or changed at any point.
2201///
2202/// A unique identifier for a model.
2203#[cfg(feature = "unstable_session_model")]
2204#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
2205#[serde(transparent)]
2206#[from(Arc<str>, String, &'static str)]
2207#[non_exhaustive]
2208pub struct ModelId(pub Arc<str>);
2209
2210#[cfg(feature = "unstable_session_model")]
2211impl ModelId {
2212 pub fn new(id: impl Into<Arc<str>>) -> Self {
2213 Self(id.into())
2214 }
2215}
2216
2217/// **UNSTABLE**
2218///
2219/// This capability is not part of the spec yet, and may be removed or changed at any point.
2220///
2221/// Information about a selectable model.
2222#[cfg(feature = "unstable_session_model")]
2223#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2224#[serde(rename_all = "camelCase")]
2225#[non_exhaustive]
2226pub struct ModelInfo {
2227 /// Unique identifier for the model.
2228 pub model_id: ModelId,
2229 /// Human-readable name of the model.
2230 pub name: String,
2231 /// Optional description of the model.
2232 #[serde(default, skip_serializing_if = "Option::is_none")]
2233 pub description: Option<String>,
2234 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2235 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2236 /// these keys.
2237 ///
2238 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2239 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2240 pub meta: Option<Meta>,
2241}
2242
2243#[cfg(feature = "unstable_session_model")]
2244impl ModelInfo {
2245 pub fn new(model_id: impl Into<ModelId>, name: impl Into<String>) -> Self {
2246 Self {
2247 model_id: model_id.into(),
2248 name: name.into(),
2249 description: None,
2250 meta: None,
2251 }
2252 }
2253
2254 /// Optional description of the model.
2255 #[must_use]
2256 pub fn description(mut self, description: impl IntoOption<String>) -> Self {
2257 self.description = description.into_option();
2258 self
2259 }
2260
2261 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2262 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2263 /// these keys.
2264 ///
2265 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2266 #[must_use]
2267 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2268 self.meta = meta.into_option();
2269 self
2270 }
2271}
2272
2273/// **UNSTABLE**
2274///
2275/// This capability is not part of the spec yet, and may be removed or changed at any point.
2276///
2277/// Request parameters for setting a session model.
2278#[cfg(feature = "unstable_session_model")]
2279#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2280#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
2281#[serde(rename_all = "camelCase")]
2282#[non_exhaustive]
2283pub struct SetSessionModelRequest {
2284 /// The ID of the session to set the model for.
2285 pub session_id: SessionId,
2286 /// The ID of the model to set.
2287 pub model_id: ModelId,
2288 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2289 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2290 /// these keys.
2291 ///
2292 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2293 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2294 pub meta: Option<Meta>,
2295}
2296
2297#[cfg(feature = "unstable_session_model")]
2298impl SetSessionModelRequest {
2299 #[must_use]
2300 pub fn new(session_id: impl Into<SessionId>, model_id: impl Into<ModelId>) -> Self {
2301 Self {
2302 session_id: session_id.into(),
2303 model_id: model_id.into(),
2304 meta: None,
2305 }
2306 }
2307
2308 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2309 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2310 /// these keys.
2311 ///
2312 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2313 #[must_use]
2314 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2315 self.meta = meta.into_option();
2316 self
2317 }
2318}
2319
2320/// **UNSTABLE**
2321///
2322/// This capability is not part of the spec yet, and may be removed or changed at any point.
2323///
2324/// Response to `session/set_model` method.
2325#[cfg(feature = "unstable_session_model")]
2326#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2327#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
2328#[serde(rename_all = "camelCase")]
2329#[non_exhaustive]
2330pub struct SetSessionModelResponse {
2331 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2332 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2333 /// these keys.
2334 ///
2335 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2336 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2337 pub meta: Option<Meta>,
2338}
2339
2340#[cfg(feature = "unstable_session_model")]
2341impl SetSessionModelResponse {
2342 #[must_use]
2343 pub fn new() -> Self {
2344 Self::default()
2345 }
2346
2347 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2348 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2349 /// these keys.
2350 ///
2351 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2352 #[must_use]
2353 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2354 self.meta = meta.into_option();
2355 self
2356 }
2357}
2358
2359// Capabilities
2360
2361/// Capabilities supported by the agent.
2362///
2363/// Advertised during initialization to inform the client about
2364/// available features and content types.
2365///
2366/// See protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)
2367#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2368#[serde(rename_all = "camelCase")]
2369#[non_exhaustive]
2370pub struct AgentCapabilities {
2371 /// Whether the agent supports `session/load`.
2372 #[serde(default)]
2373 pub load_session: bool,
2374 /// Prompt capabilities supported by the agent.
2375 #[serde(default)]
2376 pub prompt_capabilities: PromptCapabilities,
2377 /// MCP capabilities supported by the agent.
2378 #[serde(default)]
2379 pub mcp_capabilities: McpCapabilities,
2380 #[serde(default)]
2381 pub session_capabilities: SessionCapabilities,
2382 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2383 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2384 /// these keys.
2385 ///
2386 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2387 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2388 pub meta: Option<Meta>,
2389}
2390
2391impl AgentCapabilities {
2392 #[must_use]
2393 pub fn new() -> Self {
2394 Self::default()
2395 }
2396
2397 /// Whether the agent supports `session/load`.
2398 #[must_use]
2399 pub fn load_session(mut self, load_session: bool) -> Self {
2400 self.load_session = load_session;
2401 self
2402 }
2403
2404 /// Prompt capabilities supported by the agent.
2405 #[must_use]
2406 pub fn prompt_capabilities(mut self, prompt_capabilities: PromptCapabilities) -> Self {
2407 self.prompt_capabilities = prompt_capabilities;
2408 self
2409 }
2410
2411 /// MCP capabilities supported by the agent.
2412 #[must_use]
2413 pub fn mcp_capabilities(mut self, mcp_capabilities: McpCapabilities) -> Self {
2414 self.mcp_capabilities = mcp_capabilities;
2415 self
2416 }
2417
2418 /// Session capabilities supported by the agent.
2419 #[must_use]
2420 pub fn session_capabilities(mut self, session_capabilities: SessionCapabilities) -> Self {
2421 self.session_capabilities = session_capabilities;
2422 self
2423 }
2424
2425 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2426 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2427 /// these keys.
2428 ///
2429 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2430 #[must_use]
2431 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2432 self.meta = meta.into_option();
2433 self
2434 }
2435}
2436
2437/// Session capabilities supported by the agent.
2438///
2439/// As a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.
2440///
2441/// Optionally, they **MAY** support other session methods and notifications by specifying additional capabilities.
2442///
2443/// Note: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.
2444///
2445/// See protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)
2446#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2447#[non_exhaustive]
2448pub struct SessionCapabilities {
2449 /// **UNSTABLE**
2450 ///
2451 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2452 ///
2453 /// Whether the agent supports `session/list`.
2454 #[cfg(feature = "unstable_session_list")]
2455 #[serde(skip_serializing_if = "Option::is_none")]
2456 pub list: Option<SessionListCapabilities>,
2457 /// **UNSTABLE**
2458 ///
2459 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2460 ///
2461 /// Whether the agent supports `session/fork`.
2462 #[cfg(feature = "unstable_session_fork")]
2463 #[serde(skip_serializing_if = "Option::is_none")]
2464 pub fork: Option<SessionForkCapabilities>,
2465 /// **UNSTABLE**
2466 ///
2467 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2468 ///
2469 /// Whether the agent supports `session/resume`.
2470 #[cfg(feature = "unstable_session_resume")]
2471 #[serde(skip_serializing_if = "Option::is_none")]
2472 pub resume: Option<SessionResumeCapabilities>,
2473 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2474 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2475 /// these keys.
2476 ///
2477 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2478 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2479 pub meta: Option<Meta>,
2480}
2481
2482impl SessionCapabilities {
2483 #[must_use]
2484 pub fn new() -> Self {
2485 Self::default()
2486 }
2487
2488 #[cfg(feature = "unstable_session_list")]
2489 /// Whether the agent supports `session/list`.
2490 #[must_use]
2491 pub fn list(mut self, list: impl IntoOption<SessionListCapabilities>) -> Self {
2492 self.list = list.into_option();
2493 self
2494 }
2495
2496 #[cfg(feature = "unstable_session_fork")]
2497 /// Whether the agent supports `session/fork`.
2498 #[must_use]
2499 pub fn fork(mut self, fork: impl IntoOption<SessionForkCapabilities>) -> Self {
2500 self.fork = fork.into_option();
2501 self
2502 }
2503
2504 #[cfg(feature = "unstable_session_resume")]
2505 /// Whether the agent supports `session/resume`.
2506 #[must_use]
2507 pub fn resume(mut self, resume: impl IntoOption<SessionResumeCapabilities>) -> Self {
2508 self.resume = resume.into_option();
2509 self
2510 }
2511
2512 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2513 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2514 /// these keys.
2515 ///
2516 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2517 #[must_use]
2518 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2519 self.meta = meta.into_option();
2520 self
2521 }
2522}
2523
2524/// Capabilities for the `session/list` method.
2525///
2526/// By supplying `{}` it means that the agent supports listing of sessions.
2527///
2528/// Further capabilities can be added in the future for other means of filtering or searching the list.
2529#[cfg(feature = "unstable_session_list")]
2530#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2531#[non_exhaustive]
2532pub struct SessionListCapabilities {
2533 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2534 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2535 /// these keys.
2536 ///
2537 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2538 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2539 pub meta: Option<Meta>,
2540}
2541
2542#[cfg(feature = "unstable_session_list")]
2543impl SessionListCapabilities {
2544 #[must_use]
2545 pub fn new() -> Self {
2546 Self::default()
2547 }
2548 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2549 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2550 /// these keys.
2551 ///
2552 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2553 #[must_use]
2554 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2555 self.meta = meta.into_option();
2556 self
2557 }
2558}
2559
2560/// **UNSTABLE**
2561///
2562/// This capability is not part of the spec yet, and may be removed or changed at any point.
2563///
2564/// Capabilities for the `session/fork` method.
2565///
2566/// By supplying `{}` it means that the agent supports forking of sessions.
2567#[cfg(feature = "unstable_session_fork")]
2568#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2569#[non_exhaustive]
2570pub struct SessionForkCapabilities {
2571 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2572 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2573 /// these keys.
2574 ///
2575 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2576 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2577 pub meta: Option<Meta>,
2578}
2579
2580#[cfg(feature = "unstable_session_fork")]
2581impl SessionForkCapabilities {
2582 #[must_use]
2583 pub fn new() -> Self {
2584 Self::default()
2585 }
2586
2587 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2588 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2589 /// these keys.
2590 ///
2591 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2592 #[must_use]
2593 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2594 self.meta = meta.into_option();
2595 self
2596 }
2597}
2598
2599/// **UNSTABLE**
2600///
2601/// This capability is not part of the spec yet, and may be removed or changed at any point.
2602///
2603/// Capabilities for the `session/resume` method.
2604///
2605/// By supplying `{}` it means that the agent supports resuming of sessions.
2606#[cfg(feature = "unstable_session_resume")]
2607#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2608#[non_exhaustive]
2609pub struct SessionResumeCapabilities {
2610 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2611 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2612 /// these keys.
2613 ///
2614 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2615 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2616 pub meta: Option<Meta>,
2617}
2618
2619#[cfg(feature = "unstable_session_resume")]
2620impl SessionResumeCapabilities {
2621 #[must_use]
2622 pub fn new() -> Self {
2623 Self::default()
2624 }
2625
2626 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2627 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2628 /// these keys.
2629 ///
2630 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2631 #[must_use]
2632 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2633 self.meta = meta.into_option();
2634 self
2635 }
2636}
2637
2638/// Prompt capabilities supported by the agent in `session/prompt` requests.
2639///
2640/// Baseline agent functionality requires support for [`ContentBlock::Text`]
2641/// and [`ContentBlock::ResourceLink`] in prompt requests.
2642///
2643/// Other variants must be explicitly opted in to.
2644/// Capabilities for different types of content in prompt requests.
2645///
2646/// Indicates which content types beyond the baseline (text and resource links)
2647/// the agent can process.
2648///
2649/// See protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)
2650#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2651#[serde(rename_all = "camelCase")]
2652#[non_exhaustive]
2653pub struct PromptCapabilities {
2654 /// Agent supports [`ContentBlock::Image`].
2655 #[serde(default)]
2656 pub image: bool,
2657 /// Agent supports [`ContentBlock::Audio`].
2658 #[serde(default)]
2659 pub audio: bool,
2660 /// Agent supports embedded context in `session/prompt` requests.
2661 ///
2662 /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
2663 /// in prompt requests for pieces of context that are referenced in the message.
2664 #[serde(default)]
2665 pub embedded_context: bool,
2666 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2667 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2668 /// these keys.
2669 ///
2670 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2671 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2672 pub meta: Option<Meta>,
2673}
2674
2675impl PromptCapabilities {
2676 #[must_use]
2677 pub fn new() -> Self {
2678 Self::default()
2679 }
2680
2681 /// Agent supports [`ContentBlock::Image`].
2682 #[must_use]
2683 pub fn image(mut self, image: bool) -> Self {
2684 self.image = image;
2685 self
2686 }
2687
2688 /// Agent supports [`ContentBlock::Audio`].
2689 #[must_use]
2690 pub fn audio(mut self, audio: bool) -> Self {
2691 self.audio = audio;
2692 self
2693 }
2694
2695 /// Agent supports embedded context in `session/prompt` requests.
2696 ///
2697 /// When enabled, the Client is allowed to include [`ContentBlock::Resource`]
2698 /// in prompt requests for pieces of context that are referenced in the message.
2699 #[must_use]
2700 pub fn embedded_context(mut self, embedded_context: bool) -> Self {
2701 self.embedded_context = embedded_context;
2702 self
2703 }
2704
2705 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2706 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2707 /// these keys.
2708 ///
2709 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2710 #[must_use]
2711 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2712 self.meta = meta.into_option();
2713 self
2714 }
2715}
2716
2717/// MCP capabilities supported by the agent
2718#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2719#[serde(rename_all = "camelCase")]
2720#[non_exhaustive]
2721pub struct McpCapabilities {
2722 /// Agent supports [`McpServer::Http`].
2723 #[serde(default)]
2724 pub http: bool,
2725 /// Agent supports [`McpServer::Sse`].
2726 #[serde(default)]
2727 pub sse: bool,
2728 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2729 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2730 /// these keys.
2731 ///
2732 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2733 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
2734 pub meta: Option<Meta>,
2735}
2736
2737impl McpCapabilities {
2738 #[must_use]
2739 pub fn new() -> Self {
2740 Self::default()
2741 }
2742
2743 /// Agent supports [`McpServer::Http`].
2744 #[must_use]
2745 pub fn http(mut self, http: bool) -> Self {
2746 self.http = http;
2747 self
2748 }
2749
2750 /// Agent supports [`McpServer::Sse`].
2751 #[must_use]
2752 pub fn sse(mut self, sse: bool) -> Self {
2753 self.sse = sse;
2754 self
2755 }
2756
2757 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
2758 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2759 /// these keys.
2760 ///
2761 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2762 #[must_use]
2763 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2764 self.meta = meta.into_option();
2765 self
2766 }
2767}
2768
2769// Method schema
2770
2771/// Names of all methods that agents handle.
2772///
2773/// Provides a centralized definition of method names used in the protocol.
2774#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
2775#[non_exhaustive]
2776pub struct AgentMethodNames {
2777 /// Method for initializing the connection.
2778 pub initialize: &'static str,
2779 /// Method for authenticating with the agent.
2780 pub authenticate: &'static str,
2781 /// Method for creating a new session.
2782 pub session_new: &'static str,
2783 /// Method for loading an existing session.
2784 pub session_load: &'static str,
2785 /// Method for setting the mode for a session.
2786 pub session_set_mode: &'static str,
2787 /// Method for setting a configuration option for a session.
2788 pub session_set_config_option: &'static str,
2789 /// Method for sending a prompt to the agent.
2790 pub session_prompt: &'static str,
2791 /// Notification for cancelling operations.
2792 pub session_cancel: &'static str,
2793 /// Method for selecting a model for a given session.
2794 #[cfg(feature = "unstable_session_model")]
2795 pub session_set_model: &'static str,
2796 /// Method for listing existing sessions.
2797 #[cfg(feature = "unstable_session_list")]
2798 pub session_list: &'static str,
2799 /// Method for forking an existing session.
2800 #[cfg(feature = "unstable_session_fork")]
2801 pub session_fork: &'static str,
2802 /// Method for resuming an existing session.
2803 #[cfg(feature = "unstable_session_resume")]
2804 pub session_resume: &'static str,
2805}
2806
2807/// Constant containing all agent method names.
2808pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
2809 initialize: INITIALIZE_METHOD_NAME,
2810 authenticate: AUTHENTICATE_METHOD_NAME,
2811 session_new: SESSION_NEW_METHOD_NAME,
2812 session_load: SESSION_LOAD_METHOD_NAME,
2813 session_set_mode: SESSION_SET_MODE_METHOD_NAME,
2814 session_set_config_option: SESSION_SET_CONFIG_OPTION_METHOD_NAME,
2815 session_prompt: SESSION_PROMPT_METHOD_NAME,
2816 session_cancel: SESSION_CANCEL_METHOD_NAME,
2817 #[cfg(feature = "unstable_session_model")]
2818 session_set_model: SESSION_SET_MODEL_METHOD_NAME,
2819 #[cfg(feature = "unstable_session_list")]
2820 session_list: SESSION_LIST_METHOD_NAME,
2821 #[cfg(feature = "unstable_session_fork")]
2822 session_fork: SESSION_FORK_METHOD_NAME,
2823 #[cfg(feature = "unstable_session_resume")]
2824 session_resume: SESSION_RESUME_METHOD_NAME,
2825};
2826
2827/// Method name for the initialize request.
2828pub(crate) const INITIALIZE_METHOD_NAME: &str = "initialize";
2829/// Method name for the authenticate request.
2830pub(crate) const AUTHENTICATE_METHOD_NAME: &str = "authenticate";
2831/// Method name for creating a new session.
2832pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
2833/// Method name for loading an existing session.
2834pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
2835/// Method name for setting the mode for a session.
2836pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
2837/// Method name for setting a configuration option for a session.
2838pub(crate) const SESSION_SET_CONFIG_OPTION_METHOD_NAME: &str = "session/set_config_option";
2839/// Method name for sending a prompt.
2840pub(crate) const SESSION_PROMPT_METHOD_NAME: &str = "session/prompt";
2841/// Method name for the cancel notification.
2842pub(crate) const SESSION_CANCEL_METHOD_NAME: &str = "session/cancel";
2843/// Method name for selecting a model for a given session.
2844#[cfg(feature = "unstable_session_model")]
2845pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
2846/// Method name for listing existing sessions.
2847#[cfg(feature = "unstable_session_list")]
2848pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list";
2849/// Method name for forking an existing session.
2850#[cfg(feature = "unstable_session_fork")]
2851pub(crate) const SESSION_FORK_METHOD_NAME: &str = "session/fork";
2852/// Method name for resuming an existing session.
2853#[cfg(feature = "unstable_session_resume")]
2854pub(crate) const SESSION_RESUME_METHOD_NAME: &str = "session/resume";
2855
2856/// All possible requests that a client can send to an agent.
2857///
2858/// This enum is used internally for routing RPC requests. You typically won't need
2859/// to use this directly - instead, use the methods on the [`Agent`] trait.
2860///
2861/// This enum encompasses all method calls from client to agent.
2862#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
2863#[serde(untagged)]
2864#[schemars(inline)]
2865#[non_exhaustive]
2866pub enum ClientRequest {
2867 /// Establishes the connection with a client and negotiates protocol capabilities.
2868 ///
2869 /// This method is called once at the beginning of the connection to:
2870 /// - Negotiate the protocol version to use
2871 /// - Exchange capability information between client and agent
2872 /// - Determine available authentication methods
2873 ///
2874 /// The agent should respond with its supported protocol version and capabilities.
2875 ///
2876 /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
2877 InitializeRequest(InitializeRequest),
2878 /// Authenticates the client using the specified authentication method.
2879 ///
2880 /// Called when the agent requires authentication before allowing session creation.
2881 /// The client provides the authentication method ID that was advertised during initialization.
2882 ///
2883 /// After successful authentication, the client can proceed to create sessions with
2884 /// `new_session` without receiving an `auth_required` error.
2885 ///
2886 /// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
2887 AuthenticateRequest(AuthenticateRequest),
2888 /// Creates a new conversation session with the agent.
2889 ///
2890 /// Sessions represent independent conversation contexts with their own history and state.
2891 ///
2892 /// The agent should:
2893 /// - Create a new session context
2894 /// - Connect to any specified MCP servers
2895 /// - Return a unique session ID for future requests
2896 ///
2897 /// May return an `auth_required` error if the agent requires authentication.
2898 ///
2899 /// See protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)
2900 NewSessionRequest(NewSessionRequest),
2901 /// Loads an existing session to resume a previous conversation.
2902 ///
2903 /// This method is only available if the agent advertises the `loadSession` capability.
2904 ///
2905 /// The agent should:
2906 /// - Restore the session context and conversation history
2907 /// - Connect to the specified MCP servers
2908 /// - Stream the entire conversation history back to the client via notifications
2909 ///
2910 /// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
2911 LoadSessionRequest(LoadSessionRequest),
2912 #[cfg(feature = "unstable_session_list")]
2913 /// **UNSTABLE**
2914 ///
2915 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2916 ///
2917 /// Lists existing sessions known to the agent.
2918 ///
2919 /// This method is only available if the agent advertises the `listSessions` capability.
2920 ///
2921 /// The agent should return metadata about sessions with optional filtering and pagination support.
2922 ListSessionsRequest(ListSessionsRequest),
2923 #[cfg(feature = "unstable_session_fork")]
2924 /// **UNSTABLE**
2925 ///
2926 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2927 ///
2928 /// Forks an existing session to create a new independent session.
2929 ///
2930 /// This method is only available if the agent advertises the `session.fork` capability.
2931 ///
2932 /// The agent should create a new session with the same conversation context as the
2933 /// original, allowing operations like generating summaries without affecting the
2934 /// original session's history.
2935 ForkSessionRequest(ForkSessionRequest),
2936 #[cfg(feature = "unstable_session_resume")]
2937 /// **UNSTABLE**
2938 ///
2939 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2940 ///
2941 /// Resumes an existing session without returning previous messages.
2942 ///
2943 /// This method is only available if the agent advertises the `session.resume` capability.
2944 ///
2945 /// The agent should resume the session context, allowing the conversation to continue
2946 /// without replaying the message history (unlike `session/load`).
2947 ResumeSessionRequest(ResumeSessionRequest),
2948 /// Sets the current mode for a session.
2949 ///
2950 /// Allows switching between different agent modes (e.g., "ask", "architect", "code")
2951 /// that affect system prompts, tool availability, and permission behaviors.
2952 ///
2953 /// The mode must be one of the modes advertised in `availableModes` during session
2954 /// creation or loading. Agents may also change modes autonomously and notify the
2955 /// client via `current_mode_update` notifications.
2956 ///
2957 /// This method can be called at any time during a session, whether the Agent is
2958 /// idle or actively generating a response.
2959 ///
2960 /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
2961 SetSessionModeRequest(SetSessionModeRequest),
2962 /// Sets the current value for a session configuration option.
2963 SetSessionConfigOptionRequest(SetSessionConfigOptionRequest),
2964 /// Processes a user prompt within a session.
2965 ///
2966 /// This method handles the whole lifecycle of a prompt:
2967 /// - Receives user messages with optional context (files, images, etc.)
2968 /// - Processes the prompt using language models
2969 /// - Reports language model content and tool calls to the Clients
2970 /// - Requests permission to run tools
2971 /// - Executes any requested tool calls
2972 /// - Returns when the turn is complete with a stop reason
2973 ///
2974 /// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
2975 PromptRequest(PromptRequest),
2976 #[cfg(feature = "unstable_session_model")]
2977 /// **UNSTABLE**
2978 ///
2979 /// This capability is not part of the spec yet, and may be removed or changed at any point.
2980 ///
2981 /// Select a model for a given session.
2982 SetSessionModelRequest(SetSessionModelRequest),
2983 /// Handles extension method requests from the client.
2984 ///
2985 /// Extension methods provide a way to add custom functionality while maintaining
2986 /// protocol compatibility.
2987 ///
2988 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2989 ExtMethodRequest(ExtRequest),
2990}
2991
2992impl ClientRequest {
2993 /// Returns the corresponding method name of the request.
2994 #[must_use]
2995 pub fn method(&self) -> &str {
2996 match self {
2997 Self::InitializeRequest(_) => AGENT_METHOD_NAMES.initialize,
2998 Self::AuthenticateRequest(_) => AGENT_METHOD_NAMES.authenticate,
2999 Self::NewSessionRequest(_) => AGENT_METHOD_NAMES.session_new,
3000 Self::LoadSessionRequest(_) => AGENT_METHOD_NAMES.session_load,
3001 #[cfg(feature = "unstable_session_list")]
3002 Self::ListSessionsRequest(_) => AGENT_METHOD_NAMES.session_list,
3003 #[cfg(feature = "unstable_session_fork")]
3004 Self::ForkSessionRequest(_) => AGENT_METHOD_NAMES.session_fork,
3005 #[cfg(feature = "unstable_session_resume")]
3006 Self::ResumeSessionRequest(_) => AGENT_METHOD_NAMES.session_resume,
3007 Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode,
3008 Self::SetSessionConfigOptionRequest(_) => AGENT_METHOD_NAMES.session_set_config_option,
3009 Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt,
3010 #[cfg(feature = "unstable_session_model")]
3011 Self::SetSessionModelRequest(_) => AGENT_METHOD_NAMES.session_set_model,
3012 Self::ExtMethodRequest(ext_request) => &ext_request.method,
3013 }
3014 }
3015}
3016
3017/// All possible responses that an agent can send to a client.
3018///
3019/// This enum is used internally for routing RPC responses. You typically won't need
3020/// to use this directly - the responses are handled automatically by the connection.
3021///
3022/// These are responses to the corresponding `ClientRequest` variants.
3023#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
3024#[serde(untagged)]
3025#[schemars(inline)]
3026#[non_exhaustive]
3027pub enum AgentResponse {
3028 InitializeResponse(InitializeResponse),
3029 AuthenticateResponse(#[serde(default)] AuthenticateResponse),
3030 NewSessionResponse(NewSessionResponse),
3031 LoadSessionResponse(#[serde(default)] LoadSessionResponse),
3032 #[cfg(feature = "unstable_session_list")]
3033 ListSessionsResponse(ListSessionsResponse),
3034 #[cfg(feature = "unstable_session_fork")]
3035 ForkSessionResponse(ForkSessionResponse),
3036 #[cfg(feature = "unstable_session_resume")]
3037 ResumeSessionResponse(#[serde(default)] ResumeSessionResponse),
3038 SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
3039 SetSessionConfigOptionResponse(SetSessionConfigOptionResponse),
3040 PromptResponse(PromptResponse),
3041 #[cfg(feature = "unstable_session_model")]
3042 SetSessionModelResponse(SetSessionModelResponse),
3043 ExtMethodResponse(ExtResponse),
3044}
3045
3046/// All possible notifications that a client can send to an agent.
3047///
3048/// This enum is used internally for routing RPC notifications. You typically won't need
3049/// to use this directly - use the notification methods on the [`Agent`] trait instead.
3050///
3051/// Notifications do not expect a response.
3052#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
3053#[serde(untagged)]
3054#[schemars(inline)]
3055#[non_exhaustive]
3056pub enum ClientNotification {
3057 /// Cancels ongoing operations for a session.
3058 ///
3059 /// This is a notification sent by the client to cancel an ongoing prompt turn.
3060 ///
3061 /// Upon receiving this notification, the Agent SHOULD:
3062 /// - Stop all language model requests as soon as possible
3063 /// - Abort all tool call invocations in progress
3064 /// - Send any pending `session/update` notifications
3065 /// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
3066 ///
3067 /// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
3068 CancelNotification(CancelNotification),
3069 /// Handles extension notifications from the client.
3070 ///
3071 /// Extension notifications provide a way to send one-way messages for custom functionality
3072 /// while maintaining protocol compatibility.
3073 ///
3074 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3075 ExtNotification(ExtNotification),
3076}
3077
3078impl ClientNotification {
3079 /// Returns the corresponding method name of the notification.
3080 #[must_use]
3081 pub fn method(&self) -> &str {
3082 match self {
3083 Self::CancelNotification(_) => AGENT_METHOD_NAMES.session_cancel,
3084 Self::ExtNotification(ext_notification) => &ext_notification.method,
3085 }
3086 }
3087}
3088
3089/// Notification to cancel ongoing operations for a session.
3090///
3091/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
3092#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
3093#[schemars(extend("x-side" = "agent", "x-method" = SESSION_CANCEL_METHOD_NAME))]
3094#[serde(rename_all = "camelCase")]
3095#[non_exhaustive]
3096pub struct CancelNotification {
3097 /// The ID of the session to cancel operations for.
3098 pub session_id: SessionId,
3099 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3100 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3101 /// these keys.
3102 ///
3103 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3104 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
3105 pub meta: Option<Meta>,
3106}
3107
3108impl CancelNotification {
3109 #[must_use]
3110 pub fn new(session_id: impl Into<SessionId>) -> Self {
3111 Self {
3112 session_id: session_id.into(),
3113 meta: None,
3114 }
3115 }
3116
3117 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
3118 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
3119 /// these keys.
3120 ///
3121 /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
3122 #[must_use]
3123 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
3124 self.meta = meta.into_option();
3125 self
3126 }
3127}
3128
3129#[cfg(test)]
3130mod test_serialization {
3131 use super::*;
3132 use serde_json::json;
3133
3134 #[test]
3135 fn test_mcp_server_stdio_serialization() {
3136 let server = McpServer::Stdio(
3137 McpServerStdio::new("test-server", "/usr/bin/server")
3138 .args(vec!["--port".to_string(), "3000".to_string()])
3139 .env(vec![EnvVariable::new("API_KEY", "secret123")]),
3140 );
3141
3142 let json = serde_json::to_value(&server).unwrap();
3143 assert_eq!(
3144 json,
3145 json!({
3146 "name": "test-server",
3147 "command": "/usr/bin/server",
3148 "args": ["--port", "3000"],
3149 "env": [
3150 {
3151 "name": "API_KEY",
3152 "value": "secret123"
3153 }
3154 ]
3155 })
3156 );
3157
3158 let deserialized: McpServer = serde_json::from_value(json).unwrap();
3159 match deserialized {
3160 McpServer::Stdio(McpServerStdio {
3161 name,
3162 command,
3163 args,
3164 env,
3165 meta: _,
3166 }) => {
3167 assert_eq!(name, "test-server");
3168 assert_eq!(command, PathBuf::from("/usr/bin/server"));
3169 assert_eq!(args, vec!["--port", "3000"]);
3170 assert_eq!(env.len(), 1);
3171 assert_eq!(env[0].name, "API_KEY");
3172 assert_eq!(env[0].value, "secret123");
3173 }
3174 _ => panic!("Expected Stdio variant"),
3175 }
3176 }
3177
3178 #[test]
3179 fn test_mcp_server_http_serialization() {
3180 let server = McpServer::Http(
3181 McpServerHttp::new("http-server", "https://api.example.com").headers(vec![
3182 HttpHeader::new("Authorization", "Bearer token123"),
3183 HttpHeader::new("Content-Type", "application/json"),
3184 ]),
3185 );
3186
3187 let json = serde_json::to_value(&server).unwrap();
3188 assert_eq!(
3189 json,
3190 json!({
3191 "type": "http",
3192 "name": "http-server",
3193 "url": "https://api.example.com",
3194 "headers": [
3195 {
3196 "name": "Authorization",
3197 "value": "Bearer token123"
3198 },
3199 {
3200 "name": "Content-Type",
3201 "value": "application/json"
3202 }
3203 ]
3204 })
3205 );
3206
3207 let deserialized: McpServer = serde_json::from_value(json).unwrap();
3208 match deserialized {
3209 McpServer::Http(McpServerHttp {
3210 name,
3211 url,
3212 headers,
3213 meta: _,
3214 }) => {
3215 assert_eq!(name, "http-server");
3216 assert_eq!(url, "https://api.example.com");
3217 assert_eq!(headers.len(), 2);
3218 assert_eq!(headers[0].name, "Authorization");
3219 assert_eq!(headers[0].value, "Bearer token123");
3220 assert_eq!(headers[1].name, "Content-Type");
3221 assert_eq!(headers[1].value, "application/json");
3222 }
3223 _ => panic!("Expected Http variant"),
3224 }
3225 }
3226
3227 #[test]
3228 fn test_mcp_server_sse_serialization() {
3229 let server = McpServer::Sse(
3230 McpServerSse::new("sse-server", "https://sse.example.com/events")
3231 .headers(vec![HttpHeader::new("X-API-Key", "apikey456")]),
3232 );
3233
3234 let json = serde_json::to_value(&server).unwrap();
3235 assert_eq!(
3236 json,
3237 json!({
3238 "type": "sse",
3239 "name": "sse-server",
3240 "url": "https://sse.example.com/events",
3241 "headers": [
3242 {
3243 "name": "X-API-Key",
3244 "value": "apikey456"
3245 }
3246 ]
3247 })
3248 );
3249
3250 let deserialized: McpServer = serde_json::from_value(json).unwrap();
3251 match deserialized {
3252 McpServer::Sse(McpServerSse {
3253 name,
3254 url,
3255 headers,
3256 meta: _,
3257 }) => {
3258 assert_eq!(name, "sse-server");
3259 assert_eq!(url, "https://sse.example.com/events");
3260 assert_eq!(headers.len(), 1);
3261 assert_eq!(headers[0].name, "X-API-Key");
3262 assert_eq!(headers[0].value, "apikey456");
3263 }
3264 _ => panic!("Expected Sse variant"),
3265 }
3266 }
3267
3268 #[test]
3269 fn test_session_config_option_category_known_variants() {
3270 // Test serialization of known variants
3271 assert_eq!(
3272 serde_json::to_value(&SessionConfigOptionCategory::Mode).unwrap(),
3273 json!("mode")
3274 );
3275 assert_eq!(
3276 serde_json::to_value(&SessionConfigOptionCategory::Model).unwrap(),
3277 json!("model")
3278 );
3279 assert_eq!(
3280 serde_json::to_value(&SessionConfigOptionCategory::ThoughtLevel).unwrap(),
3281 json!("thought_level")
3282 );
3283
3284 // Test deserialization of known variants
3285 assert_eq!(
3286 serde_json::from_str::<SessionConfigOptionCategory>("\"mode\"").unwrap(),
3287 SessionConfigOptionCategory::Mode
3288 );
3289 assert_eq!(
3290 serde_json::from_str::<SessionConfigOptionCategory>("\"model\"").unwrap(),
3291 SessionConfigOptionCategory::Model
3292 );
3293 assert_eq!(
3294 serde_json::from_str::<SessionConfigOptionCategory>("\"thought_level\"").unwrap(),
3295 SessionConfigOptionCategory::ThoughtLevel
3296 );
3297 }
3298
3299 #[test]
3300 fn test_session_config_option_category_unknown_variants() {
3301 // Test that unknown strings are captured in Other variant
3302 let unknown: SessionConfigOptionCategory =
3303 serde_json::from_str("\"some_future_category\"").unwrap();
3304 assert_eq!(
3305 unknown,
3306 SessionConfigOptionCategory::Other("some_future_category".to_string())
3307 );
3308
3309 // Test round-trip of unknown category
3310 let json = serde_json::to_value(&unknown).unwrap();
3311 assert_eq!(json, json!("some_future_category"));
3312 }
3313
3314 #[test]
3315 fn test_session_config_option_category_custom_categories() {
3316 // Category names beginning with `_` are free for custom use
3317 let custom: SessionConfigOptionCategory =
3318 serde_json::from_str("\"_my_custom_category\"").unwrap();
3319 assert_eq!(
3320 custom,
3321 SessionConfigOptionCategory::Other("_my_custom_category".to_string())
3322 );
3323
3324 // Test round-trip preserves the custom category name
3325 let json = serde_json::to_value(&custom).unwrap();
3326 assert_eq!(json, json!("_my_custom_category"));
3327
3328 // Deserialize back and verify
3329 let deserialized: SessionConfigOptionCategory = serde_json::from_value(json).unwrap();
3330 assert_eq!(
3331 deserialized,
3332 SessionConfigOptionCategory::Other("_my_custom_category".to_string())
3333 );
3334 }
3335}