Skip to content

Commit 8ef36fd

Browse files
committed
fix: gate streamable HTTP transport on not(local) feature
1 parent 55876cb commit 8ef36fd

File tree

15 files changed

+57
-43
lines changed

15 files changed

+57
-43
lines changed

crates/rmcp/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ The transport layer is pluggable. Two built-in pairs cover the most common cases
5252
| | Client | Server |
5353
|:-:|:-:|:-:|
5454
| **stdio** | [`TokioChildProcess`](crate::transport::TokioChildProcess) | [`stdio`](crate::transport::stdio) |
55-
| **Streamable HTTP** | [`StreamableHttpClientTransport`](crate::transport::StreamableHttpClientTransport) | [`StreamableHttpService`](crate::transport::StreamableHttpService) |
55+
| **Streamable HTTP** | [`StreamableHttpClientTransport`](crate::transport::StreamableHttpClientTransport) | `StreamableHttpService` |
5656

5757
Any type that implements the [`Transport`](crate::transport::Transport) trait can be used. The [`IntoTransport`](crate::transport::IntoTransport) helper trait provides automatic conversions from:
5858

crates/rmcp/src/handler/client.rs

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use std::sync::Arc;
44
use crate::{
55
error::ErrorData as McpError,
66
model::*,
7-
service::{NotificationContext, RequestContext, RoleClient, Service, ServiceRole},
7+
service::{
8+
MaybeSendFuture, NotificationContext, RequestContext, RoleClient, Service, ServiceRole,
9+
},
810
};
911

1012
impl<H: ClientHandler> Service<RoleClient> for H {
@@ -83,15 +85,15 @@ pub trait ClientHandler: Sized + Send + Sync + 'static {
8385
fn ping(
8486
&self,
8587
context: RequestContext<RoleClient>,
86-
) -> impl Future<Output = Result<(), McpError>> + Send + '_ {
88+
) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
8789
std::future::ready(Ok(()))
8890
}
8991

9092
fn create_message(
9193
&self,
9294
params: CreateMessageRequestParams,
9395
context: RequestContext<RoleClient>,
94-
) -> impl Future<Output = Result<CreateMessageResult, McpError>> + Send + '_ {
96+
) -> impl Future<Output = Result<CreateMessageResult, McpError>> + MaybeSendFuture + '_ {
9597
std::future::ready(Err(
9698
McpError::method_not_found::<CreateMessageRequestMethod>(),
9799
))
@@ -100,7 +102,7 @@ pub trait ClientHandler: Sized + Send + Sync + 'static {
100102
fn list_roots(
101103
&self,
102104
context: RequestContext<RoleClient>,
103-
) -> impl Future<Output = Result<ListRootsResult, McpError>> + Send + '_ {
105+
) -> impl Future<Output = Result<ListRootsResult, McpError>> + MaybeSendFuture + '_ {
104106
std::future::ready(Ok(ListRootsResult::default()))
105107
}
106108

@@ -162,7 +164,8 @@ pub trait ClientHandler: Sized + Send + Sync + 'static {
162164
&self,
163165
request: CreateElicitationRequestParams,
164166
context: RequestContext<RoleClient>,
165-
) -> impl Future<Output = Result<CreateElicitationResult, McpError>> + Send + '_ {
167+
) -> impl Future<Output = Result<CreateElicitationResult, McpError>> + MaybeSendFuture + '_
168+
{
166169
// Default implementation declines all requests - real clients should override this
167170
let _ = (request, context);
168171
std::future::ready(Ok(CreateElicitationResult {
@@ -175,7 +178,7 @@ pub trait ClientHandler: Sized + Send + Sync + 'static {
175178
&self,
176179
request: CustomRequest,
177180
context: RequestContext<RoleClient>,
178-
) -> impl Future<Output = Result<CustomResult, McpError>> + Send + '_ {
181+
) -> impl Future<Output = Result<CustomResult, McpError>> + MaybeSendFuture + '_ {
179182
let CustomRequest { method, .. } = request;
180183
let _ = context;
181184
std::future::ready(Err(McpError::new(
@@ -189,61 +192,61 @@ pub trait ClientHandler: Sized + Send + Sync + 'static {
189192
&self,
190193
params: CancelledNotificationParam,
191194
context: NotificationContext<RoleClient>,
192-
) -> impl Future<Output = ()> + Send + '_ {
195+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
193196
std::future::ready(())
194197
}
195198
fn on_progress(
196199
&self,
197200
params: ProgressNotificationParam,
198201
context: NotificationContext<RoleClient>,
199-
) -> impl Future<Output = ()> + Send + '_ {
202+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
200203
std::future::ready(())
201204
}
202205
fn on_logging_message(
203206
&self,
204207
params: LoggingMessageNotificationParam,
205208
context: NotificationContext<RoleClient>,
206-
) -> impl Future<Output = ()> + Send + '_ {
209+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
207210
std::future::ready(())
208211
}
209212
fn on_resource_updated(
210213
&self,
211214
params: ResourceUpdatedNotificationParam,
212215
context: NotificationContext<RoleClient>,
213-
) -> impl Future<Output = ()> + Send + '_ {
216+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
214217
std::future::ready(())
215218
}
216219
fn on_resource_list_changed(
217220
&self,
218221
context: NotificationContext<RoleClient>,
219-
) -> impl Future<Output = ()> + Send + '_ {
222+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
220223
std::future::ready(())
221224
}
222225
fn on_tool_list_changed(
223226
&self,
224227
context: NotificationContext<RoleClient>,
225-
) -> impl Future<Output = ()> + Send + '_ {
228+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
226229
std::future::ready(())
227230
}
228231
fn on_prompt_list_changed(
229232
&self,
230233
context: NotificationContext<RoleClient>,
231-
) -> impl Future<Output = ()> + Send + '_ {
234+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
232235
std::future::ready(())
233236
}
234237

