Vapora/crates/vapora-mcp-server/src/transport_sse.rs

64 lines
1.5 KiB
Rust
Raw Normal View History

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<RequestHandler>,
}
impl SseTransport {
pub fn new(host: String, port: u16, request_handler: Arc<RequestHandler>) -> 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<Arc<RequestHandler>>,
Json(request): Json<JsonRpcRequest>,
) -> impl axum::response::IntoResponse {
let response = handler.handle(&request).await;
(StatusCode::OK, Json(response))
}