1use std::sync::Arc;
10use std::time::Duration;
11
12use crate::config::Config;
13use crate::ctx::Ctx;
14use crate::registry::Registry;
15
16pub mod args;
17pub mod handler;
18pub mod transport;
19
20#[cfg(test)]
21mod mcp_test;
22
23pub const PROTOCOL_V2024_11_05: &str = "2024-11-05";
26pub const PROTOCOL_V2025_03_26: &str = "2025-03-26";
27pub const PROTOCOL_V2025_06_18: &str = "2025-06-18";
28pub const PROTOCOL_V2025_11_25: &str = "2025-11-25";
29pub const PROTOCOL_V2026_07_28: &str = "2026-07-28"; pub const DEFAULT_VERSIONS: &[&str] = &[
33 PROTOCOL_V2026_07_28,
34 PROTOCOL_V2025_11_25,
35 PROTOCOL_V2025_06_18,
36 PROTOCOL_V2025_03_26,
37 PROTOCOL_V2024_11_05,
38];
39
40#[derive(Debug, Clone, Default)]
42pub struct Options {
43 pub name: String,
45 pub version: String,
46
47 pub versions: Vec<String>,
50
51 pub instructions: String,
53
54 pub addr: String,
56
57 pub json_response: bool,
60
61 pub stateless: bool,
63
64 pub bearer_tokens: Vec<String>,
66
67 pub session_timeout: Duration,
69
70 pub cors_origins: Vec<String>,
72
73 #[doc(hidden)]
75 pub default_ctx: Option<Arc<Ctx>>,
76
77 pub defaults: std::collections::HashMap<String, String>,
79
80 pub response_headers: Vec<(String, String)>,
83
84 pub no_server_meta: bool,
87}
88
89pub fn server(
92 reg: &Registry,
93 opts: Options,
94 ctx: Arc<Ctx>,
95) -> crate::errors::Result<handler::XyzServer> {
96 handler::build(reg, &opts, ctx)
97}
98
99pub fn run_with_config(ctx: &Ctx, reg: &Registry, args: &[String], cfg: Config) -> i32 {
102 let base = Options {
103 name: cfg.resolved_name(),
106 version: cfg.resolved_version(),
107 addr: cfg.addr.clone(),
108 bearer_tokens: cfg.bearer_tokens.clone(),
109 response_headers: cfg.response_headers.clone(),
110 no_server_meta: cfg.no_server_headers,
111 ..Default::default()
112 };
113 transport::run(ctx, reg, args, base)
114}
115
116pub fn run_context(ctx: &Ctx, reg: &Registry, args: &[String]) -> i32 {
118 transport::run(ctx, reg, args, Options::default())
119}
120
121pub fn mountable(reg: &Registry, opts: &Options) -> Option<axum::routing::Router> {
123 transport::mountable_router(reg, opts).ok()
124}
125
126pub(crate) fn protocol_version(s: &str) -> Option<rmcp::model::ProtocolVersion> {
128 match s {
129 PROTOCOL_V2024_11_05 => Some(rmcp::model::ProtocolVersion::V_2024_11_05),
130 PROTOCOL_V2025_03_26 => Some(rmcp::model::ProtocolVersion::V_2025_03_26),
131 PROTOCOL_V2025_06_18 => Some(rmcp::model::ProtocolVersion::V_2025_06_18),
132 PROTOCOL_V2025_11_25 => Some(rmcp::model::ProtocolVersion::V_2025_11_25),
133 PROTOCOL_V2026_07_28 => Some(rmcp::model::ProtocolVersion::V_2026_07_28),
134 _ => None,
135 }
136}