Skip to content

Commit 18b1e6f

Browse files
authored
feat: add middleware support to mcp_http_handler (#112)
* feat: generic middlewares * feat: extend mc_hddt_handler to support middlewares * chore: whitelist typos * chore: build issue
1 parent 150e3a0 commit 18b1e6f

File tree

13 files changed

+526
-49
lines changed

13 files changed

+526
-49
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,6 @@ todo = "deny"
9999

100100
[workspace.metadata.cargo-machete]
101101
ignored = ["bindgen", "cbindgen", "prost_build", "serde"]
102+
103+
[workspace.metadata.typos]
104+
default.extend-ignore-re = ["clonable"]

crates/rust-mcp-extra/src/id_generator/nano_id_generator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ mod tests {
6464

6565
for _ in 0..1000 {
6666
let id: String = generator.generate();
67-
assert!(seen.insert(id.clone()), "Duplicate ID: {}", id);
67+
assert!(seen.insert(id.clone()), "Duplicate ID: {id}");
6868
}
6969
}
7070
}

crates/rust-mcp-extra/src/id_generator/snow_flake_id_generator.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,7 @@ mod tests {
133133
let current_id: u64 = id.parse().expect("ID should be a valid u64");
134134
assert!(
135135
current_id > prev_id,
136-
"ID not strictly increasing: {} <= {}",
137-
current_id,
138-
prev_id
136+
"ID not strictly increasing: {current_id} <= {prev_id}"
139137
);
140138
prev_id = current_id;
141139
}

crates/rust-mcp-sdk/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,6 @@ macros = ["rust-mcp-macros/sdk"]
109109

110110
[lints]
111111
workspace = true
112+
113+
[package.metadata.typos]
114+
default.extend-ignore-re = ["clonable"]

crates/rust-mcp-sdk/src/hyper_servers/routes.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ pub mod messages_routes;
44
pub mod sse_routes;
55
pub mod streamable_http_routes;
66

7-
use crate::mcp_http::McpAppState;
8-
97
use super::HyperServerOptions;
10-
use axum::Router;
8+
use crate::mcp_http::{McpAppState, McpHttpHandler};
9+
use axum::{Extension, Router};
1110
use std::sync::Arc;
1211

1312
/// Constructs the Axum router with all application routes
@@ -21,7 +20,11 @@ use std::sync::Arc;
2120
///
2221
/// # Returns
2322
/// * `Router` - An Axum router configured with all application routes and state
24-
pub fn app_routes(state: Arc<McpAppState>, server_options: &HyperServerOptions) -> Router {
23+
pub fn app_routes(
24+
state: Arc<McpAppState>,
25+
server_options: &HyperServerOptions,
26+
http_handler: McpHttpHandler,
27+
) -> Router {
2528
let router: Router = Router::new()
2629
.merge(streamable_http_routes::routes(
2730
server_options.streamable_http_endpoint(),
@@ -42,7 +45,8 @@ pub fn app_routes(state: Arc<McpAppState>, server_options: &HyperServerOptions)
4245
r
4346
})
4447
.with_state(state)
45-
.merge(fallback_routes::routes());
48+
.merge(fallback_routes::routes())
49+
.layer(Extension(Arc::new(http_handler)));
4650

4751
router
4852
}

crates/rust-mcp-sdk/src/hyper_servers/routes/messages_routes.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
mcp_http::{McpAppState, McpHttpHandler},
44
utils::remove_query_and_hash,
55
};
6-
use axum::{extract::State, response::IntoResponse, routing::post, Router};
6+
use axum::{extract::State, response::IntoResponse, routing::post, Extension, Router};
77
use http::{HeaderMap, Method, Uri};
88
use std::sync::Arc;
99

