pub struct StreamableHttpService<S, M = LocalSessionManager> {
pub config: StreamableHttpServerConfig,
/* private fields */
}Expand description
§Streamable HTTP server
An HTTP service that implements the Streamable HTTP transport for MCP servers.
§Session management
When StreamableHttpServerConfig::stateful_mode is true (the default),
the server creates a session for each client that sends an initialize
request. The session ID is returned in the Mcp-Session-Id response header
and the client must include it on all subsequent requests.
Two tool calls carrying the same Mcp-Session-Id come from the same logical
session (typically one conversation in an LLM client). Different session IDs
mean different sessions.
The SessionManager trait controls how sessions are stored and routed:
LocalSessionManager— in-memory session store (default).NeverSessionManager— disables sessions entirely (stateless mode).
§Accessing HTTP request data from tool handlers
The service consumes the request body but injects the remaining
http::request::Parts into crate::model::Extensions, which is
accessible through crate::service::RequestContext.
§Reading the raw HTTP parts
use rmcp::handler::server::tool::Extension;
use http::request::Parts;
async fn my_tool(Extension(parts): Extension<Parts>) {
tracing::info!("http parts:{parts:?}")
}§Reading the session ID inside a tool handler
use rmcp::handler::server::tool::Extension;
use rmcp::service::RequestContext;
use rmcp::model::RoleServer;
#[tool(description = "session-aware tool")]
async fn my_tool(
&self,
Extension(parts): Extension<http::request::Parts>,
) -> Result<CallToolResult, rmcp::ErrorData> {
if let Some(session_id) = parts.headers.get("mcp-session-id") {
tracing::info!(?session_id, "called from session");
}
// ...
}§Accessing custom axum/tower extension state
State added via axum’s Extension layer is available inside
Parts.extensions:
use rmcp::service::RequestContext;
use rmcp::model::RoleServer;
#[derive(Clone)]
struct AppState { /* ... */ }
#[tool(description = "example")]
async fn my_tool(
&self,
ctx: RequestContext<RoleServer>,
) -> Result<CallToolResult, rmcp::ErrorData> {
let parts = ctx.extensions.get::<http::request::Parts>().unwrap();
let state = parts.extensions.get::<AppState>().unwrap();
// use state...
}Fields§
§config: StreamableHttpServerConfigImplementations§
Source§impl<S, M> StreamableHttpService<S, M>
impl<S, M> StreamableHttpService<S, M>
Trait Implementations§
Source§impl<S, M> Clone for StreamableHttpService<S, M>
impl<S, M> Clone for StreamableHttpService<S, M>
Source§fn clone(&self) -> StreamableHttpService<S, M>
fn clone(&self) -> StreamableHttpService<S, M>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<RequestBody, S, M> Service<Request<RequestBody>> for StreamableHttpService<S, M>
impl<RequestBody, S, M> Service<Request<RequestBody>> for StreamableHttpService<S, M>
Source§type Error = Infallible
type Error = Infallible
Source§type Future = Pin<Box<dyn Future<Output = Result<<StreamableHttpService<S, M> as Service<Request<RequestBody>>>::Response, <StreamableHttpService<S, M> as Service<Request<RequestBody>>>::Error>> + Send>>
type Future = Pin<Box<dyn Future<Output = Result<<StreamableHttpService<S, M> as Service<Request<RequestBody>>>::Response, <StreamableHttpService<S, M> as Service<Request<RequestBody>>>::Error>> + Send>>
Auto Trait Implementations§
impl<S, M> Freeze for StreamableHttpService<S, M>
impl<S, M = LocalSessionManager> !RefUnwindSafe for StreamableHttpService<S, M>
impl<S, M> Send for StreamableHttpService<S, M>
impl<S, M> Sync for StreamableHttpService<S, M>
impl<S, M> Unpin for StreamableHttpService<S, M>
impl<S, M> UnsafeUnpin for StreamableHttpService<S, M>
impl<S, M = LocalSessionManager> !UnwindSafe for StreamableHttpService<S, M>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<S, R> ServiceExt<R> for Swhere
S: Service<R>,
impl<S, R> ServiceExt<R> for Swhere
S: Service<R>,
Source§fn into_make_service(self) -> IntoMakeService<S>
fn into_make_service(self) -> IntoMakeService<S>
MakeService, that is a Service whose
response is another service. Read moreSource§fn into_make_service_with_connect_info<C>(
self,
) -> IntoMakeServiceWithConnectInfo<S, C>
fn into_make_service_with_connect_info<C>( self, ) -> IntoMakeServiceWithConnectInfo<S, C>
MakeService, that will store C’s
associated ConnectInfo in a request extension such that ConnectInfo
can extract it. Read moreSource§fn handle_error<F, T>(self, f: F) -> HandleError<Self, F, T>
fn handle_error<F, T>(self, f: F) -> HandleError<Self, F, T>
HandleError, that will handle errors
by converting them into responses. Read moreSource§impl<T, Request> ServiceExt<Request> for T
impl<T, Request> ServiceExt<Request> for T
Source§fn ready(&mut self) -> Ready<'_, Self, Request>where
Self: Sized,
fn ready(&mut self) -> Ready<'_, Self, Request>where
Self: Sized,
Source§fn ready_oneshot(self) -> ReadyOneshot<Self, Request>where
Self: Sized,
fn ready_oneshot(self) -> ReadyOneshot<Self, Request>where
Self: Sized,
Source§fn oneshot(self, req: Request) -> Oneshot<Self, Request>where
Self: Sized,
fn oneshot(self, req: Request) -> Oneshot<Self, Request>where
Self: Sized,
Service, calling it with the provided request once it is ready.Source§fn and_then<F>(self, f: F) -> AndThen<Self, F>
fn and_then<F>(self, f: F) -> AndThen<Self, F>
poll_ready method. Read moreSource§fn map_response<F, Response>(self, f: F) -> MapResponse<Self, F>
fn map_response<F, Response>(self, f: F) -> MapResponse<Self, F>
poll_ready method. Read moreSource§fn map_err<F, Error>(self, f: F) -> MapErr<Self, F>
fn map_err<F, Error>(self, f: F) -> MapErr<Self, F>
poll_ready method. Read moreSource§fn map_result<F, Response, Error>(self, f: F) -> MapResult<Self, F>
fn map_result<F, Response, Error>(self, f: F) -> MapResult<Self, F>
Result<Self::Response, Self::Error>)
to a different value, regardless of whether the future succeeds or
fails. Read more