# Configuration

The following reference covers all supported options in Mastra. You initialize and configure Mastra by instantiating the [`Mastra` class](https://mastra.ai/reference/core/mastra-class).

```ts
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  // Your options...
})
```

## Top-level options

### agents

**Type:** `Record<string, Agent>`

A record of agent instances keyed by their names. Agents are autonomous systems that can make decisions and take actions using AI models, tools, and memory.

Visit the [Agents documentation](https://mastra.ai/docs/agents/overview) to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { Agent } from '@mastra/core/agent'

export const mastra = new Mastra({
  agents: {
    weatherAgent: new Agent({
      id: 'weather-agent',
      name: 'Weather Agent',
      instructions: 'You help with weather information',
      model: 'openai/gpt-5.4',
    }),
  },
})
```

### backgroundTasks

**Type:** `BackgroundTaskManagerConfig`

Enables and configures the background task manager. When enabled, agents can dispatch long-running tool calls (including subagent invocations) to run asynchronously while the agentic loop continues. Tasks are persisted, so a configured `storage` backend is required.

Visit the [Background tasks documentation](https://mastra.ai/docs/agents/background-tasks) to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { LibSQLStore } from '@mastra/libsql'

export const mastra = new Mastra({
  storage: new LibSQLStore({
    id: 'mastra-storage',
    url: 'file:./mastra.db',
  }),
  backgroundTasks: {
    enabled: true,
    globalConcurrency: 10,
    perAgentConcurrency: 5,
    backpressure: 'queue',
    defaultTimeoutMs: 300_000,
  },
})
```

**enabled** (`boolean`): Whether background tasks are enabled. The manager only initializes when this is true and a storage backend is configured. (Default: `false`)

**globalConcurrency** (`number`): Maximum number of background tasks running concurrently across all agents. (Default: `10`)

**perAgentConcurrency** (`number`): Maximum number of background tasks running concurrently for a single agent. (Default: `5`)

**backpressure** (`'queue' | 'reject' | 'fallback-sync'`): Behavior when a concurrency limit is reached. 'queue' waits for a slot, 'reject' throws on enqueue, 'fallback-sync' runs the tool synchronously in the agentic loop instead. (Default: `'queue'`)

**defaultTimeoutMs** (`number`): Default per-task timeout in milliseconds. Can be overridden per-tool or per-call. (Default: `300000`)

**defaultRetries** (`RetryConfig`): Default retry policy applied to tasks that fail.

**defaultRetries.maxRetries** (`number`): Maximum retry attempts before the task is marked failed.

**defaultRetries.retryDelayMs** (`number`): Delay between retries in milliseconds.

**defaultRetries.backoffMultiplier** (`number`): Multiplier applied to retryDelayMs on each subsequent attempt.

**defaultRetries.maxRetryDelayMs** (`number`): Upper bound on the retry delay regardless of backoff.

**defaultRetries.retryableErrors** (`(error: Error) => boolean`): Predicate that decides whether a given error should be retried. Default: retry all errors.

**cleanup** (`CleanupConfig`): Controls how long task records are kept and how often the cleanup process runs.

**cleanup.completedTtlMs** (`number`): How long to keep completed task records, in milliseconds. Default: 1 hour.

**cleanup.failedTtlMs** (`number`): How long to keep failed task records, in milliseconds. Default: 24 hours.

**cleanup.cleanupIntervalMs** (`number`): How often the cleanup process runs, in milliseconds. Default: 1 minute.

**waitTimeoutMs** (`number`): How long the agentic loop waits for a background task to complete before moving on. If a task has not finished within this time, the loop proceeds without setting isContinued. Default: undefined (do not wait). Can be overridden per-agent or per-tool.

**onTaskComplete** (`(task: BackgroundTask) => void | Promise<void>`): Global callback invoked when any background task completes successfully. Fires in addition to per-tool and per-agent callbacks.

**onTaskFailed** (`(task: BackgroundTask) => void | Promise<void>`): Global callback invoked when any background task fails. Fires in addition to per-tool and per-agent callbacks.

### deployer

**Type:** `MastraDeployer`

Deployment provider for publishing applications to cloud platforms.

Visit the [Deployment documentation](https://mastra.ai/docs/deployment/overview) to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { NetlifyDeployer } from '@mastra/deployer-netlify'

export const mastra = new Mastra({
  deployer: new NetlifyDeployer(),
})
```

### events

**Type:** `Record<string, EventHandler | EventHandler[]>`

Event handlers for the internal pub/sub system. Maps event topics to handler functions that are called when events are published to those topics.

> **Warning:** This is used internally by Mastra's workflow engine. Most users won't need to configure this option.

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  events: {
    'my-topic': async event => {
      console.log('Event received:', event)
    },
  },
})
```

### gateways

**Type:** `Record<string, MastraModelGateway>`

Custom model router gateways for accessing LLM providers. Gateways handle provider-specific authentication, URL construction, and model resolution. Use this to add support for custom or self-hosted LLM providers.

Visit the [Custom Gateways documentation](https://mastra.ai/models/gateways/custom-gateways) to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { MyPrivateGateway } from './gateways'

export const mastra = new Mastra({
  gateways: {
    private: new MyPrivateGateway(),
  },
})
```

### idGenerator

**Type:** `(context?: IdGeneratorContext) => string`\
**Default:** `crypto.randomUUID()`

Custom ID generator function for creating unique identifiers. Mastra passes optional context so you can generate IDs based on what's being created.

`IdGeneratorContext` includes:

- `idType`: `'thread' | 'message' | 'run' | 'step' | 'generic'`
- `source?`: `'agent' | 'workflow' | 'memory'`
- `entityId?`: ID of the requesting agent/workflow/memory entity
- `threadId?`: Thread ID when relevant (for example, when creating message IDs)
- `resourceId?`: Resource ID when relevant (for example, user-scoped threads)
- `role?`: Message role when creating a message ID
- `stepType?`: Workflow step type when creating a step ID

> **Warning:** This is used internally by Mastra for creating IDs for workflow runs, agent conversations, and other resources. Most users won't need to configure this option.

```typescript
import { Mastra } from '@mastra/core'
import { nanoid } from 'nanoid'

export const mastra = new Mastra({
  idGenerator: context => {
    if (context?.idType === 'message' && context?.threadId) {
      return `msg-${context.threadId}-${nanoid(8)}`
    }

    if (context?.idType === 'run' && context?.source && context?.entityId) {
      return `${context.source}-run-${context.entityId}-${nanoid(6)}`
    }

    return nanoid()
  },
})
```

### logger

**Type:** `IMastraLogger | false`\
**Default:** `ConsoleLogger` with `INFO` level in development, `WARN` in production

Logger implementation for application logging and debugging. Set to `false` to disable logging entirely.

Visit the [Logging documentation](https://mastra.ai/docs/observability/logging) to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { PinoLogger } from '@mastra/loggers'

export const mastra = new Mastra({
  logger: new PinoLogger({ name: 'MyApp', level: 'debug' }),
})
```

### mcpServers

**Type:** `Record<string, MCPServerBase>`

MCP (Model Context Protocol) servers that expose Mastra tools, agents, workflows, and resources to MCP-compatible clients. Use this to author your own MCP servers that can be consumed by any system that supports the protocol.

Visit the [MCP Overview](https://mastra.ai/docs/mcp/overview) to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { MCPServer } from '@mastra/mcp'

const mcpServer = new MCPServer({
  id: 'my-mcp-server',
  name: 'My MCP Server',
  version: '1.0.0',
})

export const mastra = new Mastra({
  mcpServers: {
    myServer: mcpServer,
  },
})
```

### memory

**Type:** `Record<string, MastraMemory>`

A registry of memory instances that can be referenced by agents. Memory gives agents coherence across interactions by retaining relevant information from past conversations. Mastra supports three types of memory: message history for recent messages, working memory for persistent user-specific details, and semantic recall for retrieving older messages based on relevance.

Visit the [Memory documentation](https://mastra.ai/docs/memory/overview) to learn more.

> **Note:** Most users configure memory directly on agents. This top-level configuration is for defining reusable memory instances that can be shared across multiple agents.

```typescript
import { Mastra } from '@mastra/core'
import { Memory } from '@mastra/memory'
import { LibSQLStore } from '@mastra/libsql'

export const mastra = new Mastra({
  storage: new LibSQLStore({
    id: 'mastra-storage',
    url: ':memory:',
  }),
  memory: {
    chatMemory: new Memory({
      options: {
        lastMessages: 20,
      },
    }),
  },
})
```

### observability

**Type:** `ObservabilityEntrypoint`

Mastra provides observability features for AI applications. Monitor LLM operations, trace agent decisions, and debug complex workflows with tools that understand AI-specific patterns. Tracing captures model interactions, agent execution paths, tool calls, and workflow steps.

Visit the [Observability documentation](https://mastra.ai/docs/observability/overview) to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { LibSQLStore } from '@mastra/libsql'
import { Observability, DefaultExporter } from '@mastra/observability'

export const mastra = new Mastra({
  storage: new LibSQLStore({
    id: 'mastra-storage',
    url: 'file:./mastra.db',
  }),
  observability: new Observability({
    configs: {
      default: {
        serviceName: 'my-app',
        exporters: [new DefaultExporter()],
      },
    },
  }),
})
```

### processors

**Type:** `Record<string, Processor>`

Input/output processors for transforming agent inputs and outputs. Processors run at specific points in the agent's execution pipeline, allowing you to modify inputs before they reach the language model or outputs before they're returned. Use processors to add guardrails, detect prompt injection, moderate content, or apply custom business logic.

Visit the [Processors documentation](https://mastra.ai/docs/agents/processors) to learn more.

> **Note:** Most users configure processors directly on agents. This top-level configuration is for defining reusable processor instances that can be shared across multiple agents.

```typescript
import { Mastra } from '@mastra/core'
import { ModerationProcessor } from '@mastra/core/processors'

export const mastra = new Mastra({
  processors: {
    moderation: new ModerationProcessor({
      model: 'openai/gpt-5-mini',
      categories: ['hate', 'harassment', 'violence'],
    }),
  },
})
```

### pubsub

**Type:** `PubSub`\
**Default:** `EventEmitterPubSub`

Pub/sub system for event-driven communication between components. Used internally by Mastra for workflow event processing and component communication.

> **Warning:** This is used internally by Mastra. Most users won't need to configure this option.

```typescript
import { Mastra } from '@mastra/core'
import { CustomPubSub } from './pubsub'

export const mastra = new Mastra({
  pubsub: new CustomPubSub(),
})
```

### scorers

**Type:** `Record<string, Scorer>`

Scorers assess the quality of agent responses and workflow outputs. They provide quantifiable metrics for measuring agent quality using model-graded, rule-based, and statistical methods. Use scorers to track performance, compare approaches, and identify areas for improvement.

Visit the [Scorers documentation](https://mastra.ai/docs/evals/overview) to learn more.

> **Note:** Most users configure scorers directly on agents. This top-level configuration is for defining reusable scorer instances that can be shared across multiple agents.

```typescript
import { Mastra } from '@mastra/core'
import { createToxicityScorer } from '@mastra/evals/scorers/prebuilt'

export const mastra = new Mastra({
  scorers: {
    toxicity: createToxicityScorer({ model: 'openai/gpt-5-mini' }),
  },
})
```

### storage

**Type:** `MastraCompositeStore`

Storage provider for persisting application data. Used by memory, workflows, traces, and other components that require persistence. Mastra supports multiple database backends including PostgreSQL, MongoDB, libSQL, and more.

Visit the [Storage documentation](https://mastra.ai/docs/memory/storage) to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { LibSQLStore } from '@mastra/libsql'

export const mastra = new Mastra({
  storage: new LibSQLStore({
    id: 'mastra-storage',
    url: 'file:./mastra.db',
  }),
})
```

### tools

**Type:** `Record<string, Tool>`

Tools are reusable functions that agents can use to interact with external systems. Each tool defines inputs, outputs, and execution logic.

Visit the [Tools documentation](https://mastra.ai/docs/agents/using-tools) to learn more.

> **Note:** Most users configure tools directly on agents. This top-level configuration is for defining reusable tools that can be shared across multiple agents.

```typescript
import { Mastra } from '@mastra/core'
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'

const weatherTool = createTool({
  id: 'get-weather',
  description: 'Fetches weather for a city',
  inputSchema: z.object({
    city: z.string(),
  }),
  execute: async () => {
    return { temperature: 20, conditions: 'Sunny' }
  },
})

export const mastra = new Mastra({
  tools: {
    weather: weatherTool,
  },
})
```

### tts

**Type:** `Record<string, MastraVoice>`

Text-to-speech providers for voice synthesis capabilities. Register voice providers to enable agents to convert text responses into spoken audio.

Visit the [Voice documentation](https://mastra.ai/docs/voice/overview) to learn more.

> **Note:** Most users configure voice directly on agents. This top-level configuration is for defining reusable voice providers that can be shared across multiple agents.

```typescript
import { Mastra } from '@mastra/core'
import { OpenAIVoice } from '@mastra/voice-openai'

export const mastra = new Mastra({
  tts: {
    openai: new OpenAIVoice(),
  },
})
```

### vectors

**Type:** `Record<string, MastraVector>`

Vector stores for semantic search and embeddings. Used in RAG pipelines, similarity search, and other embedding-based features. Mastra supports multiple vector databases including Pinecone, PostgreSQL with pgvector, MongoDB, and more.

Visit the [RAG documentation](https://mastra.ai/docs/rag/overview) to learn more.

> **Note:** Most users create vector stores directly when building RAG pipelines. This top-level configuration is for defining reusable vector store instances that can be shared across your application.

```typescript
import { Mastra } from '@mastra/core'
import { PineconeVector } from '@mastra/pinecone'

export const mastra = new Mastra({
  vectors: {
    pinecone: new PineconeVector({
      id: 'pinecone-vector',
      apiKey: process.env.PINECONE_API_KEY,
    }),
  },
})
```

### workflows

**Type:** `Record<string, Workflow>`

Workflows define step-based execution pipelines with type-safe inputs and outputs. Use workflows for tasks that involve multiple steps with a specific execution order, giving you control over how data flows between steps.

Visit the [Workflows documentation](https://mastra.ai/docs/workflows/overview) to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { testWorkflow } from './workflows/test-workflow'

export const mastra = new Mastra({
  workflows: {
    testWorkflow,
  },
})
```

### workspace

**Type:** `Workspace`

A Mastra workspace gives agents a persistent environment for storing files and executing commands. Agents inherit the global workspace on the `Mastra` class unless they have their own workspace configured.

See the [Workspace documentation](https://mastra.ai/docs/workspace/overview) for implementation details.

```typescript
import { Mastra } from '@mastra/core'
import { Workspace, LocalFilesystem } from '@mastra/core/workspace'

const workspace = new Workspace({
  filesystem: new LocalFilesystem({ basePath: './workspace' }),
})

const mastra = new Mastra({
  workspace,
})
```

## Bundler options

### bundler.externals

**Type:** `boolean | string[]`\
**Default:** `true`

When `mastra build` is run, Mastra bundles your project into the `.mastra/output` directory. This option controls which packages are excluded from the bundle (marked as "external") and installed separately through a package manager. This is useful when the internal Mastra bundler ([Rollup](https://rollupjs.org/configuration-options/#external)) has trouble bundling certain packages.

By default, `mastra build` sets this option to `true`.

Here's an overview of what the different values mean:

- `true`: All dependencies listed in your project's `package.json` are marked as external
- `false`: No dependencies are marked as external; everything is bundled together
- `string[]`: An array of package names to mark as external, the rest will be bundled together

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  bundler: {
    externals: ['some-package', 'another-package'],
  },
})
```

### bundler.sourcemap

**Type:** `boolean`\
**Default:** `false`

Enables source map generation for the bundled output.

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  bundler: {
    sourcemap: true,
  },
})
```

### bundler.transpilePackages

**Type:** `string[]`\
**Default:** `[]`

List of packages whose source code should be transpiled through esbuild during the build process. Use this for dependencies that contain TypeScript or other code that needs compilation before bundling.

You only need this option if you're importing uncompiled source code directly. If your packages are already compiled to CommonJS or ESM, they don't need to be listed here.

Mastra automatically detects workspace packages in monorepo setups and adds them to this list, so you typically only need to specify external packages that require transpilation.

Mastra also resolves `tsconfig.json` `baseUrl` and `paths` aliases during build. This includes ESM-style imports such as `~/utils/logger.js` that point to TypeScript source files.

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  bundler: {
    transpilePackages: ['@my-org/shared-utils'],
  },
})
```

## Server options

### server.apiRoutes

**Type:** `ApiRoute[]`

Mastra automatically exposes registered agents and workflows via its server. For additional behavior you can define your own HTTP routes.

Visit the [Custom API routes](https://mastra.ai/docs/server/custom-api-routes) documentation to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { registerApiRoute } from '@mastra/core/server'

export const mastra = new Mastra({
  server: {
    apiRoutes: [
      registerApiRoute('/my-custom-route', {
        method: 'GET',
        handler: async c => {
          return c.json({ message: 'Custom route' })
        },
      }),
    ],
  },
})
```

### server.auth

**Type:** `MastraAuthConfig | MastraAuthProvider`

Authentication configuration for the server. Mastra supports multiple authentication providers including JWT, Clerk, Supabase, Firebase, WorkOS, and Auth0.

Visit the [Authentication documentation](https://mastra.ai/docs/server/auth) to learn more.

```typescript
import { Mastra } from '@mastra/core'
import { MastraJwtAuth } from '@mastra/auth'

export const mastra = new Mastra({
  server: {
    auth: new MastraJwtAuth({
      secret: process.env.MASTRA_JWT_SECRET,
      mapUserToResourceId: user => user.id,
    }),
  },
})
```

The `mapUserToResourceId` callback maps the authenticated user to a resource ID for memory/thread scoping. When provided, it's called after successful authentication and the returned value is set on the request context as `MASTRA_RESOURCE_ID_KEY`. See [Authorization (User Isolation)](https://mastra.ai/docs/server/middleware) for details.

### server.bodySizeLimit

**Type:** `number`\
**Default:** `4_718_592` (4.5 MB)

Maximum request body size in bytes. Increase this limit if your application needs to handle larger payloads.

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  server: {
    bodySizeLimit: 10 * 1024 * 1024, // 10mb
  },
})
```

### server.mcpOptions

**Type:** `object`\
**Default:** `undefined`

MCP transport options applied to all MCP HTTP and SSE routes. Use this to enable stateless mode for serverless environments (Cloudflare Workers, Vercel Edge, AWS Lambda, etc.) where persistent connections and in-memory session state are not available.

| Property             | Type           | Default     | Description                                          |
| -------------------- | -------------- | ----------- | ---------------------------------------------------- |
| `serverless`         | `boolean`      | `false`     | Run MCP in stateless mode without session management |
| `sessionIdGenerator` | `() => string` | `undefined` | Custom session ID generator function                 |

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  server: {
    mcpOptions: {
      serverless: true,
    },
  },
})
```

### server.build

Build-time configuration for server features. These options control development tools like Swagger UI and request logging, which are enabled during local development but disabled in production by default.

| Property      | Type      | Default | Description                                                                                                                                                                     |
| ------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `swaggerUI`   | `boolean` | `false` | Enable Swagger UI at `/swagger-ui` for interactive API exploration (requires `openAPIDocs` to be `true`)                                                                        |
| `apiReqLogs`  | `boolean` | `false` | Enable API request logging to the console                                                                                                                                       |
| `openAPIDocs` | `boolean` | `false` | Enable OpenAPI specification at `/api/openapi.json`. Built-in Mastra routes use `servers: [{url: "/api"}]` while custom routes get a per-path `servers: [{url: "/"}]` override. |

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  server: {
    build: {
      swaggerUI: true,
      apiReqLogs: true,
      openAPIDocs: true,
    },
  },
})
```

### server.cors

**Type:** `CorsOptions | false`

CORS (Cross-Origin Resource Sharing) configuration for the server. Set to `false` to disable CORS entirely.

| Property        | Type                 | Default                                                     | Description                                  |
| --------------- | -------------------- | ----------------------------------------------------------- | -------------------------------------------- |
| `origin`        | `string \| string[]` | `'*'`                                                       | Origins for CORS requests                    |
| `allowMethods`  | `string[]`           | `['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']`      | HTTP methods                                 |
| `allowHeaders`  | `string[]`           | `['Content-Type', 'Authorization', 'x-mastra-client-type']` | Request headers                              |
| `exposeHeaders` | `string[]`           | `['Content-Length', 'X-Requested-With']`                    | Browser headers                              |
| `credentials`   | `boolean`            | `false`                                                     | Credentials (cookies, authorization headers) |
| `maxAge`        | `number`             | `3600`                                                      | Preflight request cache duration in seconds  |

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  server: {
    cors: {
      origin: ['https://example.com'],
      allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
      allowHeaders: ['Content-Type', 'Authorization'],
      credentials: false,
    },
  },
})
```

### server.host

**Type:** `string`\
**Default:** `localhost` (or `MASTRA_HOST` environment variable if set)

Host address the Mastra development server binds to. If the `MASTRA_HOST` environment variable is set, it takes precedence over the default.

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  server: {
    host: '0.0.0.0',
  },
})
```

### server.https

**Type:** `{ key: Buffer; cert: Buffer }`

HTTPS configuration for running the development server with TLS. Mastra supports local HTTPS development through the `mastra dev --https` flag, which automatically creates and manages certificates. For custom certificate management, provide your own key and certificate files:

```typescript
import { Mastra } from '@mastra/core'
import fs from 'node:fs'

export const mastra = new Mastra({
  server: {
    https: {
      key: fs.readFileSync('path/to/key.pem'),
      cert: fs.readFileSync('path/to/cert.pem'),
    },
  },
})
```

### server.middleware

**Type:** `Middleware | Middleware[]`

Custom middleware functions to intercept requests before or after route handlers. Middleware can be used for authentication, logging, injecting request-specific context, or adding headers. Each middleware receives the Hono `Context` and a `next` function. Return a `Response` to short-circuit the request, or call `next()` to continue processing.

Visit the [Middleware documentation](https://mastra.ai/docs/server/middleware) to learn more.

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  server: {
    middleware: [
      {
        handler: async (c, next) => {
          const authHeader = c.req.header('Authorization')
          if (!authHeader) {
            return new Response('Unauthorized', { status: 401 })
          }
          await next()
        },
        path: '/api/*',
      },
    ],
  },
})
```

### server.onError

**Type:** `(err: Error, c: Context) => Response | Promise<Response>`

Custom error handler called when an unhandled error occurs. Use this to customize error responses, log errors to external services like Sentry, or implement custom error formatting.

This hook is supported by all server adapters. The `c` parameter provides a Hono-compatible context object — for non-Hono adapters (Koa, Express, Fastify), a shim is provided with commonly used methods like `c.json()` and `c.req.path`.

```typescript
import { Mastra } from '@mastra/core'
import * as Sentry from '@sentry/node'

export const mastra = new Mastra({
  server: {
    onError: (err, c) => {
      Sentry.captureException(err)

      return c.json(
        {
          error: err.message,
          timestamp: new Date().toISOString(),
        },
        500,
      )
    },
  },
})
```

### server.onValidationError

**Type:** `(error: ZodError, context: 'query' | 'body' | 'path') => { status: number; body: unknown } | undefined`

Custom handler called when a request fails Zod schema validation. Use this to customize validation error responses, change the status code, or format errors to match your API standards.

Return a `{ status, body }` object to override the default `400` response, or `undefined` to fall through to the default behavior. This hook is supported by all server adapters (Hono, Express, Fastify, Koa).

The `context` parameter indicates which part of the request failed validation:

- `'query'`: query parameters
- `'body'`: request body
- `'path'`: path parameters

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  server: {
    onValidationError: (error, context) => ({
      status: 422,
      body: {
        ok: false,
        errors: error.issues.map(i => ({
          path: i.path.join('.'),
          message: i.message,
        })),
        source: context,
      },
    }),
  },
})
```

You can also set `onValidationError` on individual routes created with `createRoute()`. A route-level hook takes precedence over the server-level hook.

### server.port

**Type:** `number`\
**Default:** `4111` (or `PORT` environment variable if set)

Port the Mastra development server binds to. If the `PORT` environment variable is set, it takes precedence over the default.

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  server: {
    port: 8080,
  },
})
```

### server.studioBase

**Type:** `string`\
**Default:** `/`

Base path for hosting [Studio](https://mastra.ai/docs/studio/overview). Use this to host the Studio on a sub-path of your existing application instead of the root.

This is useful when integrating with existing applications, using authentication tools like Cloudflare Zero Trust that benefit from shared domains, or managing multiple services under a single domain.

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  server: {
    studioBase: '/my-mastra-studio',
  },
})
```

**Example URLs:**

- Default: `http://localhost:4111/` (studio at root)
- With `studioBase`: `http://localhost:4111/my-mastra-studio/` (studio at sub-path)

### server.timeout

**Type:** `number`\
**Default:** `180000` (3 minutes)

Request timeout in milliseconds. Requests that exceed this duration will be terminated.

```typescript
import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  server: {
    timeout: 30000, // 30 seconds
  },
})
```