Skip to content

Commit 97a955c

Browse files
committed
feat: add actix-web support for streamable HTTP server transport
- Implement ActixStreamableHttpService with full feature parity to Axum implementation - Support GET (SSE streams), POST (requests), DELETE (session cleanup) endpoints - Add comprehensive logging matching SSE implementation - Use X-Accel-Buffering header constant for consistency - Create working example server (counter_streamable_http_actix.rs) - Refactor tower.rs to import StreamableHttpServerConfig from parent module - Add HEADER_X_ACCEL_BUFFERING constant to common http_header module - Update streamable_client.js to accept URL as command line argument - Configure example to bind to 127.0.0.1 for IPv4 compatibility The actix-web implementation provides identical functionality to the Axum version while following actix-web patterns and conventions.
1 parent 1389f34 commit 97a955c

File tree

7 files changed

+598
-25
lines changed

7 files changed

+598
-25
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub const HEADER_SESSION_ID: &str = "Mcp-Session-Id";
22
pub const HEADER_LAST_EVENT_ID: &str = "Last-Event-Id";
3+
pub const HEADER_X_ACCEL_BUFFERING: &str = "X-Accel-Buffering";
34
pub const EVENT_STREAM_MIME_TYPE: &str = "text/event-stream";
45
pub const JSON_MIME_TYPE: &str = "application/json";

crates/rmcp/src/transport/streamable_http_server.rs

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,76 @@
1+
//! Streamable HTTP Server Transport Module
2+
//!
3+
//! This module provides streamable HTTP transport implementations for MCP.
4+
//!
5+
//! # Type Export Strategy
6+
//!
7+
//! This module exports framework-specific implementations with explicit names:
8+
//! - `AxumStreamableHttpService` - The Axum-based streamable HTTP service implementation
9+
//! - `ActixStreamableHttpService` - The actix-web-based streamable HTTP service implementation
10+
//!
11+
//! For convenience, a type alias `StreamableHttpService` is provided that resolves to:
12+
//! - `ActixStreamableHttpService` when the `actix-web` feature is enabled
13+
//! - `AxumStreamableHttpService` when only the `axum` feature is enabled
14+
//!
15+
//! # Examples
16+
//!
17+
//! Using the convenience alias (recommended for most use cases):
18+
//! ```ignore
19+
//! use rmcp::transport::StreamableHttpService;
20+
//! let service = StreamableHttpService::new(|| Ok(handler), session_manager, config);
21+
//! ```
22+
//!
23+
//! Using explicit types (when you need a specific implementation):
24+
//! ```ignore
25+
//! #[cfg(feature = "axum")]
26+
//! use rmcp::transport::AxumStreamableHttpService;
27+
//! #[cfg(feature = "axum")]
28+
//! let service = AxumStreamableHttpService::new(|| Ok(handler), session_manager, config);
29+
//! ```
30+
131
pub mod session;
2-
#[cfg(feature = "transport-streamable-http-server")]
3-
#[cfg_attr(docsrs, doc(cfg(feature = "transport-streamable-http-server")))]
32+
33+
use std::time::Duration;
34+
35+
/// Configuration for the streamable HTTP server
36+
#[derive(Debug, Clone)]
37+
pub struct StreamableHttpServerConfig {
38+
/// The ping message duration for SSE connections.
39+
pub sse_keep_alive: Option<Duration>,
40+
/// If true, the server will create a session for each request and keep it alive.
41+
pub stateful_mode: bool,
42+
}
43+
44+
impl Default for StreamableHttpServerConfig {
45+
fn default() -> Self {
46+
Self {
47+
sse_keep_alive: Some(Duration::from_secs(15)),
48+
stateful_mode: true,
49+
}
50+
}
51+
}
52+
53+
// Axum implementation
54+
#[cfg(all(feature = "transport-streamable-http-server", feature = "axum"))]
55+
#[cfg_attr(docsrs, doc(cfg(all(feature = "transport-streamable-http-server", feature = "axum"))))]
456
pub mod tower;
57+
58+
#[cfg(all(feature = "transport-streamable-http-server", feature = "axum"))]
59+
pub use tower::StreamableHttpService as AxumStreamableHttpService;
60+
61+
// Actix-web implementation
62+
#[cfg(all(feature = "transport-streamable-http-server", feature = "actix-web"))]
63+
#[cfg_attr(docsrs, doc(cfg(all(feature = "transport-streamable-http-server", feature = "actix-web"))))]
64+
pub mod actix_impl;
65+
66+
#[cfg(all(feature = "transport-streamable-http-server", feature = "actix-web"))]
67+
pub use actix_impl::StreamableHttpService as ActixStreamableHttpService;
68+
69+
// Export the preferred implementation as StreamableHttpService (without generic parameters)
70+
#[cfg(all(feature = "transport-streamable-http-server", feature = "actix-web"))]
71+
pub use actix_impl::StreamableHttpService;
72+
73+
#[cfg(all(feature = "transport-streamable-http-server", feature = "axum", not(feature = "actix-web")))]
74+
pub use tower::StreamableHttpService;
75+
576
pub use session::{SessionId, SessionManager};
6-
#[cfg(feature = "transport-streamable-http-server")]
7-
#[cfg_attr(docsrs, doc(cfg(feature = "transport-streamable-http-server")))]
8-
pub use tower::{StreamableHttpServerConfig, StreamableHttpService};

0 commit comments

Comments
 (0)