next
flow) so you can log, collect metrics, filter/transform requests, cache, rate limit, and more.
Middleware Process
mcp-use runs middleware in a chain. When a request likeinitialize
, tools/call
, resources/read
, etc. is made, it flows through your middlewares (in order). In each middleware you can:
- Analyze the incoming request through the context
- Modify the request (and its metadata) before execution
- Execute the next handler via
await call_next(context)
- Inspect/transform the result or handle errors
- Fully supported:
stdio
,http
(streamable HTTP and SSE),sandbox
- Not yet supported:
websocket
Overview
You implement middleware by subclassingMiddleware
and overriding one or more hooks. Each hook receives:
context: MiddlewareContext[T]
- typed request contextcall_next: NextFunctionT[T, R]
- call to the next middleware or the actual MCP handler
on_call_tool
.
Quick Start
Core Types
MiddlewareContext[T]
NextFunctionT[T, R]
Middleware
base class
You override hooks on the base class. If you only need a single entry point for all requests, override on_request
.
Hook Reference
Available hooks (override any subset). Types below come frommcp.types
.
Writing Middleware
Timing Example
Built-in Middleware
Default logging
- A default logging middleware is automatically prepended by
MCPClient
. - It logs each request/response at debug level with timing.
- You don’t need to add it manually; just pass your custom middlewares.
Metrics
Instantiate and pass to the client. Each middleware exposes a getter on the instance.Middleware Chain Execution
Middleware executes in the order provided (outermost first):mw1
starts → callsawait call_next(context)
mw2
starts → callsawait call_next(context)
mw3
starts → callsawait call_next(context)
- Actual MCP call executes
mw3
resumes with resultmw2
resumes with resultmw1
resumes with result
Error Handling
Always re-raise unless you’re intentionally transforming errors.Best Practices
- Re-raise exceptions unless you have a clear alternative behavior.
- Use type hints on hooks for better IDE support.
- Keep each middleware focused on a single concern.
- Use
context.metadata
for cross-middleware communication.
Integration with MCP Clients
MCPClient
Per-session stacks
See the examples directory for a complete working example: