Agent Shipped

Guide · updated 2026-10-12 · 8 min read

Claude Code Subagents: A Practical Guide

Claude Code subagents are specialized assistants that run in their own context window, with their own system prompt, tools and permissions, and return only a summary to your main conversation. You define a custom one as a Markdown file with YAML frontmatter in .claude/agents/ (project) or ~/.claude/agents/ (personal), and Claude delegates to it when a task matches its description, or when you ask for it by name.

The main reason to use them is context. Every file Claude reads and every log it scans lands in your conversation and stays there. A subagent does that work somewhere else and hands back the part you need.

When a subagent is the right tool

The subagent docs put it plainly: use one "when a side task would flood your main conversation with search results, logs, or file contents you won't reference again." Define a custom one "when you keep spawning the same kind of worker with the same instructions."

Use a subagent when:

Stay in the main conversation when:

If what you want is a reusable prompt that runs in your current context, that's a skill, not a subagent.

The built-in subagents

You already use subagents even if you've never written one. Claude Code ships with:

Explore and Plan skip your CLAUDE.md files to stay fast and cheap. Every other built-in and custom subagent loads them unless you set omitClaudeMd: true.

A useful trick from the docs: a user or project subagent named Explore overrides the built-in and keeps its own model field, so you can define one with model: haiku to run exploration on a cheaper model.

Write your first subagent

The quickest path is to ask Claude to write it. The docs' example prompt:

Create a personal code-improver subagent in ~/.claude/agents/ that scans
files and suggests improvements for readability, performance, and best
practices. It should explain each issue, show the current code, and
provide an improved version. Make it read-only and have it use Sonnet.

Or write the file yourself. Here's a project-level reviewer at .claude/agents/code-reviewer.md:

---
name: code-reviewer
description: Reviews diffs for correctness, security and consistency with project patterns. Use after code changes, before committing.
tools: Read, Grep, Glob, Bash
model: sonnet
---

You are a senior reviewer for this repository. When invoked:

1. Run `git diff HEAD` to see the current changes.
2. For each changed file, check correctness, error handling, and whether it
   follows patterns used elsewhere in the codebase.
3. Report only issues that affect correctness, security, or the stated
   requirements. Skip style nits.

Format: a list of findings with file:line, the problem, and a suggested fix.
If you find nothing, say so in one line.

The body becomes the subagent's system prompt. Subagents get only this prompt plus basic environment details like the working directory, not the full Claude Code system prompt, so write it as a complete brief.

Claude Code watches both agent directories, so edits are picked up within a few seconds. The exception: if ~/.claude/agents/ or .claude/agents/ didn't exist when the session started, restart once after creating it.

The frontmatter fields that matter

Only name and description are required. The frontmatter reference lists many more; these are the ones I reach for most:

Field What it does
name Unique identifier. The filename doesn't need to match. No : allowed.
description When Claude should delegate. This is the trigger, so make it specific.
tools Allowlist, comma-separated or a YAML list. Omit to inherit everything available to subagents.
disallowedTools Denylist removed from the inherited or listed tools.
model sonnet, opus, haiku, fable, a full model ID, or inherit.
permissionMode default, acceptEdits, auto, dontAsk, bypassPermissions or plan.
skills Skills whose full content is preloaded into the subagent at startup.
mcpServers MCP servers for this subagent only, by name or inline definition.
hooks Hooks that run only while this subagent is active.
memory user, project or local for a persistent memory directory.
isolation worktree to work in a temporary git worktree.
maxTurns Cap on agentic turns before it stops.

Two warnings. Field names are case-sensitive camelCase, and Claude Code silently ignores a field it doesn't recognize. And a file with broken YAML, a missing name, or an opening --- that isn't on line one is skipped without a message in the session. Run claude --debug or claude plugin validate .claude/agents (v2.1.233 or later) to find out why one didn't load.

Keep descriptions short. When the combined descriptions of your custom subagents pass 15,000 tokens, Claude Code warns at startup, and they cost context in every session.

Restrict tools, two ways

An allowlist:

---
name: safe-researcher
description: Research agent with restricted capabilities
tools: Read, Grep, Glob, Bash
---

A denylist that keeps everything else, including MCP tools:

---
name: no-writes
description: Inherits the available tools except file writes
disallowedTools: Write, Edit
---

Both fields accept MCP patterns, so disallowedTools: mcp__github strips every tool from the github server. One subtlety: a disallowedTools entry like Bash(git push *) removes the whole Bash tool, not just that command. To block specific commands while keeping Bash, use a deny rule in permissions.deny in your settings.

