Skip to main content

fastmcp_server/
middleware.rs

1//! Middleware hooks for request/response interception.
2//!
3//! This provides a minimal, synchronous middleware system for MCP requests.
4//! Middleware can short-circuit requests, transform responses, and rewrite errors.
5//!
6//! # Ordering Semantics
7//!
8//! - `on_request` runs **in registration order** (first registered, first called).
9//! - `on_response` runs **in reverse order** for middleware whose `on_request` ran.
10//! - `on_error` runs **in reverse order** for middleware whose `on_request` ran.
11//!
12//! If a middleware returns `Respond` from `on_request`, the response is still
13//! passed through `on_response` for the already-entered middleware stack.
14//! If any `on_request` or `on_response` returns an error, `on_error` is invoked
15//! for the entered middleware stack to allow error rewriting.
16
17use fastmcp_core::{McpContext, McpError, McpResult};
18use fastmcp_protocol::JsonRpcRequest;
19
20/// Result of middleware request interception.
21#[derive(Debug, Clone)]
22pub enum MiddlewareDecision {
23    /// Continue normal dispatch.
24    Continue,
25    /// Short-circuit dispatch and return this JSON value as the result.
26    Respond(serde_json::Value),
27}
28
29/// Middleware hook trait for request/response interception.
30///
31/// This is intentionally minimal: synchronous hooks only, with simple
32/// short-circuit and response transform capabilities. See the module-level
33/// documentation for ordering semantics.
34pub trait Middleware: Send + Sync {
35    /// Invoked before routing the request.
36    ///
37    /// Return `Respond` to skip normal dispatch and return a custom result.
38    fn on_request(
39        &self,
40        _ctx: &McpContext,
41        _request: &JsonRpcRequest,
42    ) -> McpResult<MiddlewareDecision> {
43        Ok(MiddlewareDecision::Continue)
44    }
45
46    /// Invoked after a successful handler result is produced.
47    ///
48    /// Middleware can transform the response value (or return an error).
49    fn on_response(
50        &self,
51        _ctx: &McpContext,
52        _request: &JsonRpcRequest,
53        response: serde_json::Value,
54    ) -> McpResult<serde_json::Value> {
55        Ok(response)
56    }
57
58    /// Invoked when a handler or middleware returns an error.
59    ///
60    /// Middleware may rewrite the error before it is sent to the client.
61    fn on_error(&self, _ctx: &McpContext, _request: &JsonRpcRequest, error: McpError) -> McpError {
62        error
63    }
64}