use std::sync::Arc; use axum::{ extract::State, http::StatusCode, routing::{get, post}, Json, Router, }; use tokio::net::TcpListener; use crate::handlers::RequestHandler; use crate::protocol::JsonRpcRequest; use crate::Result; pub struct SseTransport { host: String, port: u16, request_handler: Arc, } impl SseTransport { pub fn new(host: String, port: u16, request_handler: Arc) -> Self { Self { host, port, request_handler, } } fn router(&self) -> Router { Router::new() .route("/health", get(health_handler)) .route("/mcp", post(mcp_handler)) .with_state(self.request_handler.clone()) } pub async fn bind(&self) -> Result<()> { let addr_str = format!("{}:{}", self.host, self.port); let listener = TcpListener::bind(&addr_str).await?; tracing::info!("SSE transport listening on http://{}", addr_str); let router = self.router(); axum::serve(listener, router).await?; Ok(()) } } async fn health_handler() -> impl axum::response::IntoResponse { Json(serde_json::json!({ "status": "healthy", "version": env!("CARGO_PKG_VERSION"), })) } async fn mcp_handler( State(handler): State>, Json(request): Json, ) -> impl axum::response::IntoResponse { let response = handler.handle(&request).await; (StatusCode::OK, Json(response)) }