Documentation Index Fetch the complete documentation index at: https://mintlify.com/mastra-ai/mastra/llms.txt
Use this file to discover all available pages before exploring further.
Express is the most popular Node.js web framework. The Express adapter lets you deploy Mastra on traditional Node.js servers with the full Express ecosystem.
Installation
npm install @mastra/express express
Basic Setup
Import dependencies
import express from 'express' ;
import { Mastra } from '@mastra/core' ;
import { MastraServer } from '@mastra/express' ;
Create Mastra instance
const mastra = new Mastra ({
// Your Mastra configuration
});
Create Express app and mount Mastra
const app = express ();
const server = new MastraServer ({ mastra , app });
app . listen ( 4111 );
Complete Example
import express from 'express' ;
import cors from 'cors' ;
import { Mastra } from '@mastra/core' ;
import { MastraServer } from '@mastra/express' ;
import { Agent } from '@mastra/core/agent' ;
import { createOpenAI } from '@ai-sdk/openai' ;
// Create an agent
const agent = new Agent ({
name: 'assistant' ,
instructions: 'You are a helpful assistant.' ,
model: createOpenAI ({
apiKey: process . env . OPENAI_API_KEY ! ,
}). chat ( 'gpt-4o' ),
});
// Create Mastra instance
const mastra = new Mastra ({
agents: { assistant: agent },
});
// Create Express app
const app = express ();
// Add middleware
app . use ( cors ());
app . use ( express . json ());
// Custom routes
app . get ( '/' , ( req , res ) => {
res . json ({ message: 'Mastra API' });
});
// Health check
app . get ( '/health' , ( req , res ) => {
res . json ({ status: 'ok' });
});
// Mount Mastra server
const server = new MastraServer ({
mastra ,
app ,
prefix: '/api/mastra' ,
});
// Start server
const port = 4111 ;
app . listen ( port , () => {
console . log ( `Server running on http://localhost: ${ port } ` );
});
Configuration Options
app
Express.Application
required
Express application instance
prefix
string
default: "/api/mastra"
URL prefix for Mastra routes
Body size limits for uploads: {
maxSize : 10 * 1024 * 1024 , // 10MB
onError : ( error ) => ({ error: 'File too large' })
}
Streaming configuration: {
redact : true // Redact sensitive data in streams
}
Middleware
CORS
import cors from 'cors' ;
app . use ( cors ({
origin: 'http://localhost:3000' ,
credentials: true ,
}));
const server = new MastraServer ({ mastra , app });
JSON Body Parser
import express from 'express' ;
app . use ( express . json ({ limit: '10mb' }));
app . use ( express . urlencoded ({ extended: true , limit: '10mb' }));
const server = new MastraServer ({ mastra , app });
Authentication
import { MastraAuthClerk } from '@mastra/auth-clerk' ;
const mastra = new Mastra ({
server: {
auth: new MastraAuthClerk (),
},
});
const app = express ();
const server = new MastraServer ({ mastra , app });
// Auth middleware is automatically added
Logging
import morgan from 'morgan' ;
app . use ( morgan ( 'combined' ));
const server = new MastraServer ({ mastra , app });
Helmet (Security)
import helmet from 'helmet' ;
app . use ( helmet ());
const server = new MastraServer ({ mastra , app });
Rate Limiting
import rateLimit from 'express-rate-limit' ;
const limiter = rateLimit ({
windowMs: 15 * 60 * 1000 , // 15 minutes
max: 100 , // max 100 requests per window
});
app . use ( '/api/' , limiter );
const server = new MastraServer ({ mastra , app });
Custom Routes
Add Custom Endpoints
const app = express ();
app . use ( express . json ());
// Custom routes before Mastra
app . get ( '/health' , ( req , res ) => {
res . json ({ status: 'ok' });
});
app . post ( '/custom/endpoint' , async ( req , res ) => {
const body = req . body ;
res . json ({ received: body });
});
// Mount Mastra
const server = new MastraServer ({ mastra , app });
Access Mastra Context
app . get ( '/custom/agent-status' , ( req , res ) => {
const mastra = res . locals . mastra ; // Access Mastra instance
const agents = Object . keys ( mastra . agents || {});
res . json ({ agents });
});
const server = new MastraServer ({ mastra , app });
Streaming
Express adapter supports SSE streaming for agent responses:
// Mastra automatically handles streaming
const response = await fetch ( 'http://localhost:4111/api/mastra/agents/assistant/stream' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
messages: [{ role: 'user' , content: 'Hello!' }],
}),
});
const reader = response . body . getReader ();
while ( true ) {
const { done , value } = await reader . read ();
if ( done ) break ;
console . log ( new TextDecoder (). decode ( value ));
}
File Uploads
Handle file uploads with body limits:
const server = new MastraServer ({
mastra ,
app ,
bodyLimitOptions: {
maxSize: 50 * 1024 * 1024 , // 50MB
onError : ( error ) => ({
error: 'File size exceeds 50MB limit' ,
code: 'FILE_TOO_LARGE' ,
}),
},
});
Error Handling
Custom Error Handler
app . use (( err , req , res , next ) => {
console . error ( 'Error:' , err );
res . status ( err . status || 500 ). json ({
error: err . message ,
stack: process . env . NODE_ENV === 'development' ? err . stack : undefined ,
});
});
const server = new MastraServer ({ mastra , app });
404 Handler
app . use (( req , res ) => {
res . status ( 404 ). json ({ error: 'Not found' });
});
const server = new MastraServer ({ mastra , app });
HTTPS
Development
import https from 'https' ;
import fs from 'fs' ;
const options = {
key: fs . readFileSync ( 'key.pem' ),
cert: fs . readFileSync ( 'cert.pem' ),
};
const server = new MastraServer ({ mastra , app });
https . createServer ( options , app ). listen ( 443 );
Production
Use a reverse proxy like Nginx or Caddy:
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:4111;
proxy_http_version 1.1 ;
proxy_set_header Upgrade $ http_upgrade ;
proxy_set_header Connection 'upgrade' ;
proxy_set_header Host $ host ;
proxy_cache_bypass $ http_upgrade ;
}
}
Testing
import request from 'supertest' ;
import express from 'express' ;
import { MastraServer } from '@mastra/express' ;
describe ( 'Mastra API' , () => {
const app = express ();
const server = new MastraServer ({ mastra , app });
it ( 'should return agents list' , async () => {
const res = await request ( app )
. get ( '/api/mastra/agents' )
. expect ( 200 );
expect ( res . body ). toHaveProperty ( 'agents' );
});
});
Best Practices
Middleware Order Matters Add middleware before mounting MastraServer: app . use ( cors ());
app . use ( express . json ());
app . use ( helmet ());
const server = new MastraServer ({ mastra , app });
Use Helmet for Security Protect against common vulnerabilities:
Enable Compression import compression from 'compression' ;
app . use ( compression ());
Set Trust Proxy When behind a reverse proxy: app . set ( 'trust proxy' , 1 );
Process Management
PM2
module.exports = {
apps : [{
name : 'mastra-api' ,
script : './dist/index.js' ,
instances : 'max' ,
exec_mode : 'cluster' ,
env : {
NODE_ENV : 'production' ,
PORT : 4111 ,
},
}],
};
pm2 start ecosystem.config.js
Systemd
/etc/systemd/system/mastra.service
[Unit]
Description =Mastra API
After =network.target
[Service]
Type =simple
User =node
WorkingDirectory =/app
ExecStart =/usr/bin/node /app/dist/index.js
Restart =always
Environment = NODE_ENV =production
[Install]
WantedBy =multi-user.target
Deployment
Docker
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 4111
CMD [ "node" , "dist/index.js" ]
Docker Compose
version : '3.8'
services :
api :
build : .
ports :
- "4111:4111"
environment :
- NODE_ENV=production
- DATABASE_URL=postgresql://user:pass@postgres:5432/mastra
depends_on :
- postgres
postgres :
image : postgres:16
environment :
- POSTGRES_PASSWORD=password
volumes :
- postgres-data:/var/lib/postgresql/data
volumes :
postgres-data :
Hono Adapter Lightweight edge-optimized alternative
Authentication Add authentication to your Mastra API
Express Documentation Official Express documentation
Express Best Practices Security best practices