Harness overview
The Harness feature is in alpha stage and subject to breaking changes in minor versions until it graduates from its alpha status.
The Harness is a session controller for building interactive agent applications. It handles the runtime concerns that sit between your UI and the agent loop: managing conversation threads, switching between agent modes, persisting state, gating tool execution with approvals, and coordinating subagents. You can focus on what your agent does rather than how to wire it together.
A Harness exposes a Session — the per-conversation runtime state that tracks the active mode, model, thread binding, permission grants, follow-up queue, and token usage. The Harness is the shared host; the Session is the conversation running inside it. In a multi-user host, the same Harness can back many Sessions at once.
Mastra Code is the flagship Harness implementation: A terminal-based coding agent with multi-model support, persistent conversations, and plan-then-execute workflows.
What you can buildDirect link to What you can build
The Harness is designed for applications where a user has an ongoing, interactive session with one or more AI agents:
| Application | How the Harness helps |
|---|---|
| Coding agents (TUI or IDE) | Plan mode reasons about changes, build mode executes them. Thread persistence resumes conversations across sessions. Tool approvals gate destructive operations like file writes. |
| Multi-step assistants | A research mode gathers information, a drafting mode produces output. Shared state tracks progress. Subagents handle focused subtasks (e.g., web search, code review). |
| Copilot UIs | Model switching lets users pick the right model for the job. Permission policies control which tools run automatically vs. requiring confirmation. Event subscriptions drive real-time UI updates. |
| Autonomous task runners | Background agents with structured task lists, heartbeat handlers for health checks, and observational memory for learning across threads. |
When to use the HarnessDirect link to When to use the Harness
Use the Harness when your application needs:
- Multiple agent modes that share one conversation thread (e.g., plan → build → review)
- A control layer between your UI and the agent loop (model switching, state persistence, thread management)
- Tool approval flows and permission policies for human-in-the-loop gating
- Subagent orchestration to delegate focused subtasks with constrained tools
- Session continuity with persistent threads, state, and observational memory across restarts
For single-shot agent calls or basic request-response patterns, use the Agent class directly. The Harness adds value when you need session state, mode switching, or interactive approval flows.
Key capabilitiesDirect link to Key capabilities
- Session: Per-conversation state — active thread, mode, model, grants, follow-ups, token usage, and the display snapshot — accessed through
harness.session. See Session. - Modes: Define distinct agent personalities (instructions, tools, model) and switch between them without losing conversation context. See Modes.
- Threads and state: Persist conversations and structured state across sessions, users, and mode switches. See Threads and state.
- Subagents: Spawn focused child agents with constrained tools for subtasks, optionally forking the parent conversation. See Subagents.
- Tool approvals and permissions: Configure which tools require user confirmation, grant session-wide exceptions, and handle interactive tool suspension. See Tool approvals.
- Model management: Switch models per-mode at runtime, track usage, and resolve gateway-backed models.
- Follow-ups and steering: Queue messages while the agent is running, or inject mid-stream instructions to redirect the agent.
- Event system: Subscribe to typed events (message updates, mode changes, tool approvals) or coalesced
HarnessDisplayStatesnapshots to drive your UI. - Observational memory: Automatic summarization and reflection across threads for long-running agent sessions.
QuickstartDirect link to Quickstart
Import the Harness class and create a new instance with an agent, storage backend, and modes:
import { Agent } from '@mastra/core/agent'
import { Harness } from '@mastra/core/harness'
import { LibSQLStore } from '@mastra/libsql'
const agent = new Agent({
name: 'assistant',
instructions: 'Help the user plan and complete tasks.',
model: 'openai/gpt-5.5',
})
const harness = new Harness({
id: 'my-agent',
agent,
storage: new LibSQLStore({ url: 'file:./data.db' }),
modes: [
{
id: 'plan',
name: 'Plan',
metadata: { default: true },
instructions: 'Reason about changes before making them.',
},
{ id: 'build', name: 'Build', instructions: 'Implement the approved plan.' },
],
})
harness.subscribe(event => {
if (event.type === 'message_update') {
console.log(event.message)
}
})
await harness.init()
await harness.selectOrCreateThread()
await harness.sendMessage({ content: 'Hello!' })
Visit the Harness reference for the full constructor parameters and method signatures.
ArchitectureDirect link to Architecture
The Harness sits between your application layer and the underlying agent loop:
┌──────────────────────────┐
│ Your App (TUI/Web/API) │
└────────────┬─────────────┘
│ commands (sendMessage, switchMode, approve)
│ events (message_update, tool_approval_required)
┌────────────▼─────────────┐
│ Harness (shared host) │
│ Config · Storage │
│ Thread lifecycle │
│ Permission policy │
│ Subagent spawning │
│ Event bus │
│ ┌─────────────────────┐ │
│ │ harness.session │ │
│ │ identity · thread │ │
│ │ mode · model · run │ │
│ │ grants · follow-ups │ │
│ │ display state │ │
│ └─────────────────────┘ │
└────────────┬─────────────┘
│
┌────────────▼──────────────┐
│ Agent + Memory + Tools │
└───────────────────────────┘
Your app sends commands (send a message, switch mode, approve a tool call) and receives typed events. The Harness manages the lifecycle internally: persisting threads, routing to the correct mode agent, enforcing permissions, and emitting events as state changes.
Next stepsDirect link to Next steps
- Session: The per-conversation state on a Harness
- Modes: Define and switch between agent personalities
- Threads and state: Manage persistent conversations
- Subagents: Delegate focused subtasks
- Tool approvals and permissions: Human-in-the-loop gating
- API reference: Full constructor and method docs