# Server API Reference

> API reference for server - 3 entries


---

## Reference: MastraServer

> API reference for the MastraServer abstract class used to create server adapters.

The `MastraServer` abstract class is the base for all server adapters. Extend this class to create adapters for frameworks other than Hono or Express.

## Import

```typescript
import { MastraServer } from '@mastra/server/server-adapter';
```

## Type parameters

```typescript
MastraServer<TApp, TRequest, TResponse>
```

| Parameter | Description |
|-----------|-------------|
| `TApp` | Framework app type (e.g., `Hono`, `Application`) |
| `TRequest` | Framework request type |
| `TResponse` | Framework response/context type |

## Constructor

```typescript
constructor(options: MastraServerOptions<TApp>)
```

### Options

## Abstract methods

These methods must be implemented by adapters:

### registerContextMiddleware()

Attach Mastra context to every request.

```typescript
abstract registerContextMiddleware(): void
```

**Context to attach:**
- `mastra` - Mastra instance
- `requestContext` - Request-scoped context
- `tools` - Available tools
- `abortSignal` - Request cancellation signal

### registerAuthMiddleware()

Register authentication and authorization middleware.

```typescript
abstract registerAuthMiddleware(): void
```

### registerRoute()

Register a single route with the framework.

```typescript
abstract registerRoute(
  app: TApp,
  route: ServerRoute,
  options: { prefix?: string }
): Promise<void>
```

### getParams()

Extract parameters from the request.

```typescript
abstract getParams(
  route: ServerRoute,
  request: TRequest
): Promise<{
  urlParams: Record<string, string>;
  queryParams: Record<string, string>;
  body: unknown;
}>
```

### sendResponse()

Send response based on route type.

```typescript
abstract sendResponse(
  route: ServerRoute,
  response: TResponse,
  result: unknown
): Promise<unknown>
```

### stream()

Handle streaming responses.

```typescript
abstract stream(
  route: ServerRoute,
  response: TResponse,
  result: unknown
): Promise<unknown>
```

## Instance methods

### init()

Initialize the server by registering all middleware and routes.

```typescript
async init(): Promise<void>
```

Calls in order:
1. `registerContextMiddleware()`
2. `registerAuthMiddleware()`
3. `registerRoutes()`

### registerRoutes()

Register all Mastra routes.

```typescript
async registerRoutes(): Promise<void>
```

### getApp()

Get the framework app instance.

```typescript
getApp<T = TApp>(): T
```

### parsePathParams()

Validate path parameters with the route's Zod schema.

```typescript
async parsePathParams(
  route: ServerRoute,
  params: Record<string, string>
): Promise<Record<string, unknown>>
```

### parseQueryParams()

Validate query parameters with the route's Zod schema.

```typescript
async parseQueryParams(
  route: ServerRoute,
  params: Record<string, string>
): Promise<Record<string, unknown>>
```

### parseBody()

Validate request body with the route's Zod schema.

```typescript
async parseBody(
  route: ServerRoute,
  body: unknown
): Promise<unknown>
```

### registerOpenAPIRoute()

Register an endpoint that serves the OpenAPI specification.

```typescript
async registerOpenAPIRoute(
  app: TApp,
  config: OpenAPIConfig,
  options: { prefix?: string }
): Promise<void>
```

## Protected methods

### mergeRequestContext()

Merge request context from multiple sources (query params and body).

```typescript
protected mergeRequestContext(options: {
  paramsRequestContext?: Record<string, any>;
  bodyRequestContext?: Record<string, any>;
}): RequestContext
```

## Types

### BodyLimitOptions

```typescript
interface BodyLimitOptions {
  maxSize: number;
  onError: (error: unknown) => unknown;
}
```

### StreamOptions

```typescript
interface StreamOptions {
  redact?: boolean;
}
```

### MCPOptions

```typescript
interface MCPOptions {
  serverless?: boolean;
  sessionIdGenerator?: () => string;
}
```

| Property | Description |
|----------|-------------|
| `serverless` | When `true`, runs MCP in stateless mode without session management. Use for serverless environments like Cloudflare Workers or Vercel Edge. |
| `sessionIdGenerator` | Custom function to generate session IDs. |

## Example

```typescript
import { MastraServer, ServerRoute } from '@mastra/server/server-adapter';
import type { Mastra } from '@mastra/core';

export class MyServer extends MastraServer<MyApp, MyRequest, MyResponse> {
  registerContextMiddleware(): void {
    this.app.use('*', (req, res, next) => {
      res.locals.mastra = this.mastra;
      next();
    });
  }

  registerAuthMiddleware(): void {
    const auth = this.mastra.getServer()?.auth;
    if (!auth) return;
    // Implement auth
  }

  async registerRoute(app, route, { prefix }) {
    // Implement route registration
  }

  async getParams(route, request) {
    return {
      urlParams: request.params,
      queryParams: request.query,
      body: request.body,
    };
  }

  async sendResponse(route, response, result) {
    return response.json(result);
  }

  async stream(route, response, result) {
    // Implement streaming
  }
}
```

## Related

- [Server Adapters](https://mastra.ai/docs/server/server-adapters) - Using adapters
- [Custom Adapters](https://mastra.ai/docs/server/custom-adapters) - Creating custom adapters
- [createRoute()](https://mastra.ai/reference/server/create-route) - Creating custom routes

---

## Reference: createRoute()

> API reference for createRoute() function used to define type-safe routes with validation and OpenAPI generation.

The `createRoute()` function creates type-safe routes with Zod validation. When an `openapiPath` is configured on the server adapter, it generates OpenAPI schema entries from the supplied Zod schemas.

## Import

```typescript
import { createRoute } from '@mastra/server/server-adapter';
```

## Signature

```typescript
function createRoute<TPath, TQuery, TBody, TResponse, TResponseType>(
  config: RouteConfig<TPath, TQuery, TBody, TResponse, TResponseType>
): ServerRoute
```

## Parameters

## Handler parameters

The handler receives validated parameters plus runtime context:

```typescript
handler: async (params) => {
  // From schemas (typed from Zod)
  params.id;              // From pathParamSchema
  params.filter;          // From queryParamSchema
  params.name;            // From bodySchema

  // Runtime context (always available)
  params.mastra;          // Mastra instance
  params.requestContext;  // Request-scoped context
  params.tools;           // Available tools
  params.abortSignal;     // Request cancellation signal
  params.taskStore;       // A2A task storage
}
```

## Return value

Returns a `ServerRoute` object that can be registered with an adapter.

## Examples

### GET route with path params

```typescript
import { createRoute } from '@mastra/server/server-adapter';
import { z } from 'zod';

const getAgent = createRoute({
  method: 'GET',
  path: '/api/agents/:agentId',
  responseType: 'json',
  pathParamSchema: z.object({
    agentId: z.string(),
  }),
  responseSchema: z.object({
    name: z.string(),
    description: z.string().optional(),
  }),
  summary: 'Get agent by ID',
  tags: ['Agents'],
  handler: async ({ agentId, mastra }) => {
    return mastra.getAgent(agentId);
  },
});
```

### POST route with body

```typescript
const createItem = createRoute({
  method: 'POST',
  path: '/api/items',
  responseType: 'json',
  bodySchema: z.object({
    name: z.string(),
    value: z.number(),
  }),
  responseSchema: z.object({
    id: z.string(),
    name: z.string(),
    value: z.number(),
  }),
  handler: async ({ name, value, mastra }) => {
    // name and value are typed from bodySchema
    return { id: 'new-id', name, value };
  },
});
```

### Query params with coercion

```typescript
const listItems = createRoute({
  method: 'GET',
  path: '/api/items',
  responseType: 'json',
  queryParamSchema: z.object({
    page: z.coerce.number().default(0),
    limit: z.coerce.number().default(50),
    enabled: z.coerce.boolean().optional(),
  }),
  handler: async ({ page, limit, enabled, mastra }) => {
    // page, limit, enabled are typed and coerced
    return { items: [], page, limit };
  },
});
```

### Streaming route

```typescript
const streamAgent = createRoute({
  method: 'POST',
  path: '/api/agents/:agentId/stream',
  responseType: 'stream',
  streamFormat: 'sse',
  pathParamSchema: z.object({
    agentId: z.string(),
  }),
  bodySchema: z.object({
    messages: z.array(z.any()),
  }),
  handler: async ({ agentId, messages, mastra, abortSignal }) => {
    const agent = mastra.getAgent(agentId);
    return agent.stream(messages, { abortSignal });
  },
});
```

### Custom body size limit

```typescript
const uploadRoute = createRoute({
  method: 'POST',
  path: '/api/upload',
  responseType: 'json',
  maxBodySize: 50 * 1024 * 1024, // 50MB
  bodySchema: z.object({
    file: z.string(),
  }),
  handler: async ({ file }) => {
    return { uploaded: true };
  },
});
```

## Schema patterns

### Passthrough for extensibility

```typescript
const bodySchema = z.object({
  required: z.string(),
}).passthrough(); // Allow unknown fields
```

### Date coercion

```typescript
const querySchema = z.object({
  fromDate: z.coerce.date().optional(),
  toDate: z.coerce.date().optional(),
});
```

### Union types

```typescript
const bodySchema = z.object({
  messages: z.union([
    z.array(z.any()),
    z.string(),
  ]),
});
```

## Error handling

Throw an error with a `status` property to return specific HTTP status codes from handlers. If using Hono, you can use `HTTPException` from `hono/http-exception`:

```typescript
import { createRoute } from '@mastra/server/server-adapter';
import { HTTPException } from 'hono/http-exception';

const getAgent = createRoute({
  method: 'GET',
  path: '/api/agents/:agentId',
  responseType: 'json',
  pathParamSchema: z.object({ agentId: z.string() }),
  handler: async ({ agentId, mastra }) => {
    const agent = mastra.getAgent(agentId);
    if (!agent) {
      throw new HTTPException(404, { message: `Agent '${agentId}' not found` });
    }
    return agent;
  },
});
```

For Express or framework-agnostic code, throw an error with a `status` property:

```typescript
class HttpError extends Error {
  constructor(public status: number, message: string) {
    super(message);
  }
}

// In handler:
throw new HttpError(404, `Agent '${agentId}' not found`);
```

Common status codes:

| Code | Meaning |
|------|---------|
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 500 | Internal Server Error |

## Related

- [Server Routes](https://mastra.ai/reference/server/routes) - Default Mastra routes
- [MastraServer](https://mastra.ai/reference/server/mastra-server) - Server adapter class
- [Server Adapters](https://mastra.ai/docs/server/server-adapters) - Using adapters

---

## Reference: Server Routes

> API reference for HTTP routes registered by Mastra server adapters.

Server adapters register these routes when you call `server.init()`. All routes are prefixed with the `prefix` option if configured.

## Agents

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/agents` | List all agents |
| `GET` | `/api/agents/:agentId` | Get agent by ID |
| `POST` | `/api/agents/:agentId/generate` | Generate agent response |
| `POST` | `/api/agents/:agentId/stream` | Stream agent response |
| `GET` | `/api/agents/:agentId/tools` | List agent tools |
| `POST` | `/api/agents/:agentId/tools/:toolId/execute` | Execute agent tool |

### Generate request body

```typescript
{
  messages: CoreMessage[] | string;       // Required
  instructions?: string;                   // System instructions
  system?: string;                         // System prompt
  context?: CoreMessage[];                 // Additional context
  memory?: { key: string } | boolean;      // Memory config
  resourceId?: string;                     // Resource identifier
  threadId?: string;                       // Thread identifier
  runId?: string;                          // Run identifier
  maxSteps?: number;                       // Max tool steps
  activeTools?: string[];                  // Tools to enable
  toolChoice?: ToolChoice;                 // Tool selection mode
  requestContext?: Record<string, unknown>; // Request context
  output?: ZodSchema;                      // Structured output schema
}
```

### Generate response

```typescript
{
  text: string;
  toolCalls?: ToolCall[];
  finishReason: string;
  usage?: {
    promptTokens: number;
    completionTokens: number;
  };
}
```

## Workflows

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/workflows` | List all workflows |
| `GET` | `/api/workflows/:workflowId` | Get workflow by ID |
| `POST` | `/api/workflows/:workflowId/create-run` | Create a new workflow run |
| `POST` | `/api/workflows/:workflowId/start-async` | Start workflow and await result |
| `POST` | `/api/workflows/:workflowId/stream` | Stream workflow execution |
| `POST` | `/api/workflows/:workflowId/resume` | Resume suspended workflow |
| `POST` | `/api/workflows/:workflowId/resume-async` | Resume asynchronously |
| `GET` | `/api/workflows/:workflowId/runs` | List workflow runs |
| `GET` | `/api/workflows/:workflowId/runs/:runId` | Get specific run |

### Create run request body

```typescript
{
  resourceId?: string;     // Associate run with a resource (e.g., user ID)
  disableScorers?: boolean; // Disable scorers for this run
}
```

### Start-async request body

```typescript
{
  resourceId?: string;     // Associate run with a resource (e.g., user ID)
  inputData?: unknown;
  initialState?: unknown;
  requestContext?: Record<string, unknown>;
  tracingOptions?: {
    spanName?: string;
    attributes?: Record<string, unknown>;
  };
}
```

### Stream workflow request body

```typescript
{
  resourceId?: string;     // Associate run with a resource (e.g., user ID)
  inputData?: unknown;
  initialState?: unknown;
  requestContext?: Record<string, unknown>;
  closeOnSuspend?: boolean;
}
```

### Resume request body

```typescript
{
  step?: string | string[];
  resumeData?: unknown;
  requestContext?: Record<string, unknown>;
}
```

## Tools

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/tools` | List all tools |
| `GET` | `/api/tools/:toolId` | Get tool by ID |
| `POST` | `/api/tools/:toolId/execute` | Execute tool |

### Execute tool request body

```typescript
{
  data: unknown;  // Tool input data
  requestContext?: Record<string, unknown>;
}
```

## Memory

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/memory/threads` | List threads |
| `GET` | `/api/memory/threads/:threadId` | Get thread |
| `POST` | `/api/memory/threads` | Create thread |
| `DELETE` | `/api/memory/threads/:threadId` | Delete thread |
| `POST` | `/api/memory/threads/:threadId/clone` | Clone thread |
| `GET` | `/api/memory/threads/:threadId/messages` | Get thread messages |
| `POST` | `/api/memory/threads/:threadId/messages` | Add message |

### Create thread request body

```typescript
{
  resourceId: string;
  title?: string;
  metadata?: Record<string, unknown>;
}
```

### Clone thread request body

```typescript
{
  newThreadId?: string;           // Custom ID for cloned thread
  resourceId?: string;            // Override resource ID
  title?: string;                 // Custom title for clone
  metadata?: Record<string, unknown>;  // Additional metadata
  options?: {
    messageLimit?: number;        // Max messages to clone
    messageFilter?: {
      startDate?: Date;           // Clone messages after this date
      endDate?: Date;             // Clone messages before this date
      messageIds?: string[];      // Clone specific messages
    };
  };
}
```

### Clone thread response

```typescript
{
  thread: {
    id: string;
    resourceId: string;
    title: string;
    createdAt: Date;
    updatedAt: Date;
    metadata: {
      clone: {
        sourceThreadId: string;
        clonedAt: Date;
        lastMessageId?: string;
      };
      // ... other metadata
    };
  };
  clonedMessages: MastraDBMessage[];
}
```

## Vectors

| Method | Path | Description |
|--------|------|-------------|
| `POST` | `/api/vectors/:vectorName/upsert` | Upsert vectors |
| `POST` | `/api/vectors/:vectorName/query` | Query vectors |
| `POST` | `/api/vectors/:vectorName/delete` | Delete vectors |

### Upsert request body

```typescript
{
  vectors: Array<{
    id: string;
    values: number[];
    metadata?: Record<string, unknown>;
  }>;
}
```

### Query request body

```typescript
{
  vector: number[];
  topK?: number;
  filter?: Record<string, unknown>;
  includeMetadata?: boolean;
}
```

## MCP

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/mcp/servers` | List MCP servers |
| `GET` | `/api/mcp/servers/:serverId/tools` | List server tools |
| `POST` | `/api/mcp/:serverId` | MCP HTTP transport |
| `GET` | `/api/mcp/:serverId/sse` | MCP SSE transport |

## Logs

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/logs` | List logs |
| `GET` | `/api/logs/:runId` | Get logs by run ID |

### Query parameters

```typescript
{
  page?: number;
  perPage?: number;
  transportId?: string;
}
```

## Telemetry

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/telemetry/traces` | List traces |
| `GET` | `/api/telemetry/traces/:traceId` | Get trace |
| `GET` | `/api/telemetry/traces/:traceId/spans` | Get trace spans |

## Common query parameters

### Pagination

Most list endpoints support:

```typescript
{
  page?: number;   // Page number (0-indexed)
  perPage?: number; // Items per page (default: 10)
}
```

### Filtering

Workflow runs support:

```typescript
{
  fromDate?: string;  // ISO date string
  toDate?: string;    // ISO date string
  status?: string;    // Run status filter
  resourceId?: string; // Filter by resource
}
```

## Error responses

All routes return errors in this format:

```typescript
{
  error: string;      // Error message
  details?: unknown;  // Additional details
}
```

Common status codes:

| Code | Meaning |
|------|---------|
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Missing/invalid auth |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Resource doesn't exist |
| 500 | Internal Server Error |

## Related

- [createRoute()](https://mastra.ai/reference/server/create-route) - Creating custom routes
- [Server Adapters](https://mastra.ai/docs/server/server-adapters) - Using adapters