2.9.0
Middleware adds behavior that applies across multiple operations—authentication, logging, rate limiting, or request transformation—without modifying individual tools or resources.
Overview
MCP middleware forms a pipeline around your server’s operations. When a request arrives, it flows through each middleware in order—each can inspect, modify, or reject the request before passing it along. After the operation completes, the response flows back through the same middleware in reverse order.- Pre-process: Validate authentication, log incoming requests, check rate limits
- Post-process: Transform responses, record timing metrics, handle errors consistently
call_next(context). Calling it continues the chain; not calling it stops processing entirely.
Execution Order
Middleware executes in the order added to the server. The first middleware runs first on the way in and last on the way out:Server Composition
When using mounted servers, middleware behavior follows a clear hierarchy:- Parent middleware runs for all requests, including those routed to mounted servers
- Mounted server middleware only runs for requests handled by that specific server
child_tool flow through the parent’s AuthMiddleware first, then through the child’s LoggingMiddleware.
Hooks
Rather than processing every message identically, FastMCP provides specialized hooks at different levels of specificity. Multiple hooks fire for a single request, going from general to specific:
When a client calls a tool, the middleware chain processes
on_message first, then on_request, then on_call_tool. This hierarchy lets you target exactly the right scope—use on_message for logging everything, on_request for authentication, and on_call_tool for tool-specific behavior.
Hook Signature
Every hook follows the same pattern:context—MiddlewareContextcontaining request informationcall_next— Async function to continue the middleware chain
MiddlewareContext
Thecontext parameter provides access to request details:
Message Hooks
on_message
Called for every MCP message—both requests and notifications.on_request
Called for MCP requests that expect a response.on_notification
Called for fire-and-forget MCP notifications.Operation Hooks
on_call_tool
Called when a tool is executed. Thecontext.message contains name (tool name) and arguments (dict).
ToolError.
on_read_resource
Called when a resource is read. Thecontext.message contains uri (resource URI).
on_get_prompt
Called when a prompt is retrieved. Thecontext.message contains name (prompt name) and arguments (dict).
on_list_tools
Called when listing available tools. Returns a list of FastMCPTool objects before MCP conversion.
list[Tool] — Can be filtered before returning to client.
on_list_resources
Called when listing available resources. Returns FastMCPResource objects.
list[Resource]
on_list_resource_templates
Called when listing resource templates.list[ResourceTemplate]
on_list_prompts
Called when listing available prompts.list[Prompt]
on_initialize
New in version2.13.0
Called when a client connects and initializes the session. This hook cannot modify the initialization response.
None — The initialization response is handled internally by the MCP protocol.
Raw Handler
For complete control over all messages, override__call__ instead of individual hooks:
Session Availability
New in version2.13.1
The MCP session may not be available during certain phases like initialization. Check before accessing session-specific attributes:
Built-in Middleware
FastMCP includes production-ready middleware for common server concerns.Logging
LoggingMiddleware provides human-readable request and response logging. StructuredLoggingMiddleware outputs JSON-formatted logs for aggregation tools like Datadog or Splunk.
Timing
TimingMiddleware logs execution duration for all requests. DetailedTimingMiddleware provides per-operation timing with separate tracking for tools, resources, and prompts.
Caching
Each settings class accepts:
enabled— Enable/disable caching for this operationttl— Time-to-live in secondsincluded_*/excluded_*— Whitelist or blacklist specific items
Rate Limiting
RateLimitingMiddleware uses a token bucket algorithm allowing controlled bursts. SlidingWindowRateLimitingMiddleware provides precise time-window rate limiting without burst allowance.
For sliding window rate limiting:
Error Handling
ErrorHandlingMiddleware provides centralized error logging and transformation. RetryMiddleware automatically retries with exponential backoff for transient failures.
For automatic retries:
Ping
New in version3.0.0
The ping task starts on the first message and stops automatically when the session ends. Most useful for stateful HTTP connections; has no effect on stateless connections.
Tool Injection
ToolInjectionMiddleware dynamically injects tools during request processing. PromptToolMiddleware and ResourceToolMiddleware provide compatibility layers for clients that cannot list or access prompts and resources directly—they expose those capabilities as tools.
Response Limiting
New in version3.0.0
TextContent block. For non-text responses, the serialized JSON is used as the text source.
If a tool defines an
output_schema, truncated responses will no longer conform to that schema — the client will receive a plain TextContent block instead of the expected structured output. Keep this in mind when setting size limits for tools with structured responses.Combining Middleware
Order matters. Place middleware that should run first (on the way in) earliest:Custom Middleware
When the built-in middleware doesn’t fit your needs—custom authentication schemes, domain-specific logging, or request transformation—subclassMiddleware and override the hooks you need.
Denying Requests
Raise the appropriate error type to stop processing and return an error to the client.
Do not return error values or skip
call_next() to indicate errors—raise exceptions for proper error propagation.
Modifying Requests
Change the message before passing it down the chain.Modifying Responses
Transform results after the handler executes.Filtering Lists
List operations return FastMCP objects that you can filter before they reach the client. When filtering list results, also block execution in the corresponding operation hook to maintain consistency:Accessing Component Metadata
During execution hooks, component metadata (like tags) isn’t directly available. Look up the component through the server:Storing State
New in version2.11.0
Middleware can store state that tools access later through the FastMCP context.
Constructor Parameters
Initialize middleware with configuration:Error Handling in Custom Middleware
Wrapcall_next() to handle errors from downstream middleware and handlers.