mastra/Core Concepts
Server
Deploy Mastra as a standalone server with various adapters and authentication
serverdeploymentadaptersauthentication
Server
Deploy Mastra as a standalone server with various adapters.
Topics
- Overview - Introduction to Mastra Server
- Server Adapters - Express, Fastify, Hono, Koa
- Custom Adapters - Build your own adapter
- Middleware - Add middleware to the server
- Request Context - Handle request context
- Custom API Routes - Add custom routes
- Mastra Client - Client SDK for connecting
- Auth - Authentication configuration
Mastra Server
Mastra Server provides a standalone server for deploying AI agents and workflows.
Quick Start
import { MastraServer } from '@mastra/server';
const server = new MastraServer({
mastra: myMastra,
port: 3000,
});
await server.start();
Server Options
const server = new MastraServer({
mastra: myMastra,
port: 3000,
host: '0.0.0.0',
cors: {
origin: '*',
},
logging: true,
});
Health Check
const health = await fetch('http://localhost:3000/health');
const { status, version, uptime } = await health.json();
Shutdown
await server.stop();
Mastra Client
Client SDK for connecting to a Mastra server.
Installation
npm install @mastra/client
Basic Usage
import { MastraClient } from '@mastra/client';
const client = new MastraClient({
baseUrl: 'http://localhost:3000',
apiKey: 'your-api-key',
});
// Get an agent
const agent = client.getAgent('myAgent');
// Generate a response
const response = await agent.generate('Hello, world!');
console.log(response.text);
Client Options
const client = new MastraClient({
baseUrl: 'http://localhost:3000',
apiKey: 'your-api-key',
timeout: 30000,
headers: {
'X-Custom-Header': 'value',
},
});
Streaming
const stream = await agent.stream('Tell me a story');
for await (const chunk of stream) {
process.stdout.write(chunk.text);
}
Workflows
const workflow = client.getWorkflow('myWorkflow');
const run = await workflow.createRun();
await run.start({ input: 'test' });
Error Handling
try {
const response = await agent.generate('Hello');
} catch (error) {
if (error instanceof MastraClientError) {
console.error('Client error:', error.message);
} else if (error instanceof MastraServerError) {
console.error('Server error:', error.status, error.message);
}
}
Server Adapters
Connect Mastra to different web frameworks.
Available Adapters
- Express - Express.js adapter
- Fastify - Fastify adapter
- Hono - Hono adapter
- Koa - Koa adapter
Express Adapter
import { createExpressAdapter } from '@mastra/server/express';
const app = express();
const adapter = createExpressAdapter({
mastra: myMastra,
});
app.use('/api/mastra', adapter);
Fastify Adapter
import { createFastifyAdapter } from '@mastra/server/fastify';
const fastify = Fastify();
const adapter = createFastifyAdapter({
mastra: myMastra,
});
await fastify.register(adapter, { prefix: '/api/mastra' });
Hono Adapter
import { createHonoAdapter } from '@mastra/server/hono';
import { Hono } from 'hono';
const app = new Hono();
const adapter = createHonoAdapter({
mastra: myMastra,
});
app.route('/api/mastra', adapter);
Koa Adapter
import { createKoaAdapter } from '@mastra/server/koa';
import Koa from 'koa';
const app = new Koa();
const adapter = createKoaAdapter({
mastra: myMastra,
});
app.use(adapter.routes());
Custom Adapters
Build your own server adapter for any framework.
Adapter Interface
import { Adapter, AdapterRequest, AdapterResponse } from '@mastra/server';
class MyAdapter implements Adapter {
async handle(request: AdapterRequest): Promise<AdapterResponse> {
// Process request
const result = await this.mastra.handle(request);
// Return response
return {
status: 200,
body: result,
headers: {
'Content-Type': 'application/json',
},
};
}
}
Registering Routes
class MyAdapter implements Adapter {
registerRoute(method: string, path: string, handler: Function) {
// Register the route with your framework
}
}
Error Handling
class MyAdapter implements Adapter {
async handle(request: AdapterRequest): Promise<AdapterResponse> {
try {
const result = await this.mastra.handle(request);
return { status: 200, body: result };
} catch (error) {
return {
status: error.status || 500,
body: { error: error.message },
};
}
}
}
Middleware
Add middleware to the Mastra server.
Built-in Middleware
const server = new MastraServer({
mastra: myMastra,
middleware: [
cors(),
compression(),
logger(),
],
});
Custom Middleware
const server = new MastraServer({
mastra: myMastra,
middleware: [
async (request, next) => {
const start = Date.now();
const response = await next(request);
console.log(`${request.path} - ${Date.now() - start}ms`);
return response;
},
],
});
Middleware Types
- Logging - Log requests and responses
- Authentication - Verify API keys, JWTs
- Rate Limiting - Prevent abuse
- CORS - Handle cross-origin requests
- Compression - Compress responses
Framework Middleware
For Express/Fastify/etc., use the framework's native middleware:
const adapter = createExpressAdapter({
mastra: myMastra,
});
app.use(cookieParser());
app.use(helmet());
app.use(rateLimit({ max: 100 }));
app.use('/api/mastra', adapter);
Request Context
Access request context in handlers and tools.
Context Object
interface RequestContext {
request: AdapterRequest;
mastra: Mastra;
agent?: Agent;
user?: User;
metadata: Record<string, unknown>;
}
Accessing Context
// In a tool
const myTool = createTool({
name: 'myTool',
execute: async (input, context) => {
const userId = context.user?.id;
const requestId = context.metadata.requestId;
return { userId, requestId };
},
});
Setting Context
// Server middleware
const server = new MastraServer({
mastra: myMastra,
middleware: [
async (request, next) => {
const enhancedRequest = {
...request,
metadata: {
...request.metadata,
requestId: generateId(),
userId: getUserId(request),
},
};
return next(enhancedRequest);
},
],
});
Context in Workflows
workflow.step('process', async ({ context }) => {
const userId = context.user?.id;
// Use userId to personalize processing
});
Custom API Routes
Add custom routes to the Mastra server.
Adding Routes
const server = new MastraServer({
mastra: myMastra,
customRoutes: [
{
method: 'GET',
path: '/health',
handler: () => new Response('OK'),
},
{
method: 'POST',
path: '/webhook',
handler: async (request) => {
const body = await request.json();
// Process webhook
return Response.json({ received: true });
},
},
],
});
Route Handler
const handler = async (request: Request): Promise<Response> => {
// Access mastra instance
const agent = mastra.getAgent('myAgent');
// Process request
const body = await request.json();
const result = await agent.generate(body.prompt);
return Response.json({ result });
};
Dynamic Routes
customRoutes: [
{
method: 'GET',
path: '/users/:id',
handler: async (request) => {
const id = request.params.id;
const user = await getUser(id);
return Response.json(user);
},
},
],
Route Options
{
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
path: string,
handler: Function,
middleware?: Function[],
}
Server Auth
Authentication providers for Mastra Server.
Supported Providers
- Auth0
- Better Auth
- Clerk
- Firebase
- JSON Web Token (JWT)
- Okta
- Supabase
- WorkOS
- Custom Auth Provider
- Composite Auth
- Simple Auth
Simple Auth
Simple API key authentication for Mastra Server.
Configuration
import { SimpleAuthProvider } from '@mastra/auth';
const server = new MastraServer({
auth: {
provider: new SimpleAuthProvider({
apiKeys: [
{ key: 'sk_test_123', userId: 'user-1' },
{ key: 'sk_test_456', userId: 'user-2' },
],
}),
},
});
Adding API Keys
server.auth.addAPIKey({
key: 'sk_test_789',
userId: 'user-3',
metadata: { role: 'admin' },
});
Using API Keys
// Include API key in header
fetch('/api/agent', {
headers: {
'Authorization': 'Bearer sk_test_123',
},
});
Protected Routes
server.route({
path: '/api/agent',
auth: { required: true },
handler: async (request) => {
const user = request.user;
return Response.json({ userId: user.id });
},
});
JSON Web Token (JWT)
Configure custom JWT authentication for Mastra Server.
Configuration
import { JWTProvider } from '@mastra/auth';
const server = new MastraServer({
auth: {
provider: new JWTProvider({
secret: 'your-secret-key',
issuer: 'mastra',
audience: 'api',
expiresIn: '1d',
}),
},
});
Generating Tokens
const token = await server.generateToken({
userId: 'user-123',
role: 'admin',
});
Verifying Tokens
server.route({
path: '/api/protected',
auth: { required: true },
handler: async (request) => {
const user = request.user;
return Response.json({ user });
},
});
Token Payload
interface JWTPayload {
userId: string;
role: string;
iat: number;
exp: number;
iss: string;
aud: string;
}
Custom Auth Provider
Build your own authentication provider.
Interface
import { AuthProvider, AuthResult } from '@mastra/auth';
class CustomAuthProvider implements AuthProvider {
async authenticate(request: Request): Promise<AuthResult> {
// Extract and verify credentials
const token = request.headers.get('Authorization');
if (!token) {
return { authenticated: false };
}
// Verify token
const user = await verifyMyToken(token);
return {
authenticated: true,
user: {
id: user.id,
email: user.email,
metadata: user.metadata,
},
};
}
async generateToken(user: User): Promise<string> {
return generateMyToken(user);
}
}
Usage
const server = new MastraServer({
auth: {
provider: new CustomAuthProvider(),
},
});
Error Handling
class CustomAuthProvider implements AuthProvider {
async authenticate(request: Request): Promise<AuthResult> {
try {
// Authentication logic
} catch (error) {
return {
authenticated: false,
error: 'Authentication failed',
};
}
}
}