> Discover all available pages from the documentation index: https://mastra.ai/llms.txt

# Elysia adapter

The `@mastra/elysia` package provides a server adapter for running Mastra with [Elysia](https://elysiajs.com).

> **Note:** For general adapter concepts, constructor options, and initialization flow, see [Server Adapters](https://mastra.ai/docs/server/server-adapters).

## Installation

Install the Elysia adapter and Elysia framework:

**npm**:

```bash
npm install @mastra/elysia@latest elysia
```

**pnpm**:

```bash
pnpm add @mastra/elysia@latest elysia
```

**Yarn**:

```bash
yarn add @mastra/elysia@latest elysia
```

**Bun**:

```bash
bun add @mastra/elysia@latest elysia
```

## Usage example

```typescript
import { Elysia } from 'elysia'
import { MastraServer } from '@mastra/elysia'
import { mastra } from './mastra'

const app = new Elysia()
const server = new MastraServer({ app, mastra })

await server.init()

app.listen(3000)

console.log('Server running on http://localhost:3000')
```

## Constructor parameters

**app** (`Elysia`): Elysia app instance

**mastra** (`Mastra`): Mastra instance

**prefix** (`string`): Route path prefix (e.g., /api/v2) (Default: `''`)

**openapiPath** (`string`): Path to serve OpenAPI spec (e.g., /openapi.json) (Default: `''`)

**bodyLimitOptions** (`BodyLimitOptions`): Request body size limits

**streamOptions** (`StreamOptions`): Stream redaction config. When true (default), redacts sensitive data from stream chunks before sending to clients. (Default: `{ redact: true }`)

**customRouteAuthConfig** (`Map<string, boolean>`): Per-route auth overrides. Keys are METHOD:PATH (e.g., GET:/api/health). Value false makes route public, true requires auth.

**tools** (`ToolsInput`): Available tools for the server

**taskStore** (`InMemoryTaskStore`): Task store for A2A (Agent-to-Agent) operations

**mcpOptions** (`MCPOptions`): MCP transport options. Set serverless: true for stateless environments like Vercel Edge.

## Adding custom routes

Add routes directly to the Elysia app:

```typescript
import { Elysia } from 'elysia'
import { MastraServer } from '@mastra/elysia'
import { mastra } from './mastra'

const app = new Elysia()
const server = new MastraServer({ app, mastra })

// Before init - runs before Mastra middleware
app.get('/early-health', () => ({ status: 'ok' }))

await server.init()

// After init - has access to Mastra context
app.get('/custom', ({ mastra }) => {
  return { agents: Object.keys(mastra.listAgents()) }
})
```

> **Tip:** Routes added before `init()` run without Mastra context. Add routes after `init()` to access the Mastra instance and request context.

When you want Mastra-managed auth and route metadata such as `requiresAuth`, prefer [`registerApiRoute()`](https://mastra.ai/reference/server/register-api-route). For raw Elysia routes mounted directly on `app`, use `createAuthMiddleware()`:

```typescript
import { Elysia } from 'elysia'
import { createAuthMiddleware, MastraServer } from '@mastra/elysia'
import { mastra } from './mastra'

const app = new Elysia()
const server = new MastraServer({ app, mastra })

await server.init()

app.get('/custom/protected', async ctx => {
  const authResponse = await createAuthMiddleware({ mastra })(ctx)
  if (authResponse) return authResponse

  const user = ctx.requestContext.get('user')
  return { user }
})

app.get('/custom/public', async ctx => {
  const authResponse = await createAuthMiddleware({ mastra, requiresAuth: false })(ctx)
  if (authResponse) return authResponse

  return { ok: true }
})
```

## Accessing context

In Elysia handlers registered after `init()`, access Mastra context from the handler context:

```typescript
app.get('/custom', ({ mastra, requestContext, abortSignal }) => {
  const agent = mastra.getAgent('myAgent')
  const user = requestContext.get('user')

  return { agent: agent.name, user, aborted: abortSignal.aborted }
})
```

Available context keys:

| Key                     | Description                                                    |
| ----------------------- | -------------------------------------------------------------- |
| `mastra`                | Mastra instance                                                |
| `requestContext`        | Request context map                                            |
| `abortSignal`           | Request cancellation signal                                    |
| `registeredTools`       | Available tools                                                |
| `taskStore`             | Task store for A2A operations                                  |
| `customRouteAuthConfig` | Per-route auth overrides                                       |
| `user`                  | Authenticated user in `requestContext` when auth is configured |

## OpenAPI helpers

Use `getMastraOpenAPIDoc()` when you need to pass Mastra's generated OpenAPI document to Elysia tooling such as `@elysiajs/openapi`:

```typescript
import { openapi } from '@elysiajs/openapi'
import { Elysia } from 'elysia'
import { getMastraOpenAPIDoc, MastraServer } from '@mastra/elysia'
import { mastra } from './mastra'

const app = new Elysia()
const server = new MastraServer({ app, mastra })

await server.init()

app.use(
  openapi({
    documentation: getMastraOpenAPIDoc(server),
  }),
)
```

Call `clearMastraOpenAPICache(server)` if you need to regenerate the cached document for the same server instance.

## MCP support

The Elysia adapter supports both MCP HTTP and MCP SSE transports.

## Manual initialization

For custom middleware ordering, call each method separately instead of `init()`. See [manual initialization](https://mastra.ai/docs/server/server-adapters) for details.