Skip to main content

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}