Hono adapter
The @mastra/hono package provides a server adapter for running Mastra with Hono. For general adapter concepts (constructor options, initialization flow, etc.), see Server Adapters.
InstallationDirect link to Installation
Install the Hono adapter and Hono framework:
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/hono@latest hono
pnpm add @mastra/hono@latest hono
yarn add @mastra/hono@latest hono
bun add @mastra/hono@latest hono
Usage exampleDirect link to Usage example
import { Hono } from 'hono'
import { HonoBindings, HonoVariables, MastraServer } from '@mastra/hono'
import { mastra } from './mastra'
const app = new Hono<{ Bindings: HonoBindings; Variables: HonoVariables }>()
const server = new MastraServer({ app, mastra })
await server.init()
export default app
Constructor parametersDirect link to Constructor parameters
app:
mastra:
prefix?:
/api/v2)openapiPath?:
/openapi.json)bodyLimitOptions?:
streamOptions?:
customRouteAuthConfig?:
METHOD:PATH (e.g., GET:/api/health). Value false makes route public, true requires auth.tools?:
taskStore?:
mcpOptions?:
serverless: true for stateless environments like Cloudflare Workers or Vercel Edge.Adding custom routesDirect link to Adding custom routes
Add routes directly to the Hono app:
import { Hono } from 'hono'
import { HonoBindings, HonoVariables, MastraServer } from '@mastra/hono'
const app = new Hono<{ Bindings: HonoBindings; Variables: HonoVariables }>()
const server = new MastraServer({ app, mastra })
// Before init - runs before Mastra middleware
app.get('/early-health', c => c.json({ status: 'ok' }))
await server.init()
// After init - has access to Mastra context
app.get('/custom', c => {
const mastraInstance = c.get('mastra')
return c.json({ agents: Object.keys(mastraInstance.listAgents()) })
})
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(). For raw Hono routes mounted directly on app, use createAuthMiddleware():
import { Hono } from 'hono'
import { createAuthMiddleware, HonoBindings, HonoVariables, MastraServer } from '@mastra/hono'
import { mastra } from './mastra'
const app = new Hono<{ Bindings: HonoBindings; Variables: HonoVariables }>()
const server = new MastraServer({ app, mastra })
await server.init()
app.get('/custom/protected', createAuthMiddleware({ mastra }), c => {
const user = c.get('requestContext').get('user')
return c.json({ user })
})
app.get('/custom/public', createAuthMiddleware({ mastra, requiresAuth: false }), c => {
return c.json({ ok: true })
})
Accessing contextDirect link to Accessing context
In Hono middleware and route handlers, access Mastra context via c.get():
app.get('/custom', async c => {
const mastra = c.get('mastra')
const requestContext = c.get('requestContext')
const abortSignal = c.get('abortSignal')
const agent = mastra.getAgent('myAgent')
return c.json({ agent: agent.name })
})
Available context keys:
| Key | Description |
|---|---|
mastra | Mastra instance |
requestContext | Request context map |
abortSignal | Request cancellation signal |
tools | Available tools |
taskStore | Task store for A2A operations |
customRouteAuthConfig | Per-route auth overrides |
user | Authenticated user (if auth configured) |
Adding middlewareDirect link to Adding middleware
Add Hono middleware with app.use() before init() to run it on every request. Mastra context isn't available at that point:
import { Hono } from 'hono'
import { HonoBindings, HonoVariables, MastraServer } from '@mastra/hono'
const app = new Hono<{ Bindings: HonoBindings; Variables: HonoVariables }>()
// Runs on every request, before Mastra context exists
app.use('*', async (c, next) => {
console.log(`${c.req.method} ${c.req.url}`)
await next()
})
const server = new MastraServer({ app, mastra })
await server.init()
Middleware added after init() never runs for Mastra's routes. Hono dispatches handlers in registration order, so middleware registered after the routes only applies to routes added later.
To run middleware with Mastra context on Mastra's routes, use server.middleware in the Mastra config. The adapter registers it during init(), after the context step and before any route. These handlers are skipped for routes declared public with requiresAuth: false, so they can't block endpoints such as the Studio sign-in routes:
import { Mastra } from '@mastra/core'
export const mastra = new Mastra({
server: {
middleware: [
async (c, next) => {
c.get('requestContext').set('locale', c.req.header('accept-language') ?? 'en')
await next()
},
],
},
})
Manual initializationDirect link to Manual initialization
For custom middleware ordering, call each method separately instead of init(). See manual initialization for details.
ExamplesDirect link to Examples
- Hono Adapter: Basic Hono server setup
RelatedDirect link to Related
- Server Adapters: Shared adapter concepts
- MastraServer Reference: Full API reference
- createRoute() Reference: Creating type-safe custom routes