235238
fn on_url_elicitation_notification_complete(
236239
&self,
237240
params: ElicitationResponseNotificationParam,
238241
context: NotificationContext<RoleClient>,
239-
) -> impl Future<Output = ()> + Send + '_ {
242+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
240243
std::future::ready(())
241244
}
242245
fn on_custom_notification(
243246
&self,
244247
notification: CustomNotification,
245248
context: NotificationContext<RoleClient>,
246-
) -> impl Future<Output = ()> + Send + '_ {
249+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
247250
let _ = (notification, context);
248251
std::future::ready(())
249252
}
@@ -269,99 +272,99 @@ macro_rules! impl_client_handler_for_wrapper {
269272
fn ping(
270273
&self,
271274
context: RequestContext<RoleClient>,
272-
) -> impl Future<Output = Result<(), McpError>> + Send + '_ {
275+
) -> impl Future<Output = Result<(), McpError>> + MaybeSendFuture + '_ {
273276
(**self).ping(context)
274277
}
275278

276279
fn create_message(
277280
&self,
278281
params: CreateMessageRequestParams,
279282
context: RequestContext<RoleClient>,
280-
) -> impl Future<Output = Result<CreateMessageResult, McpError>> + Send + '_ {
283+
) -> impl Future<Output = Result<CreateMessageResult, McpError>> + MaybeSendFuture + '_ {
281284
(**self).create_message(params, context)
282285
}
283286

284287
fn list_roots(
285288
&self,
286289
context: RequestContext<RoleClient>,
287-
) -> impl Future<Output = Result<ListRootsResult, McpError>> + Send + '_ {
290+
) -> impl Future<Output = Result<ListRootsResult, McpError>> + MaybeSendFuture + '_ {
288291
(**self).list_roots(context)
289292
}
290293

291294
fn create_elicitation(
292295
&self,
293296
request: CreateElicitationRequestParams,
294297
context: RequestContext<RoleClient>,
295-
) -> impl Future<Output = Result<CreateElicitationResult, McpError>> + Send + '_ {
298+
) -> impl Future<Output = Result<CreateElicitationResult, McpError>> + MaybeSendFuture + '_ {
296299
(**self).create_elicitation(request, context)
297300
}
298301

299302
fn on_custom_request(
300303
&self,
301304
request: CustomRequest,
302305
context: RequestContext<RoleClient>,
303-
) -> impl Future<Output = Result<CustomResult, McpError>> + Send + '_ {
306+
) -> impl Future<Output = Result<CustomResult, McpError>> + MaybeSendFuture + '_ {
304307
(**self).on_custom_request(request, context)
305308
}
306309

307310
fn on_cancelled(
308311
&self,
309312
params: CancelledNotificationParam,
310313
context: NotificationContext<RoleClient>,
311-
) -> impl Future<Output = ()> + Send + '_ {
314+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
312315
(**self).on_cancelled(params, context)
313316
}
314317

315318
fn on_progress(
316319
&self,
317320
params: ProgressNotificationParam,
318321
context: NotificationContext<RoleClient>,
319-
) -> impl Future<Output = ()> + Send + '_ {
322+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
320323
(**self).on_progress(params, context)
321324
}
322325

323326
fn on_logging_message(
324327
&self,
325328
params: LoggingMessageNotificationParam,
326329
context: NotificationContext<RoleClient>,
327-
) -> impl Future<Output = ()> + Send + '_ {
330+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
328331
(**self).on_logging_message(params, context)
329332
}
330333

331334
fn on_resource_updated(
332335
&self,
333336
params: ResourceUpdatedNotificationParam,
334337
context: NotificationContext<RoleClient>,
335-
) -> impl Future<Output = ()> + Send + '_ {
338+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
336339
(**self).on_resource_updated(params, context)
337340
}
338341

339342
fn on_resource_list_changed(
340343
&self,
341344
context: NotificationContext<RoleClient>,
342-
) -> impl Future<Output = ()> + Send + '_ {
345+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
343346
(**self).on_resource_list_changed(context)
344347
}
345348

346349
fn on_tool_list_changed(
347350
&self,
348351
context: NotificationContext<RoleClient>,
349-
) -> impl Future<Output = ()> + Send + '_ {
352+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
350353
(**self).on_tool_list_changed(context)
351354
}
352355

