docs/src/mastra-code/configuration.mdx
Mastra Code is configured through project-level files, global settings, and environment variables. Configuration files live in .mastracode/ directories at the project and user levels.
Mastra Code supports two authentication methods: API keys (environment variables) and OAuth (provider subscriptions). You can use either or both.
The simplest way to get started is to set API key environment variables for the providers you want to use. Mastra Code auto-detects these on startup:
export ANTHROPIC_API_KEY=sk-ant-...
export OPENAI_API_KEY=sk-...
export GOOGLE_GENERATIVE_AI_API_KEY=...
export DEEPSEEK_API_KEY=...
export CEREBRAS_API_KEY=...
Mastra Code uses Mastra's model router, which routes requests to the correct provider based on the model ID and available API keys. No OAuth login is required when using API keys.
When you select a model from the model selector (/models) that doesn't have an API key configured, Mastra Code prompts you to enter one. The prompt displays the required environment variable name (for example, ANTHROPIC_API_KEY) and lets you paste your key directly.
auth.json and set in the current process environment. The model becomes available immediately.Stored API keys persist across sessions. On the next startup, Mastra Code loads them into the environment automatically. Environment variables always take priority — if you later set a key via export, it overrides the stored value.
If you have an Anthropic Claude Max or OpenAI ChatGPT Plus subscription, you can authenticate via OAuth to use your subscription instead of API keys. Run /login in the TUI to start the flow.
| Provider | OAuth flow | What you get |
|---|---|---|
| Anthropic | Claude Max subscription | Access to Claude models via your subscription |
| OpenAI | ChatGPT Plus / Codex | Access to OpenAI models via your subscription |
OAuth credentials are stored in auth.json alongside the database in the app data directory. During onboarding, you can skip the OAuth step if you already have API keys configured.
When resolving Anthropic models, Mastra Code checks for credentials in this order:
/login)ANTHROPIC_API_KEY environment variable or stored API key credentialTo switch from OAuth to API key usage, log out with /logout and set your ANTHROPIC_API_KEY environment variable.
Authenticating with a Claude Max subscription through OAuth is a grey area. Anthropic has reportedly banned users for using Claude max credentials outside of Claude Code, so it may violate Anthropic Terms of Service.
Mastra Code can connect to external MCP servers and make their tools available to the agent. Configure servers in JSON files:
| Priority | Path | Scope |
|---|---|---|
| Highest | .mastracode/mcp.json | Project |
~/.mastracode/mcp.json | Global | |
| Lowest | .claude/settings.local.json | Project (Claude Code compatible) |
Project config overrides global config by server name. Claude Code settings are the lowest priority fallback.
Mastra Code supports two transport types for MCP servers: stdio (local process) and HTTP (remote server via Streamable HTTP or SSE).
Launch a local process that communicates via stdin/stdout. Requires a command field. The args and env fields are optional.
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["-y", "@my-org/mcp-server"],
"env": {
"API_KEY": "your-key"
}
}
}
}
Connect to a remote MCP server via URL. Requires a url field. The optional headers field lets you pass static headers such as authentication tokens.
{
"mcpServers": {
"remote-api": {
"url": "https://mcp.example.com/sse",
"headers": {
"Authorization": "Bearer your-token"
}
}
}
}
Since headers only supports static values, use a stdio wrapper for dynamic authentication such as token refresh.
On startup, Mastra Code connects to all configured servers and reports the status:
MCP: 2 server(s) connected, 15 tool(s)
Invalid or ambiguous entries (for example, specifying both command and url, or providing an invalid URL) are skipped with a reason:
MCP: Skipped "bad-server": Missing required field: "command" (stdio) or "url" (http)
Tools from MCP servers are namespaced as serverName_toolName and appear in the agent's tool list alongside built-in tools. Use /mcp to see the status of all servers, including their transport type and any skipped entries.
Hooks are user-configured shell commands that run at specific lifecycle events. Use hooks for custom validation, logging, notifications, or integration with external systems.
{
"PreToolUse": [
{
"type": "command",
"command": "node scripts/validate-tool.js",
"matcher": {
"tool_name": "execute_command"
},
"timeout": 5000,
"description": "Validate shell commands before execution"
}
],
"PostToolUse": [
{
"type": "command",
"command": "node scripts/log-tool.js",
"description": "Log tool usage"
}
]
}
| Event | When it fires | Can block? |
|---|---|---|
PreToolUse | Before a tool call executes | Yes |
PostToolUse | After a tool call completes | No |
Stop | When an agent response ends (complete, aborted, or error) | Yes |
UserPromptSubmit | When the user sends a message | Yes |
SessionStart | When a session begins | No |
SessionEnd | When a session ends | No |
Notification | When the TUI fires a notification | No |
UserPromptSubmit runs before a non-command prompt is sent to the agent. If a hook blocks, the prompt is not sent.
Hook processes receive a JSON payload on stdin with context about the event:
{
"session_id": "thread-abc123",
"cwd": "/path/to/project",
"hook_event_name": "PreToolUse",
"tool_name": "execute_command",
"tool_input": { "command": "npm test" }
}
For blocking events (PreToolUse, Stop, UserPromptSubmit), the hook can respond on stdout with a JSON object:
{
"decision": "block",
"reason": "This command is not allowed"
}
| Priority | Path | Scope |
|---|---|---|
| Higher | .mastracode/hooks.json | Project (appended after global) |
| Lower | ~/.mastracode/hooks.json | Global (runs first) |
Global hooks run before project hooks. For the same event, all hooks execute in order.
Define reusable prompt templates as markdown files. Mastra Code scans these directories for .md files:
| Priority | Path | Scope |
|---|---|---|
| Highest | .mastracode/commands/ | Project |
.claude/commands/ | Project (Claude Code compatible) | |
~/.mastracode/commands/ | Global | |
| Lowest | ~/.claude/commands/ | Global (Claude Code compatible) |
Each command file can include YAML frontmatter with name and description fields:
---
name: review
description: Review the current diff for issues
---
Review my current git diff. Look for bugs, security issues,
and violations of the project's coding standards.
The filename (or directory structure) determines the command name. For example, git/commit.md becomes /git:commit.
Commands support variables like $ARGUMENTS for positional args, @filename for file content injection, and !command for shell command output.
Skills are structured instruction files that the agent loads automatically based on trigger conditions. They provide domain-specific guidance without manually pasting instructions.
Mastra Code scans these directories for skills:
| Priority | Path | Scope |
|---|---|---|
| Highest | .mastracode/skills/ | Project |
.claude/skills/ | Project (Claude Code compatible) | |
~/.mastracode/skills/ | Global | |
| Lowest | ~/.claude/skills/ | Global (Claude Code compatible) |
Each skill is a directory containing a SKILL.md file with instructions and trigger descriptions. Skills installed via symlinks (e.g., from npx skills add) are automatically resolved.
Mastra Code loads project-specific instructions from AGENTS.md or CLAUDE.md files and injects them into the agent's system prompt. This is how you can customize the agent's behavior for your project.
For project instructions (first match wins):
AGENTS.md or CLAUDE.md in the project root.claude/AGENTS.md or .claude/CLAUDE.md.mastracode/AGENTS.md or .mastracode/CLAUDE.mdFor global instructions (first match wins):
~/.claude/AGENTS.md or ~/.claude/CLAUDE.md~/.mastracode/AGENTS.md or ~/.mastracode/CLAUDE.md~/.config/claude/AGENTS.md or ~/.config/claude/CLAUDE.md~/.config/mastracode/AGENTS.md or ~/.config/mastracode/CLAUDE.mdAGENTS.md takes priority over CLAUDE.md when both exist at the same location.
Mastra Code stores threads, messages, state, and observational memory in a database. It uses LibSQL by default with a local file — no setup needed.
To switch to a remote LibSQL (Turso) or PostgreSQL backend, run /settings and select a storage backend. You'll be prompted for a connection URL.
If a PostgreSQL connection fails on startup, Mastra Code falls back to LibSQL and shows a warning so you can fix the connection via /settings.
Observational memory (OM) uses background agents to maintain a dense log of observations and reflections about the conversation, providing long-term context that persists across sessions.
Control whether observations are scoped to individual threads or shared across all threads for a project:
| Scope | Behavior |
|---|---|
thread (default) | Observations are private to each conversation thread |
resource | Observations are shared across all threads for the same project |
Configure the scope through:
MASTRA_OM_SCOPE environment variable ("thread" or "resource").mastracode/database.json → omScope field~/.mastracode/database.json → omScope fieldThe observer and reflector models default to google/gemini-2.5-flash. Override them per-thread through the /settings panel or in the harness state.
| Threshold | Default | Description |
|---|---|---|
| Observation threshold | 30,000 tokens | Token count that triggers an observation pass |
| Reflection threshold | 40,000 tokens | Token count that triggers a reflection pass |
Mastra Code detects your terminal's color scheme and applies a matching dark or light theme. You can override the detected theme with the /theme slash command or the MASTRA_THEME environment variable.
MASTRA_THEME environment variable — explicit dark or light/theme command (stored in settings.json)COLORFGBG environment variable (set by some terminals like iTerm2 and Konsole)Use the /theme command to change the theme at runtime:
/theme light
/theme dark
/theme auto
Running /theme with no arguments shows the current theme. The choice is persisted across sessions.
| Variable | Description |
|---|---|
MASTRA_DB_URL | LibSQL database URL (e.g., libsql://... or file:./data.db) |
MASTRA_DB_AUTH_TOKEN | Auth token for remote LibSQL database |
MASTRA_DB_PATH | Override the local database file path |
MASTRA_USER_ID | Override the auto-detected user identity |
MASTRA_RESOURCE_ID | Override the auto-detected project resource ID |
MASTRA_OM_SCOPE | Observational memory scope (thread or resource) |
DEFAULT_OM_MODEL_ID | Default model for OM observer and reflector |
MASTRA_PLANS_DIR | Override the directory where approved plans are saved (default: app data directory) |
MASTRA_THEME | Color theme override (dark or light) |
TAVILY_API_KEY | Enable Tavily-powered web search and extract tools |
Resource IDs determine how threads are grouped. By default, Mastra Code generates one from the Git remote URL or filesystem path. Override it to share threads across repositories or isolate threads within a monorepo:
{
"resourceId": "my-custom-project-id"
}
You can also set MASTRA_RESOURCE_ID as an environment variable. Two users who set the same resource ID share threads and observations for that resource.