1use std::sync::Arc;
4
5use allframe_core::router::Router;
6
7use super::tools::McpTool;
8
9pub struct McpServer {
11 router: Arc<Router>,
12 tools: Vec<McpTool>,
13}
14
15impl McpServer {
16 pub fn new(router: Router) -> Self {
18 let tools = Self::discover_tools(&router);
19 Self {
20 router: Arc::new(router),
21 tools,
22 }
23 }
24
25 fn discover_tools(router: &Router) -> Vec<McpTool> {
27 router
28 .list_handlers()
29 .iter()
30 .map(|name| McpTool::from_handler_name(name))
31 .collect()
32 }
33
34 pub fn tool_count(&self) -> usize {
36 self.tools.len()
37 }
38
39 pub async fn list_tools(&self) -> Vec<McpTool> {
41 self.tools.clone()
42 }
43
44 pub async fn call_tool(
46 &self,
47 name: &str,
48 args: serde_json::Value,
49 ) -> Result<serde_json::Value, String> {
50 if !self.tools.iter().any(|t| t.name == name) {
52 return Err(format!("Tool not found: {}", name));
53 }
54
55 let request = format!("{}", args);
58
59 match self.router.call_handler(name, &request).await {
61 Ok(response) => {
62 Ok(serde_json::Value::String(response))
64 }
65 Err(e) => Err(format!("Tool execution failed: {}", e)),
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_server_creation() {
76 let router = Router::new();
77 let server = McpServer::new(router);
78 assert_eq!(server.tool_count(), 0);
79 }
80
81 #[test]
82 fn test_server_tool_discovery() {
83 let mut router = Router::new();
84 router.register("test1", || async { "result1".to_string() });
85 router.register("test2", || async { "result2".to_string() });
86
87 let server = McpServer::new(router);
88 assert_eq!(server.tool_count(), 2);
89 }
90
91 #[tokio::test]
92 async fn test_server_list_tools() {
93 let mut router = Router::new();
94 router.register("handler1", || async { "r1".to_string() });
95
96 let server = McpServer::new(router);
97 let tools = server.list_tools().await;
98
99 assert_eq!(tools.len(), 1);
100 assert_eq!(tools[0].name, "handler1");
101 }
102
103 #[tokio::test]
104 async fn test_server_call_tool() {
105 let mut router = Router::new();
106 router.register("echo", || async { "echoed".to_string() });
107
108 let server = McpServer::new(router);
109 let result = server.call_tool("echo", serde_json::json!({})).await;
110
111 assert!(result.is_ok());
112 }
113
114 #[tokio::test]
115 async fn test_server_call_unknown_tool() {
116 let router = Router::new();
117 let server = McpServer::new(router);
118 let result = server.call_tool("unknown", serde_json::json!({})).await;
119
120 assert!(result.is_err());
121 assert!(result.unwrap_err().contains("not found"));
122 }
123}