remote_mcp_kernel/handlers/
mcp_server.rs1use rmcp::{
8 Error as McpError, RoleServer, ServerHandler, handler::server::router::tool::ToolRouter,
9 model::*, service::RequestContext, tool, tool_handler, tool_router,
10};
11
12use crate::server_info::helpers::*;
13
14#[derive(Clone)]
19pub struct McpServer {
20 tool_router: ToolRouter<McpServer>,
22}
23
24impl McpServer {
25 pub fn new() -> Self {
27 Self {
28 tool_router: Self::tool_router(),
29 }
30 }
31}
32
33#[tool_router]
35impl McpServer {
36 #[tool(description = "Get OAuth provider information and capabilities")]
38 async fn get_oauth_info(&self) -> Result<CallToolResult, McpError> {
39 Ok(CallToolResult::success(vec![Content::text(
40 oauth_provider_info_response().to_string(),
41 )]))
42 }
43
44 #[tool(description = "Check the health status of the OAuth provider")]
46 async fn health_check(&self) -> Result<CallToolResult, McpError> {
47 Ok(CallToolResult::success(vec![Content::text(
48 health_check_response().to_string(),
49 )]))
50 }
51}
52
53#[tool_handler]
55impl ServerHandler for McpServer {
56 fn get_info(&self) -> rmcp::model::ServerInfo {
57 mcp_server_info()
58 }
59
60 async fn list_resources(
61 &self,
62 _request: Option<PaginatedRequestParam>,
63 _: RequestContext<RoleServer>,
64 ) -> Result<ListResourcesResult, McpError> {
65 Ok(ListResourcesResult {
66 resources: vec![],
67 next_cursor: None,
68 })
69 }
70
71 async fn read_resource(
72 &self,
73 ReadResourceRequestParam { uri }: ReadResourceRequestParam,
74 _: RequestContext<RoleServer>,
75 ) -> Result<ReadResourceResult, McpError> {
76 Err(McpError::resource_not_found(
77 "resource_not_found",
78 Some(serde_json::json!({ "uri": uri })),
79 ))
80 }
81
82 async fn list_prompts(
83 &self,
84 _request: Option<PaginatedRequestParam>,
85 _: RequestContext<RoleServer>,
86 ) -> Result<ListPromptsResult, McpError> {
87 Ok(ListPromptsResult {
88 next_cursor: None,
89 prompts: vec![],
90 })
91 }
92
93 async fn get_prompt(
94 &self,
95 GetPromptRequestParam { .. }: GetPromptRequestParam,
96 _: RequestContext<RoleServer>,
97 ) -> Result<GetPromptResult, McpError> {
98 Err(McpError::invalid_params("prompt not found", None))
99 }
100
101 async fn list_resource_templates(
102 &self,
103 _request: Option<PaginatedRequestParam>,
104 _: RequestContext<RoleServer>,
105 ) -> Result<ListResourceTemplatesResult, McpError> {
106 Ok(ListResourceTemplatesResult {
107 next_cursor: None,
108 resource_templates: Vec::new(),
109 })
110 }
111
112 async fn initialize(
113 &self,
114 _request: InitializeRequestParam,
115 _context: RequestContext<RoleServer>,
116 ) -> Result<InitializeResult, McpError> {
117 Ok(mcp_initialize_result())
118 }
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[tokio::test]
126 async fn test_mcp_server_creation() {
127 let mcp_server = McpServer::new();
128
129 let _tool_router = &mcp_server.tool_router;
131 }
132
133 #[tokio::test]
134 async fn test_mcp_server_oauth_info_tool() {
135 let mcp_server = McpServer::new();
136 let result = mcp_server.get_oauth_info().await.unwrap();
137
138 assert!(!result.content.is_empty());
140
141 let content_str = format!("{:?}", result.content[0]);
143 assert!(content_str.contains("MCP GitHub OAuth Provider"));
144 }
145
146 #[tokio::test]
147 async fn test_mcp_server_health_check() {
148 let mcp_server = McpServer::new();
149 let result = mcp_server.health_check().await.unwrap();
150
151 assert!(!result.content.is_empty());
153 }
154}