Claude Code subagents tutorial: build and restrict one
Claude Code subagents tutorial: create a custom subagent, choose project or user scope, restrict its tools, and invoke it by name, @-mention or --agent.
A subagent is a specialized assistant that Claude Code delegates to, with its own context window, system prompt and tool access. This Claude Code subagents tutorial builds one from the official quickstart, then covers scope, frontmatter, tool restriction and invocation. Everything below was checked against the Create custom subagents page on 2026-10-10; fields and defaults change between releases, so confirm against the current page.
What a subagent is and when it beats the main conversation
Per the subagents docs, each subagent works in its own context window with a custom system prompt and its own tool access and permissions, and returns only a summary to the main conversation. Use one when a side task would flood your main conversation with output you will not reference again.
Stay in the main conversation when:
- you need frequent back-and-forth;
- several phases share a lot of context;
- the change is small and targeted;
- latency matters.
If you want a reusable workflow that runs in the main context, the docs point to a Claude Code skill instead (see Extend Claude with skills). Anthropic’s guide How and when to use subagents in Claude Code covers the delegate-or-not decision in more depth.
Built-in subagents you already have
Claude Code ships built-in subagents, including Explore (read-only, for searching and analyzing code), Plan and general-purpose, per the docs. Explore and Plan skip CLAUDE.md and the git status snapshot; the other built-ins load them. Check the docs for the full list before relying on a specific built-in.
Step 1: create your first subagent
The quickstart asks Claude to create a personal subagent in ~/.claude/agents/. The resulting file looks like this (copied from the docs):
---
name: code-improver
description: Scans files and suggests improvements for readability, performance, and best practices. Use after writing or modifying code.
tools: Read, Grep, Glob
model: sonnet
---
You are a code improvement specialist. For each issue you find, explain
the problem, show the current code, and provide an improved version.
Test it with a plain request:
Use the code-improver agent to suggest improvements in this project
The delegation shows up as code-improver(Suggest code improvements). The docs say the /agents view reminds you that you can also edit the agent folders directly. If a new subagent is not found, restart the session, but the docs say this applies only when ~/.claude/agents/ did not exist before the session started. Added or edited files are otherwise picked up within seconds, with an exception for directories added through --add-dir.
Where subagent files live
| Location | Scope | Commit it? |
|---|---|---|
.claude/agents/ |
Current project | Yes, to share with the team |
~/.claude/agents/ |
All your projects | No, personal |
Per the docs, when two subagents share a name, the higher-priority location wins; the project folder ranks above the user folder. Managed settings and the --agents flag also define subagents, so check the full priority table in the docs before relying on an override. Subagent folders are scanned recursively, identity comes only from the name field, and names must be unique. Subagents shipped by plugins ignore the hooks, mcpServers and permissionMode fields.
Frontmatter fields that matter
Only name and description are required. Claude decides when to delegate mostly from description, so write it as a trigger: what the agent does and when to use it. Adding “use proactively” encourages delegation.
| Field | What it does |
|---|---|
name |
Unique identifier. |
description |
When Claude should delegate to this subagent. |
tools |
Allowlist, as a list or comma-separated string. Omitted means all tools are inherited. |
disallowedTools |
Denylist of tools to remove. |
model |
sonnet, opus, haiku, fable, a full model ID, or inherit. |
permissionMode |
default, acceptEdits, auto, dontAsk, bypassPermissions, plan; manual is an alias for default. |
The docs list further fields (maxTurns, skills, mcpServers, hooks, memory, effort, background, omitClaudeMd, isolation). Unknown fields are ignored without an error, so a typo in a camelCase name fails silently. The Markdown body is the system prompt. The subagent receives that prompt plus environment details such as the working directory, not the full Claude Code system prompt. For the hooks field and subagent lifecycle events, see the hooks reference and our Claude Code hooks examples.
Restrict what a subagent can do
Two documented approaches, both from the subagents docs:
tools: Read, Grep, Glob, Bash
disallowedTools: Write, Edit
The first is an allowlist: the subagent gets only those tools. The second removes specific tools from what it would otherwise inherit. To limit which subagents a main agent can launch, the docs use the form tools: Agent(worker, researcher), Read, Bash.
Here is a read-only reviewer modeled on the docs’ code-reviewer example, which uses tools: Read, Grep, Glob, Bash and model: inherit. The prompt body is our own shortened version, not the official one:
---
name: code-reviewer
description: Reviews code for bugs and maintainability. Use proactively after writing or modifying code.
tools: Read, Grep, Glob, Bash
model: inherit
---
You are a code reviewer. Run `git diff` to see recent changes, review only
those files, and report issues grouped by severity with the file and line.
Do not edit files.
Note that Bash is still a way to change files, so a reviewer that must never write should drop it, or you should enforce limits with permissions rather than prompt wording. That last point is our inference, not a documented guarantee.
Invoke a subagent
The docs describe three ways:
- Natural language: “Use the test-runner subagent to fix failing tests”. Claude may or may not delegate.
- @-mention:
@"code-reviewer (agent)" look at the auth changesguarantees that agent runs. - Whole session:
claude --agent code-reviewerruns the session as that agent.
Common patterns
- Isolate high-volume output. “Use a subagent to run the test suite and report only the failing tests with their error messages” keeps logs out of your main context.
- Parallel research. Ask for independent investigations at once and receive summaries.
- Chaining. Feed one subagent’s summary into the next step.
Pitfalls
- Description budget. Past 15,000 cumulative tokens of descriptions (built-ins excluded), Claude Code warns at startup, though everything is still loaded. Keep descriptions short.
- Plugin limits. Plugin subagents ignore
hooks,mcpServersandpermissionMode. - New agents directory. Restart only if
~/.claude/agents/did not exist when the session began. - Context and token use. The docs warn that many subagents returning results consume main context, and each one spends its own tokens.
- Silent typos. Unknown frontmatter fields are ignored, so check names such as
disallowedToolsexactly.
What to change in your setup
Items 1 to 4 follow the docs; item 5 is our inference.
- Move recurring noisy tasks (test runs, log digging, codebase search) into a subagent with a narrow
description. - Commit shared subagents to
.claude/agents/and keep personal ones in~/.claude/agents/. - Set
toolsexplicitly on every subagent instead of inheriting everything. - Add
@"name (agent)"to your workflow when you need a specific agent, not a guess. - Audit your combined descriptions and drop the ones you never trigger, since each one is loaded at startup.
FAQ
- Where do Claude Code subagents live?
- In Markdown files with YAML frontmatter. `.claude/agents/` holds project subagents you can commit, and `~/.claude/agents/` holds your personal ones. Higher-priority locations exist, so check the scope table in the [subagents docs](https://code.claude.com/docs/en/sub-agents).
- Which frontmatter fields are required for a Claude Code subagent?
- Only `name` and `description`. Everything else, such as `tools`, `model` or `permissionMode`, is optional, and an omitted `tools` field means the subagent inherits all tools ([docs](https://code.claude.com/docs/en/sub-agents)).
- How do I make a Claude Code subagent read-only?
- Use an allowlist such as `tools: Read, Grep, Glob`, or a denylist such as `disallowedTools: Write, Edit`. Both are documented in the [subagents docs](https://code.claude.com/docs/en/sub-agents).
- How do I force Claude Code to use a specific subagent?
- @-mention it, for example `@"code-reviewer (agent)" look at the auth changes`, or start the whole session with `claude --agent code-reviewer` ([docs](https://code.claude.com/docs/en/sub-agents)).