use rmcp::{
Error as McpError, RoleServer, ServerHandler, handler::server::router::tool::ToolRouter,
model::*, service::RequestContext, tool, tool_handler, tool_router,
};
use crate::server_info::helpers::*;
#[derive(Clone)]
pub struct McpServer {
tool_router: ToolRouter<McpServer>,
}
impl McpServer {
pub fn new() -> Self {
Self {
tool_router: Self::tool_router(),
}
}
}
#[tool_router]
impl McpServer {
#[tool(description = "Get OAuth provider information and capabilities")]
async fn get_oauth_info(&self) -> Result<CallToolResult, McpError> {
Ok(CallToolResult::success(vec![Content::text(
oauth_provider_info_response().to_string(),
)]))
}
#[tool(description = "Check the health status of the OAuth provider")]
async fn health_check(&self) -> Result<CallToolResult, McpError> {
Ok(CallToolResult::success(vec![Content::text(
health_check_response().to_string(),
)]))
}
}
#[tool_handler]
impl ServerHandler for McpServer {
fn get_info(&self) -> rmcp::model::ServerInfo {
mcp_server_info()
}
async fn list_resources(
&self,
_request: Option<PaginatedRequestParam>,
_: RequestContext<RoleServer>,
) -> Result<ListResourcesResult, McpError> {
Ok(ListResourcesResult {
resources: vec![],
next_cursor: None,
})
}
async fn read_resource(
&self,
ReadResourceRequestParam { uri }: ReadResourceRequestParam,
_: RequestContext<RoleServer>,
) -> Result<ReadResourceResult, McpError> {
Err(McpError::resource_not_found(
"resource_not_found",
Some(serde_json::json!({ "uri": uri })),
))
}
async fn list_prompts(
&self,
_request: Option<PaginatedRequestParam>,
_: RequestContext<RoleServer>,
) -> Result<ListPromptsResult, McpError> {
Ok(ListPromptsResult {
next_cursor: None,
prompts: vec![],
})
}
async fn get_prompt(
&self,
GetPromptRequestParam { .. }: GetPromptRequestParam,
_: RequestContext<RoleServer>,
) -> Result<GetPromptResult, McpError> {
Err(McpError::invalid_params("prompt not found", None))
}
async fn list_resource_templates(
&self,
_request: Option<PaginatedRequestParam>,
_: RequestContext<RoleServer>,
) -> Result<ListResourceTemplatesResult, McpError> {
Ok(ListResourceTemplatesResult {
next_cursor: None,
resource_templates: Vec::new(),
})
}
async fn initialize(
&self,
_request: InitializeRequestParam,
_context: RequestContext<RoleServer>,
) -> Result<InitializeResult, McpError> {
Ok(mcp_initialize_result())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_mcp_server_creation() {
let mcp_server = McpServer::new();
let _tool_router = &mcp_server.tool_router;
}
#[tokio::test]
async fn test_mcp_server_oauth_info_tool() {
let mcp_server = McpServer::new();
let result = mcp_server.get_oauth_info().await.unwrap();
assert!(!result.content.is_empty());
let content_str = format!("{:?}", result.content[0]);
assert!(content_str.contains("MCP GitHub OAuth Provider"));
}
#[tokio::test]
async fn test_mcp_server_health_check() {
let mcp_server = McpServer::new();
let result = mcp_server.health_check().await.unwrap();
assert!(!result.content.is_empty());
}
}