For finer control, attach a PreToolUse hook in the subagent's frontmatter. The docs' example is a database reader that runs every Bash command through ./scripts/validate-readonly-query.sh, which exits with code 2 if the query contains INSERT, UPDATE, DELETE and the like. Our hooks examples guide covers how exit codes work.

Keep MCP servers out of your main context

This is one of the most underused features. Define a server inline in a subagent and only that subagent gets its tools; your main conversation never pays for the tool descriptions:

---
name: browser-tester
description: Tests features in a real browser using Playwright
mcpServers:
  - playwright:
      type: stdio
      command: npx
      args: ["-y", "@playwright/mcp@latest"]
  - github
---

Use the Playwright tools to navigate, screenshot, and interact with pages.

The string entry github reuses a server you've already configured. Inline servers in a project's .claude/agents/ only load after you've trusted that folder.

Invoking subagents

Three levels, from suggestion to guarantee:

  1. Natural language: "Use the code-reviewer subagent to check my changes." Claude decides.
  2. @-mention: type @ and pick it, or write @agent-code-reviewer. That subagent runs for that task.
  3. Whole session: claude --agent code-reviewer makes the main thread take on that agent's system prompt, tools and model. Set "agent": "code-reviewer" in .claude/settings.json to make it the project default.

In an interactive session, Claude Code runs the subagents Claude spawns in the background by default, so you can keep working. Background subagents get a smaller built-in tool set. Run /tasks to see what's running and which model each one is on.

Patterns worth stealing

Isolate noisy work. "Use a subagent to run the test suite and report only the failing tests with their error messages." The full output stays in the subagent.

Parallel research. "Research the authentication, database, and API modules in parallel using separate subagents." Works best when the paths are independent. Each subagent's result lands back in your context, so many verbose reports can still fill it.

Chain them. "Use the code-reviewer subagent to find performance issues, then use the optimizer subagent to fix them."

Adversarial review. The best practices page recommends having a fresh subagent review the diff against your plan before you call a task done, because it sees only the diff and the criteria, not the reasoning that produced them. Tell it to flag only gaps that affect correctness or requirements, or you'll chase findings forever.

Memory for reviewers. Add memory: project and the subagent gets a directory at .claude/agent-memory/<name>/ that persists across sessions. Put a line in its prompt telling it to record patterns and recurring issues it finds.

Cost and limits

Subagents send their own requests, which count toward the same usage limits as your main conversation. To control spend, set model: haiku or sonnet on routine agents. To force one model onto every subagent, set both CLAUDE_CODE_SUBAGENT_MODEL and CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1 in the env block of your settings.

By default a subagent can spawn its own subagents up to three layers deep (CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH), and 20 can run at once before spawning fails with Concurrent subagent limit reached (CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS). To stop Claude using a particular one, add "Agent(Explore)" or "Agent(my-agent)" to permissions.deny.

Bottom line

Start with one subagent: a read-only reviewer with a tight description and model: sonnet. Use the built-in Explore subagent for search by just asking Claude to "use a subagent to investigate X." Add more only when you notice yourself pasting the same instructions into delegation prompts. Keep descriptions short, restrict tools by default, and remember that a subagent's result still lands in your context, so ask for summaries, not transcripts. For how this fits with CLAUDE.md, hooks and skills, see Claude Code best practices.

Subscribe to Agent Shipped for tested subagent setups and other agent workflows, twice a week.

FAQ

What is a subagent in Claude Code?

A subagent is a specialized assistant that runs in its own context window with its own system prompt, tool access and permissions. Claude delegates a task to it and gets back only a summary, which keeps search results and logs out of your main conversation.

Where do I put custom subagent files?

Project subagents go in .claude/agents/ and can be committed to git. Personal subagents that work in every project go in ~/.claude/agents/. Each one is a Markdown file with YAML frontmatter that needs at least name and description.

Do subagents cost extra?

Subagents send their own requests, and those count toward the same usage limits as your main conversation. You can lower the cost by setting model to haiku or sonnet for routine work.

Can a subagent spawn other subagents?

Yes. By default a subagent can spawn its own, up to three layers below the main conversation. Change the limit with CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH, or set it to 1 to turn nesting off.

Get the field guide

Join builders who use coding agents every day. Free, twice a week, unsubscribe in one click.

No spam. You get the CLAUDE.md starter pack in your welcome email.

Keep reading