1use std::{path::PathBuf, sync::Arc};
7
8use derive_more::{Display, From};
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11
12use crate::ext::ExtRequest;
13use crate::{
14 ClientCapabilities, ContentBlock, ExtNotification, ExtResponse, ProtocolVersion, SessionId,
15};
16
17#[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 pub protocol_version: ProtocolVersion,
31 #[serde(default)]
33 pub client_capabilities: ClientCapabilities,
34 #[serde(skip_serializing_if = "Option::is_none")]
38 pub client_info: Option<Implementation>,
39 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
41 pub meta: Option<serde_json::Value>,
42}
43
44impl InitializeRequest {
45 #[must_use]
46 pub fn new(protocol_version: ProtocolVersion) -> Self {
47 Self {
48 protocol_version,
49 client_capabilities: ClientCapabilities::default(),
50 client_info: None,
51 meta: None,
52 }
53 }
54
55 #[must_use]
57 pub fn client_capabilities(mut self, client_capabilities: ClientCapabilities) -> Self {
58 self.client_capabilities = client_capabilities;
59 self
60 }
61
62 #[must_use]
64 pub fn client_info(mut self, client_info: Implementation) -> Self {
65 self.client_info = Some(client_info);
66 self
67 }
68
69 #[must_use]
71 pub fn meta(mut self, meta: serde_json::Value) -> Self {
72 self.meta = Some(meta);
73 self
74 }
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
83#[schemars(extend("x-side" = "agent", "x-method" = INITIALIZE_METHOD_NAME))]
84#[serde(rename_all = "camelCase")]
85#[non_exhaustive]
86pub struct InitializeResponse {
87 pub protocol_version: ProtocolVersion,
92 #[serde(default)]
94 pub agent_capabilities: AgentCapabilities,
95 #[serde(default)]
97 pub auth_methods: Vec<AuthMethod>,
98 #[serde(skip_serializing_if = "Option::is_none")]
102 pub agent_info: Option<Implementation>,
103 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
105 pub meta: Option<serde_json::Value>,
106}
107
108impl InitializeResponse {
109 #[must_use]
110 pub fn new(protocol_version: ProtocolVersion) -> Self {
111 Self {
112 protocol_version,
113 agent_capabilities: AgentCapabilities::default(),
114 auth_methods: vec![],
115 agent_info: None,
116 meta: None,
117 }
118 }
119
120 #[must_use]
122 pub fn agent_capabilities(mut self, agent_capabilities: AgentCapabilities) -> Self {
123 self.agent_capabilities = agent_capabilities;
124 self
125 }
126
127 #[must_use]
129 pub fn auth_methods(mut self, auth_methods: Vec<AuthMethod>) -> Self {
130 self.auth_methods = auth_methods;
131 self
132 }
133
134 #[must_use]
136 pub fn agent_info(mut self, agent_info: Implementation) -> Self {
137 self.agent_info = Some(agent_info);
138 self
139 }
140
141 #[must_use]
143 pub fn meta(mut self, meta: serde_json::Value) -> Self {
144 self.meta = Some(meta);
145 self
146 }
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
153#[serde(rename_all = "camelCase")]
154#[non_exhaustive]
155pub struct Implementation {
156 pub name: String,
159 pub title: Option<String>,
164 pub version: String,
167 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
169 pub meta: Option<serde_json::Value>,
170}
171
172impl Implementation {
173 pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
174 Self {
175 name: name.into(),
176 title: None,
177 version: version.into(),
178 meta: None,
179 }
180 }
181
182 #[must_use]
187 pub fn title(mut self, title: impl Into<String>) -> Self {
188 self.title = Some(title.into());
189 self
190 }
191
192 #[must_use]
194 pub fn meta(mut self, meta: serde_json::Value) -> Self {
195 self.meta = Some(meta);
196 self
197 }
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
206#[schemars(extend("x-side" = "agent", "x-method" = AUTHENTICATE_METHOD_NAME))]
207#[serde(rename_all = "camelCase")]
208#[non_exhaustive]
209pub struct AuthenticateRequest {
210 pub method_id: AuthMethodId,
213 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
215 pub meta: Option<serde_json::Value>,
216}
217
218impl AuthenticateRequest {
219 #[must_use]
220 pub fn new(method_id: impl Into<AuthMethodId>) -> Self {
221 Self {
222 method_id: method_id.into(),
223 meta: None,
224 }
225 }
226
227 #[must_use]
228 pub fn meta(mut self, meta: serde_json::Value) -> Self {
229 self.meta = Some(meta);
230 self
231 }
232}
233
234#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
236#[serde(rename_all = "camelCase")]
237#[schemars(extend("x-side" = "agent", "x-method" = AUTHENTICATE_METHOD_NAME))]
238#[non_exhaustive]
239pub struct AuthenticateResponse {
240 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
242 pub meta: Option<serde_json::Value>,
243}
244
245impl AuthenticateResponse {
246 #[must_use]
247 pub fn new() -> Self {
248 Self::default()
249 }
250
251 #[must_use]
252 pub fn meta(mut self, meta: serde_json::Value) -> Self {
253 self.meta = Some(meta);
254 self
255 }
256}
257
258#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
259#[serde(transparent)]
260#[from(Arc<str>, String, &'static str)]
261#[non_exhaustive]
262pub struct AuthMethodId(pub Arc<str>);
263
264impl AuthMethodId {
265 pub fn new(id: impl Into<Arc<str>>) -> Self {
266 Self(id.into())
267 }
268}
269
270#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
272#[serde(rename_all = "camelCase")]
273#[non_exhaustive]
274pub struct AuthMethod {
275 pub id: AuthMethodId,
277 pub name: String,
279 pub description: Option<String>,
281 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
283 pub meta: Option<serde_json::Value>,
284}
285
286impl AuthMethod {
287 pub fn new(id: impl Into<AuthMethodId>, name: impl Into<String>) -> Self {
288 Self {
289 id: id.into(),
290 name: name.into(),
291 description: None,
292 meta: None,
293 }
294 }
295
296 #[must_use]
298 pub fn description(mut self, description: impl Into<String>) -> Self {
299 self.description = Some(description.into());
300 self
301 }
302
303 #[must_use]
305 pub fn meta(mut self, meta: serde_json::Value) -> Self {
306 self.meta = Some(meta);
307 self
308 }
309}
310
311#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
317#[schemars(extend("x-side" = "agent", "x-method" = SESSION_NEW_METHOD_NAME))]
318#[serde(rename_all = "camelCase")]
319#[non_exhaustive]
320pub struct NewSessionRequest {
321 pub cwd: PathBuf,
323 pub mcp_servers: Vec<McpServer>,
325 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
327 pub meta: Option<serde_json::Value>,
328}
329
330impl NewSessionRequest {
331 pub fn new(cwd: impl Into<PathBuf>) -> Self {
332 Self {
333 cwd: cwd.into(),
334 mcp_servers: vec![],
335 meta: None,
336 }
337 }
338
339 #[must_use]
341 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
342 self.mcp_servers = mcp_servers;
343 self
344 }
345
346 #[must_use]
348 pub fn meta(mut self, meta: serde_json::Value) -> Self {
349 self.meta = Some(meta);
350 self
351 }
352}
353
354#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
358#[schemars(extend("x-side" = "agent", "x-method" = SESSION_NEW_METHOD_NAME))]
359#[serde(rename_all = "camelCase")]
360#[non_exhaustive]
361pub struct NewSessionResponse {
362 pub session_id: SessionId,
366 #[serde(skip_serializing_if = "Option::is_none")]
370 pub modes: Option<SessionModeState>,
371 #[cfg(feature = "unstable_session_model")]
377 #[serde(skip_serializing_if = "Option::is_none")]
378 pub models: Option<SessionModelState>,
379 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
381 pub meta: Option<serde_json::Value>,
382}
383
384impl NewSessionResponse {
385 #[must_use]
386 pub fn new(session_id: impl Into<SessionId>) -> Self {
387 Self {
388 session_id: session_id.into(),
389 modes: None,
390 #[cfg(feature = "unstable_session_model")]
391 models: None,
392 meta: None,
393 }
394 }
395
396 #[must_use]
400 pub fn modes(mut self, modes: SessionModeState) -> Self {
401 self.modes = Some(modes);
402 self
403 }
404
405 #[cfg(feature = "unstable_session_model")]
411 #[must_use]
412 pub fn models(mut self, models: SessionModelState) -> Self {
413 self.models = Some(models);
414 self
415 }
416
417 #[must_use]
419 pub fn meta(mut self, meta: serde_json::Value) -> Self {
420 self.meta = Some(meta);
421 self
422 }
423}
424
425#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
433#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
434#[serde(rename_all = "camelCase")]
435#[non_exhaustive]
436pub struct LoadSessionRequest {
437 pub mcp_servers: Vec<McpServer>,
439 pub cwd: PathBuf,
441 pub session_id: SessionId,
443 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
445 pub meta: Option<serde_json::Value>,
446}
447
448impl LoadSessionRequest {
449 pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
450 Self {
451 mcp_servers: vec![],
452 cwd: cwd.into(),
453 session_id: session_id.into(),
454 meta: None,
455 }
456 }
457
458 #[must_use]
460 pub fn mcp_servers(mut self, mcp_servers: Vec<McpServer>) -> Self {
461 self.mcp_servers = mcp_servers;
462 self
463 }
464
465 #[must_use]
467 pub fn meta(mut self, meta: serde_json::Value) -> Self {
468 self.meta = Some(meta);
469 self
470 }
471}
472
473#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
475#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LOAD_METHOD_NAME))]
476#[serde(rename_all = "camelCase")]
477#[non_exhaustive]
478pub struct LoadSessionResponse {
479 #[serde(default, skip_serializing_if = "Option::is_none")]
483 pub modes: Option<SessionModeState>,
484 #[cfg(feature = "unstable_session_model")]
490 #[serde(default, skip_serializing_if = "Option::is_none")]
491 pub models: Option<SessionModelState>,
492 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
494 pub meta: Option<serde_json::Value>,
495}
496
497impl LoadSessionResponse {
498 #[must_use]
499 pub fn new() -> Self {
500 Self::default()
501 }
502
503 #[must_use]
507 pub fn modes(mut self, modes: SessionModeState) -> Self {
508 self.modes = Some(modes);
509 self
510 }
511
512 #[cfg(feature = "unstable_session_model")]
518 #[must_use]
519 pub fn models(mut self, models: SessionModelState) -> Self {
520 self.models = Some(models);
521 self
522 }
523
524 #[must_use]
526 pub fn meta(mut self, meta: serde_json::Value) -> Self {
527 self.meta = Some(meta);
528 self
529 }
530}
531
532#[cfg(feature = "unstable_session_list")]
542#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
543#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
544#[serde(rename_all = "camelCase")]
545#[non_exhaustive]
546pub struct ListSessionsRequest {
547 #[serde(skip_serializing_if = "Option::is_none")]
549 pub cwd: Option<PathBuf>,
550 #[serde(skip_serializing_if = "Option::is_none")]
552 pub cursor: Option<String>,
553 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
555 pub meta: Option<serde_json::Value>,
556}
557
558#[cfg(feature = "unstable_session_list")]
559impl ListSessionsRequest {
560 #[must_use]
561 pub fn new() -> Self {
562 Self::default()
563 }
564
565 #[must_use]
567 pub fn cwd(mut self, cwd: impl Into<PathBuf>) -> Self {
568 self.cwd = Some(cwd.into());
569 self
570 }
571
572 #[must_use]
574 pub fn cursor(mut self, cursor: impl Into<String>) -> Self {
575 self.cursor = Some(cursor.into());
576 self
577 }
578
579 #[must_use]
581 pub fn meta(mut self, meta: serde_json::Value) -> Self {
582 self.meta = Some(meta);
583 self
584 }
585}
586
587#[cfg(feature = "unstable_session_list")]
593#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
594#[schemars(extend("x-side" = "agent", "x-method" = SESSION_LIST_METHOD_NAME))]
595#[serde(rename_all = "camelCase")]
596#[non_exhaustive]
597pub struct ListSessionsResponse {
598 pub sessions: Vec<SessionInfo>,
600 #[serde(skip_serializing_if = "Option::is_none")]
603 pub next_cursor: Option<String>,
604 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
606 pub meta: Option<serde_json::Value>,
607}
608
609#[cfg(feature = "unstable_session_list")]
610impl ListSessionsResponse {
611 #[must_use]
612 pub fn new(sessions: Vec<SessionInfo>) -> Self {
613 Self {
614 sessions,
615 next_cursor: None,
616 meta: None,
617 }
618 }
619
620 #[must_use]
621 pub fn next_cursor(mut self, next_cursor: impl Into<String>) -> Self {
622 self.next_cursor = Some(next_cursor.into());
623 self
624 }
625
626 #[must_use]
628 pub fn meta(mut self, meta: serde_json::Value) -> Self {
629 self.meta = Some(meta);
630 self
631 }
632}
633
634#[cfg(feature = "unstable_session_list")]
640#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
641#[serde(rename_all = "camelCase")]
642#[non_exhaustive]
643pub struct SessionInfo {
644 pub session_id: SessionId,
646 pub cwd: PathBuf,
648 #[serde(skip_serializing_if = "Option::is_none")]
650 pub title: Option<String>,
651 #[serde(skip_serializing_if = "Option::is_none")]
653 pub updated_at: Option<String>,
654 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
656 pub meta: Option<serde_json::Value>,
657}
658
659#[cfg(feature = "unstable_session_list")]
660impl SessionInfo {
661 pub fn new(session_id: impl Into<SessionId>, cwd: impl Into<PathBuf>) -> Self {
662 Self {
663 session_id: session_id.into(),
664 cwd: cwd.into(),
665 title: None,
666 updated_at: None,
667 meta: None,
668 }
669 }
670
671 #[must_use]
673 pub fn title(mut self, title: impl Into<String>) -> Self {
674 self.title = Some(title.into());
675 self
676 }
677
678 #[must_use]
680 pub fn updated_at(mut self, updated_at: impl Into<String>) -> Self {
681 self.updated_at = Some(updated_at.into());
682 self
683 }
684
685 #[must_use]
687 pub fn meta(mut self, meta: serde_json::Value) -> Self {
688 self.meta = Some(meta);
689 self
690 }
691}
692
693#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
697#[serde(rename_all = "camelCase")]
698#[non_exhaustive]
699pub struct SessionModeState {
700 pub current_mode_id: SessionModeId,
702 pub available_modes: Vec<SessionMode>,
704 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
706 pub meta: Option<serde_json::Value>,
707}
708
709impl SessionModeState {
710 #[must_use]
711 pub fn new(
712 current_mode_id: impl Into<SessionModeId>,
713 available_modes: Vec<SessionMode>,
714 ) -> Self {
715 Self {
716 current_mode_id: current_mode_id.into(),
717 available_modes,
718 meta: None,
719 }
720 }
721
722 #[must_use]
724 pub fn meta(mut self, meta: serde_json::Value) -> Self {
725 self.meta = Some(meta);
726 self
727 }
728}
729
730#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
734#[serde(rename_all = "camelCase")]
735#[non_exhaustive]
736pub struct SessionMode {
737 pub id: SessionModeId,
738 pub name: String,
739 #[serde(default, skip_serializing_if = "Option::is_none")]
740 pub description: Option<String>,
741 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
743 pub meta: Option<serde_json::Value>,
744}
745
746impl SessionMode {
747 pub fn new(id: impl Into<SessionModeId>, name: impl Into<String>) -> Self {
748 Self {
749 id: id.into(),
750 name: name.into(),
751 description: None,
752 meta: None,
753 }
754 }
755
756 #[must_use]
757 pub fn description(mut self, description: impl Into<String>) -> Self {
758 self.description = Some(description.into());
759 self
760 }
761
762 #[must_use]
764 pub fn meta(mut self, meta: serde_json::Value) -> Self {
765 self.meta = Some(meta);
766 self
767 }
768}
769
770#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, From, Display)]
772#[serde(transparent)]
773#[from(Arc<str>, String, &'static str)]
774#[non_exhaustive]
775pub struct SessionModeId(pub Arc<str>);
776
777impl SessionModeId {
778 pub fn new(id: impl Into<Arc<str>>) -> Self {
779 Self(id.into())
780 }
781}
782
783#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
785#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
786#[serde(rename_all = "camelCase")]
787#[non_exhaustive]
788pub struct SetSessionModeRequest {
789 pub session_id: SessionId,
791 pub mode_id: SessionModeId,
793 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
795 pub meta: Option<serde_json::Value>,
796}
797
798impl SetSessionModeRequest {
799 #[must_use]
800 pub fn new(session_id: impl Into<SessionId>, mode_id: impl Into<SessionModeId>) -> Self {
801 Self {
802 session_id: session_id.into(),
803 mode_id: mode_id.into(),
804 meta: None,
805 }
806 }
807
808 #[must_use]
809 pub fn meta(mut self, meta: serde_json::Value) -> Self {
810 self.meta = Some(meta);
811 self
812 }
813}
814
815#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
817#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODE_METHOD_NAME))]
818#[serde(rename_all = "camelCase")]
819#[non_exhaustive]
820pub struct SetSessionModeResponse {
821 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
822 pub meta: Option<serde_json::Value>,
823}
824
825impl SetSessionModeResponse {
826 #[must_use]
827 pub fn new() -> Self {
828 Self::default()
829 }
830
831 #[must_use]
832 pub fn meta(mut self, meta: serde_json::Value) -> Self {
833 self.meta = Some(meta);
834 self
835 }
836}
837
838#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
847#[serde(tag = "type", rename_all = "snake_case")]
848#[schemars(extend("discriminator" = {"propertyName": "type"}))]
849#[non_exhaustive]
850pub enum McpServer {
851 Http(McpServerHttp),
855 Sse(McpServerSse),
859 #[serde(untagged)]
863 Stdio(McpServerStdio),
864}
865
866#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
868#[serde(rename_all = "camelCase")]
869#[non_exhaustive]
870pub struct McpServerHttp {
871 pub name: String,
873 pub url: String,
875 pub headers: Vec<HttpHeader>,
877 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
879 pub meta: Option<serde_json::Value>,
880}
881
882impl McpServerHttp {
883 pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
884 Self {
885 name: name.into(),
886 url: url.into(),
887 headers: Vec::new(),
888 meta: None,
889 }
890 }
891
892 #[must_use]
894 pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
895 self.headers = headers;
896 self
897 }
898
899 #[must_use]
901 pub fn meta(mut self, meta: serde_json::Value) -> Self {
902 self.meta = Some(meta);
903 self
904 }
905}
906
907#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
909#[serde(rename_all = "camelCase")]
910#[non_exhaustive]
911pub struct McpServerSse {
912 pub name: String,
914 pub url: String,
916 pub headers: Vec<HttpHeader>,
918 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
920 pub meta: Option<serde_json::Value>,
921}
922
923impl McpServerSse {
924 pub fn new(name: impl Into<String>, url: impl Into<String>) -> Self {
925 Self {
926 name: name.into(),
927 url: url.into(),
928 headers: Vec::new(),
929 meta: None,
930 }
931 }
932
933 #[must_use]
935 pub fn headers(mut self, headers: Vec<HttpHeader>) -> Self {
936 self.headers = headers;
937 self
938 }
939
940 #[must_use]
942 pub fn meta(mut self, meta: serde_json::Value) -> Self {
943 self.meta = Some(meta);
944 self
945 }
946}
947
948#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
950#[serde(rename_all = "camelCase")]
951#[non_exhaustive]
952pub struct McpServerStdio {
953 pub name: String,
955 pub command: PathBuf,
957 pub args: Vec<String>,
959 pub env: Vec<EnvVariable>,
961 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
963 pub meta: Option<serde_json::Value>,
964}
965
966impl McpServerStdio {
967 pub fn new(name: impl Into<String>, command: impl Into<PathBuf>) -> Self {
968 Self {
969 name: name.into(),
970 command: command.into(),
971 args: Vec::new(),
972 env: Vec::new(),
973 meta: None,
974 }
975 }
976
977 #[must_use]
979 pub fn args(mut self, args: Vec<String>) -> Self {
980 self.args = args;
981 self
982 }
983
984 #[must_use]
986 pub fn env(mut self, env: Vec<EnvVariable>) -> Self {
987 self.env = env;
988 self
989 }
990
991 #[must_use]
993 pub fn meta(mut self, meta: serde_json::Value) -> Self {
994 self.meta = Some(meta);
995 self
996 }
997}
998
999#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1001#[serde(rename_all = "camelCase")]
1002#[non_exhaustive]
1003pub struct EnvVariable {
1004 pub name: String,
1006 pub value: String,
1008 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1010 pub meta: Option<serde_json::Value>,
1011}
1012
1013impl EnvVariable {
1014 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1015 Self {
1016 name: name.into(),
1017 value: value.into(),
1018 meta: None,
1019 }
1020 }
1021
1022 #[must_use]
1024 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1025 self.meta = Some(meta);
1026 self
1027 }
1028}
1029
1030#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1032#[serde(rename_all = "camelCase")]
1033#[non_exhaustive]
1034pub struct HttpHeader {
1035 pub name: String,
1037 pub value: String,
1039 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1041 pub meta: Option<serde_json::Value>,
1042}
1043
1044impl HttpHeader {
1045 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
1046 Self {
1047 name: name.into(),
1048 value: value.into(),
1049 meta: None,
1050 }
1051 }
1052
1053 #[must_use]
1055 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1056 self.meta = Some(meta);
1057 self
1058 }
1059}
1060
1061#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
1069#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1070#[serde(rename_all = "camelCase")]
1071#[non_exhaustive]
1072pub struct PromptRequest {
1073 pub session_id: SessionId,
1075 pub prompt: Vec<ContentBlock>,
1089 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1091 pub meta: Option<serde_json::Value>,
1092}
1093
1094impl PromptRequest {
1095 #[must_use]
1096 pub fn new(session_id: impl Into<SessionId>, prompt: Vec<ContentBlock>) -> Self {
1097 Self {
1098 session_id: session_id.into(),
1099 prompt,
1100 meta: None,
1101 }
1102 }
1103
1104 #[must_use]
1106 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1107 self.meta = Some(meta);
1108 self
1109 }
1110}
1111
1112#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1116#[schemars(extend("x-side" = "agent", "x-method" = SESSION_PROMPT_METHOD_NAME))]
1117#[serde(rename_all = "camelCase")]
1118#[non_exhaustive]
1119pub struct PromptResponse {
1120 pub stop_reason: StopReason,
1122 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1124 pub meta: Option<serde_json::Value>,
1125}
1126
1127impl PromptResponse {
1128 #[must_use]
1129 pub fn new(stop_reason: StopReason) -> Self {
1130 Self {
1131 stop_reason,
1132 meta: None,
1133 }
1134 }
1135
1136 #[must_use]
1138 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1139 self.meta = Some(meta);
1140 self
1141 }
1142}
1143
1144#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1148#[serde(rename_all = "snake_case")]
1149#[non_exhaustive]
1150pub enum StopReason {
1151 EndTurn,
1153 MaxTokens,
1155 MaxTurnRequests,
1158 Refusal,
1162 Cancelled,
1169}
1170
1171#[cfg(feature = "unstable_session_model")]
1179#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1180#[serde(rename_all = "camelCase")]
1181#[non_exhaustive]
1182pub struct SessionModelState {
1183 pub current_model_id: ModelId,
1185 pub available_models: Vec<ModelInfo>,
1187 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1189 pub meta: Option<serde_json::Value>,
1190}
1191
1192#[cfg(feature = "unstable_session_model")]
1193impl SessionModelState {
1194 #[must_use]
1195 pub fn new(current_model_id: impl Into<ModelId>, available_models: Vec<ModelInfo>) -> Self {
1196 Self {
1197 current_model_id: current_model_id.into(),
1198 available_models,
1199 meta: None,
1200 }
1201 }
1202
1203 #[must_use]
1205 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1206 self.meta = Some(meta);
1207 self
1208 }
1209}
1210
1211#[cfg(feature = "unstable_session_model")]
1217#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
1218#[serde(transparent)]
1219#[from(Arc<str>, String, &'static str)]
1220#[non_exhaustive]
1221pub struct ModelId(pub Arc<str>);
1222
1223#[cfg(feature = "unstable_session_model")]
1224impl ModelId {
1225 pub fn new(id: impl Into<Arc<str>>) -> Self {
1226 Self(id.into())
1227 }
1228}
1229
1230#[cfg(feature = "unstable_session_model")]
1236#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1237#[serde(rename_all = "camelCase")]
1238#[non_exhaustive]
1239pub struct ModelInfo {
1240 pub model_id: ModelId,
1242 pub name: String,
1244 #[serde(default, skip_serializing_if = "Option::is_none")]
1246 pub description: Option<String>,
1247 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1249 pub meta: Option<serde_json::Value>,
1250}
1251
1252#[cfg(feature = "unstable_session_model")]
1253impl ModelInfo {
1254 pub fn new(model_id: impl Into<ModelId>, name: impl Into<String>) -> Self {
1255 Self {
1256 model_id: model_id.into(),
1257 name: name.into(),
1258 description: None,
1259 meta: None,
1260 }
1261 }
1262
1263 #[must_use]
1265 pub fn description(mut self, description: impl Into<String>) -> Self {
1266 self.description = Some(description.into());
1267 self
1268 }
1269
1270 #[must_use]
1272 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1273 self.meta = Some(meta);
1274 self
1275 }
1276}
1277
1278#[cfg(feature = "unstable_session_model")]
1284#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1285#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1286#[serde(rename_all = "camelCase")]
1287#[non_exhaustive]
1288pub struct SetSessionModelRequest {
1289 pub session_id: SessionId,
1291 pub model_id: ModelId,
1293 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1295 pub meta: Option<serde_json::Value>,
1296}
1297
1298#[cfg(feature = "unstable_session_model")]
1299impl SetSessionModelRequest {
1300 #[must_use]
1301 pub fn new(session_id: impl Into<SessionId>, model_id: impl Into<ModelId>) -> Self {
1302 Self {
1303 session_id: session_id.into(),
1304 model_id: model_id.into(),
1305 meta: None,
1306 }
1307 }
1308
1309 #[must_use]
1311 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1312 self.meta = Some(meta);
1313 self
1314 }
1315}
1316
1317#[cfg(feature = "unstable_session_model")]
1323#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1324#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_MODEL_METHOD_NAME))]
1325#[serde(rename_all = "camelCase")]
1326#[non_exhaustive]
1327pub struct SetSessionModelResponse {
1328 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1330 pub meta: Option<serde_json::Value>,
1331}
1332
1333#[cfg(feature = "unstable_session_model")]
1334impl SetSessionModelResponse {
1335 #[must_use]
1336 pub fn new() -> Self {
1337 Self::default()
1338 }
1339
1340 #[must_use]
1342 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1343 self.meta = Some(meta);
1344 self
1345 }
1346}
1347
1348#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1357#[serde(rename_all = "camelCase")]
1358#[non_exhaustive]
1359pub struct AgentCapabilities {
1360 #[serde(default)]
1362 pub load_session: bool,
1363 #[serde(default)]
1365 pub prompt_capabilities: PromptCapabilities,
1366 #[serde(default)]
1368 pub mcp_capabilities: McpCapabilities,
1369 #[serde(default)]
1370 pub session_capabilities: SessionCapabilities,
1371 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1373 pub meta: Option<serde_json::Value>,
1374}
1375
1376impl AgentCapabilities {
1377 #[must_use]
1378 pub fn new() -> Self {
1379 Self::default()
1380 }
1381
1382 #[must_use]
1384 pub fn load_session(mut self, load_session: bool) -> Self {
1385 self.load_session = load_session;
1386 self
1387 }
1388
1389 #[must_use]
1391 pub fn prompt_capabilities(mut self, prompt_capabilities: PromptCapabilities) -> Self {
1392 self.prompt_capabilities = prompt_capabilities;
1393 self
1394 }
1395
1396 #[must_use]
1398 pub fn mcp_capabilities(mut self, mcp_capabilities: McpCapabilities) -> Self {
1399 self.mcp_capabilities = mcp_capabilities;
1400 self
1401 }
1402
1403 #[must_use]
1405 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1406 self.meta = Some(meta);
1407 self
1408 }
1409}
1410
1411#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1421#[non_exhaustive]
1422pub struct SessionCapabilities {
1423 #[cfg(feature = "unstable_session_list")]
1429 #[serde(skip_serializing_if = "Option::is_none")]
1430 pub list: Option<SessionListCapabilities>,
1431 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1433 pub meta: Option<serde_json::Value>,
1434}
1435
1436impl SessionCapabilities {
1437 #[must_use]
1438 pub fn new() -> Self {
1439 Self::default()
1440 }
1441
1442 #[cfg(feature = "unstable_session_list")]
1443 #[must_use]
1445 pub fn list(mut self, list: SessionListCapabilities) -> Self {
1446 self.list = Some(list);
1447 self
1448 }
1449
1450 #[must_use]
1452 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1453 self.meta = Some(meta);
1454 self
1455 }
1456}
1457
1458#[cfg(feature = "unstable_session_list")]
1464#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1465#[non_exhaustive]
1466pub struct SessionListCapabilities {
1467 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1469 pub meta: Option<serde_json::Value>,
1470}
1471
1472#[cfg(feature = "unstable_session_list")]
1473impl SessionListCapabilities {
1474 #[must_use]
1475 pub fn new() -> Self {
1476 Self::default()
1477 }
1478 #[must_use]
1480 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1481 self.meta = Some(meta);
1482 self
1483 }
1484}
1485
1486#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1499#[serde(rename_all = "camelCase")]
1500#[non_exhaustive]
1501pub struct PromptCapabilities {
1502 #[serde(default)]
1504 pub image: bool,
1505 #[serde(default)]
1507 pub audio: bool,
1508 #[serde(default)]
1513 pub embedded_context: bool,
1514 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1516 pub meta: Option<serde_json::Value>,
1517}
1518
1519impl PromptCapabilities {
1520 #[must_use]
1521 pub fn new() -> Self {
1522 Self::default()
1523 }
1524
1525 #[must_use]
1527 pub fn image(mut self, image: bool) -> Self {
1528 self.image = image;
1529 self
1530 }
1531
1532 #[must_use]
1534 pub fn audio(mut self, audio: bool) -> Self {
1535 self.audio = audio;
1536 self
1537 }
1538
1539 #[must_use]
1544 pub fn embedded_context(mut self, embedded_context: bool) -> Self {
1545 self.embedded_context = embedded_context;
1546 self
1547 }
1548
1549 #[must_use]
1551 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1552 self.meta = Some(meta);
1553 self
1554 }
1555}
1556
1557#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1559#[serde(rename_all = "camelCase")]
1560#[non_exhaustive]
1561pub struct McpCapabilities {
1562 #[serde(default)]
1564 pub http: bool,
1565 #[serde(default)]
1567 pub sse: bool,
1568 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1570 pub meta: Option<serde_json::Value>,
1571}
1572
1573impl McpCapabilities {
1574 #[must_use]
1575 pub fn new() -> Self {
1576 Self::default()
1577 }
1578
1579 #[must_use]
1581 pub fn http(mut self, http: bool) -> Self {
1582 self.http = http;
1583 self
1584 }
1585
1586 #[must_use]
1588 pub fn sse(mut self, sse: bool) -> Self {
1589 self.sse = sse;
1590 self
1591 }
1592
1593 #[must_use]
1595 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1596 self.meta = Some(meta);
1597 self
1598 }
1599}
1600
1601#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
1607#[non_exhaustive]
1608pub struct AgentMethodNames {
1609 pub initialize: &'static str,
1611 pub authenticate: &'static str,
1613 pub session_new: &'static str,
1615 pub session_load: &'static str,
1617 pub session_set_mode: &'static str,
1619 pub session_prompt: &'static str,
1621 pub session_cancel: &'static str,
1623 #[cfg(feature = "unstable_session_model")]
1625 pub session_set_model: &'static str,
1626 #[cfg(feature = "unstable_session_list")]
1628 pub session_list: &'static str,
1629}
1630
1631pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
1633 initialize: INITIALIZE_METHOD_NAME,
1634 authenticate: AUTHENTICATE_METHOD_NAME,
1635 session_new: SESSION_NEW_METHOD_NAME,
1636 session_load: SESSION_LOAD_METHOD_NAME,
1637 session_set_mode: SESSION_SET_MODE_METHOD_NAME,
1638 session_prompt: SESSION_PROMPT_METHOD_NAME,
1639 session_cancel: SESSION_CANCEL_METHOD_NAME,
1640 #[cfg(feature = "unstable_session_model")]
1641 session_set_model: SESSION_SET_MODEL_METHOD_NAME,
1642 #[cfg(feature = "unstable_session_list")]
1643 session_list: SESSION_LIST_METHOD_NAME,
1644};
1645
1646pub(crate) const INITIALIZE_METHOD_NAME: &str = "initialize";
1648pub(crate) const AUTHENTICATE_METHOD_NAME: &str = "authenticate";
1650pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
1652pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
1654pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
1656pub(crate) const SESSION_PROMPT_METHOD_NAME: &str = "session/prompt";
1658pub(crate) const SESSION_CANCEL_METHOD_NAME: &str = "session/cancel";
1660#[cfg(feature = "unstable_session_model")]
1662pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
1663#[cfg(feature = "unstable_session_list")]
1665pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list";
1666
1667#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
1674#[serde(untagged)]
1675#[schemars(inline)]
1676#[non_exhaustive]
1677pub enum ClientRequest {
1678 InitializeRequest(InitializeRequest),
1689 AuthenticateRequest(AuthenticateRequest),
1699 NewSessionRequest(NewSessionRequest),
1712 LoadSessionRequest(LoadSessionRequest),
1723 #[cfg(feature = "unstable_session_list")]
1724 ListSessionsRequest(ListSessionsRequest),
1734 SetSessionModeRequest(SetSessionModeRequest),
1748 PromptRequest(PromptRequest),
1760 #[cfg(feature = "unstable_session_model")]
1761 SetSessionModelRequest(SetSessionModelRequest),
1767 ExtMethodRequest(ExtRequest),
1774}
1775
1776impl ClientRequest {
1777 #[must_use]
1779 pub fn method(&self) -> &str {
1780 match self {
1781 Self::InitializeRequest(_) => AGENT_METHOD_NAMES.initialize,
1782 Self::AuthenticateRequest(_) => AGENT_METHOD_NAMES.authenticate,
1783 Self::NewSessionRequest(_) => AGENT_METHOD_NAMES.session_new,
1784 Self::LoadSessionRequest(_) => AGENT_METHOD_NAMES.session_load,
1785 #[cfg(feature = "unstable_session_list")]
1786 Self::ListSessionsRequest(_) => AGENT_METHOD_NAMES.session_list,
1787 Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode,
1788 Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt,
1789 #[cfg(feature = "unstable_session_model")]
1790 Self::SetSessionModelRequest(_) => AGENT_METHOD_NAMES.session_set_model,
1791 Self::ExtMethodRequest(ext_request) => &ext_request.method,
1792 }
1793 }
1794}
1795
1796#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
1803#[serde(untagged)]
1804#[schemars(inline)]
1805#[non_exhaustive]
1806pub enum AgentResponse {
1807 InitializeResponse(InitializeResponse),
1808 AuthenticateResponse(#[serde(default)] AuthenticateResponse),
1809 NewSessionResponse(NewSessionResponse),
1810 LoadSessionResponse(#[serde(default)] LoadSessionResponse),
1811 #[cfg(feature = "unstable_session_list")]
1812 ListSessionsResponse(ListSessionsResponse),
1813 SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
1814 PromptResponse(PromptResponse),
1815 #[cfg(feature = "unstable_session_model")]
1816 SetSessionModelResponse(SetSessionModelResponse),
1817 ExtMethodResponse(ExtResponse),
1818}
1819
1820#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
1827#[serde(untagged)]
1828#[schemars(inline)]
1829#[non_exhaustive]
1830pub enum ClientNotification {
1831 CancelNotification(CancelNotification),
1843 ExtNotification(ExtNotification),
1850}
1851
1852impl ClientNotification {
1853 #[must_use]
1855 pub fn method(&self) -> &str {
1856 match self {
1857 Self::CancelNotification(_) => AGENT_METHOD_NAMES.session_cancel,
1858 Self::ExtNotification(ext_notification) => &ext_notification.method,
1859 }
1860 }
1861}
1862
1863#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1867#[schemars(extend("x-side" = "agent", "x-method" = SESSION_CANCEL_METHOD_NAME))]
1868#[serde(rename_all = "camelCase")]
1869#[non_exhaustive]
1870pub struct CancelNotification {
1871 pub session_id: SessionId,
1873 #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")]
1875 pub meta: Option<serde_json::Value>,
1876}
1877
1878impl CancelNotification {
1879 #[must_use]
1880 pub fn new(session_id: impl Into<SessionId>) -> Self {
1881 Self {
1882 session_id: session_id.into(),
1883 meta: None,
1884 }
1885 }
1886
1887 #[must_use]
1889 pub fn meta(mut self, meta: serde_json::Value) -> Self {
1890 self.meta = Some(meta);
1891 self
1892 }
1893}
1894
1895#[cfg(test)]
1896mod test_serialization {
1897 use super::*;
1898 use serde_json::json;
1899
1900 #[test]
1901 fn test_mcp_server_stdio_serialization() {
1902 let server = McpServer::Stdio(
1903 McpServerStdio::new("test-server", "/usr/bin/server")
1904 .args(vec!["--port".to_string(), "3000".to_string()])
1905 .env(vec![EnvVariable::new("API_KEY", "secret123")]),
1906 );
1907
1908 let json = serde_json::to_value(&server).unwrap();
1909 assert_eq!(
1910 json,
1911 json!({
1912 "name": "test-server",
1913 "command": "/usr/bin/server",
1914 "args": ["--port", "3000"],
1915 "env": [
1916 {
1917 "name": "API_KEY",
1918 "value": "secret123"
1919 }
1920 ]
1921 })
1922 );
1923
1924 let deserialized: McpServer = serde_json::from_value(json).unwrap();
1925 match deserialized {
1926 McpServer::Stdio(McpServerStdio {
1927 name,
1928 command,
1929 args,
1930 env,
1931 meta: _,
1932 }) => {
1933 assert_eq!(name, "test-server");
1934 assert_eq!(command, PathBuf::from("/usr/bin/server"));
1935 assert_eq!(args, vec!["--port", "3000"]);
1936 assert_eq!(env.len(), 1);
1937 assert_eq!(env[0].name, "API_KEY");
1938 assert_eq!(env[0].value, "secret123");
1939 }
1940 _ => panic!("Expected Stdio variant"),
1941 }
1942 }
1943
1944 #[test]
1945 fn test_mcp_server_http_serialization() {
1946 let server = McpServer::Http(
1947 McpServerHttp::new("http-server", "https://api.example.com").headers(vec![
1948 HttpHeader::new("Authorization", "Bearer token123"),
1949 HttpHeader::new("Content-Type", "application/json"),
1950 ]),
1951 );
1952
1953 let json = serde_json::to_value(&server).unwrap();
1954 assert_eq!(
1955 json,
1956 json!({
1957 "type": "http",
1958 "name": "http-server",
1959 "url": "https://api.example.com",
1960 "headers": [
1961 {
1962 "name": "Authorization",
1963 "value": "Bearer token123"
1964 },
1965 {
1966 "name": "Content-Type",
1967 "value": "application/json"
1968 }
1969 ]
1970 })
1971 );
1972
1973 let deserialized: McpServer = serde_json::from_value(json).unwrap();
1974 match deserialized {
1975 McpServer::Http(McpServerHttp {
1976 name,
1977 url,
1978 headers,
1979 meta: _,
1980 }) => {
1981 assert_eq!(name, "http-server");
1982 assert_eq!(url, "https://api.example.com");
1983 assert_eq!(headers.len(), 2);
1984 assert_eq!(headers[0].name, "Authorization");
1985 assert_eq!(headers[0].value, "Bearer token123");
1986 assert_eq!(headers[1].name, "Content-Type");
1987 assert_eq!(headers[1].value, "application/json");
1988 }
1989 _ => panic!("Expected Http variant"),
1990 }
1991 }
1992
1993 #[test]
1994 fn test_mcp_server_sse_serialization() {
1995 let server = McpServer::Sse(
1996 McpServerSse::new("sse-server", "https://sse.example.com/events")
1997 .headers(vec![HttpHeader::new("X-API-Key", "apikey456")]),
1998 );
1999
2000 let json = serde_json::to_value(&server).unwrap();
2001 assert_eq!(
2002 json,
2003 json!({
2004 "type": "sse",
2005 "name": "sse-server",
2006 "url": "https://sse.example.com/events",
2007 "headers": [
2008 {
2009 "name": "X-API-Key",
2010 "value": "apikey456"
2011 }
2012 ]
2013 })
2014 );
2015
2016 let deserialized: McpServer = serde_json::from_value(json).unwrap();
2017 match deserialized {
2018 McpServer::Sse(McpServerSse {
2019 name,
2020 url,
2021 headers,
2022 meta: _,
2023 }) => {
2024 assert_eq!(name, "sse-server");
2025 assert_eq!(url, "https://sse.example.com/events");
2026 assert_eq!(headers.len(), 1);
2027 assert_eq!(headers[0].name, "X-API-Key");
2028 assert_eq!(headers[0].value, "apikey456");
2029 }
2030 _ => panic!("Expected Sse variant"),
2031 }
2032 }
2033}