Skip to content

Commit f5860d1

Browse files
authored
fix: Disable statefulness to attempt to fix initialize race condition (#351)
* fix: Disable statefulness to attempt to fix initialize race condition * Change stateful_mode to being configuratable on the transport * Use ..Default syntax * changeset * Add new flag to docs config reference page
1 parent 95b3c3e commit f5860d1

File tree

4 files changed

+24
-7
lines changed

4 files changed

+24
-7
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### fix: Disable statefulness to fix initialize race condition - @swcollard PR #351
2+
3+
We've been seeing errors with state and session handling in the MCP Server. Whether that is requests being sent before the initialized notification is processed. Or running a fleet of MCP Server pods behind a round robin load balancer. A new configuration option under the streamable_http transport `stateful_mode`, allows disabling session handling which appears to fix the race condition issue.

crates/apollo-mcp-server/src/server.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ pub enum Transport {
8080
/// The port to bind to
8181
#[serde(default = "Transport::default_port")]
8282
port: u16,
83+
84+
#[serde(default = "Transport::default_stateful_mode")]
85+
stateful_mode: bool,
8386
},
8487
}
8588

@@ -91,6 +94,10 @@ impl Transport {
9194
fn default_port() -> u16 {
9295
5000
9396
}
97+
98+
fn default_stateful_mode() -> bool {
99+
true
100+
}
94101
}
95102

96103
#[bon]

crates/apollo-mcp-server/src/server/states/starting.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::{net::SocketAddr, sync::Arc};
22

33
use apollo_compiler::{Name, Schema, ast::OperationType, validation::Valid};
44
use axum::{Router, extract::Query, http::StatusCode, response::Json, routing::get};
5-
use rmcp::transport::StreamableHttpService;
65
use rmcp::transport::streamable_http_server::session::local::LocalSessionManager;
6+
use rmcp::transport::{StreamableHttpServerConfig, StreamableHttpService};
77
use rmcp::{
88
ServiceExt as _,
99
transport::{SseServer, sse_server::SseServerConfig, stdio},
@@ -126,6 +126,7 @@ impl Starting {
126126
auth: _,
127127
address: _,
128128
port: _,
129+
stateful_mode: _,
129130
},
130131
true,
131132
) => Some(HealthCheck::new(self.config.health_check.clone())),
@@ -168,14 +169,18 @@ impl Starting {
168169
auth,
169170
address,
170171
port,
172+
stateful_mode,
171173
} => {
172174
info!(port = ?port, address = ?address, "Starting MCP server in Streamable HTTP mode");
173175
let running = running.clone();
174176
let listen_address = SocketAddr::new(address, port);
175177
let service = StreamableHttpService::new(
176178
move || Ok(running.clone()),
177179
LocalSessionManager::default().into(),
178-
Default::default(),
180+
StreamableHttpServerConfig {
181+
stateful_mode,
182+
..Default::default()
183+
},
179184
);
180185
let mut router =
181186
with_auth!(axum::Router::new().nest_service("/mcp", service), auth);

docs/source/config-file.mdx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,13 @@ The available fields depend on the value of the nested `type` key:
147147

148148
##### Streamable HTTP
149149

150-
| Option | Value | Value Type | Description |
151-
| :-------- | :-------------------- | :--------- | :------------------------------------------------------------------------ |
152-
| `type` | `"streamable_http"` | | Host the MCP server on the configuration, using streamable HTTP messages. |
153-
| `address` | `127.0.0.1` (default) | `IpAddr` | The IP address to bind to |
154-
| `port` | `5000` (default) | `u16` | The port to bind to |
150+
| Option | Value | Value Type | Description |
151+
| :-------------- | :-------------------- | :--------- | :------------------------------------------------------------------------ |
152+
| `type` | `"streamable_http"` | | Host the MCP server on the configuration, using streamable HTTP messages. |
153+
| `address` | `127.0.0.1` (default) | `IpAddr` | The IP address to bind to |
154+
| `port` | `5000` (default) | `u16` | The port to bind to |
155+
| `stateful_mode` | `true` (default) | `bool` | Flag to enable or disable stateful mode and session management. |
156+
155157

156158
##### SSE (Deprecated, use StreamableHTTP)
157159

0 commit comments

Comments
 (0)