1use std::{path::PathBuf, sync::Arc};
7
8use derive_more::{Display, From};
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11use serde_json::value::RawValue;
12
13use crate::ext::ExtRequest;
14use crate::{ClientCapabilities, ContentBlock, ExtNotification, ProtocolVersion, SessionId};
15
16#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
24#[schemars(extend("x-side" = "agent", "x-method" = INITIALIZE_METHOD_NAME))]
25#[serde(rename_all = "camelCase")]
26#[non_exhaustive]
27pub struct InitializeRequest {
28 pub protocol_version: ProtocolVersion,
30 #[serde(default)]
32 pub client_capabilities: ClientCapabilities,
33 #[serde(skip_serializing_if = "Option::is_none")]
37 pub client_info: Option<Implementation>,
38 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
40 pub meta: Option<serde_json::Value>,
41}
42
43impl InitializeRequest {
44 #[must_use]
45 pub fn new(protocol_version: ProtocolVersion) -> Self {
46 Self {
47 protocol_version,
48 client_capabilities: ClientCapabilities::default(),
49 client_info: None,
50 meta: None,
51 }
52 }
53
54 #[must_use]
56 pub fn client_capabilities(mut self, client_capabilities: ClientCapabilities) -> Self {
57 self.client_capabilities = client_capabilities;
58 self
59 }
60
61 #[must_use]
63 pub fn client_info(mut self, client_info: Implementation) -> Self {
64 self.client_info = Some(client_info);
65 self
66 }
67
68 #[must_use]
70 pub fn meta(mut self, meta: serde_json::Value) -> Self {
71 self.meta = Some(meta);
72 self
73 }
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
82#[schemars(extend("x-side" = "agent", "x-method" = INITIALIZE_METHOD_NAME))]
83#[serde(rename_all = "camelCase")]
84#[non_exhaustive]
85pub struct InitializeResponse {
86 pub protocol_version: ProtocolVersion,
91 #[serde(default)]
93 pub agent_capabilities: AgentCapabilities,
94 #[serde(default)]
96 pub auth_methods: Vec<AuthMethod>,
97 #[serde(skip_serializing_if = "Option::is_none")]
101 pub agent_info: Option<Implementation>,
102 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
104 pub meta: Option<serde_json::Value>,
105}
106
107impl InitializeResponse {
108 #[must_use]
109 pub fn new(protocol_version: ProtocolVersion) -> Self {
110 Self {
111 protocol_version,
112 agent_capabilities: AgentCapabilities::default(),
113 auth_methods: vec![],
114 agent_info: None,
115 meta: None,
116 }
117 }
118
119 #[must_use]
121 pub fn agent_capabilities(mut self, agent_capabilities: AgentCapabilities) -> Self {
122 self.agent_capabilities = agent_capabilities;
123 self
124 }
125
126 #[must_use]
128 pub fn auth_methods(mut self, auth_methods: Vec<AuthMethod>) -> Self {
129 self.auth_methods = auth_methods;
130 self
131 }
132
133 #[must_use]
135 pub fn agent_info(mut self, agent_info: Implementation) -> Self {
136 self.agent_info = Some(agent_info);
137 self
138 }
139
140 #[must_use]
142 pub fn meta(mut self, meta: serde_json::Value) -> Self {
143 self.meta = Some(meta);
144 self
145 }
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
152#[serde(rename_all = "camelCase")]
153#[non_exhaustive]
154pub struct Implementation {
155 pub name: String,
158 pub title: Option<String>,
163 pub version: String,
166 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
168 pub meta: Option<serde_json::Value>,
169}
170
171impl Implementation {
172 pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
173 Self {
174 name: name.into(),
175 title: None,
176 version: version.into(),
177 meta: None,
178 }
179 }
180
181 #[must_use]
186 pub fn title(mut self, title: impl Into<String>) -> Self {
187 self.title = Some(title.into());
188 self
189 }
190
191 #[must_use]
193 pub fn meta(mut self, meta: serde_json::Value) -> Self {
194 self.meta = Some(meta);
195 self
196 }
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
205#[schemars(extend("x-side" = "agent", "x-method" = AUTHENTICATE_METHOD_NAME))]
206#[serde(rename_all = "camelCase")]
207#[non_exhaustive]
208pub struct AuthenticateRequest {
209 pub method_id: AuthMethodId,
212 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
214 pub meta: Option<serde_json::Value>,
215}
216
217impl AuthenticateRequest {
218 #[must_use]
219 pub fn new(method_id: AuthMethodId) -> Self {
220 Self {
221 method_id,
222 meta: None,
223 }
224 }
225
226 #[must_use]
227 pub fn meta(mut self, meta: serde_json::Value) -> Self {
228 self.meta = Some(meta);
229 self
230 }
231}
232
233#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
235#[serde(rename_all = "camelCase")]
236#[schemars(extend("x-side" = "agent", "x-method" = AUTHENTICATE_METHOD_NAME))]
237#[non_exhaustive]
238pub struct AuthenticateResponse {
239 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
241 pub meta: Option<serde_json::Value>,
242}
243
244impl AuthenticateResponse {
245 #[must_use]
246 pub fn new() -> Self {
247 Self::default()
248 }
249
250 #[must_use]
251 pub fn meta(mut self, meta: serde_json::Value) -> Self {
252 self.meta = Some(meta);
253 self
254 }
255}
256
257#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
258#[serde(transparent)]
259#[from(Arc<str>, String, &'static str)]
260#[non_exhaustive]
261pub struct AuthMethodId(pub Arc<str>);
262
263impl AuthMethodId {
264 pub fn new(id: impl Into<Arc<str>>) -> Self {
265 Self(id.into())
266 }
267}
268
269#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
271#[serde(rename_all = "camelCase")]
272#[non_exhaustive]
273pub struct AuthMethod {
274 pub id: AuthMethodId,
276 pub name: String,
278 pub description: Option<String>,
280 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
282 pub meta: Option<serde_json::Value>,
283}
284
285impl AuthMethod {
286 pub fn new(id: AuthMethodId, name: impl Into<String>) -> Self {
287 Self {
288 id,
289 name: name.into(),
290 description: None,
291 meta: None,
292 }
293 }
294
295 #[must_use]
297 pub fn description(mut self, description: impl Into<String>) -> Self {
298 self.description = Some(description.into());
299 self
300 }
301
302 #[must_use]
304 pub fn meta(mut self, meta: serde_json::Value) -> Self {
305 self.meta = Some(meta);
306 self
307 }
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
316#[schemars(extend("x-side" = "agent", "x-method" = SESSION_NEW_METHOD_NAME))]
317#[serde(rename_all = "camelCase")]
318#[non_exhaustive]
319pub struct NewSessionRequest {
320 pub cwd: PathBuf,
322 pub mcp_servers: Vec<McpServer>,
324 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
326 pub meta: Option<serde_json::Value>,
327}
328
329impl NewSessionRequest {
330 pub fn new(cwd: impl Into<PathBuf>) -> Self {
331 Self {
332 cwd: cwd.into(),
333 mcp_servers: vec![],
334 meta: None,
335 }
336 }
337
338 #[must_use]
340 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
341 self.mcp_servers = mcp_servers;
342 self
343 }
344
345 #[must_use]
347 pub fn meta(mut self, meta: serde_json::Value) -> Self {
348 self.meta = Some(meta);
349 self
350 }
351}
352
353#[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 NewSessionResponse {
361 pub session_id: SessionId,
365 #[serde(skip_serializing_if = "Option::is_none")]
369 pub modes: Option<SessionModeState>,
370 #[cfg(feature = "unstable_session_model")]
376 #[serde(skip_serializing_if = "Option::is_none")]
377 pub models: Option<SessionModelState>,
378 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
380 pub meta: Option<serde_json::Value>,
381}
382
383impl NewSessionResponse {
384 #[must_use]
385 pub fn new(session_id: SessionId) -> Self {
386 Self {
387 session_id,
388 modes: None,
389 #[cfg(feature = "unstable_session_model")]
390 models: None,
391 meta: None,
392 }
393 }
394
395 #[must_use]
399 pub fn modes(mut self, modes: SessionModeState) -> Self {
400 self.modes = Some(modes);
401 self
402 }
403
404 #[cfg(feature = "unstable_session_model")]
410 #[must_use]
411 pub fn models(mut self, models: SessionModelState) -> Self {
412 self.models = Some(models);
413 self
414 }
415
416 #[must_use]
418 pub fn meta(mut self, meta: serde_json::Value) -> Self {
419 self.meta = Some(meta);
420 self
421 }
422}
423
424#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
432#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
433#[serde(rename_all = "camelCase")]
434#[non_exhaustive]
435pub struct LoadSessionRequest {
436 pub mcp_servers: Vec<McpServer>,
438 pub cwd: PathBuf,
440 pub session_id: SessionId,
442 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
444 pub meta: Option<serde_json::Value>,
445}
446
447impl LoadSessionRequest {
448 pub fn new(session_id: SessionId, cwd: impl Into<PathBuf>) -> Self {
449 Self {
450 mcp_servers: vec![],
451 cwd: cwd.into(),
452 session_id,
453 meta: None,
454 }
455 }
456
457 #[must_use]
459 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
460 self.mcp_servers = mcp_servers;
461 self
462 }
463
464 #[must_use]
466 pub fn meta(mut self, meta: serde_json::Value) -> Self {
467 self.meta = Some(meta);
468 self
469 }
470}
471
472#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
474#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
475#[serde(rename_all = "camelCase")]
476#[non_exhaustive]
477pub struct LoadSessionResponse {
478 #[serde(default, skip_serializing_if = "Option::is_none")]
482 pub modes: Option<SessionModeState>,
483 #[cfg(feature = "unstable_session_model")]
489 #[serde(default, skip_serializing_if = "Option::is_none")]
490 pub models: Option<SessionModelState>,
491 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
493 pub meta: Option<serde_json::Value>,
494}
495
496impl LoadSessionResponse {
497 #[must_use]
498 pub fn new() -> Self {
499 Self::default()
500 }
501
502 #[must_use]
506 pub fn modes(mut self, modes: SessionModeState) -> Self {
507 self.modes = Some(modes);
508 self
509 }
510
511 #[cfg(feature = "unstable_session_model")]
517 #[must_use]
518 pub fn models(mut self, models: SessionModelState) -> Self {
519 self.models = Some(models);
520 self
521 }
522
523 #[must_use]
525 pub fn meta(mut self, meta: serde_json::Value) -> Self {
526 self.meta = Some(meta);
527 self
528 }
529}
530
531#[cfg(feature = "unstable_session_list")]
541#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
542#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
543#[serde(rename_all = "camelCase")]
544#[non_exhaustive]
545pub struct ListSessionsRequest {
546 #[serde(skip_serializing_if = "Option::is_none")]
548 pub cwd: Option<PathBuf>,
549 #[serde(skip_serializing_if = "Option::is_none")]
551 pub cursor: Option<String>,
552 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
554 pub meta: Option<serde_json::Value>,
555}
556
557#[cfg(feature = "unstable_session_list")]
558impl ListSessionsRequest {
559 #[must_use]
560 pub fn new() -> Self {
561 Self::default()
562 }
563
564 #[must_use]
566 pub fn cwd(mut self, cwd: impl Into<PathBuf>) -> Self {
567 self.cwd = Some(cwd.into());
568 self
569 }
570
571 #[must_use]
573 pub fn cursor(mut self, cursor: impl Into<String>) -> Self {
574 self.cursor = Some(cursor.into());
575 self
576 }
577
578 #[must_use]
580 pub fn meta(mut self, meta: serde_json::Value) -> Self {
581 self.meta = Some(meta);
582 self
583 }
584}
585
586#[cfg(feature = "unstable_session_list")]
592#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
593#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
594#[serde(rename_all = "camelCase")]
595#[non_exhaustive]
596pub struct ListSessionsResponse {
597 pub sessions: Vec<SessionInfo>,
599 #[serde(skip_serializing_if = "Option::is_none")]
602 pub next_cursor: Option<String>,
603 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
605 pub meta: Option<serde_json::Value>,
606}
607
608#[cfg(feature = "unstable_session_list")]
609impl ListSessionsResponse {
610 #[must_use]
611 pub fn new(sessions: Vec<SessionInfo>) -> Self {
612 Self {
613 sessions,
614 next_cursor: None,
615 meta: None,
616 }
617 }
618
619 #[must_use]
620 pub fn next_cursor(mut self, next_cursor: impl Into<String>) -> Self {
621 self.next_cursor = Some(next_cursor.into());
622 self
623 }
624
625 #[must_use]
627 pub fn meta(mut self, meta: serde_json::Value) -> Self {
628 self.meta = Some(meta);
629 self
630 }
631}
632
633#[cfg(feature = "unstable_session_list")]
639#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
640#[serde(rename_all = "camelCase")]
641#[non_exhaustive]
642pub struct SessionInfo {
643 pub session_id: SessionId,
645 pub cwd: PathBuf,
647 #[serde(skip_serializing_if = "Option::is_none")]
649 pub title: Option<String>,
650 #[serde(skip_serializing_if = "Option::is_none")]
652 pub updated_at: Option<String>,
653 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
655 pub meta: Option<serde_json::Value>,
656}
657
658#[cfg(feature = "unstable_session_list")]
659impl SessionInfo {
660 pub fn new(session_id: SessionId, cwd: impl Into<PathBuf>) -> Self {
661 Self {
662 session_id,
663 cwd: cwd.into(),
664 title: None,
665 updated_at: None,
666 meta: None,
667 }
668 }
669
670 #[must_use]
672 pub fn title(mut self, title: impl Into<String>) -> Self {
673 self.title = Some(title.into());
674 self
675 }
676
677 #[must_use]
679 pub fn updated_at(mut self, updated_at: impl Into<String>) -> Self {
680 self.updated_at = Some(updated_at.into());
681 self
682 }
683
684 #[must_use]
686 pub fn meta(mut self, meta: serde_json::Value) -> Self {
687 self.meta = Some(meta);
688 self
689 }
690}
691
692#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
696#[serde(rename_all = "camelCase")]
697#[non_exhaustive]
698pub struct SessionModeState {
699 pub current_mode_id: SessionModeId,
701 pub available_modes: Vec<SessionMode>,
703 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
705 pub meta: Option<serde_json::Value>,
706}
707
708impl SessionModeState {
709 #[must_use]
710 pub fn new(current_mode_id: SessionModeId, available_modes: Vec<SessionMode>) -> Self {
711 Self {
712 current_mode_id,
713 available_modes,
714 meta: None,
715 }
716 }
717
718 #[must_use]
720 pub fn meta(mut self, meta: serde_json::Value) -> Self {
721 self.meta = Some(meta);
722 self
723 }
724}
725
726#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
730#[serde(rename_all = "camelCase")]
731#[non_exhaustive]
732pub struct SessionMode {
733 pub id: SessionModeId,
734 pub name: String,
735 #[serde(default, skip_serializing_if = "Option::is_none")]
736 pub description: Option<String>,
737 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
739 pub meta: Option<serde_json::Value>,
740}
741
742impl SessionMode {
743 pub fn new(id: SessionModeId, name: impl Into<String>) -> Self {
744 Self {
745 id,
746 name: name.into(),
747 description: None,
748 meta: None,
749 }
750 }
751
752 #[must_use]
753 pub fn description(mut self, description: impl Into<String>) -> Self {
754 self.description = Some(description.into());
755 self
756 }
757
758 #[must_use]
760 pub fn meta(mut self, meta: serde_json::Value) -> Self {
761 self.meta = Some(meta);
762 self
763 }
764}
765
766#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
768#[serde(transparent)]
769#[from(Arc<str>, String, &'static str)]
770#[non_exhaustive]
771pub struct SessionModeId(pub Arc<str>);
772
773impl SessionModeId {
774 pub fn new(id: impl Into<Arc<str>>) -> Self {
775 Self(id.into())
776 }
777}
778
779#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
781#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
782#[serde(rename_all = "camelCase")]
783#[non_exhaustive]
784pub struct SetSessionModeRequest {
785 pub session_id: SessionId,
787 pub mode_id: SessionModeId,
789 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
791 pub meta: Option<serde_json::Value>,
792}
793
794impl SetSessionModeRequest {
795 #[must_use]
796 pub fn new(session_id: SessionId, mode_id: SessionModeId) -> Self {
797 Self {
798 session_id,
799 mode_id,
800 meta: None,
801 }
802 }
803
804 #[must_use]
805 pub fn meta(mut self, meta: serde_json::Value) -> Self {
806 self.meta = Some(meta);
807 self
808 }
809}
810
811#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
813#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
814#[serde(rename_all = "camelCase")]
815#[non_exhaustive]
816pub struct SetSessionModeResponse {
817 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
818 pub meta: Option<serde_json::Value>,
819}
820
821impl SetSessionModeResponse {
822 #[must_use]
823 pub fn new() -> Self {
824 Self::default()
825 }
826
827 #[must_use]
828 pub fn meta(mut self, meta: serde_json::Value) -> Self {
829 self.meta = Some(meta);
830 self
831 }
832}
833
834#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
843#[serde(tag = "type", rename_all = "snake_case")]
844#[schemars(extend("discriminator" = {"propertyName": "type"}))]
845#[non_exhaustive]
846pub enum McpServer {
847 Http(McpServerHttp),
851 Sse(McpServerSse),
855 #[serde(untagged)]
859 Stdio(McpServerStdio),
860}
861
862#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
864#[serde(rename_all = "camelCase")]
865#[non_exhaustive]
866pub struct McpServerHttp {
867 pub name: String,
869 pub url: String,
871 pub headers: Vec<HttpHeader>,
873 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
875 pub meta: Option<serde_json::Value>,
876}
877
878impl McpServerHttp {
879 pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
880 Self {
881 name: name.into(),
882 url: url.into(),
883 headers: Vec::new(),
884 meta: None,
885 }
886 }
887
888 #[must_use]
890 pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
891 self.headers = headers;
892 self
893 }
894
895 #[must_use]
897 pub fn meta(mut self, meta: serde_json::Value) -> Self {
898 self.meta = Some(meta);
899 self
900 }
901}
902
903#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
905#[serde(rename_all = "camelCase")]
906#[non_exhaustive]
907pub struct McpServerSse {
908 pub name: String,
910 pub url: String,
912 pub headers: Vec<HttpHeader>,
914 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
916 pub meta: Option<serde_json::Value>,
917}
918
919impl McpServerSse {
920 pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
921 Self {
922 name: name.into(),
923 url: url.into(),
924 headers: Vec::new(),
925 meta: None,
926 }
927 }
928
929 #[must_use]
931 pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
932 self.headers = headers;
933 self
934 }
935
936 #[must_use]
938 pub fn meta(mut self, meta: serde_json::Value) -> Self {
939 self.meta = Some(meta);
940 self
941 }
942}
943
944#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
946#[serde(rename_all = "camelCase")]
947#[non_exhaustive]
948pub struct McpServerStdio {
949 pub name: String,
951 pub command: PathBuf,
953 pub args: Vec<String>,
955 pub env: Vec<EnvVariable>,
957 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
959 pub meta: Option<serde_json::Value>,
960}
961
962impl McpServerStdio {
963 pub fn new(name: impl Into<String>, command: impl Into<PathBuf>) -> Self {
964 Self {
965 name: name.into(),
966 command: command.into(),
967 args: Vec::new(),
968 env: Vec::new(),
969 meta: None,
970 }
971 }
972
973 #[must_use]
975 pub fn args(mut self, args: Vec<String>) -> Self {
976 self.args = args;
977 self
978 }
979
980 #[must_use]
982 pub fn env(mut self, env: Vec<EnvVariable>) -> Self {
983 self.env = env;
984 self
985 }
986
987 #[must_use]
989 pub fn meta(mut self, meta: serde_json::Value) -> Self {
990 self.meta = Some(meta);
991 self
992 }
993}
994
995#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
997#[serde(rename_all = "camelCase")]
998#[non_exhaustive]
999pub struct EnvVariable {
1000 pub name: String,
1002 pub value: String,
1004 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1006 pub meta: Option<serde_json::Value>,
1007}
1008
1009impl EnvVariable {
1010 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1011 Self {
1012 name: name.into(),
1013 value: value.into(),
1014 meta: None,
1015 }
1016 }
1017
1018 #[must_use]
1020 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1021 self.meta = Some(meta);
1022 self
1023 }
1024}
1025
1026#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1028#[serde(rename_all = "camelCase")]
1029#[non_exhaustive]
1030pub struct HttpHeader {
1031 pub name: String,
1033 pub value: String,
1035 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1037 pub meta: Option<serde_json::Value>,
1038}
1039
1040impl HttpHeader {
1041 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1042 Self {
1043 name: name.into(),
1044 value: value.into(),
1045 meta: None,
1046 }
1047 }
1048
1049 #[must_use]
1051 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1052 self.meta = Some(meta);
1053 self
1054 }
1055}
1056
1057#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
1065#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1066#[serde(rename_all = "camelCase")]
1067#[non_exhaustive]
1068pub struct PromptRequest {
1069 pub session_id: SessionId,
1071 pub prompt: Vec<ContentBlock>,
1085 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1087 pub meta: Option<serde_json::Value>,
1088}
1089
1090impl PromptRequest {
1091 #[must_use]
1092 pub fn new(session_id: SessionId, prompt: Vec<ContentBlock>) -> Self {
1093 Self {
1094 session_id,
1095 prompt,
1096 meta: None,
1097 }
1098 }
1099
1100 #[must_use]
1102 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1103 self.meta = Some(meta);
1104 self
1105 }
1106}
1107
1108#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1112#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1113#[serde(rename_all = "camelCase")]
1114#[non_exhaustive]
1115pub struct PromptResponse {
1116 pub stop_reason: StopReason,
1118 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1120 pub meta: Option<serde_json::Value>,
1121}
1122
1123impl PromptResponse {
1124 #[must_use]
1125 pub fn new(stop_reason: StopReason) -> Self {
1126 Self {
1127 stop_reason,
1128 meta: None,
1129 }
1130 }
1131
1132 #[must_use]
1134 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1135 self.meta = Some(meta);
1136 self
1137 }
1138}
1139
1140#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1144#[serde(rename_all = "snake_case")]
1145#[non_exhaustive]
1146pub enum StopReason {
1147 EndTurn,
1149 MaxTokens,
1151 MaxTurnRequests,
1154 Refusal,
1158 Cancelled,
1165}
1166
1167#[cfg(feature = "unstable_session_model")]
1175#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1176#[serde(rename_all = "camelCase")]
1177#[non_exhaustive]
1178pub struct SessionModelState {
1179 pub current_model_id: ModelId,
1181 pub available_models: Vec<ModelInfo>,
1183 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1185 pub meta: Option<serde_json::Value>,
1186}
1187
1188#[cfg(feature = "unstable_session_model")]
1189impl SessionModelState {
1190 #[must_use]
1191 pub fn new(current_model_id: ModelId, available_models: Vec<ModelInfo>) -> Self {
1192 Self {
1193 current_model_id,
1194 available_models,
1195 meta: None,
1196 }
1197 }
1198
1199 #[must_use]
1201 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1202 self.meta = Some(meta);
1203 self
1204 }
1205}
1206
1207#[cfg(feature = "unstable_session_model")]
1213#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
1214#[serde(transparent)]
1215#[from(Arc<str>, String, &'static str)]
1216#[non_exhaustive]
1217pub struct ModelId(pub Arc<str>);
1218
1219#[cfg(feature = "unstable_session_model")]
1220impl ModelId {
1221 pub fn new(id: impl Into<Arc<str>>) -> Self {
1222 Self(id.into())
1223 }
1224}
1225
1226#[cfg(feature = "unstable_session_model")]
1232#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1233#[serde(rename_all = "camelCase")]
1234#[non_exhaustive]
1235pub struct ModelInfo {
1236 pub model_id: ModelId,
1238 pub name: String,
1240 #[serde(default, skip_serializing_if = "Option::is_none")]
1242 pub description: Option<String>,
1243 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1245 pub meta: Option<serde_json::Value>,
1246}
1247
1248#[cfg(feature = "unstable_session_model")]
1249impl ModelInfo {
1250 pub fn new(model_id: ModelId, name: impl Into<String>) -> Self {
1251 Self {
1252 model_id,
1253 name: name.into(),
1254 description: None,
1255 meta: None,
1256 }
1257 }
1258
1259 #[must_use]
1261 pub fn description(mut self, description: impl Into<String>) -> Self {
1262 self.description = Some(description.into());
1263 self
1264 }
1265
1266 #[must_use]
1268 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1269 self.meta = Some(meta);
1270 self
1271 }
1272}
1273
1274#[cfg(feature = "unstable_session_model")]
1280#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1281#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1282#[serde(rename_all = "camelCase")]
1283#[non_exhaustive]
1284pub struct SetSessionModelRequest {
1285 pub session_id: SessionId,
1287 pub model_id: ModelId,
1289 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1291 pub meta: Option<serde_json::Value>,
1292}
1293
1294#[cfg(feature = "unstable_session_model")]
1295impl SetSessionModelRequest {
1296 #[must_use]
1297 pub fn new(session_id: SessionId, model_id: ModelId) -> Self {
1298 Self {
1299 session_id,
1300 model_id,
1301 meta: None,
1302 }
1303 }
1304
1305 #[must_use]
1307 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1308 self.meta = Some(meta);
1309 self
1310 }
1311}
1312
1313#[cfg(feature = "unstable_session_model")]
1319#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1320#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1321#[serde(rename_all = "camelCase")]
1322#[non_exhaustive]
1323pub struct SetSessionModelResponse {
1324 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1326 pub meta: Option<serde_json::Value>,
1327}
1328
1329#[cfg(feature = "unstable_session_model")]
1330impl SetSessionModelResponse {
1331 #[must_use]
1332 pub fn new() -> Self {
1333 Self::default()
1334 }
1335
1336 #[must_use]
1338 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1339 self.meta = Some(meta);
1340 self
1341 }
1342}
1343
1344#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1353#[serde(rename_all = "camelCase")]
1354#[non_exhaustive]
1355pub struct AgentCapabilities {
1356 #[serde(default)]
1358 pub load_session: bool,
1359 #[serde(default)]
1361 pub prompt_capabilities: PromptCapabilities,
1362 #[serde(default)]
1364 pub mcp_capabilities: McpCapabilities,
1365 #[serde(default)]
1366 pub session_capabilities: SessionCapabilities,
1367 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1369 pub meta: Option<serde_json::Value>,
1370}
1371
1372impl AgentCapabilities {
1373 #[must_use]
1374 pub fn new() -> Self {
1375 Self::default()
1376 }
1377
1378 #[must_use]
1380 pub fn load_session(mut self, load_session: bool) -> Self {
1381 self.load_session = load_session;
1382 self
1383 }
1384
1385 #[must_use]
1387 pub fn prompt_capabilities(mut self, prompt_capabilities: PromptCapabilities) -> Self {
1388 self.prompt_capabilities = prompt_capabilities;
1389 self
1390 }
1391
1392 #[must_use]
1394 pub fn mcp_capabilities(mut self, mcp_capabilities: McpCapabilities) -> Self {
1395 self.mcp_capabilities = mcp_capabilities;
1396 self
1397 }
1398
1399 #[must_use]
1401 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1402 self.meta = Some(meta);
1403 self
1404 }
1405}
1406
1407#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1417#[non_exhaustive]
1418pub struct SessionCapabilities {
1419 #[cfg(feature = "unstable_session_list")]
1425 #[serde(skip_serializing_if = "Option::is_none")]
1426 pub list: Option<SessionListCapabilities>,
1427 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1429 pub meta: Option<serde_json::Value>,
1430}
1431
1432impl SessionCapabilities {
1433 #[must_use]
1434 pub fn new() -> Self {
1435 Self::default()
1436 }
1437
1438 #[cfg(feature = "unstable_session_list")]
1439 #[must_use]
1441 pub fn list(mut self, list: SessionListCapabilities) -> Self {
1442 self.list = Some(list);
1443 self
1444 }
1445
1446 #[must_use]
1448 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1449 self.meta = Some(meta);
1450 self
1451 }
1452}
1453
1454#[cfg(feature = "unstable_session_list")]
1460#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1461#[non_exhaustive]
1462pub struct SessionListCapabilities {
1463 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1465 pub meta: Option<serde_json::Value>,
1466}
1467
1468#[cfg(feature = "unstable_session_list")]
1469impl SessionListCapabilities {
1470 #[must_use]
1471 pub fn new() -> Self {
1472 Self::default()
1473 }
1474 #[must_use]
1476 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1477 self.meta = Some(meta);
1478 self
1479 }
1480}
1481
1482#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1495#[serde(rename_all = "camelCase")]
1496#[non_exhaustive]
1497pub struct PromptCapabilities {
1498 #[serde(default)]
1500 pub image: bool,
1501 #[serde(default)]
1503 pub audio: bool,
1504 #[serde(default)]
1509 pub embedded_context: bool,
1510 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1512 pub meta: Option<serde_json::Value>,
1513}
1514
1515impl PromptCapabilities {
1516 #[must_use]
1517 pub fn new() -> Self {
1518 Self::default()
1519 }
1520
1521 #[must_use]
1523 pub fn image(mut self, image: bool) -> Self {
1524 self.image = image;
1525 self
1526 }
1527
1528 #[must_use]
1530 pub fn audio(mut self, audio: bool) -> Self {
1531 self.audio = audio;
1532 self
1533 }
1534
1535 #[must_use]
1540 pub fn embedded_context(mut self, embedded_context: bool) -> Self {
1541 self.embedded_context = embedded_context;
1542 self
1543 }
1544
1545 #[must_use]
1547 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1548 self.meta = Some(meta);
1549 self
1550 }
1551}
1552
1553#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1555#[serde(rename_all = "camelCase")]
1556#[non_exhaustive]
1557pub struct McpCapabilities {
1558 #[serde(default)]
1560 pub http: bool,
1561 #[serde(default)]
1563 pub sse: bool,
1564 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1566 pub meta: Option<serde_json::Value>,
1567}
1568
1569impl McpCapabilities {
1570 #[must_use]
1571 pub fn new() -> Self {
1572 Self::default()
1573 }
1574
1575 #[must_use]
1577 pub fn http(mut self, http: bool) -> Self {
1578 self.http = http;
1579 self
1580 }
1581
1582 #[must_use]
1584 pub fn sse(mut self, sse: bool) -> Self {
1585 self.sse = sse;
1586 self
1587 }
1588
1589 #[must_use]
1591 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1592 self.meta = Some(meta);
1593 self
1594 }
1595}
1596
1597#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1603#[non_exhaustive]
1604pub struct AgentMethodNames {
1605 pub initialize: &'static str,
1607 pub authenticate: &'static str,
1609 pub session_new: &'static str,
1611 pub session_load: &'static str,
1613 pub session_set_mode: &'static str,
1615 pub session_prompt: &'static str,
1617 pub session_cancel: &'static str,
1619 #[cfg(feature = "unstable_session_model")]
1621 pub session_set_model: &'static str,
1622 #[cfg(feature = "unstable_session_list")]
1624 pub session_list: &'static str,
1625}
1626
1627pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
1629 initialize: INITIALIZE_METHOD_NAME,
1630 authenticate: AUTHENTICATE_METHOD_NAME,
1631 session_new: SESSION_NEW_METHOD_NAME,
1632 session_load: SESSION_LOAD_METHOD_NAME,
1633 session_set_mode: SESSION_SET_MODE_METHOD_NAME,
1634 session_prompt: SESSION_PROMPT_METHOD_NAME,
1635 session_cancel: SESSION_CANCEL_METHOD_NAME,
1636 #[cfg(feature = "unstable_session_model")]
1637 session_set_model: SESSION_SET_MODEL_METHOD_NAME,
1638 #[cfg(feature = "unstable_session_list")]
1639 session_list: SESSION_LIST_METHOD_NAME,
1640};
1641
1642pub(crate) const INITIALIZE_METHOD_NAME: &str = "initialize";
1644pub(crate) const AUTHENTICATE_METHOD_NAME: &str = "authenticate";
1646pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
1648pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
1650pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
1652pub(crate) const SESSION_PROMPT_METHOD_NAME: &str = "session/prompt";
1654pub(crate) const SESSION_CANCEL_METHOD_NAME: &str = "session/cancel";
1656#[cfg(feature = "unstable_session_model")]
1658pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
1659#[cfg(feature = "unstable_session_list")]
1661pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list";
1662
1663#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
1670#[serde(untagged)]
1671#[schemars(extend("x-docs-ignore" = true))]
1672#[non_exhaustive]
1673pub enum ClientRequest {
1674 InitializeRequest(InitializeRequest),
1685 AuthenticateRequest(AuthenticateRequest),
1695 NewSessionRequest(NewSessionRequest),
1708 LoadSessionRequest(LoadSessionRequest),
1719 #[cfg(feature = "unstable_session_list")]
1720 ListSessionsRequest(ListSessionsRequest),
1730 SetSessionModeRequest(SetSessionModeRequest),
1744 PromptRequest(PromptRequest),
1756 #[cfg(feature = "unstable_session_model")]
1757 SetSessionModelRequest(SetSessionModelRequest),
1763 ExtMethodRequest(ExtRequest),
1770}
1771
1772#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
1779#[serde(untagged)]
1780#[schemars(extend("x-docs-ignore" = true))]
1781#[non_exhaustive]
1782pub enum AgentResponse {
1783 InitializeResponse(InitializeResponse),
1784 AuthenticateResponse(#[serde(default)] AuthenticateResponse),
1785 NewSessionResponse(NewSessionResponse),
1786 LoadSessionResponse(#[serde(default)] LoadSessionResponse),
1787 #[cfg(feature = "unstable_session_list")]
1788 ListSessionsResponse(ListSessionsResponse),
1789 SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
1790 PromptResponse(PromptResponse),
1791 #[cfg(feature = "unstable_session_model")]
1792 SetSessionModelResponse(SetSessionModelResponse),
1793 ExtMethodResponse(#[schemars(with = "serde_json::Value")] Arc<RawValue>),
1794}
1795
1796#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
1803#[serde(untagged)]
1804#[schemars(extend("x-docs-ignore" = true))]
1805#[non_exhaustive]
1806pub enum ClientNotification {
1807 CancelNotification(CancelNotification),
1819 ExtNotification(ExtNotification),
1826}
1827
1828#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1832#[schemars(extend("x-side" = "agent", "x-method" = SESSION_CANCEL_METHOD_NAME))]
1833#[serde(rename_all = "camelCase")]
1834#[non_exhaustive]
1835pub struct CancelNotification {
1836 pub session_id: SessionId,
1838 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1840 pub meta: Option<serde_json::Value>,
1841}
1842
1843impl CancelNotification {
1844 #[must_use]
1845 pub fn new(session_id: SessionId) -> Self {
1846 Self {
1847 session_id,
1848 meta: None,
1849 }
1850 }
1851
1852 #[must_use]
1854 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1855 self.meta = Some(meta);
1856 self
1857 }
1858}
1859
1860#[cfg(test)]
1861mod test_serialization {
1862 use super::*;
1863 use serde_json::json;
1864
1865 #[test]
1866 fn test_mcp_server_stdio_serialization() {
1867 let server = McpServer::Stdio(
1868 McpServerStdio::new("test-server", "/usr/bin/server")
1869 .args(vec!["--port".to_string(), "3000".to_string()])
1870 .env(vec![EnvVariable::new("API_KEY", "secret123")]),
1871 );
1872
1873 let json = serde_json::to_value(&server).unwrap();
1874 assert_eq!(
1875 json,
1876 json!({
1877 "name": "test-server",
1878 "command": "/usr/bin/server",
1879 "args": ["--port", "3000"],
1880 "env": [
1881 {
1882 "name": "API_KEY",
1883 "value": "secret123"
1884 }
1885 ]
1886 })
1887 );
1888
1889 let deserialized: McpServer = serde_json::from_value(json).unwrap();
1890 match deserialized {
1891 McpServer::Stdio(McpServerStdio {
1892 name,
1893 command,
1894 args,
1895 env,
1896 meta: _,
1897 }) => {
1898 assert_eq!(name, "test-server");
1899 assert_eq!(command, PathBuf::from("/usr/bin/server"));
1900 assert_eq!(args, vec!["--port", "3000"]);
1901 assert_eq!(env.len(), 1);
1902 assert_eq!(env[0].name, "API_KEY");
1903 assert_eq!(env[0].value, "secret123");
1904 }
1905 _ => panic!("Expected Stdio variant"),
1906 }
1907 }
1908
1909 #[test]
1910 fn test_mcp_server_http_serialization() {
1911 let server = McpServer::Http(
1912 McpServerHttp::new("http-server", "https://api.example.com").headers(vec![
1913 HttpHeader::new("Authorization", "Bearer token123"),
1914 HttpHeader::new("Content-Type", "application/json"),
1915 ]),
1916 );
1917
1918 let json = serde_json::to_value(&server).unwrap();
1919 assert_eq!(
1920 json,
1921 json!({
1922 "type": "http",
1923 "name": "http-server",
1924 "url": "https://api.example.com",
1925 "headers": [
1926 {
1927 "name": "Authorization",
1928 "value": "Bearer token123"
1929 },
1930 {
1931 "name": "Content-Type",
1932 "value": "application/json"
1933 }
1934 ]
1935 })
1936 );
1937
1938 let deserialized: McpServer = serde_json::from_value(json).unwrap();
1939 match deserialized {
1940 McpServer::Http(McpServerHttp {
1941 name,
1942 url,
1943 headers,
1944 meta: _,
1945 }) => {
1946 assert_eq!(name, "http-server");
1947 assert_eq!(url, "https://api.example.com");
1948 assert_eq!(headers.len(), 2);
1949 assert_eq!(headers[0].name, "Authorization");
1950 assert_eq!(headers[0].value, "Bearer token123");
1951 assert_eq!(headers[1].name, "Content-Type");
1952 assert_eq!(headers[1].value, "application/json");
1953 }
1954 _ => panic!("Expected Http variant"),
1955 }
1956 }
1957
1958 #[test]
1959 fn test_mcp_server_sse_serialization() {
1960 let server = McpServer::Sse(
1961 McpServerSse::new("sse-server", "https://sse.example.com/events")
1962 .headers(vec![HttpHeader::new("X-API-Key", "apikey456")]),
1963 );
1964
1965 let json = serde_json::to_value(&server).unwrap();
1966 assert_eq!(
1967 json,
1968 json!({
1969 "type": "sse",
1970 "name": "sse-server",
1971 "url": "https://sse.example.com/events",
1972 "headers": [
1973 {
1974 "name": "X-API-Key",
1975 "value": "apikey456"
1976 }
1977 ]
1978 })
1979 );
1980
1981 let deserialized: McpServer = serde_json::from_value(json).unwrap();
1982 match deserialized {
1983 McpServer::Sse(McpServerSse {
1984 name,
1985 url,
1986 headers,
1987 meta: _,
1988 }) => {
1989 assert_eq!(name, "sse-server");
1990 assert_eq!(url, "https://sse.example.com/events");
1991 assert_eq!(headers.len(), 1);
1992 assert_eq!(headers[0].name, "X-API-Key");
1993 assert_eq!(headers[0].value, "apikey456");
1994 }
1995 _ => panic!("Expected Sse variant"),
1996 }
1997 }
1998}