Skip to main content
Middleware runs shared logic around MCP operations and HTTP requests. Use it for logging, authorization, request shaping, rate limiting, headers, custom routes, and other cross-cutting behavior. This guide explains where each middleware layer fits and how to apply common patterns.

Choose MCP middleware or Hono middleware

Use MCP middleware when logic depends on a parsed MCP operation. Use Hono middleware when logic belongs at the HTTP layer before MCP parsing. MCP middleware patterns use the mcp: prefix. Hono middleware uses normal server.use(...) calls. Both layers are request-scoped, and there is no transport session affinity between calls.

Wrap MCP tool calls

Register MCP middleware with server.use("mcp:<method>", handler). The handler receives the parsed operation context and a next() function.
Call next() to continue to the next middleware or the operation handler. Return its result unless you intentionally replace the response.

Match the right operation

Use the narrowest pattern that covers the behavior: Exact middleware can inspect or replace its method-specific result. The mcp:* wildcard is pass-through: call next() or throw, and do not replace the downstream result. MCP middleware does not wrap initialization, completion, log-level changes, or subscription listener requests.

Read the originating HTTP request

ctx.request is the originating Hono HonoRequest when the operation came from HTTP. Read headers with ctx.request.header(name), the path with ctx.request.path, and the underlying Web Request with ctx.request.raw.
Values set by Hono middleware with c.set() are available through ctx.get(). Client metadata and middleware state belong to the current request only.

Add an OAuth scope guard

Configure OAuth before reading ctx.auth. Middleware on an authenticated server receives verified provider identity and scopes.
Use server authentication to verify bearer tokens before relying on ctx.auth.

Rate-limit expensive operations

Use middleware when the limit applies to a class of operations instead of one tool. Key limits by a verified identity and store distributed counters in a shared backend.
Use ctx.auth.clientId when the limit should apply to an OAuth client rather than an end user. Never use a transport session ID, self-reported client metadata, or an unverified header as an authorization or rate-limit key.

Filter discovery results

List middleware receives the item array rather than the protocol envelope:
Keep filtering rules predictable. Hidden tools should not be required for normal user workflows.

Order middleware deliberately

Middleware runs in registration order. The first registered handler is the outermost wrapper.
A practical order is logging, authorization, rate limiting, then operation-specific validation. Logging can observe rejected requests while the remaining middleware rejects expensive work early.

Use Hono middleware and routes

MCPServer exposes its Hono application as server.app. It also provides bound helpers such as server.use, server.get, server.post, and server.delete.
Use Hono middleware for raw HTTP policy and custom routes. Use MCP middleware when you need ctx.method, parsed ctx.params, verified ctx.auth, or a method-specific MCP result.

Test middleware locally

Run the development server:
Open http://localhost:3000/mcp/inspector, then call tools, list resources, and request prompts. Verify both allowed and rejected paths, transformed list results, response headers, and custom Hono routes. The maintained middleware example includes a runnable tool-call wrapper and a protected discovery request.

Next steps

Authentication

Configure OAuth before relying on verified middleware identity.

Tools

Design the tool callbacks that MCP middleware wraps.

Notifications

Send request-scoped progress, logs, and protocol notifications.

Middleware example

Run the maintained middleware server and verification scenario.