use crate::core::error::McpResult;
use crate::protocol::types::{JsonRpcRequest, JsonRpcResponse};
use crate::server::mcp_server::McpServer;
use crate::transport::http::HttpServerTransport;
use crate::transport::traits::ServerTransport;
use std::sync::Arc;
use tokio::sync::Mutex;
pub struct HttpMcpServer {
server: Arc<Mutex<McpServer>>,
transport: Option<HttpServerTransport>,
}
impl HttpMcpServer {
pub fn new(name: String, version: String) -> Self {
Self {
server: Arc::new(Mutex::new(McpServer::new(name, version))),
transport: None,
}
}
pub async fn server(&self) -> Arc<Mutex<McpServer>> {
self.server.clone()
}
pub async fn start(&mut self, mut transport: HttpServerTransport) -> McpResult<()> {
let server_clone = self.server.clone();
transport
.set_request_handler(move |request: JsonRpcRequest| {
let server = server_clone.clone();
let (tx, rx) = tokio::sync::oneshot::channel();
tokio::spawn(async move {
let server_guard = server.lock().await;
let response = server_guard
.handle_request(request)
.await
.unwrap_or_else(|e| {
tracing::error!("Error handling HTTP request: {}", e);
JsonRpcResponse {
jsonrpc: "2.0".to_string(),
id: serde_json::Value::Null,
result: Some(serde_json::json!({
"error": {
"code": -32603,
"message": e.to_string()
}
})),
}
});
let _ = tx.send(response);
});
rx
})
.await;
transport.start().await?;
self.transport = Some(transport);
Ok(())
}
pub async fn stop(&mut self) -> McpResult<()> {
if let Some(transport) = &mut self.transport {
transport.stop().await?;
}
self.transport = None;
Ok(())
}
pub fn is_running(&self) -> bool {
self.transport.as_ref().is_some_and(|t| t.is_running())
}
}