A subagent definition looks like a few lines of YAML. Most of the ways it goes wrong are silent: a misspelled field is ignored, a “read-only” agent can write files, a permission setting gets overridden by the parent. None of those produce an error.
This is the reference for the definition file. If you haven’t yet, Subagents explains what one is for.
Where definitions live
A definition is a Markdown file with YAML frontmatter (a block of key-value settings between two --- lines) followed by the agent’s instructions. It can live in:
.claude/agents/for the project.~/.claude/agents/for you, across projects.- The session-level
--agentscommand-line option, which takes JSON. - A plugin, which is a bundle of skills, hooks, and agents you install together.
Only name and description are required. The subagent documentation is the authority for the rest.
Fields
name: Must be unique. It can’t contain:or start with-. Project and user agent files must declare it; without it, Claude Code treats the file as adjacent documentation and skips registration. Only plugin agents fall back to the filename.description: Tells Claude when to delegate to this agent. You need it for automatic delegation, which means it works like a routing rule.tools: An allowlist, as a comma-separated string or a YAML list. ListingAgent(the tool that starts subagents) lets the agent delegate. WritingAgent(researcher, analyst)limits it to those agents, but only when the agent is running the whole session with--agent. In an ordinary subagent definition, the parenthesized list is ignored.disallowedTools: Removes tools from the inherited set. A name pattern likemcp__*(every tool an MCP server supplies) works. A pattern with a specifier, likeBash(git push *), removes the whole tool, not just that command. For command-level blocks, use a deny rule in your settings instead.permissionMode: How much the agent may do without asking.defaultasks before edits and commands.acceptEditsauto-approves file edits.planis read-only planning.autolets a classifier (a background model check) approve actions it judges safe.bypassPermissionsskips prompts entirely.dontAskauto-denies any call that would otherwise prompt. If you don’t set the field, the agent uses the session’s mode. Heads up: if the parent is inauto,acceptEdits, orbypassPermissions, the subagent runs in that mode and ignores its own setting. Aplanreviewer isn’t read-only underauto. See the permissions documentation for what each mode does.model:sonnet,opus,haiku,fable, a full model ID, orinheritto use the parent’s.effort: How hard the model thinks:low,medium,high,xhigh, ormax.maxTurns: Stops the agent after N agentic turns, where each agentic turn is one request to the model plus the tool calls it makes. Output is marked partial if it hits the cap.background:trueforces the agent to run in the background. With fork mode on, which is the interactive default, subagents normally run in the background. Where fork mode is off, including headless (claude -p) and SDK defaults, Claude usually runs them in the background but chooses foreground when it needs the result before continuing. Setbackground: truewhen a worker must stay in the background; see the scheduling rules.isolation:worktreeruns the agent in its own git worktree (an extra checkout of the same repository, in its own directory). By default it branches from your default branch, not your currentHEAD. Setworktree.baseRefto"head"in your Claude Code settings to branch from your current commit instead, or name the exact commit in the assignment and have the worker check it out first. (Worktrees in Practice covers this trap.)initialPrompt: Auto-submits the first message when the agent runs as the main session with--agent.skills: Skills to preload at startup. This preloads them. It doesn’t restrict which others the agent can reach.mcpServers: MCP server names or inline definitions scoped to this agent. (An MCP server is a program that adds tools to the harness over the Model Context Protocol.)hooks: Lifecycle hooks scoped to this agent.memory: Gives the agent a persistent memory directory. Set it touser,project, orlocal:userstores it under~/.claude/agent-memory/<agent-name>/.projectstores it under.claude/agent-memory/<agent-name>/, which can be committed to the repository.localstores it under.claude/agent-memory-local/<agent-name>/, which stays out of version control.
omitClaudeMd: On v2.1.271+, skips user, project, and localCLAUDE.mdinstructions for a spawned subagent. Managed policy still loads for ordinary definitions; managed definitions can omit it too. The field is ignored when the definition runs as the main session through--agentor theagentsetting. It is not a policy-free context switch; see the frontmatter reference.color: Terminal display color, such asred,blue,green,yellow,purple,orange,pink, orcyan.experimental.cacheTtl:5mor1h, the lifetime of this one agent’s prompt cache. ThesubagentPromptCacheTtlsetting does the same job session-wide for everything outside your main conversation. Per Claude Code’s prompt caching documentation, that setting is checked first, so it wins when both are set.
Gotchas
- Omitting
toolsinherits everything: The subagent gets whatever the parent has. To make a leaf worker that can’t delegate any further, listtoolsexplicitly and leaveAgentout. - Bash is the soft spot: A shell can write files, so a “read-only” agent with
Bashisn’t. Back it with a settings deny rule, aPreToolUsehook (a script that runs before a tool call), or the sandbox (operating-system-level isolation that limits what files and network the agent’s shell commands can reach, no matter what the model decides). - Model selection takes the first match: The model passed when spawning, then the definition’s
model, then theCLAUDE_CODE_SUBAGENT_MODELenvironment variable, then the parent’s model. Forks (subagents that start with a copy of your conversation) always run on the parent’s model. Check/tasks, the command that lists your session’s tasks and the model each subagent actually ran on. - Unknown fields fail silently: Write
max_turnsinstead ofmaxTurns, and it’s ignored without so much as a warning. - Plugin agents drop fields:
hooks,mcpServers,permissionMode, andinitialPromptall get dropped from agents that ship in a plugin. - Background by default: With fork mode enabled, as it is by default in interactive sessions, subagents run in the background. Where fork mode is off, foreground execution is available;
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1forces foreground execution. Some tools are unavailable in the background. In an interactive session, a permission request is shown in the main session with the requesting subagent identified, and the worker waits for your answer. In an unattended run, nobody may be present to answer; define how that run reports a blocked action instead of granting broader access to avoid the prompt. - Limits: 20 subagents running at once and three layers of nesting by default (a subagent starting subagents, which start more). Four children per agent across three layers is 4 + 16 + 64 = 84 workers. (Please don’t.)
Choosing a model per stage
Not every stage of a workflow needs the same model. What matters is the cost of a mistake at that stage:
| Stage | Examples | Cost of a mistake | Claude Code model | Codex-side equivalent |
|---|---|---|---|---|
| Mechanical | Listing files, extracting fields, grepping a known pattern | Low: checkable by hand in seconds | haiku | Luna |
| Discovery | “Find bugs in this module” | High and invisible: a miss never reaches verification | sonnet | Sol |
| Judging | Refuting a finding, scoring competing approaches | High: nothing checks the checker | opus | Sol |
| Synthesis | Merging findings, writing the final report | Highest: it’s the version someone acts on | opus | Sol |
For narrow but careful work, raise the effort field before moving to a bigger model. Compare cost per accepted result, not per run. Prompt Caching and Cost has the prices behind these names.
Claude Code versus Codex
The biggest difference is who decides to delegate.
Claude Code treats delegation as something the model does on its own. It reads each agent’s description, so descriptions work like routing rules, and you can also force a choice with an @-mention or --agent. In Claude Code, you tune the model’s judgment.
Codex delegates when you ask directly or when applicable AGENTS.md or skill instructions request it. You can name the agents and roster in the prompt, but also inspect those standing instructions: they can trigger parallel work without a new delegation request each turn. Codex runs the agents and gathers their results; every worker adds token usage and concurrency.
Next, Delegating Well covers how to write the assignment these definitions get handed.
Set tools, set model, and check /tasks. Don’t trust the defaults.