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 Cloudx-mastra-client-type
: identifies the client SDK, e.g.js
orpython
x-mastra-dev-playground
: request triggered from a local playground