Skip to content

Streamable HTTP connection leak #266

Description

@howardjohn

Describe the bug
Connections are not closed using streamable HTTP

To Reproduce
Steps to reproduce the behavior:

  1. Run a streamable HTTP server with this library: cargo run --example servers_counter_streamhttp
  2. Connect to it and call tools multiple times. Each tool call will open a new connection that is never closed.

This is reproducible with MCP inspector and with the example client. I changed the client to send many tool calls:

cargo run --example clients_streamable_http
diff --git a/examples/clients/src/streamable_http.rs b/examples/clients/src/streamable_http.rs
index 634ec61..577613d 100644
--- a/examples/clients/src/streamable_http.rs+++ b/examples/clients/src/streamable_http.rs@@ -4,6 +4,7 @@ use rmcp::{
model::{CallToolRequestParam, ClientCapabilities, ClientInfo, Implementation},
transport::StreamableHttpClientTransport,
};
+use std::time::Duration;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
#[tokio::main]
@@ -37,13 +38,16 @@ async fn main() -> Result<()> {
let tools = client.list_tools(Default::default()).await?;
tracing::info!("Available tools: {tools:#?}");
- let tool_result = client- .call_tool(CallToolRequestParam {- name: "increment".into(),- arguments: serde_json::json!({}).as_object().cloned(),- })- .await?;- tracing::info!("Tool result: {tool_result:#?}");+ for i in 0..100 {+ let tool_result = client+ .call_tool(CallToolRequestParam {+ name: "increment".into(),+ arguments: serde_json::json!({}).as_object().cloned(),+ })+ .await?;+ tracing::info!("Tool result: {tool_result:#?}");+ tokio::time::sleep(Duration::from_secs(1)).await;+ }
client.cancel().await?;
Ok(())
}

Expected behavior
Connection is reused or closed

Metadata

Metadata

Assignees

Labels

T-bugBug fixes and error corrections

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions