Build Custom Claude Code Subagents: Memory, Tools, Models
Why custom subagents change how you work with Claude Code
Long Claude Code sessions degrade in two ways. The context window fills with search results, file contents, and dead-end explorations that you will never reference again. And the assistant accumulates instructions that conflict, drift, or override each other across unrelated tasks. By hour three of a serious refactor, you are spending more time re-anchoring Claude than getting work done.
Custom subagents fix both problems with one mechanism. A subagent is a specialised Claude worker that runs in its own context window, with its own system prompt, its own tool restrictions, and optionally its own persistent memory across sessions. When you delegate a task to a subagent, it does the work in isolation and returns only the summary. Your main thread stays focused on the high-level intent. The subagent does not pollute your context with search dumps or exploration logs.
This guide is the reference you need to build subagents that hold their shape over time. It covers the full frontmatter field set, every memory scope option, the rules around tool access, model overrides, and the patterns that actually produce useful specialists. For a wider look at how parallel subagent execution works in Claude Code, see Claude Code subagents and multi-agent workflows. If you are setting up Claude Code for the first time, the Claude Code setup guide is a better starting point.
What a custom subagent actually is
A custom subagent in Claude Code is a markdown file with YAML frontmatter, stored at .claude/agents/<name>.md (project scope) or ~/.claude/agents/<name>.md (user scope). The frontmatter declares the agent's metadata and configuration. The markdown body below the frontmatter becomes the agent's system prompt.
When Claude invokes the subagent, three things happen. A fresh context window is allocated. The agent's system prompt is loaded (the markdown body, not the main session's prompt). And the agent runs against whatever task was delegated to it, with access only to the tools its configuration permits.
The subagent's transcript is independent of the main session. The main thread sees only the final result the subagent returns, not the intermediate work. This is the core context-management property: the subagent does the heavy lifting in its own window and your main session stays clean.
Built-in subagents you already have
Claude Code ships with three built-in subagents that Claude delegates to automatically when appropriate. You do not configure these. They exist and route correctly out of the box.
Explore is a fast, read-only agent that uses Haiku for low-latency codebase search. It has access to read-only tools (no Write or Edit). Claude delegates to Explore when it needs to find files, search for patterns, or analyse code without making changes. Explore accepts a thoroughness level: quick for targeted lookups, medium for balanced exploration, or very thorough for comprehensive analysis.
Plan runs during plan mode to gather context before presenting a plan. It inherits the main conversation's model and is also restricted to read-only tools. Plan exists because subagents cannot spawn other subagents, so this is the dedicated research path during planning.
General-purpose handles complex, multi-step tasks that need both exploration and modification. It inherits the main conversation's model and has access to all tools. Claude delegates to general-purpose when the task requires more than a single specialist can handle: complex reasoning across multiple sources, multi-step operations with file changes, or research that produces code.
You will rarely invoke these directly. Claude routes to them automatically based on what the current task demands. The reason to understand them is so that when you create custom subagents, you do not duplicate work the built-ins already cover.
Quickstart: your first custom subagent
The fastest way to create a custom subagent is the /agents command inside Claude Code. It opens a tabbed interface for managing subagents, including a guided creation flow that lets Claude generate the agent definition for you.
Run /agents in a Claude Code session. Choose the Library tab and select Create new agent. Pick a scope: Personal saves to ~/.claude/agents/ so the agent is available across every project on your machine. Project saves to .claude/agents/ in the current project, which means it can be committed to version control and shared with your team.
Choose Generate with Claude and describe what the agent should do. A description like "A code reviewer that scans for readability and best-practice issues, explains each one, and provides an improved version" produces a working agent with a sensible identifier, description, and system prompt.
Select tools. For a read-only reviewer, you want Read-only tools (Read, Grep, Glob). Leaving every tool selected means the agent inherits all tools from the main conversation, which defeats the point of a constrained specialist.
Pick a model. Sonnet is the default and balances capability and speed. Haiku is cheaper and works well for mechanical tasks (linting, lookup, simple analysis). Opus is for agents that need complex reasoning. Pick the smallest model that produces good output for your specific task.
Configure memory. If you set the memory scope, the subagent gets a persistent directory where it can accumulate learnings across sessions. Project memory lives at .claude/agent-memory/<name>/ and can be committed. User memory lives at ~/.claude/agent-memory/<name>/ and follows you across every project. Local memory lives at .claude/agent-memory-local/<name>/ and is project-specific but not version-controlled.
Save the agent. It is available immediately. Invoke it by name: "Use the code-reviewer agent to suggest improvements in src/auth.ts".
Writing subagent files directly
The /agents interface is fast, but for repeatable, version-controlled, shareable agent definitions you write the markdown files directly. Drop a file at .claude/agents/<name>.md:
---
name: code-reviewer
description: Reviews code for quality and best practices. Use after any code change.
tools: Read, Grep, Glob
model: sonnet
memory: project
---
You are a code reviewer with one job: surface concrete, actionable improvements.
When invoked, read the relevant files and return findings in this format:
1. Each issue: file path and line number
2. The problem: tone, clarity, performance, security
3. The current code, quoted
4. An improved version with explanation
Do not edit files directly. Return findings only.
Update your memory with patterns you find repeatedly, such as naming
conventions, framework idioms, or recurring anti-patterns. That knowledge
should compound across sessions.
The frontmatter declares metadata. The markdown body is the system prompt. Subagents receive only this system prompt, not the full Claude Code system prompt, so the prompt must contain everything the agent needs to behave correctly.
One important gotcha: file-based subagents are loaded at session start. If you edit a subagent file directly on disk, you must restart Claude Code for the changes to take effect. Agents created or edited through the /agents interface take effect immediately with no restart needed.
The full frontmatter reference
Every YAML frontmatter field Claude Code supports for custom subagents:
| Field | Required | What it does |
|---|---|---|
name |
Yes | Unique identifier, lowercase with hyphens. The filename does not have to match. |
description |
Yes | When Claude should delegate to this agent. Written as a trigger condition, not a job title. |
tools |
No | Allowlist of tools the agent can use. Inherits all if omitted. |
disallowedTools |
No | Denylist of tools removed from the inherited or specified list. |
model |
No | sonnet, opus, haiku, a full model ID, or inherit. Defaults to inherit. |
permissionMode |
No | default, acceptEdits, auto, dontAsk, bypassPermissions, or plan. |
maxTurns |
No | Maximum agentic turns before the subagent stops. |
skills |
No | Skills to preload into the agent's context at startup. |
mcpServers |
No | MCP servers available to the agent. |
hooks |
No | Lifecycle hooks scoped to this subagent. |
memory |
No | Persistent memory scope: user, project, or local. |
background |
No | Set true to always run as a background task. |
effort |
No | Effort level: low, medium, high, xhigh, max. |
isolation |
No | Set to worktree to give the agent a temporary git worktree. |
color |
No | Display color in the task list. |
initialPrompt |
No | Auto-submitted as the first user turn when running as the main session agent. |
Only name and description are required. Everything else is optional with sensible defaults. The description field is load-bearing because Claude reads it to decide when to delegate. Write it as a trigger condition ("Reviews code for quality and security. Use after any code change.") rather than a role label ("Reviews code.").
How memory scopes work
When the memory field is set, the subagent gets a persistent directory it reads at the start of every session and writes to during work. This is where cross-session learning lives.
| Scope | Directory | Use case |
|---|---|---|
user |
~/.claude/agent-memory/<name>/ |
Agent should remember learnings across every project on your machine |
project |
.claude/agent-memory/<name>/ |
Agent's knowledge is project-specific and you want it in version control |
local |
.claude/agent-memory-local/<name>/ |
Agent's knowledge is project-specific but you do not want it committed |
When memory is enabled, three things change automatically. The first 200 lines or 25KB of MEMORY.md (whichever comes first) is injected into the agent's system prompt at session start. The agent's system prompt is augmented with instructions for reading and writing to its memory directory. And Read, Write, and Edit tools are automatically enabled so the agent can manage its memory files, regardless of what the tools allowlist says.
That last point is important. If you set tools: Read, Grep, Glob and memory: project on the same agent, the agent can still call Write and Edit (it needs them to update MEMORY.md). The allowlist constrains the agent at the conceptual level (the system prompt tells it to return findings, not rewrite files) but the tools themselves are present.
For a hard sandbox where the agent physically cannot write to source files, leave memory unset. Or use permissionMode: dontAsk combined with a tools allowlist that excludes Write and Edit, knowing memory-management tools will not be available either.
Tool access: allowlist vs denylist
Two ways to control what tools a custom subagent can call.
The tools field is an allowlist. The agent can use only the listed tools (plus the Read/Write/Edit auto-enabled if memory is set). Anything not listed is unavailable. This is the strict mode.
---
name: safe-researcher
description: Research agent with strictly read-only access
tools: Read, Grep, Glob, Bash
---
The disallowedTools field is a denylist. The agent inherits every tool from the main conversation except the listed tools. Use this when you want to remove a specific capability without rewriting the whole allowlist.
---
name: no-writes
description: Inherits every tool except file writes
disallowedTools: Write, Edit
---
If both are set, disallowedTools is applied first, then tools is resolved against the remaining pool. A tool listed in both is removed.
Picking a model
The model field controls which model the subagent uses. Three flavours:
A model alias: sonnet, opus, haiku. These resolve to the current default model in each family.
A full model ID: claude-opus-4-7, claude-sonnet-4-6, and so on. Use this when you need a specific model version pinned, not just the latest in the family.
The string inherit: the agent uses the same model as the main conversation. This is the default if model is omitted.
The cost-control move is to set model: haiku on every mechanical agent: linters, lookup tools, file finders, simple code-style reviewers. Haiku is fast and cheap, and for narrow well-defined tasks it produces output indistinguishable from Sonnet. Reserve the default (inherit) for agents that need complex reasoning across many files or unusual situations.
Subagent scope and priority
When multiple subagents share the same name, the higher-priority location wins. The order is:
- Managed settings (organisation-wide, deployed via managed settings)
--agentsCLI flag (current session only, passed as JSON when launching).claude/agents/(current project, the most common scope)~/.claude/agents/(all your projects)- Plugin
agents/directory (where the plugin is enabled)
Project subagents are discovered by walking up from the current working directory. Directories added with --add-dir grant file access but are not scanned for subagents. Subagents inside a plugin's agents/ directory become part of a scoped identifier: a file at agents/review/security.md in plugin my-plugin registers as my-plugin:review:security.
For most teams the right pattern is: project-specific agents go in .claude/agents/ and get committed to version control. Reusable personal agents go in ~/.claude/agents/. Team-distributed agents go in a plugin or are vendored into each repo.
Invoking custom subagents
Two paths to actually use a subagent: explicit and implicit.
Explicit invocation is the reliable one. Ask for the agent by name: "Use the code-reviewer agent to review src/auth.ts". Claude routes the task directly to that agent, no ambiguity.
Implicit delegation relies on the description field. Claude reads every available subagent's description when planning a task and delegates to the first one whose description matches. This works when the descriptions are specific and unambiguous. It fails when descriptions overlap or when the task is ambiguous.
For agents you want Claude to use automatically, write the description as a trigger condition with clear scope: "Reviews API response shapes against TypeScript declarations. Use when modifying API contracts or type definitions." For agents you want available but only when explicitly asked, write a description that is descriptive but does not aggressively self-promote.
Permission modes
The permissionMode field controls how the subagent handles tool-call confirmations. Six values:
default: prompts for confirmation on actions that need itacceptEdits: accepts file edits without promptingauto: accepts most actions automaticallydontAsk: never prompts, fails on actions that would require confirmationbypassPermissions: skips all permission checks (use carefully)plan: read-only mode for planning, used by the Plan built-in subagent
For agents that you trust to run unattended (overnight refactors, bulk operations, CI integrations), acceptEdits or auto removes the prompt-confirm friction. For agents that should never make changes (security reviewers, audit tools, code analysers), plan keeps them safely in read-only territory.
Plugin subagents ignore permissionMode. The plugin's declared permissions take precedence.
Subagents cannot spawn other subagents
A subagent runs in its own context but cannot delegate further. If the subagent needs to invoke a tool that would normally spawn another subagent (like Agent or Task), the call fails. This is by design: nested subagent delegation creates context-management problems and unpredictable behaviour.
The exception is when an agent runs as the main thread via claude --agent. In that mode it can spawn subagents using the Agent tool. Inside the tools field, you can restrict which subagent types it can spawn using Agent(worker, researcher) syntax. To allow all subagents, use bare Agent. To block subagent spawning entirely, omit Agent from the tools list.
Three custom subagents your team should ship first
Three patterns that pay for themselves quickly:
A code reviewer scoped to read-only tools and project memory. It learns your codebase conventions across sessions. Within three weeks it knows your tone for error messages, your naming rules, your test patterns, your security boundaries.
A debug specialist scoped to read tools and Bash (so it can run tests). It captures debugging strategies in its memory. Recurring bugs in your stack become one-question lookups: "Why does this build fail?" and it already knows the three usual causes for your project.
A doc auditor scoped to read tools only, with no memory. It compares your README, your API docs, and your CLAUDE.md against the actual code on each run. It catches doc drift before it confuses the next developer.
Build one. Use it for a week. Update its memory after every useful run. The first iteration is rough; by the third iteration it is faster than doing the work yourself.
A subagent that pays for itself
The point of a custom subagent is compounding. Each run teaches it something. The memory file grows. The descriptions sharpen. The system prompt gets refined as you notice failure modes.
Start with a single agent that handles a task you do at least weekly. Set memory: project so the agent's learnings live in your repo. Set model: haiku if the task is mechanical, or leave the default if it needs reasoning. Write the description as a specific trigger condition. Constrain the tools list to the minimum the task needs.
Run the agent. After each useful run, tell it to update its memory with what it noticed. By the end of the month you have a specialist that nobody else has, that knows your codebase in a way no general-purpose assistant can match.
For pre-built specialists wired to compound this way out of the box (newsletter pipelines, SEO research, brand voice calibration), the Claudify skills system ships custom agents that work together as a team. Each one runs in its own context, with its own memory, with the tool restrictions baked in.
Or build your own from this guide. The mechanism is identical. The investment is one file plus the discipline to update memory after each run.
Ready to ship
Custom Claude Code subagents are the single highest-leverage move in 2026 for anyone running long sessions or working on complex codebases. They keep your main context clean, they enforce constraints that Claude cannot violate, and they accumulate institutional knowledge across sessions in a way no other Claude Code feature does.
Start with one agent for the task you do most. Use the /agents command to scaffold it. Save it with memory: project so the knowledge sticks. Refine the description after the first ten runs. The compounding starts immediately and never stops.
For a complete Claude Code system that ships with custom subagents pre-built (and a CLAUDE.md, skills, hooks, and a knowledge-base layer all wired together), explore Claudify or read more guides on the Claudify blog.
More like this
Ready to upgrade your Claude Code setup?
Get Claudify