@@ -18,10 +18,13 @@ pub async fn handle_messages(
1818
uri: Uri,
1919
headers: HeaderMap,
2020
State(state): State<Arc<McpAppState>>,
21+
Extension(http_handler): Extension<Arc<McpHttpHandler>>,
2122
message: String,
2223
) -> TransportServerResult<impl IntoResponse> {
2324
let request = McpHttpHandler::create_request(Method::POST, uri, headers, Some(&message));
24-
let generic_response = McpHttpHandler::handle_sse_message(request, state.clone()).await?;
25+
let generic_response = http_handler
26+
.handle_sse_message(request, state.clone())
27+
.await?;
2528
let (parts, body) = generic_response.into_parts();
2629
let resp = axum::response::Response::from_parts(parts, axum::body::Body::new(body));
2730
Ok(resp)

crates/rust-mcp-sdk/src/hyper_servers/routes/sse_routes.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@ pub fn routes(sse_endpoint: &str, sse_message_endpoint: &str) -> Router<Arc<McpA
3636
/// * `TransportServerResult<impl IntoResponse>` - The SSE response stream or an error
3737
pub async fn handle_sse(
3838
Extension(sse_message_endpoint): Extension<SseMessageEndpoint>,
39+
Extension(http_handler): Extension<Arc<McpHttpHandler>>,
3940
State(state): State<Arc<McpAppState>>,
4041
) -> TransportServerResult<impl IntoResponse> {
4142
let SseMessageEndpoint(sse_message_endpoint) = sse_message_endpoint;
42-
let generic_response =
43-
McpHttpHandler::handle_sse_connection(state.clone(), Some(&sse_message_endpoint)).await?;
43+
let generic_response = http_handler
44+
.handle_sse_connection(state.clone(), Some(&sse_message_endpoint))
45+
.await?;
4446
let (parts, body) = generic_response.into_parts();
4547
let resp = axum::response::Response::from_parts(parts, axum::body::Body::new(body));
4648
Ok(resp)

crates/rust-mcp-sdk/src/hyper_servers/routes/streamable_http_routes.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::hyper_servers::error::TransportServerResult;
22
use crate::mcp_http::{McpAppState, McpHttpHandler};
33
use axum::routing::get;
4+
use axum::Extension;
45
use axum::{
56
extract::{Query, State},
67
response::IntoResponse,
@@ -24,9 +25,10 @@ pub async fn handle_streamable_http_get(
2425
headers: HeaderMap,
2526
uri: Uri,
2627
State(state): State<Arc<McpAppState>>,
28+
Extension(http_handler): Extension<Arc<McpHttpHandler>>,
2729
) -> TransportServerResult<impl IntoResponse> {
2830
let request = McpHttpHandler::create_request(Method::GET, uri, headers, None);
29-
let generic_res = McpHttpHandler::handle_streamable_http(request, state).await?;
31+
let generic_res = http_handler.handle_streamable_http(request, state).await?;
3032
let (parts, body) = generic_res.into_parts();
3133
let resp = axum::response::Response::from_parts(parts, axum::body::Body::new(body));
3234
Ok(resp)
@@ -36,12 +38,13 @@ pub async fn handle_streamable_http_post(
3638
headers: HeaderMap,
3739
uri: Uri,
3840
State(state): State<Arc<McpAppState>>,
41+
Extension(http_handler): Extension<Arc<McpHttpHandler>>,
3942
Query(_params): Query<HashMap<String, String>>,
4043
payload: String,
4144
) -> TransportServerResult<impl IntoResponse> {
4245
let request =
4346
McpHttpHandler::create_request(Method::POST, uri, headers, Some(payload.as_str()));
44-
let generic_res = McpHttpHandler::handle_streamable_http(request, state).await?;
47+
let generic_res = http_handler.handle_streamable_http(request, state).await?;
4548
let (parts, body) = generic_res.into_parts();
4649
let resp = axum::response::Response::from_parts(parts, axum::body::Body::new(body));
4750
Ok(resp)
@@ -51,9 +54,10 @@ pub async fn handle_streamable_http_delete(
5154
headers: HeaderMap,
5255
uri: Uri,
5356
State(state): State<Arc<McpAppState>>,
57+
Extension(http_handler): Extension<Arc<McpHttpHandler>>,
5458
) -> TransportServerResult<impl IntoResponse> {
5559
let request = McpHttpHandler::create_request(Method::DELETE, uri, headers, None);
56-
let generic_res = McpHttpHandler::handle_streamable_http(request, state).await?;
60+
let generic_res = http_handler.handle_streamable_http(request, state).await?;
5761
let (parts, body) = generic_res.into_parts();
5862
let resp = axum::response::Response::from_parts(parts, axum::body::Body::new(body));
5963
Ok(resp)

crates/rust-mcp-sdk/src/hyper_servers/server.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
utils::{
66
DEFAULT_MESSAGES_ENDPOINT, DEFAULT_SSE_ENDPOINT, DEFAULT_STREAMABLE_HTTP_ENDPOINT,
77
},
8-
McpAppState,
8+
McpAppState, McpHttpHandler,
99
},
1010
mcp_server::hyper_runtime::HyperRuntime,
1111
mcp_traits::{mcp_handler::McpServerHandler, IdGenerator},
@@ -275,7 +275,9 @@ impl HyperServer {
275275
dns_rebinding_protection: server_options.dns_rebinding_protection,
276276
event_store: server_options.event_store.as_ref().map(Arc::clone),
277277
});
278-
let app = app_routes(Arc::clone(&state), &server_options);
278+
279+
let http_handler = McpHttpHandler::new(); //TODO: add auth handlers
280+
let app = app_routes(Arc::clone(&state), &server_options, http_handler);
279281
Self {
280282
app,
281283
state,

crates/rust-mcp-sdk/src/mcp_http.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ mod app_state;
22
mod mcp_http_handler;
33
pub(crate) mod mcp_http_utils;
44

5+
mod mcp_http_middleware; //TODO:
6+
57
pub use app_state::*;
68
pub use mcp_http_handler::*;
9+
pub use mcp_http_middleware::Middleware;
710

811
pub(crate) mod utils {
912
pub use super::mcp_http_utils::*;

0 commit comments

Comments
 (0)