Editor
Editor works like a CMS for Mastra agents. Collaborators can change an agent's instructions and tools in Studio without accessing the codebase or writing code. They can test changes before making them live.
TypeScript defines the agent's default values. Editor saves changes separately instead of updating the source code, so collaborators can improve the agent while developers retain control over its model, identity, and runtime.
A deployed Studio makes Editor available to collaborators outside local development.
Watch the Mastra Editor workshop for a guided walkthrough.
When to use EditorDirect link to When to use Editor
Use Editor when an agent is defined in code but the people responsible for its behavior shouldn't edit the codebase. It works well when instructions or tools change often and need testing before they reach users. If developers own every change and release agent configuration with the application, keep the agent configuration in code instead.
QuickstartDirect link to Quickstart
Install @mastra/editor. This quickstart uses LibSQL to store Editor changes:
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/editor @mastra/libsql
pnpm add @mastra/editor @mastra/libsql
yarn add @mastra/editor @mastra/libsql
bun add @mastra/editor @mastra/libsql
Add MastraEditor and storage to the Mastra instance. Existing storage can be reused instead of adding the LibSQL store shown here.
import { Mastra } from '@mastra/core'
import { MastraEditor } from '@mastra/editor'
import { LibSQLStore } from '@mastra/libsql'
export const mastra = new Mastra({
agents: {/* existing agents */},
storage: new LibSQLStore({
id: 'mastra-storage',
url: 'file:./mastra.db',
}),
editor: new MastraEditor(),
})
Use Editor in StudioDirect link to Use Editor in Studio
In Studio, open Agents, select an agent, then select Editor. Collaborators can update the agent's instructions and tools based on its Editor permissions.
With database storage, save changes as a draft to test them without affecting the live agent. Publish the draft when it's ready to use.
InstructionsDirect link to Instructions
The Instructions section shows the agent's system prompt defined in code. Collaborators can override it or add instruction blocks.
An instruction block can include values from the current request. For example, {{userName}} inserts a name supplied through request context. A display condition can show a block only for a customer, role, or feature flag.
Prompt blocksDirect link to Prompt blocks
A prompt block is a saved piece of instruction text that can be used by more than one agent. Create one under Prompts, publish it, then open an agent's Instructions section and select Add block.
For example, agents for support, returns, and order status may all need the same refund policy. Save the policy as a prompt block and add it to each agent. When the policy changes, update and publish the block once instead of editing three agents.
When a prompt block changes, every agent that references its published version receives the update. Draft changes are used only while previewing, so they don't affect the live agents until the block is published.
See the prompt blocks reference for template syntax, conditions, versions, and APIs.
ToolsDirect link to Tools
Tools let an agent take actions. Collaborators choose from the tools available to Editor, but they can't implement new tools in Studio. How tools become available depends on their source:
- Project tools must be implemented and registered in the Mastra project by a developer.
- Integration tools become available after a developer registers a provider such as Composio or Arcade. Collaborators can then browse the provider's catalog and add tools without each tool being added in code first.
- MCP tools become available when an MCP client is configured. A collaborator with access can create the client in Studio, then choose from the tools exposed by its servers.
In the agent's Tools section, collaborators can add the tools it needs or rewrite a tool's description for that agent. A more specific description helps the agent understand when to use the tool without changing the tool itself.
Project toolsDirect link to Project tools
Developers can register a project tool on the Mastra instance to make it available in Editor:
import { Mastra } from '@mastra/core'
import { MastraEditor } from '@mastra/editor'
import { searchOrders } from './tools/search-orders'
export const mastra = new Mastra({
tools: {
searchOrders,
},
agents: {/* agents */},
editor: new MastraEditor(),
})
The Studio tool picker lists the tool. A collaborator can add it to an agent when that agent allows tool editing. The agent's Editor view also lists tools attached in code.
ComposioDirect link to Composio
Composio provides tools for services such as GitHub, Slack, and Gmail. Register the provider with a Composio API key to make its tool catalog available in Editor:
import { Mastra } from '@mastra/core'
import { MastraEditor } from '@mastra/editor'
import { ComposioToolProvider } from '@mastra/editor/composio'
export const mastra = new Mastra({
agents: {/* agents */},
editor: new MastraEditor({
toolProviders: {
composio: new ComposioToolProvider({
apiKey: process.env.COMPOSIO_API_KEY!,
}),
},
}),
})
Composio tool IDs look like GITHUB_CREATE_ISSUE. By default, a selected tool uses the connection associated with the agent's author. See connection scope to use each caller's connection instead.
ArcadeDirect link to Arcade
Arcade provides another catalog of tools with built-in authentication. Register it with an Arcade API key:
import { Mastra } from '@mastra/core'
import { MastraEditor } from '@mastra/editor'
import { ArcadeToolProvider } from '@mastra/editor/arcade'
export const mastra = new Mastra({
agents: {/* agents */},
editor: new MastraEditor({
toolProviders: {
arcade: new ArcadeToolProvider({
apiKey: process.env.ARCADE_API_KEY!,
}),
},
}),
})
Arcade tool IDs use Toolkit.ToolName format, such as Github.GetRepository.
MCP clientsDirect link to MCP clients
Collaborators can also create a reusable MCP client in Studio and add its tools to an agent. Stored clients can start a local stdio server or connect to a remote HTTP server. Tool filters let each agent use only the tools it needs from that server.
See the Editor tools reference for MCP configuration, conditions, filtering, and resolution order. See ToolProvider for provider options.
Decide what collaborators can editDirect link to Decide what collaborators can edit
By default, collaborators can change an agent's instructions and manage its tools, including their descriptions. The agent's id, name, and model always come from code.
Use the agent's editor field to limit what can be changed:
import { Agent } from '@mastra/core/agent'
export const supportAgent = new Agent({
id: 'support-agent',
name: 'Support agent',
instructions: 'Help customers with Acme products.',
model: 'openai/gpt-5.6-sol',
editor: {
instructions: true,
tools: {
description: true,
},
},
})
This agent lets collaborators change its instructions and improve the descriptions of tools already attached to it. They can't add or remove tools.
editor value | What collaborators can change |
|---|---|
| Omitted | Instructions, tools, and tool descriptions |
false | Nothing |
{ instructions: true } | Instructions |
{ tools: true } | Tools and tool descriptions |
{ tools: { description: true } } | Descriptions of tools already added in code |
Studio shows everything else as read-only. See editor overrides for the complete configuration.
Choose where changes are storedDirect link to Choose where changes are stored
Editor can save changes in the configured database or as files in the repository.
Database storageDirect link to Database storage
The database option is the default. Editor uses the storage configured on the Mastra instance, so the application and Editor can share the same backend.
To use a separate backend for Editor data, set the editor option on MastraCompositeStore. Storage domains without an explicit route continue to use its default store.
The following example keeps application and Editor data in separate LibSQL files:
import { Mastra } from '@mastra/core'
import { MastraCompositeStore } from '@mastra/core/storage'
import { MastraEditor } from '@mastra/editor'
import { LibSQLStore } from '@mastra/libsql'
export const mastra = new Mastra({
agents: {/* existing agents */},
storage: new MastraCompositeStore({
id: 'mastra-storage',
default: new LibSQLStore({
id: 'app-storage',
url: 'file:./mastra.db',
}),
editor: new LibSQLStore({
id: 'editor-storage',
url: 'file:./editor.db',
}),
}),
editor: new MastraEditor(),
})
Repository filesDirect link to Repository files
Use the code source to keep overrides alongside application code. Developers can review the files in pull requests and deploy them with the application:
import { Mastra } from '@mastra/core'
import { MastraEditor } from '@mastra/editor'
export const mastra = new Mastra({
agents: {/* existing agents */},
editor: new MastraEditor({
source: 'code',
codePath: './mastra/editor',
}),
})
In this mode, each edited agent has one JSON override file. Editor doesn't generate TypeScript or change the file where the agent was created. By default, an agent with the ID support-agent gets this file:
mastra/editor/agents/support-agent.json
The file contains only the parts managed by Editor. For example:
{
"instructions": "Help customers with Acme products and answer in their language.",
"tools": {
"searchOrders": {
"description": "Look up an order by its number"
}
}
}
The agent's model, name, and other code-owned fields stay in its TypeScript file. Mastra reads the JSON and applies these values when the agent runs.
When a collaborator saves in Studio, they can write the file to the local filesystem or download it. With a source-control integration, Studio can open a pull request instead. Git then provides the review and version history.
See MastraEditor for file locations and source options.
VersioningDirect link to Versioning
Database-backed agents and prompt blocks use draft and published versions. Saving creates a draft while the live agent continues using the published version. Publishing makes the draft live. Restoring an older version creates a draft that collaborators can test before publishing.
Code-backed agent overrides use JSON files and Git history.
Select a versionDirect link to Select a version
An application can choose a stored version for each request by passing a status (published or draft) or an exact version ID:
const publishedAgent = await mastra.getAgentById('support-agent', {
status: 'published',
})
const draftAgent = await mastra.getAgentById('support-agent', {
status: 'draft',
})
const versionedAgent = await mastra.getAgentById('support-agent', {
versionId: 'abc-123',
})
Version selection supports:
- Compare two versions in an A/B test.
- Give a draft to a small group before publishing it for everyone.
- Keep production on the published version while staging uses the latest draft.
- Pin a customer to a particular version.
The same version controls work when a supervisor calls sub-agents. Developers can test a draft sub-agent without changing the rest of the system.
See the Editor versioning reference for version selection, sub-agent behavior, REST endpoints, and SDK methods.
Programmatic accessDirect link to Programmatic access
Everything available in Studio is also available programmatically through mastra.getEditor(), the REST API, or the Client SDK. Use it to script bulk updates or seed stored configurations from code. It can also power automation that tunes agents based on evaluation results.
Call mastra.getEditor() when application code has access to the Mastra instance:
import { mastra } from '../mastra'
const editor = mastra.getEditor()!
await editor.agent.update({
id: 'support-agent',
instructions: 'Help customers with Acme products. Reply in their language.',
})
The direct editor.agent.update() method activates the new version immediately. To create a draft without changing the live agent, use the stored-agent REST API or Client SDK instead:
curl -X PATCH http://localhost:4111/api/stored/agents/support-agent \
-H "Content-Type: application/json" \
-d '{
"instructions": "Help customers with Acme products. Reply in their language."
}'
The default server prefix is /api. Developers can set a custom prefix in the server configuration.
See the MastraEditor namespaces and Client SDK agents API for available operations.