One Prompt, A Tree of Agents

A close read of subagents — isolated Claude instances the main conversation spawns for focused work, and everything that governs what they see, what they can touch, and what comes back.

Parent  delegates and waits (or doesn't) Subagent  starts fresh, returns a summary 13 sections
01Why it exists

Four Reasons to Delegate

A subagent isn't a shortcut for calling a tool — it's a separate agent instance, and that separation is the entire point.

isolation

Context stays clean

A subagent can read dozens of files; only its final message reaches the parent, not every file it opened.

parallelization

Time of the slowest, not the sum

Style, security, and coverage checks run at once instead of one after another.

specialization

A tailored system prompt

Domain expertise — SQL migration rules, security checklists — lives in the subagent, not cluttering the main prompt.

restriction

A narrower blast radius

A doc reviewer given only Read and Grep literally cannot edit a file, by omission — not by asking politely.

02Isolation, precisely

What Crosses the Boundary

Unless it's a fork, a subagent's context starts fresh — but "fresh" isn't "empty." Here's exactly what it does and doesn't get.

 ReceivesDoes not receive
PromptIts own system prompt + the Agent tool's task stringThe parent's system prompt
HistoryThe parent's conversation history or tool results
Project contextCLAUDE.md hierarchy (Explore/Plan skip this)
SkillsOnly what's listed in its skills fieldAny skill content already loaded in the parent
ToolsParent's set, or the subset in toolsAnything omitted — no prompt, no error, just absent
The only thing you actively pass from parent to subagent is the Agent tool's prompt string. Put every file path, error message, and decision the subagent needs directly in it — nothing else carries over.
03Definition

A File, or a Line of Code

Filesystem-based at .claude/agents/<name>.md, or defined inline via the SDK's agents option — same shape either way.

.claude/agents/code-reviewer.md
---
name: code-reviewer
description: Security and quality
  review specialist.
tools: Read, Grep, Glob
model: sonnet
---

You are a code review specialist.
Identify security issues, check
performance, verify standards.
AgentDefinition (SDK)
AgentDefinition(
  description="Expert code review...",
  prompt="You are a code review...",
  tools=["Read", "Grep", "Glob"],
  model="sonnet",
)
# a programmatic agent overrides
# a filesystem one with the same name
Only name/description (filesystem) or description/prompt (SDK) are required. Everything else — tools, model, skills, permissionMode, maxTurns, background, effort — narrows the default.
04Batteries included

Three Built-Ins, No Setup

Before writing a single custom agent, three types are already available.

Explore

Read-only search

Skips CLAUDE.md and git status to stay fast. Write and Edit are denied outright. One-shot — no agentId, can't be resumed.

Plan

Research for plan mode

Same read-only tool set and the same CLAUDE.md/git-status skip as Explore. Also one-shot.

general-purpose

Exploration + action

Every subagent tool available. Loads the full CLAUDE.md hierarchy and a git status snapshot. Resumable via its agentId.

Claude can spawn general-purpose without you defining anything — it's the fallback when the Agent tool is called with no subagent_type.
05Invocation

Matched, or Named Outright

Claude reads a subagent's description the same way it reads a skill's — as the entire basis for an autonomous decision.

Automatic match description fits the task Explicit mention "use the code-reviewer agent" Agent tool call subagent_type + prompt runs, isolated
Explicit mention bypasses matching entirely and guarantees which agent runs. Either way, Agent needs to be in allowedTools for it to auto-approve — otherwise it falls through to your permission callback.
06Execution mode

Blocking, or Not

Since v2.1.198, omitting the mode defaults to background — the reverse of earlier behavior.

 ForegroundBackground
Main conversationBlocks until the subagent finishesContinues immediately; result lands as a later notification
Permission promptsPassed straight through to youSurface in the main session, naming the requesting subagent
Built-in tool setSame as the main sessionA fixed, reduced list — MCP tools are unaffected
Set background: true on a subagent definition to force it regardless of what Claude requests. And a real fix worth knowing: before v2.1.211, a background subagent's permission-requiring call was auto-denied; from v2.1.211 on, you actually see the prompt and can approve it.
07Scoping

Absence, Not Denial

A tool left out of tools isn't refused with a prompt or an error — it simply isn't in the subagent's session at all.

Read-only analysis

Read, Grep, Glob

Can examine code but structurally cannot modify or execute anything.

Test execution

Bash, Read, Grep

Can run commands and parse their output, nothing more.

Omit tools entirely for full access to every tool available to subagents. disallowedTools works the other direction — and accepts MCP server-level patterns: mcp__server, mcp__server__*, or mcp__* for every MCP tool from any server.
08Skills, revisited

Loaded Upfront, Not Discovered

A subagent's skills field injects full skill content at startup — the opposite of the main session's on-demand matching.

Main session

Dynamic discovery

Every skill's description sits in context; Claude decides at runtime whether one matches, then loads its body.

Subagent with skills: [...]

Preloaded at startup

Listed skills' full bodies are already there when the subagent's first turn begins — unlisted skills stay reachable through the Skill tool.

This is the other half of what the Skills deck's context: fork showed: a skill can hand its content to a subagent as its task, and a subagent can hand skill content to itself as startup context. Two directions, same two building blocks.
09Boundaries

Depth, Concurrency, Spend

A subagent can spawn subagents of its own — one prompt really can grow into a tree. Three caps keep that tree bounded.

depth

CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH

Default 3 layers below the main agent. At the limit, the bottom subagent just does the work itself instead of delegating further.

concurrency

CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS

Default 20 running at once. Past it: "Concurrent subagent limit reached" — ultracode sessions are exempt.

spend

maxBudgetUsd / max_budget_usd

No default limit. At the cap: no new subagents, running background ones stop, query ends with error_max_budget_usd.

Claude Opus 5 delegates to subagents more readily than earlier models — these three caps matter most on Opus-5-driven queries.
10Continuity

Picking a Subagent Back Up

A resumed subagent keeps its full history — every prior tool call, result, and reasoning step, not just its final summary.

First query() call capture session_id +agentId from the result … later … second query(), resume: session_id,prompt references the agentId continues with full prior context
Only general-purpose or a custom agent returns an agentId — Explore and Plan are one-shot by design and can't be resumed this way. Also: hitting maxTurns marks the output partial, which is exactly the signal that tells you a resume is worth doing.
11Security

What Comes Back Isn't Fully Trusted

A subagent's final message could contain text engineered to look like a system instruction. Since v2.1.210, Claude Code neutralizes that before the parent ever reads it.

control-tag imitation

A fake <system-reminder>

A backslash goes in right after the opening angle bracket. Nothing is deleted.

turn markers

A line starting Human:

Gets a backslash before the colon, so it can't fake a conversation-turn boundary.

permission mentions

References to real config

settings.json, bypassPermissions — kept as written, not touched.

For the first two categories, Claude Code prepends a [harness: ...] marker line naming what it caught. This is escaping, not editing — the scan never removes or rewords the subagent's actual text, it just strips the ability to impersonate the harness.
12The model

Fresh Context, One Summary Back

Parent delegates a task, keeps its own context clean Subagent starts fresh, does the work, returns one message

Everything here — frontmatter, built-in types, foreground vs. background, depth and spend caps, output scanning — exists to make that one exchange safe to repeat at scale: a parent that stays lean, and a subagent whose mess never leaves the room it made it in.

01 / 13
use ← → or click the edges to navigate