353356
fn on_prompt_list_changed(
354357
&self,
355358
context: NotificationContext<RoleClient>,
356-
) -> impl Future<Output = ()> + Send + '_ {
359+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
357360
(**self).on_prompt_list_changed(context)
358361
}
359362

360363
fn on_custom_notification(
361364
&self,
362365
notification: CustomNotification,
363366
context: NotificationContext<RoleClient>,
364-
) -> impl Future<Output = ()> + Send + '_ {
367+
) -> impl Future<Output = ()> + MaybeSendFuture + '_ {
365368
(**self).on_custom_notification(notification, context)
366369
}
367370

crates/rmcp/src/handler/server/prompt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
77
use std::{future::Future, marker::PhantomData};
88

9+
#[cfg(not(feature = "local"))]
910
use futures::future::BoxFuture;
10-
#[allow(unused_imports)]
1111
use serde::de::DeserializeOwned;
1212

1313
use super::common::{AsRequestContext, FromContextPart};

crates/rmcp/src/handler/server/tool.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::{
44
marker::PhantomData,
55
};
66

7+
#[cfg(not(feature = "local"))]
78
use futures::future::BoxFuture;
89
use serde::de::DeserializeOwned;
910

crates/rmcp/src/service.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use futures::FutureExt;
2+
#[cfg(not(feature = "local"))]
3+
use futures::future::BoxFuture;
14
#[cfg(feature = "local")]
25
use futures::future::LocalBoxFuture;
3-
use futures::{FutureExt, future::BoxFuture};
46
use thiserror::Error;
57

68
// ---------------------------------------------------------------------------

crates/rmcp/src/service/tower.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{future::poll_fn, marker::PhantomData};
33
use tower_service::Service as TowerService;
44

55
use super::NotificationContext;
6-
use crate::service::{RequestContext, Service, ServiceRole};
6+
use crate::service::{MaybeSendFuture, RequestContext, Service, ServiceRole};
77

88
pub struct TowerHandler<S, R: ServiceRole> {
99
pub service: S,
@@ -44,7 +44,7 @@ where
4444
&self,
4545
_notification: R::PeerNot,
4646
_context: NotificationContext<R>,
47-
) -> impl Future<Output = Result<(), crate::ErrorData>> + Send + '_ {
47+
) -> impl Future<Output = Result<(), crate::ErrorData>> + MaybeSendFuture + '_ {
4848
std::future::ready(Ok(()))
4949
}
5050

crates/rmcp/src/transport.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//! | transport | client | server |
88
//! |:-: |:-: |:-: |
99
//! | std IO | [`child_process::TokioChildProcess`] | [`io::stdio`] |
10-
//! | streamable http | [`streamable_http_client::StreamableHttpClientTransport`] | [`streamable_http_server::StreamableHttpService`] |
10+
//! | streamable http | [`streamable_http_client::StreamableHttpClientTransport`] | `streamable_http_server::StreamableHttpService` |
1111
//!
1212
//!## Helper Transport Types
1313
//! Thers are several helper transport types that can help you to create transport quickly.
@@ -107,7 +107,7 @@ pub use auth::{
107107
// pub mod ws;
108108
#[cfg(feature = "transport-streamable-http-server-session")]
109109
pub mod streamable_http_server;
110-
#[cfg(feature = "transport-streamable-http-server")]
110+
#[cfg(all(feature = "transport-streamable-http-server", not(feature = "local")))]
111111
pub use streamable_http_server::tower::{StreamableHttpServerConfig, StreamableHttpService};
112112

113113
#[cfg(feature = "transport-streamable-http-client")]
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pub mod session;
2-
#[cfg(feature = "transport-streamable-http-server")]
2+
#[cfg(all(feature = "transport-streamable-http-server", not(feature = "local")))]
33
pub mod tower;
44
pub use session::{SessionId, SessionManager};
5-
#[cfg(feature = "transport-streamable-http-server")]
5+
#[cfg(all(feature = "transport-streamable-http-server", not(feature = "local")))]
66
pub use tower::{StreamableHttpServerConfig, StreamableHttpService};

crates/rmcp/src/transport/streamable_http_server/session.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub mod never;
3333

3434
/// Controls how MCP sessions are created, validated, and closed.
3535
///
36-
/// The [`StreamableHttpService`](super::StreamableHttpService) calls into this
36+
/// The `StreamableHttpService` calls into this
3737
/// trait for every HTTP request that carries (or should carry) a session ID.
3838
///
3939
/// See the [module-level docs](self) for background on sessions.

crates/rmcp/src/transport/streamable_http_server/tower.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl<S, M> Clone for StreamableHttpService<S, M> {
204204
impl<RequestBody, S, M> tower_service::Service<Request<RequestBody>> for StreamableHttpService<S, M>
205205
where
206206
RequestBody: Body + Send + 'static,
207-
S: crate::Service<RoleServer>,
207+
S: crate::Service<RoleServer> + Send + 'static,
208208
M: SessionManager,
209209
RequestBody::Error: Display,
210210
RequestBody::Data: Send + 'static,

0 commit comments

Comments
 (0)