Skip to Content
DocsServer & DBMiddleware

Middleware

Mastra servers can execute custom middleware functions before or after an API route handler is invoked. This is useful for things like authentication, logging, injecting request-specific context or adding CORS headers.

A middleware receives the Hono  Context (c) and a next function. If it returns a Response the request is short-circuited. Calling next() continues processing the next middleware or route handler.

import { Mastra } from "@mastra/core"; export const mastra = new Mastra({ server: { middleware: [ { handler: async (c, next) => { // Example: Add authentication check const authHeader = c.req.header("Authorization"); if (!authHeader) { return new Response("Unauthorized", { status: 401 }); } await next(); }, path: "/api/*", }, // Add a global request logger async (c, next) => { console.log(`${c.req.method} ${c.req.url}`); await next(); }, ], }, });

To attach middleware to a single route pass the middleware option to registerApiRoute:

registerApiRoute("/my-custom-route", { method: "GET", middleware: [ async (c, next) => { console.log(`${c.req.method} ${c.req.url}`); await next(); }, ], handler: async (c) => { const mastra = c.get("mastra"); return c.json({ message: "Hello, world!" }); }, });

Common examples

Authentication

{ handler: async (c, next) => { const authHeader = c.req.header('Authorization'); if (!authHeader || !authHeader.startsWith('Bearer ')) { return new Response('Unauthorized', { status: 401 }); } // Validate token here await next(); }, path: '/api/*', }

CORS support

{ handler: async (c, next) => { c.header('Access-Control-Allow-Origin', '*'); c.header( 'Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS', ); c.header( 'Access-Control-Allow-Headers', 'Content-Type, Authorization', ); if (c.req.method === 'OPTIONS') { return new Response(null, { status: 204 }); } await next(); }, }

Request logging

{ handler: async (c, next) => { const start = Date.now(); await next(); const duration = Date.now() - start; console.log(`${c.req.method} ${c.req.url} - ${duration}ms`); }, }

Special Mastra headers

When integrating with Mastra Cloud or custom clients the following headers can be inspected by middleware to tailor behaviour:

{ handler: async (c, next) => { const isFromMastraCloud = c.req.header('x-mastra-cloud') === 'true'; const clientType = c.req.header('x-mastra-client-type'); const isDevPlayground = c.req.header('x-mastra-dev-playground') === 'true'; if (isFromMastraCloud) { // Special handling } await next(); }, }
  • x-mastra-cloud: request originates from Mastra Cloud
  • x-mastra-client-type: identifies the client SDK, e.g. js or python
  • x-mastra-dev-playground: request triggered from a local playground