mcp_tools/servers/
mod.rs

1//! MCP Server implementations
2
3pub mod code_analysis;
4pub mod file_operations;
5pub mod git_tools;
6pub mod system_tools;
7pub mod web_tools;
8
9// Re-export server types
10pub use code_analysis::CodeAnalysisServer;
11pub use file_operations::FileOperationsServer;
12pub use git_tools::GitToolsServer;
13pub use system_tools::SystemToolsServer;
14pub use web_tools::WebToolsServer;
15
16use crate::common::{McpServerBase, ServerConfig};
17use crate::{McpToolsError, Result};
18
19/// Server type enumeration
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub enum ServerType {
22    FileOperations,
23    GitTools,
24    CodeAnalysis,
25    WebTools,
26    SystemTools,
27}
28
29impl std::str::FromStr for ServerType {
30    type Err = McpToolsError;
31
32    fn from_str(s: &str) -> Result<Self> {
33        match s.to_lowercase().as_str() {
34            "file" | "file-operations" | "files" => Ok(Self::FileOperations),
35            "git" | "git-tools" => Ok(Self::GitTools),
36            "code" | "code-analysis" => Ok(Self::CodeAnalysis),
37            "web" | "web-tools" => Ok(Self::WebTools),
38            "system" | "system-tools" => Ok(Self::SystemTools),
39            _ => Err(McpToolsError::Config(format!("Unknown server type: {}", s))),
40        }
41    }
42}
43
44impl std::fmt::Display for ServerType {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        match self {
47            Self::FileOperations => write!(f, "file-operations"),
48            Self::GitTools => write!(f, "git-tools"),
49            Self::CodeAnalysis => write!(f, "code-analysis"),
50            Self::WebTools => write!(f, "web-tools"),
51            Self::SystemTools => write!(f, "system-tools"),
52        }
53    }
54}
55
56/// Create a server instance based on type
57pub async fn create_server(
58    server_type: ServerType,
59    config: ServerConfig,
60) -> Result<Box<dyn McpServerBase>> {
61    match server_type {
62        ServerType::FileOperations => {
63            let server = FileOperationsServer::new(config).await?;
64            Ok(Box::new(server))
65        }
66        ServerType::GitTools => {
67            let server = GitToolsServer::new(config).await?;
68            Ok(Box::new(server))
69        }
70        ServerType::CodeAnalysis => {
71            let server = CodeAnalysisServer::new(config).await?;
72            Ok(Box::new(server))
73        }
74        ServerType::WebTools => {
75            let server = WebToolsServer::new(config).await?;
76            Ok(Box::new(server))
77        }
78        ServerType::SystemTools => {
79            let server = SystemToolsServer::new(config).await?;
80            Ok(Box::new(server))
81        }
82    }
83}
84
85/// Get default configuration for a server type
86pub fn get_default_config(server_type: ServerType) -> ServerConfig {
87    let mut config = ServerConfig::default();
88
89    match server_type {
90        ServerType::FileOperations => {
91            config.name = "File Operations MCP Server".to_string();
92            config.description = "File system operations with security validation".to_string();
93            config.port = 3001;
94        }
95        ServerType::GitTools => {
96            config.name = "Git Tools MCP Server".to_string();
97            config.description = "Git repository management and analysis".to_string();
98            config.port = 3002;
99        }
100        ServerType::CodeAnalysis => {
101            config.name = "Code Analysis MCP Server".to_string();
102            config.description = "Language-aware code analysis and refactoring".to_string();
103            config.port = 3003;
104        }
105        ServerType::WebTools => {
106            config.name = "Web Tools MCP Server".to_string();
107            config.description = "Web scraping and HTTP operations".to_string();
108            config.port = 3004;
109        }
110        ServerType::SystemTools => {
111            config.name = "System Tools MCP Server".to_string();
112            config.description = "System information and process management".to_string();
113            config.port = 3005;
114        }
115    }
116
117    config
118}
119
120/// Get all available server types
121pub fn get_available_servers() -> Vec<ServerType> {
122    vec![
123        ServerType::FileOperations,
124        ServerType::GitTools,
125        ServerType::CodeAnalysis,
126        ServerType::WebTools,
127        ServerType::SystemTools,
128    ]
129}
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134
135    #[test]
136    fn test_server_type_parsing() {
137        assert_eq!(
138            "file".parse::<ServerType>().unwrap(),
139            ServerType::FileOperations
140        );
141        assert_eq!(
142            "git-tools".parse::<ServerType>().unwrap(),
143            ServerType::GitTools
144        );
145        assert_eq!(
146            "code".parse::<ServerType>().unwrap(),
147            ServerType::CodeAnalysis
148        );
149        assert_eq!("web".parse::<ServerType>().unwrap(), ServerType::WebTools);
150        assert_eq!(
151            "system".parse::<ServerType>().unwrap(),
152            ServerType::SystemTools
153        );
154
155        assert!("invalid".parse::<ServerType>().is_err());
156    }
157
158    #[test]
159    fn test_server_type_display() {
160        assert_eq!(ServerType::FileOperations.to_string(), "file-operations");
161        assert_eq!(ServerType::GitTools.to_string(), "git-tools");
162        assert_eq!(ServerType::CodeAnalysis.to_string(), "code-analysis");
163        assert_eq!(ServerType::WebTools.to_string(), "web-tools");
164        assert_eq!(ServerType::SystemTools.to_string(), "system-tools");
165    }
166
167    #[test]
168    fn test_default_configs() {
169        let file_config = get_default_config(ServerType::FileOperations);
170        assert_eq!(file_config.port, 3001);
171        assert!(file_config.name.contains("File Operations"));
172
173        let git_config = get_default_config(ServerType::GitTools);
174        assert_eq!(git_config.port, 3002);
175        assert!(git_config.name.contains("Git Tools"));
176    }
177
178    #[test]
179    fn test_available_servers() {
180        let servers = get_available_servers();
181        assert_eq!(servers.len(), 5);
182        assert!(servers.contains(&ServerType::FileOperations));
183        assert!(servers.contains(&ServerType::GitTools));
184    }
185}