Server adapters
Trust: ★★★☆☆ (0.90) · 0 validations · developer_reference
Published: 2026-05-10 · Source: crawler_authoritative
Tình huống
Mastra documentation for integrating with Express, Hono, Fastify, Koa, and NestJS HTTP server frameworks with full configuration control.
Insight
Server adapters allow Mastra to run with existing HTTP server frameworks instead of the default Hono server. Five official adapters are available: @mastra/express, @mastra/hono, @mastra/fastify, @mastra/koa, and @mastra/nestjs. Each adapter provides a MastraServer class that accepts an app instance and mastra reference. The init() method performs three sequential steps: registerContextMiddleware() attaches the Mastra instance and request context to requests, registerAuthMiddleware() runs adapter auth hooks for built-in routes (raw routes should use createAuthMiddleware() helper), and registerRoutes() registers all API routes including MCP routes. Manual initialization allows calling each method separately for custom middleware ordering. Custom routes added before init() lack Mastra context access, while routes added after have full context including authenticated user. The prefix option changes default routes from /api/agents, /api/workflows to custom paths like /api/v2/agents. OpenAPI specs can be generated by setting openapiPath to an endpoint like /openapi.json, derived from Zod schemas on routes. Stream redaction enabled by default redacts system prompts, tool definitions, API keys, and internal config from HTTP stream chunks while preserving full data in internal callbacks. Per-route auth overrides use METHOD:PATH format with Map configuration supporting wildcards, where false makes routes public and true requires auth. Configuration sources differ between server config (auth, bodySizeLimit, onError) and adapter constructor (prefix, openapiPath, bodyLimitOptions, streamOptions, customRouteAuthConfig, mcpOptions). Server config options like port, host, cors, timeout, apiRoutes, and middleware only apply to mastra build and are ignored by adapters. MCP support registers HTTP and SSE transport routes when MCP servers are configured, with serverless: true mode for Cloudflare Workers and Vercel Edge environments via mcpOptions.
Hành động
Initialize the framework app and pass it to MastraServer constructor with the mastra instance. Call await server.init() to register middleware and routes, or call registerContextMiddleware(), registerAuthMiddleware(), and registerRoutes() separately for manual control. Add custom routes before init() if they don’t need Mastra context, or after init() if they do. Use customRouteAuthConfig Map with METHOD:PATH keys to override authentication for specific routes (e.g., [‘GET:/api/health’, false] for public health checks). Set prefix option for API versioning. Set streamOptions.redact to false only for internal debugging. For MCP serverless mode, set mcpOptions.serverless: true in server config or adapter constructor. Access the underlying app via server.getApp() or mastra.getServerApp(). Configure CORS and port directly with framework instead of server config when using adapters.
Kết quả
Mastra routes register at prefix paths (default /api/*), MCP routes register for HTTP and SSE transports, stream responses redact sensitive data at HTTP boundary while preserving full data in callbacks, per-route auth overrides apply using METHOD:PATH wildcard matching.
Điều kiện áp dụng
Applies when using any of the five official server adapters (express, hono, fastify, koa, nestjs) instead of mastra build. MCP serverless mode for Cloudflare Workers/Vercel Edge requires mcpOptions.serverless: true.
Nội dung gốc (Original)
Server adapters
Server adapters let you run Mastra with your own HTTP server instead of the Hono server generated by mastra build. They provide more control over the server setup, including custom middleware ordering, authentication, logging, and deployment configuration. You can still integrate Mastra into any Node.js application without changing how agents or workflows execute.
When to use server adapters
- You want Mastra’s endpoints added automatically to an existing application
- You need direct access to the server instance for custom configuration
- Your team prefers using another server framework instead of the Hono server created by
mastra build.
Tip: For deployments without custom server requirements, use
mastra buildinstead. It configures server setup, registers middleware, and applies deployment settings based on your project configuration. See Server Configuration.If you want to use Studio with your server adapter, use
mastra studioto only launch the Studio UI.
Available adapters
Mastra currently provides these official server adapters:
You can build your own adapter, read custom adapters for details.
Installation
Install the adapter for the framework of your choice.
Express:
npm:
npm install @mastra/express@latestpnpm:
pnpm add @mastra/express@latestYarn:
yarn add @mastra/express@latestBun:
bun add @mastra/express@latestHono:
npm install @mastra/express@latestFastify:
pnpm add @mastra/express@latestKoa:
yarn add @mastra/express@latestNestJS:
bun add @mastra/express@latestTab 6:
npm:
npm install @mastra/hono@latestpnpm:
pnpm add @mastra/hono@latestYarn:
yarn add @mastra/hono@latestBun:
bun add @mastra/hono@latestTab 7:
npm install @mastra/hono@latestTab 8:
pnpm add @mastra/hono@latestTab 9:
yarn add @mastra/hono@latestTab 10:
bun add @mastra/hono@latestTab 11:
npm:
npm install @mastra/fastify@latestpnpm:
pnpm add @mastra/fastify@latestYarn:
yarn add @mastra/fastify@latestBun:
bun add @mastra/fastify@latestTab 12:
npm install @mastra/fastify@latestTab 13:
pnpm add @mastra/fastify@latestTab 14:
yarn add @mastra/fastify@latestTab 15:
bun add @mastra/fastify@latestTab 16:
npm:
npm install @mastra/koa@latestpnpm:
pnpm add @mastra/koa@latestYarn:
yarn add @mastra/koa@latestBun:
bun add @mastra/koa@latestTab 17:
npm install @mastra/koa@latestTab 18:
pnpm add @mastra/koa@latestTab 19:
yarn add @mastra/koa@latestTab 20:
bun add @mastra/koa@latestTab 21:
npm:
npm install @mastra/nestjs@latestpnpm:
pnpm add @mastra/nestjs@latestYarn:
yarn add @mastra/nestjs@latestBun:
bun add @mastra/nestjs@latestTab 22:
npm install @mastra/nestjs@latestTab 23:
pnpm add @mastra/nestjs@latestTab 24:
yarn add @mastra/nestjs@latestTab 25:
bun add @mastra/nestjs@latestConfiguration
Initialize your app as usual, then create a MastraServer by passing in the app and your main mastra instance from src/mastra/index.ts. Calling init() automatically registers Mastra middleware and all available endpoints. You can continue adding your own routes as normal, either before or after init(), and they’ll run alongside Mastra’s endpoints.
Express:
import express from 'express'
import { MastraServer } from '@mastra/express'
import { mastra } from './mastra'
const app = express()
app.use(express.json())
const server = new MastraServer({ app, mastra })
await server.init()
app.listen(4111, () => {
console.log('Server running on port 4111')
})Info: See the Express Adapter documentation for full configuration options.
Hono:
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
import { HonoBindings, HonoVariables, MastraServer } from '@mastra/hono'
import { mastra } from './mastra'
const app = new Hono<{ Bindings: HonoBindings; Variables: HonoVariables }>()
const server = new MastraServer({ app, mastra })
await server.init()
serve({ fetch: app.fetch, port: 4111 }, () => {
console.log('Server running on port 4111')
})Info: See the Hono Adapter documentation for full configuration options.
Fastify:
import Fastify from 'fastify'
import { MastraServer } from '@mastra/fastify'
import { mastra } from './mastra'
const app = Fastify()
const server = new MastraServer({ app, mastra })
await server.init()
app.get('/health', async request => {
const mastraInstance = request.mastra
const agents = Object.keys(mastraInstance.listAgents())
return { status: 'ok', agents }
})
const port = 4111
app.listen({ port }, () => {
console.log(`Server running on http://localhost:${port}`)
console.log(`Try: curl http://localhost:${port}/api/agents`)
})Info: See the Fastify Adapter documentation for full configuration options.
Koa:
import Koa from 'koa'
import bodyParser from 'koa-bodyparser'
import { MastraServer } from '@mastra/koa'
import { mastra } from './mastra'
const app = new Koa()
app.use(bodyParser()) // Required for body parsing
const server = new MastraServer({ app, mastra })
await server.init()
app.use(async (ctx, next) => {
if (ctx.path === '/health' && ctx.method === 'GET') {
const mastraInstance = ctx.state.mastra
const agents = Object.keys(mastraInstance.listAgents())
ctx.body = { status: 'ok', agents }
return
}
await next()
})
const port = 4111
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`)
console.log(`Try: curl http://localhost:${port}/api/agents`)
})Info: See the Koa Adapter documentation for full configuration options.
NestJS:
import { Module } from '@nestjs/common'
import { MastraModule } from '@mastra/nestjs'
import { mastra } from './mastra'
@Module({
imports: [
MastraModule.register({
mastra,
}),
],
})
export class AppModule {}import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
async function bootstrap() {
const app = await NestFactory.create(AppModule)
await app.listen(3000)
}
bootstrap()Info: See the NestJS Adapter documentation for full configuration options.
Initialization flow
Calling init() runs three steps in order. Understanding this flow helps when you need to insert your own middleware at specific points.
registerContextMiddleware(): Attaches the Mastra instance, request context, tools, and abort signal to every request. This makes Mastra available to all subsequent middleware and route handlers.registerAuthMiddleware(): Runs the adapter auth hook during initialization. Official adapters enforce auth inline when Mastra registers built-in routes andregisterApiRoute()routes, so raw framework routes should use the adapter’s exportedcreateAuthMiddleware()helper when they need Mastra auth.registerRoutes(): Registers all Mastra API routes for agents, workflows, and other features. Also registers MCP routes if MCP servers are configured.
Manual initialization
For custom middleware ordering, call each method separately instead of init(). This is useful when you need middleware that runs before Mastra’s context is set up, or when you need to insert logic between the initialization steps.
const server = new MastraServer({ app, mastra });
// Your middleware first
app.use(loggingMiddleware);
server.registerContextMiddleware();
// Middleware that needs Mastra context
app.use(customMiddleware);
await server.registerRoutes();
// Routes after Mastra
app.get('/health', ...);Tip: Use manual initialization when you need middleware that runs before Mastra’s context is available, or when you need to insert middleware between the context and auth steps.
Adding custom routes
You can add your own routes to the app alongside Mastra’s routes.
- Routes added before
init()won’t have Mastra context available. - Routes added after
init()have access to the Mastra context (the Mastra instance, request context, authenticated user, etc.). - When you want Mastra-managed auth and route metadata such as
requiresAuth, preferregisterApiRoute(). - When you mount routes directly on the framework app, use the adapter’s exported
createAuthMiddleware()helper if those routes need Mastra auth.
Info: Visit “Adding custom routes” for Express and Hono for more information.
Route prefixes
By default, Mastra routes are registered at /api/agents, /api/workflows, etc. Use the prefix option to change this. This is useful for API versioning or when integrating with an existing app that has its own /api routes.
const server = new MastraServer({
app,
mastra,
prefix: '/api/v2',
})With this prefix, Mastra routes become /api/v2/agents, /api/v2/workflows, etc. Custom routes you add directly to the app aren’t affected by this prefix.
OpenAPI spec
Mastra can generate an OpenAPI specification for all registered routes. This is useful for documentation, client generation, or integration with API tools. Enable it by setting the openapiPath option:
const server = new MastraServer({
app,
mastra,
openapiPath: '/openapi.json',
})The spec is generated from the Zod schemas defined on each route and served at the specified path. It includes all Mastra routes as well as any custom routes created with createRoute().
Stream data redaction
When streaming agent responses over HTTP, the HTTP streaming layer redacts sensitive information from stream chunks before sending them to clients. This prevents accidental exposure of:
- System prompts and agent instructions
- Tool definitions and their parameters
- API keys and other credentials in request bodies
- Internal configuration data
This redaction happens at the HTTP boundary, so internal callbacks like onStepFinish still have access to the full request data for debugging and observability purposes.
By default, redaction is enabled. Configure this behavior via streamOptions. Set redact: false only for internal services or debugging scenarios where you need access to the full request data in stream responses.
const server = new MastraServer({
app,
mastra,
streamOptions: {
redact: true, // Default
},
})Info: See MastraServer for full configuration options.
Per-route auth overrides
When authentication is configured on your Mastra instance, all routes require authentication by default. Sometimes you need exceptions: public health check endpoints, webhook receivers, or admin routes that need stricter controls.
Use customRouteAuthConfig to override authentication behavior for specific routes. Keys follow the format METHOD:PATH where method is GET, POST, PUT, DELETE, or ALL. Paths support wildcards (*) for matching multiple routes. Setting a value to false makes the route public, while true requires authentication.
const server = new MastraServer({
app,
mastra,
customRouteAuthConfig: new Map([
// Public health check
['GET:/api/health', false],
// Public API spec
['GET:/api/openapi.json', false],
// Public webhook endpoints
['POST:/api/webhooks/*', false],
// Require auth even if globally disabled
['POST:/api/admin/reset', true],
// Protect all methods on internal routes
['ALL:/api/internal/*', true],
]),
})Info: See MastraServer for full configuration options.
Accessing the app
After creating the adapter, you may still need access to the underlying framework app. This is useful when passing it to a platform’s serve function or when adding routes from another module.
// Via the MastraServer instance
const app = server.getApp()
// Via the Mastra instance (available after adapter construction)
const app = mastra.getServerApp()Both methods return the same app instance. Use whichever is more convenient based on what’s in scope.
Server config vs adapter options
When using server adapters, configuration comes from two places: the Mastra server config (passed to the Mastra constructor) and the adapter constructor options. Understanding which options come from where helps avoid confusion when settings don’t seem to take effect.
Used by adapters
The adapter reads these settings from mastra.getServer():
| Option | Description |
|---|---|
auth | Authentication config, used by registerAuthMiddleware(). |
bodySizeLimit | Default body size limit in bytes. Can be overridden per-adapter via bodyLimitOptions. |
onError | Custom error handler called when an unhandled error occurs in a route handler. See server.onError. |
Adapter constructor only
These options are passed directly to the adapter constructor and aren’t read from the Mastra config:
| Option | Description |
|---|---|
prefix | Route path prefix |
openapiPath | OpenAPI spec endpoint |
bodyLimitOptions | Body size limit with custom error handler |
streamOptions | Stream redaction settings |
customRouteAuthConfig | Per-route auth overrides |
mcpOptions | MCP transport options (e.g., serverless: true for stateless environments) |
Not used by adapters
These server config options are only used by mastra build and have no effect when using adapters directly:
| Option | Used by |
|---|---|
port, host | mastra dev, mastra build |
cors | mastra build adds CORS middleware |
timeout | mastra build |
apiRoutes | registerApiRoute() for mastra build |
middleware | Middleware config for mastra build |
When using adapters, configure these features directly with your framework. For example, add CORS middleware using Hono’s or Express’s built-in CORS packages, and set the port when calling your framework’s listen function.
MCP support
Server adapters register MCP (Model Context Protocol) routes during registerRoutes() when MCP servers are configured in your Mastra instance. MCP allows external tools and services to connect to your Mastra server and interact with your agents.
The adapter registers routes for both HTTP and SSE (Server-Sent Events) transports, enabling different client connection patterns.
Serverless mode
For serverless environments like Cloudflare Workers or Vercel Edge, enable stateless mode via mcpOptions.
When using the Mastra deployer (the standard mastra dev / mastra build path), set mcpOptions in your server config:
const mastra = new Mastra({
server: {
mcpOptions: {
serverless: true,
},
},
})When manually creating a server adapter, pass mcpOptions directly:
const server = new MastraServer({
app,
mastra,
mcpOptions: {
serverless: true,
},
})When serverless: true, MCP HTTP requests run without session management, making them compatible with stateless execution environments.
See MCP for configuration details and how to set up MCP servers.
Related
- Hono Adapter - Hono-specific setup
- Express Adapter - Express-specific setup
- NestJS Adapter - NestJS-specific setup
- Custom Adapters - Building adapters for other frameworks
- Server Configuration - Using
mastra buildinstead - Authentication - Configuring auth for your server
- MastraServer Reference - Full API reference
- createRoute() Reference - Creating type-safe custom routes
Liên kết
- Nền tảng: Dev Framework · Mastra
- Nguồn: https://mastra.ai/docs/server/server-adapters
Xem thêm: