feat(transport): support streamable http server (#152)

* feat(transport): support streamable http server

* refactor(transport): add common module for shared transport utilities

* perf(tracing): add more log for streamable http session

* fix(test): fix port conflict in test with js

* fix(transport): fix id generating and session management

1. cancel when deleting
2. use `wrapping` and `saturating` correctly

* chore(naming): rename sse server to streamable http server
This commit is contained in:
4t145 2025-05-08 13:57:51 +08:00 • committed by GitHub
commit 57e14c56e8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 1247 additions and 20 deletions

View file

@ -1,3 +1,5 @@
[package]
name = "mcp-server-examples"
version = "0.1.5"
@ -5,7 +7,7 @@ edition = "2024"
publish = false
[dependencies]
rmcp= { path = "../../crates/rmcp", features = ["server", "transport-sse-server", "transport-io", "auth"] }
rmcp= { path = "../../crates/rmcp", features = ["server", "transport-sse-server", "transport-io", "transport-streamable-http-server", "auth"] }
tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread", "io-std", "signal"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
@ -49,6 +51,10 @@ path = "src/axum_router.rs"
name = "servers_generic_server"
path = "src/generic_service.rs"
[[example]]
name = "servers_axum_streamable_http"
path = "src/axum_streamable_http.rs"
[[example]]
name = "servers_auth_sse"
path = "src/auth_sse.rs"

View file

@ -0,0 +1,29 @@
use rmcp::transport::streamable_http_server::axum::StreamableHttpServer;
use tracing_subscriber::{
layer::SubscriberExt,
util::SubscriberInitExt,
{self},
};
mod common;
use common::counter::Counter;
const BIND_ADDRESS: &str = "127.0.0.1:8000";
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::registry()
.with(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| "debug".to_string().into()),
)
.with(tracing_subscriber::fmt::layer())
.init();
let ct = StreamableHttpServer::serve(BIND_ADDRESS.parse()?)
.await?
.with_service(Counter::new);
tokio::signal::ctrl_c().await?;
ct.cancel();
Ok(())
}

View file

@ -13,6 +13,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
let io = (tokio::io::stdin(), tokio::io::stdout());
serve_server(generic_service, io).await?.waiting().await?;
serve_server(generic_service, io).await?;
Ok(())
}