use rmcp::{
ServiceExt,
model::{ClientCapabilities, ClientInfo},
transport::{
sse::SseTransport,
sse_server::{SseServer, SseServerConfig},
},
};
use rmcp_proxy::{
proxy_handler::ProxyHandler, sse_client::SseClientConfig, sse_server::SseServerSettings,
};
use std::error::Error as StdError;
use tokio_util::sync::CancellationToken;
use tracing::info;
pub async fn run_sse_proxy(
setting: SseServerSettings,
config: SseClientConfig,
) -> Result<(), Box<dyn StdError>> {
info!("Running SSE proxy with URL: {}", config.url);
if !config.headers.is_empty() {
info!("Note: Custom headers are not currently supported for SSE transport");
}
let transport = SseTransport::start(&config.url).await?;
let client_info = ClientInfo {
protocol_version: Default::default(),
capabilities: ClientCapabilities::builder()
.enable_experimental()
.enable_roots()
.enable_roots_list_changed()
.enable_sampling()
.build(),
..Default::default()
};
let client = client_info.serve(transport).await?;
let server_info = client.peer_info();
info!("Connected to server: {}", server_info.server_info.name);
let proxy_handler = ProxyHandler::new(client);
let config = SseServerConfig {
bind: setting.bind_addr,
sse_path: "/sse".to_string(),
post_path: "/message".to_string(),
ct: CancellationToken::new(),
};
let sse_server = SseServer::serve_with_config(config.clone()).await?;
let ct = sse_server.with_service(move || proxy_handler.clone());
tokio::signal::ctrl_c().await?;
ct.cancel();
Ok(())
}