crates_docs/server/mod.rs
1//! 服务器模块
2//!
3//! 提供 MCP 服务器实现,支持多种传输协议(stdio、HTTP、SSE、Hybrid)。
4//!
5//! # 主要组件
6//!
7//! - `CratesDocsServer`: 主服务器结构体
8//! - `handler`: MCP 请求处理
9//! - `transport`: 传输层实现
10//! - `auth`: OAuth 认证支持
11//!
12//! # 示例
13//!
14//! ```rust,no_run
15//! use crates_docs::{AppConfig, CratesDocsServer};
16//!
17//! #[tokio::main]
18//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
19//! let config = AppConfig::default();
20//! let server = CratesDocsServer::new(config)?;
21//!
22//! // 运行 HTTP 服务器
23//! server.run_http().await?;
24//!
25//! Ok(())
26//! }
27//! ```
28
29pub mod auth;
30pub mod auth_middleware;
31pub mod handler;
32pub mod transport;
33
34use crate::cache::Cache;
35use crate::config::AppConfig;
36use crate::error::Result;
37use crate::tools::ToolRegistry;
38use rust_mcp_sdk::schema::{
39 Implementation, InitializeResult, ProtocolVersion, ServerCapabilities, ServerCapabilitiesTools,
40};
41use std::sync::Arc;
42
43/// 从配置模块重新导出 `ServerConfig` 以保持向后兼容
44pub use crate::config::ServerConfig;
45
46/// 从 handler 模块重新导出 `CratesDocsHandler`
47pub use handler::CratesDocsHandler;
48
49/// Crates Docs MCP 服务器
50///
51/// 主服务器结构体,管理配置、工具注册表和缓存。
52/// 支持多种传输协议:stdio、HTTP、SSE、Hybrid。
53///
54/// # 字段
55///
56/// - `config`: 应用配置
57/// - `tool_registry`: 工具注册表
58/// - `cache`: 缓存实例
59#[derive(Clone)]
60pub struct CratesDocsServer {
61 config: AppConfig,
62 tool_registry: Arc<ToolRegistry>,
63 cache: Arc<dyn Cache>,
64}
65
66impl CratesDocsServer {
67 /// 从组件创建服务器(内部初始化逻辑)
68 ///
69 /// # 参数
70 ///
71 /// * `config` - 应用配置
72 /// * `cache` - 缓存实例
73 ///
74 /// # 错误
75 ///
76 /// 如果文档服务创建失败,返回错误
77 fn from_parts(config: AppConfig, cache: Arc<dyn Cache>) -> crate::error::Result<Self> {
78 // Create document service with cache configuration
79 let doc_service = Arc::new(crate::tools::docs::DocService::with_config(
80 cache.clone(),
81 &config.cache,
82 )?);
83
84 // Create tool registry
85 let tool_registry = Arc::new(crate::tools::create_default_registry(&doc_service));
86
87 Ok(Self {
88 config,
89 tool_registry,
90 cache,
91 })
92 }
93
94 /// 创建新的服务器实例(同步)
95 ///
96 /// # 参数
97 ///
98 /// * `config` - 应用配置
99 ///
100 /// # 错误
101 ///
102 /// 如果缓存创建失败,返回错误
103 ///
104 /// # 注意
105 ///
106 /// 此方法仅支持内存缓存。如需使用 Redis,请使用 [`new_async`](Self::new_async) 方法。
107 ///
108 /// # 示例
109 ///
110 /// ```rust,no_run
111 /// use crates_docs::{AppConfig, CratesDocsServer};
112 ///
113 /// let config = AppConfig::default();
114 /// let server = CratesDocsServer::new(config).expect("Failed to create server");
115 /// ```
116 pub fn new(config: AppConfig) -> Result<Self> {
117 let cache_box: Box<dyn Cache> = crate::cache::create_cache(&config.cache)?;
118 let cache: Arc<dyn Cache> = Arc::from(cache_box);
119 Self::from_parts(config, cache)
120 }
121
122 /// 创建新的服务器实例(异步)
123 ///
124 /// # 参数
125 ///
126 /// * `config` - 应用配置
127 ///
128 /// # 错误
129 ///
130 /// 如果缓存创建失败,返回错误
131 ///
132 /// # 注意
133 ///
134 /// 支持内存缓存和 Redis 缓存(需要启用 `cache-redis` feature)。
135 ///
136 /// # 示例
137 ///
138 /// ```rust,no_run
139 /// use crates_docs::{AppConfig, CratesDocsServer};
140 ///
141 /// #[tokio::main]
142 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
143 /// let config = AppConfig::default();
144 /// let server = CratesDocsServer::new_async(config).await?;
145 /// Ok(())
146 /// }
147 /// ```
148 #[allow(unused_variables)]
149 #[allow(clippy::unused_async)]
150 pub async fn new_async(config: AppConfig) -> Result<Self> {
151 // Decide which creation method to use based on cache type and feature
152 #[cfg(feature = "cache-redis")]
153 {
154 let cache_box: Box<dyn Cache> = crate::cache::create_cache_async(&config.cache).await?;
155 let cache: Arc<dyn Cache> = Arc::from(cache_box);
156 Self::from_parts(config, cache)
157 }
158
159 #[cfg(not(feature = "cache-redis"))]
160 {
161 // No cache-redis feature, fall back to synchronous creation
162 let cache_box: Box<dyn Cache> = crate::cache::create_cache(&config.cache)?;
163 let cache: Arc<dyn Cache> = Arc::from(cache_box);
164 Self::from_parts(config, cache)
165 }
166 }
167
168 /// 获取服务器配置
169 #[must_use]
170 pub fn config(&self) -> &AppConfig {
171 &self.config
172 }
173
174 /// 获取工具注册表
175 #[must_use]
176 pub fn tool_registry(&self) -> &Arc<ToolRegistry> {
177 &self.tool_registry
178 }
179
180 /// 获取缓存实例
181 #[must_use]
182 pub fn cache(&self) -> &Arc<dyn Cache> {
183 &self.cache
184 }
185
186 /// 获取服务器信息
187 ///
188 /// 返回 MCP 初始化结果,包含服务器元数据和能力信息
189 #[must_use]
190 pub fn server_info(&self) -> InitializeResult {
191 InitializeResult {
192 server_info: Implementation {
193 name: self.config.server.name.clone(),
194 version: self.config.server.version.clone(),
195 title: Some("Crates Docs MCP Server".to_string()),
196 description: self.config.server.description.clone(),
197 icons: self.config.server.icons.clone(),
198 website_url: self.config.server.website_url.clone(),
199 },
200 capabilities: ServerCapabilities {
201 tools: Some(ServerCapabilitiesTools { list_changed: None }),
202 resources: None,
203 prompts: None,
204 experimental: None,
205 completions: None,
206 logging: None,
207 tasks: None,
208 },
209 protocol_version: ProtocolVersion::V2025_11_25.into(),
210 instructions: Some(
211 "Use this server to query Rust crate documentation. Supports crate lookup, crate search, and health check."
212 .to_string(),
213 ),
214 meta: None,
215 }
216 }
217
218 /// 运行 Stdio 服务器
219 ///
220 /// # 错误
221 ///
222 /// 如果服务器启动失败,返回错误
223 pub async fn run_stdio(&self) -> Result<()> {
224 transport::run_stdio_server(self).await
225 }
226
227 /// 运行 HTTP 服务器
228 ///
229 /// # 错误
230 ///
231 /// 如果服务器启动失败,返回错误
232 pub async fn run_http(&self) -> Result<()> {
233 transport::run_http_server(self).await
234 }
235
236 /// 运行 SSE 服务器
237 ///
238 /// # 错误
239 ///
240 /// 如果服务器启动失败,返回错误
241 pub async fn run_sse(&self) -> Result<()> {
242 transport::run_sse_server(self).await
243 }
244}