--- title: "Custom Subagents in Claude Code" aliases: [subagents, claude-code-subagents, custom-agents] tags: [claude-code, subagents, multi-agent, context-management, automation] sources: [raw/Create custom subagents.md] created: 2026-04-17 updated: 2026-04-17 --- # Custom Subagents in Claude Code Subagents are specialized AI assistants that run in their **own context window** with a custom system prompt, specific tool access, and independent permissions. Claude automatically delegates tasks to them based on description matching, or you can invoke them explicitly. **Primary use case:** isolate side tasks (search, test runs, log parsing) that would flood the main conversation with output you won't reference again — the subagent returns only the summary. See also: [[wiki/claude-code/overview|Claude Code Overview]], [[wiki/agent-sdk/configure-permissions|Permissions Guide]], [[wiki/claude-code/mcp-integration|MCP Integration]] --- ## Built-in Subagents | Name | Model | Tools | Purpose | |------|-------|-------|---------| | **Explore** | Haiku | Read-only | Codebase search and analysis | | **Plan** | inherit | Read-only | Architecture and implementation planning | | **General-purpose** | inherit | All | Catch-all delegation | Explore takes a thoroughness hint: `quick`, `medium`, or `very thorough`. --- ## Creating Subagents ### Via `/agents` command (recommended) Opens a tabbed UI: **Running** tab (live subagents) + **Library** tab (create/edit/delete). Loads the subagent immediately without restarting. ### Via markdown file ```markdown --- name: code-reviewer description: Reviews code for quality and best practices tools: Read, Glob, Grep model: sonnet --- You are a code reviewer. Analyze code and provide specific, actionable feedback. ``` Save to: - `.claude/agents/` — project scope (check into git for team sharing) - `~/.claude/agents/` — user scope (all projects) Manually added files require a session restart or `/agents` reload. ### Via CLI flag (session-only) ```shell claude --agents '{ "code-reviewer": { "description": "Expert code reviewer. Use proactively after code changes.", "prompt": "You are a senior code reviewer...", "tools": ["Read", "Grep", "Glob", "Bash"], "model": "sonnet" } }' ``` --- ## Frontmatter Fields | Field | Required | Notes | |-------|----------|-------| | `name` | Yes | Lowercase with hyphens | | `description` | Yes | Used by Claude to decide when to delegate | | `tools` | No | Allowlist; inherits all if omitted | | `disallowedTools` | No | Denylist applied before `tools` allowlist | | `model` | No | `sonnet`, `opus`, `haiku`, full model ID, or `inherit` (default) | | `permissionMode` | No | `default`, `acceptEdits`, `auto`, `dontAsk`, `bypassPermissions`, `plan` | | `maxTurns` | No | Cap agentic turns | | `skills` | No | Inject skill content at startup (not inherited from parent) | | `mcpServers` | No | Inline or named server references | | `hooks` | No | Lifecycle hooks scoped to this subagent | | `memory` | No | `user`, `project`, or `local` — persistent cross-session memory | | `background` | No | `true` to always run as background task | | `isolation` | No | `worktree` — isolated git copy, auto-cleaned if no changes | | `effort` | No | `low`, `medium`, `high`, `xhigh`, `max` | | `color` | No | `red`, `blue`, `green`, `yellow`, `purple`, `orange`, `pink`, `cyan` | | `initialPrompt` | No | Auto-submitted first turn when used as main session agent | --- ## Scope & Priority | Location | Scope | Priority | |----------|-------|----------| | Managed settings | Organization | 1 (highest) | | `--agents` CLI flag | Current session | 2 | | `.claude/agents/` | Current project | 3 | | `~/.claude/agents/` | All user projects | 4 | | Plugin `agents/` dir | Where plugin enabled | 5 (lowest) | When names collide, higher priority wins. Plugin subagents **cannot** use `hooks`, `mcpServers`, or `permissionMode`. --- ## Model Selection Resolution order for a subagent's model: 1. `CLAUDE_CODE_SUBAGENT_MODEL` env var 2. Per-invocation `model` parameter 3. Subagent frontmatter `model` 4. Main conversation model --- ## Tool Control **Allowlist** (`tools`): only these tools are available. **Denylist** (`disallowedTools`): inherit all except these. **Both**: denylist applied first, then allowlist from the remainder. To restrict which subagent types can be spawned (when running as main thread via `--agent`): ```yaml tools: Agent(worker, researcher), Read, Bash ``` Omit `Agent` entirely to prevent spawning any subagent. --- ## Persistent Memory ```yaml memory: project # or user / local ``` | Scope | Location | Use when | |-------|----------|----------| | `user` | `~/.claude/agent-memory//` | Cross-project learnings | | `project` | `.claude/agent-memory//` | Project-specific, shareable via git | | `local` | `.claude/agent-memory-local//` | Project-specific, not in git | When enabled, the subagent gets Read/Write/Edit tools automatically and its system prompt includes first 200 lines of `MEMORY.md`. --- ## Hooks in Subagents ### Frontmatter hooks (subagent-scoped) Fire only while that subagent is active. **Do not fire** when running as main session via `--agent`. ```yaml hooks: PreToolUse: - matcher: "Bash" hooks: - type: command command: "./scripts/validate-command.sh" PostToolUse: - matcher: "Edit|Write" hooks: - type: command command: "./scripts/run-linter.sh" ``` `Stop` hooks in frontmatter are converted to `SubagentStop` at runtime. ### Session-level hooks (settings.json) ```json { "hooks": { "SubagentStart": [{ "matcher": "db-agent", "hooks": [...] }], "SubagentStop": [{ "hooks": [...] }] } } ``` --- ## Invoking Subagents | Method | Effect | |--------|--------| | Natural language ("use the X subagent") | Claude decides whether to delegate | | `@"subagent-name (agent)"` | Guarantees that subagent runs | | `claude --agent code-reviewer` | Whole session uses that subagent's prompt + tools | | `agent` key in `.claude/settings.json` | Default for every session in the project | --- ## Foreground vs Background - **Foreground**: blocks main conversation; permission prompts pass through - **Background**: concurrent; permissions approved upfront; `AskUserQuestion` fails silently - Press **Ctrl+B** to background a running task - Disable all background tasks: `CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1` --- ## Common Patterns ### Isolate high-volume operations ```text Use a subagent to run the test suite and report only failing tests with error messages ``` ### Parallel research ```text Research the auth, database, and API modules in parallel using separate subagents ``` ### Chain subagents ```text Use code-reviewer to find performance issues, then use optimizer to fix them ``` --- ## When NOT to Use a Subagent - Task needs frequent back-and-forth or iterative refinement → main conversation - Quick targeted change → main conversation - Latency matters → main conversation (subagents start fresh) - Reusable prompt/workflow in main context → [[wiki/agent-sdk/skills-in-sdk|Skills]] - Nested delegation needed → Skills or chain from main conversation - Quick question already in context → `/btw` command (no tools, answer discarded) **Note:** Subagents cannot spawn other subagents. --- ## Example Subagents ### Code Reviewer (read-only) ```markdown --- name: code-reviewer description: Expert code review specialist. Proactively reviews code for quality, security, and maintainability. Use immediately after writing or modifying code. tools: Read, Grep, Glob, Bash model: inherit --- You are a senior code reviewer... ``` ### Debugger (read + write) ```markdown --- name: debugger description: Debugging specialist for errors, test failures, and unexpected behavior. Use proactively when encountering any issues. tools: Read, Edit, Bash, Grep, Glob --- ``` ### DB Query Validator (hook-gated Bash) ```markdown --- name: db-reader description: Execute read-only database queries. tools: Bash hooks: PreToolUse: - matcher: "Bash" hooks: - type: command command: "./scripts/validate-readonly-query.sh" --- ``` Exit code 2 from the hook blocks the command and returns the error to Claude. --- ## Disabling Subagents ```json { "permissions": { "deny": ["Agent(Explore)", "Agent(my-custom-agent)"] } } ``` Or via CLI: `claude --disallowedTools "Agent(Explore)"` --- ## Key Takeaways - Subagents run in **isolated context windows** — verbose output never pollutes your main conversation - Define them as `.md` files in `.claude/agents/` (project) or `~/.claude/agents/` (user) - The `description` field is the routing key — write it clearly so Claude knows when to delegate - Use `tools` or `disallowedTools` to enforce least-privilege access - `model: haiku` for fast/cheap research tasks; `model: opus` for deep analysis - `memory: project` enables cross-session learning stored alongside the codebase - `isolation: worktree` gives the subagent a throwaway git clone — safe for risky operations - Subagents **cannot** spawn other subagents; use Skills or chain from main conversation - Background subagents run concurrently; permissions must be approved upfront --- ## Sources - [Create custom subagents — Claude Code docs](https://code.claude.com/docs/en/sub-agents)