AGENTS.md Claude Code Multi-agent

AGENTS.md for Multi-Agent Workflows: Orchestrator and Subagent Configuration Guide 2026

The Prompt Shelf ·

Multi-agent systems in Claude Code have moved well past the “spawn a subagent and hope” phase. With the .claude/agents/ directory as the canonical configuration layer, you now have fine-grained control over tool access, model choice, memory scope, and spawn permissions — all declared in Markdown files that live in your repository.

This guide covers the full configuration surface: the frontmatter fields that matter, the orchestration patterns that scale, and the mistakes that quietly degrade performance. The focus is practical — real config snippets, concrete tradeoffs, and enough context to understand why each setting exists.

Where Subagent Config Fits in the Claude Code Stack

Before diving into syntax, it helps to understand what the .claude/agents/ layer is and is not.

Claude Code reads instructions from multiple layers at startup:

  1. System prompt — the model’s baseline behavior (not user-editable)
  2. CLAUDE.md / AGENTS.md — project and user-level instructions loaded into the main conversation
  3. .claude/agents/<name>.md — subagent definitions: tool access, model, system prompt, memory, and lifecycle hooks for individual agents

The subagent definition layer sits below CLAUDE.md. A subagent gets only its own system prompt (from the markdown body) plus basic environment details like working directory. It does not inherit the parent conversation’s CLAUDE.md context unless explicitly configured. That isolation is by design — it prevents context contamination where a parent agent’s style guide bleeds into a security reviewer’s output.

The practical implication: if you want a subagent to follow project conventions, write those conventions into the subagent’s system prompt, or use the skills field to inject relevant content. Don’t assume CLAUDE.md will carry the context over.

Subagent File Structure and Required Fields

Subagent files are Markdown files with YAML frontmatter, stored at:

  • .claude/agents/ — project scope (check into version control)
  • ~/.claude/agents/ — user scope (available across all projects)

Only name and description are strictly required. Everything else is optional but consequential.

---
name: code-reviewer
description: Reviews staged code changes for quality, security, and best practices. Use after making edits to any source file.
tools: Read, Grep, Glob
model: sonnet
memory: project
---

You are a senior code reviewer specializing in TypeScript and Node.js.
When invoked, analyze the specified files and return:
1. A severity-ranked list of issues (critical / warning / suggestion)
2. For each issue: the file, line range, problem description, and a corrected snippet
3. A one-sentence overall assessment

Do not suggest stylistic changes that conflict with existing patterns in the codebase.

A few things worth noting here:

description is the delegation trigger. Claude reads descriptions to decide when to delegate. Write it as a task-match statement, not a capability description. “Reviews staged code changes after edits to source files” works better than “An expert code reviewer with deep knowledge of security patterns.”

name becomes the agent type identifier. It must be lowercase with hyphens. Hooks receive it as agent_type. If two files in the same scope declare the same name, Claude Code silently keeps one and discards the other — name collisions fail without warnings.

The markdown body is the complete system prompt. The subagent receives only this content, not the main conversation’s system prompt. Be explicit about the output format you want.

Tool Scoping: The Key to Safe Subagents

Tool scoping is where most multi-agent configurations either succeed or introduce silent problems. There are two approaches: allowlist with tools, and denylist with disallowedTools.

Allowlist: Explicit Minimum Permissions

---
name: safe-researcher
description: Searches and reads the codebase to answer questions. Never modifies files.
tools: Read, Grep, Glob, Bash
---

This subagent can only read files, search with grep/glob patterns, and run shell commands. It cannot write files, make edits, or use any MCP tools. When you need a subagent to be read-only, an allowlist is the safer choice — it’s impossible for a configuration mistake to accidentally grant Write access.

The tradeoff: you must enumerate every tool the subagent legitimately needs. If you later add an MCP server that the subagent should use, you have to update the tools field.

Denylist: Selective Restriction

---
name: no-writes
description: Inherits all capabilities except direct file writing.
disallowedTools: Write, Edit
---

Denylist is more convenient when a subagent needs most of the parent’s tools minus a few dangerous ones. The subagent inherits everything — Bash, MCP tools, all configured integrations — except what you’ve explicitly removed.

If both fields are set, disallowedTools is applied first, then tools resolves against what remains. A tool in both lists is always removed.

MCP Server Scoping

You can also grant or deny entire MCP servers:

---
name: local-only
description: Reads and analyzes code without any external service access.
disallowedTools: mcp__*
---

mcp__* removes every MCP tool from every server. For finer control, mcp__github removes all tools from the github server while keeping others. This is useful for agents that should stay local — a security auditor that definitely should not push to GitHub, or a documentation writer that shouldn’t have database access.

The “Helpfully Destructive” Problem

The most common tool scoping mistake is giving subagents more access than they need because it feels more capable. A code-reviewer that has Write access will occasionally decide to “fix” issues it finds rather than just reporting them. A test-runner with Edit access might modify test files to make tests pass. These aren’t bugs in the model — they’re emergent behaviors from having tools available.

The principle: give each subagent exactly the tools it needs to complete its designated task, and nothing more.

---
name: code-reviewer
description: Reviews code and reports issues. Does not modify files.
tools: Read, Grep, Glob
# Explicitly no Bash — can't run scripts
# Explicitly no Write/Edit — can't modify files
---

Model Selection and Cost Strategy

The model field accepts aliases (sonnet, opus, haiku, fable), full model IDs (claude-sonnet-4-6, claude-opus-4-8), or inherit. When omitted, it defaults to inherit.

model: haiku      # Fast, cheap — good for search/exploration tasks
model: sonnet     # Balanced — good for code review, documentation
model: opus       # Most capable — reserve for complex reasoning
model: inherit    # Uses the main conversation's model

Claude Code resolves the model in priority order:

  1. CLAUDE_CODE_SUBAGENT_MODEL environment variable
  2. The per-invocation model parameter (when Claude spawns the subagent)
  3. The subagent definition’s model frontmatter
  4. The main conversation’s model

The built-in Explore subagent always uses Haiku — fast and cheap for codebase search. The built-in Plan subagent inherits from the main conversation because planning benefits from the same reasoning capability.

A practical cost strategy for a typical SaaS repo:

SubagentModelRationale
explorerhaikuFile search, grep operations — volume work
code-reviewersonnetPattern recognition, security analysis
architectopusSystem design decisions, tradeoff analysis
doc-writersonnetStructured output, follows templates well
test-runnerhaikuExecutes commands, reports output

Haiku handles tasks where volume matters more than reasoning depth. Opus is reserved for tasks where a wrong architectural decision compounds into hours of rework.

Memory Isolation in Practice

The memory field enables a persistent directory that survives across conversations. When set, the subagent’s system prompt is augmented at startup with the first 200 lines or 25 KB of MEMORY.md in its memory directory — whichever limit is hit first.

---
name: code-reviewer
description: Reviews code for quality and best practices
memory: project
---

You are a code reviewer. Before starting work, read your memory for patterns
you've seen before. After completing a review, update your memory with:
- New anti-patterns you found
- Recurring issues in specific files or modules
- Architectural decisions that explain why certain patterns exist

The three memory scopes:

ScopeLocationUse case
user~/.claude/agent-memory/<name>/Cross-project learning
project.claude/agent-memory/<name>/Shareable via version control
local.claude/agent-memory-local/<name>/Project-specific, not committed

The isolation boundary matters. Each subagent has its own memory directory. Your code-reviewer subagent’s MEMORY.md is invisible to your security-auditor subagent. Knowledge accumulates per-agent, not across the team.

This means the orchestrator and subagents have genuinely separate memory stores. The orchestrator’s MEMORY.md should contain project-level patterns, architectural decisions, and task routing heuristics. Individual subagent MEMORY.md files should contain their domain-specific learnings — the reviewer’s list of recurring issues, the doc-writer’s knowledge of which modules have the most outdated documentation.

The 200-line / 25 KB injection limit is a hard constraint, not a soft guideline. Design MEMORY.md accordingly: front-load the most critical information, use structured lists over prose, and include an active curation step in the subagent’s system prompt. A MEMORY.md that grows unbounded stops being read in full at line 201.

Orchestration Patterns

Three patterns cover most multi-agent scenarios. The right one depends on whether tasks are independent, dependent, or hierarchical.

Pattern 1: Hub-and-Spoke (Most Common)

One primary orchestrator decomposes a task and delegates to specialist subagents. Subagents run sequentially or in parallel and return results to the orchestrator, which synthesizes and decides next steps.

Orchestrator
├── code-reviewer    (Read, Grep, Glob)
├── test-runner      (Bash, Read)
└── doc-writer       (Read, Write, Grep)

The orchestrator definition:

---
name: dev-orchestrator
description: Coordinates code review, testing, and documentation workflows for a SaaS repo
tools: Agent(code-reviewer, test-runner, doc-writer), Read, Bash
model: sonnet
memory: project
---

You are the development orchestrator for this repository. When given a task:

1. Identify which specialists are needed
2. Delegate to them in the appropriate order (review before test, test before doc)
3. Collect their outputs and identify conflicts or blockers
4. Return a consolidated summary with any required follow-up

Never modify source files directly. Delegate all file modifications to specialists.

The Agent(code-reviewer, test-runner, doc-writer) syntax in tools is an allowlist that restricts which subagent types this agent can spawn. If the orchestrator tries to spawn any other type, it fails and only sees the listed types. This prevents an orchestrator from spawning ad-hoc agents outside its defined scope.

Pattern 2: Sequential Pipeline

Tasks flow through a defined sequence where each step depends on the previous. Common for review-test-deploy pipelines.

architect → implementer → reviewer → test-runner

Each stage’s output becomes the next stage’s input. Subagents don’t need to know about each other — the orchestrator manages the handoffs.

---
name: pipeline-orchestrator
description: Runs the full feature implementation pipeline: design → implement → review → test
tools: Agent(architect, implementer, code-reviewer, test-runner), Read
model: opus
---

Execute the feature pipeline in strict sequence. Do not proceed to the next stage if
the current stage returns a blocking issue. Pass the full output of each stage as
context to the next.

Sequential pipelines benefit from model: opus at the orchestration layer — the orchestrator makes the gate decisions, and a wrong call cascades.

Pattern 3: Parallel Fan-Out

Independent tasks run simultaneously, then results are merged. Useful for analysis tasks (lint different modules, check multiple languages, run multiple validators).

---
name: multi-linter
description: Runs parallel linting across TypeScript, CSS, and SQL files
tools: Agent(ts-linter, css-linter, sql-linter), Read
model: haiku
---

Fan out to all three linters simultaneously. Merge their outputs into a single
severity-ranked report, deduplicating issues that appear in multiple linters.

Fan-out is where Claude Code’s parallel agent capabilities shine — multiple subagents run concurrently and return independent results. The orchestration cost is low (Haiku is sufficient), and the wall-clock time is the max of the individual runs rather than their sum.

Configuration difference from sequential: fan-out orchestrators need model: haiku (merge work is simple), looser tool restrictions (just Agent + Read for collecting outputs), and explicit merge instructions in the system prompt.

Real-World Three-Subagent Setup for a SaaS Repo

Here’s a concrete .claude/agents/ setup for a TypeScript SaaS repo with the three most useful specialists.

File structure:

.claude/
└── agents/
    ├── architect.md
    ├── implementer.md
    └── reviewer.md

architect.md — System design and decision-making:

---
name: architect
description: Analyzes system design questions, evaluates tradeoffs, and produces implementation plans. Use for any task involving new modules, API design, or database schema changes.
tools: Read, Grep, Glob
model: opus
memory: project
effort: high
---

You are the system architect. Your output is always a structured implementation plan:

## Context
What the change is and why it's needed.

## Affected Components
Files and modules impacted.

## Implementation Steps
Numbered, actionable steps for the implementer.

## Tradeoffs
What you considered but didn't choose and why.

## Risk
What could go wrong and how to detect it.

Do not write implementation code. Produce plans only.

implementer.md — Writes code based on architect’s plans:

---
name: implementer
description: Implements code changes following an architectural plan. Use after the architect has produced a plan.
tools: Read, Write, Edit, Grep, Glob, Bash
model: sonnet
memory: local
---

You are the implementer. You receive an architectural plan and execute it.

Before writing any code:
1. Read the relevant source files to understand existing patterns
2. Check your memory for conventions specific to this codebase
3. Identify any conflicts between the plan and existing code

Write code that matches the existing style. Do not introduce new dependencies
without noting them explicitly in your output.

reviewer.md — Reviews changes, reports issues:

---
name: reviewer
description: Reviews code changes for correctness, security vulnerabilities, and adherence to project conventions. Use after any implementation is complete.
tools: Read, Grep, Glob
model: sonnet
memory: project
---

You are the code reviewer. Review with these priorities in order:
1. **Correctness** — Does the code do what the plan says?
2. **Security** — SQL injection, XSS, unvalidated inputs, exposed secrets
3. **Performance** — N+1 queries, unbounded loops, missing indexes
4. **Conventions** — Does it match the existing codebase patterns?

Output format:
- BLOCKING issues first (must fix before merge)
- WARNINGS second (should fix)
- SUGGESTIONS last (optional improvements)

If no blocking issues exist, say so explicitly at the top.

The reviewer has Read, Grep, Glob only — no Bash, no Write. It cannot execute code or modify files. This is intentional: a reviewer that can run scripts might decide to “test” its findings, which introduces side effects outside the defined pipeline.

Spawn Permission Scoping

When running as the main session agent (via claude --agent), you can restrict which subagents an orchestrator is allowed to spawn:

tools: Agent(code-reviewer, test-runner, doc-writer), Read, Bash

This is an allowlist — only those three types can be spawned. Any attempt to spawn a type not listed fails, and the orchestrator only sees the listed types in its available tool descriptions.

To allow spawning any subagent without restriction:

tools: Agent, Read, Bash

To prevent spawning entirely, omit Agent from tools entirely.

Important: This allowlist only applies when the agent runs as the main session (claude --agent). Inside a subagent definition, listing Agent in tools enables nested spawning, but the Agent(type1, type2) syntax restricts are ignored. Deeply nested hierarchies need to manage their own spawn permissions via disallowedTools instead.

Common Mistakes

Over-permissioning Subagents

The most common mistake. Giving a subagent all tools “just in case” turns every subagent into a general-purpose agent, which defeats the purpose of specialization. A reviewer with Write access will rewrite code. A test-runner with Edit access will modify tests to make them pass. Keep tool scopes minimal.

Cross-contaminating Context

Subagents have isolated context windows by design. If you pass context via the task description (what the parent sends when delegating), keep it concise and structured. Dumping the entire parent conversation history into the task prompt degrades subagent performance — the model spends attention parsing irrelevant context instead of doing the work.

The correct approach: the orchestrator synthesizes relevant context for each delegate, rather than forwarding everything.

MEMORY.md Bloat

The 200-line / 25 KB injection limit is easy to hit if subagents accumulate learnings without curation. A MEMORY.md that hits the limit means the agent only reads the oldest entries — the most recently learned, often most relevant, information is silently dropped.

Build curation into the subagent’s system prompt: “Before writing new entries to MEMORY.md, remove or consolidate entries that are no longer relevant. Keep the file under 150 lines.”

LLM-Generated Subagent Configs

Claude Code’s /agents command lets you generate a subagent definition by describing what you want. The generated frontmatter is functional but generic — the description is usually too broad, the tools field often includes more than necessary, and the system prompt defaults to capability descriptions rather than output format specifications.

In practice, multi-agent setups degrade noticeably when subagent definitions drift from their actual usage — a pattern often described as semantic drift. A large factor is vague initial configuration: when the description doesn’t precisely match the task type, the model’s delegation routing becomes inconsistent.

Treat AI-generated configs as a starting point, not a finished product. The three fields that most need human refinement are:

  • description: make it a precise task-match statement
  • tools: trim to the minimum necessary
  • System prompt: specify output format explicitly, not just “be an expert at X”

Misplacing Project vs User Scope

Project subagents (.claude/agents/) are for repo-specific roles. User subagents (~/.claude/agents/) are for personal workflows you use across projects. A common mistake is putting general-purpose agents in a repo’s .claude/agents/ and checking them in — other contributors then get agents tuned for your personal workflow. Keep personal agents at ~/.claude/agents/.

What Loads at Startup

One frequently misunderstood point: what context actually reaches a subagent at startup?

  • Custom subagents: load CLAUDE.md files and parent git status (same as the main conversation)
  • Built-in Explore and Plan: skip CLAUDE.md and git status intentionally (speed optimization)
  • Subagent system prompt: the markdown body only
  • Memory: first 200 lines / 25 KB of MEMORY.md if memory is configured
  • Skills: full content of any skills listed in the skills field

The parent conversation’s history, tool results, and intermediate outputs do not automatically transfer to a subagent. The parent must explicitly pass context in the delegation task description.

This isolation is what makes subagents safe to parallelize — independent context windows, no shared state, results returned as structured text.

Summary

.claude/agents/ subagent definitions give you a configuration layer that sits between system prompts and the codebase. The key operational decisions for any multi-agent setup:

  1. Tool scope first: define what each subagent is not allowed to do before you define what it can do
  2. Match model to task complexity: Haiku for volume tasks, Opus for decisions with long-range consequences
  3. Memory per agent, not shared: orchestrator and subagents have separate MEMORY.md files; design both intentionally
  4. Pick a pattern: hub-and-spoke for most workflows, sequential pipeline for dependent stages, parallel fan-out for independent analysis
  5. Write descriptions as delegation triggers, not capability descriptions — the model uses them to route

The configuration syntax is stable enough to version control and share across teams. A well-configured .claude/agents/ directory is an asset that compounds — each agent accumulates domain knowledge, routing improves as descriptions get refined, and the whole system gets faster to spin up on a new codebase than starting from scratch.

FAQ

What is the .claude/agents/ directory in Claude Code?

The .claude/agents/ directory is the configuration layer for subagent definitions in Claude Code. Each Markdown file in this directory defines a subagent using YAML frontmatter — name, description, tools, model, and memory — plus a markdown body that becomes the subagent’s complete system prompt. Files placed at .claude/agents/ have project scope and can be checked into version control; files at ~/.claude/agents/ have user scope and are available across all projects.

How do I restrict which tools a subagent can access?

Use the tools field for an allowlist — only listed tools are accessible — or disallowedTools for a denylist that removes specific tools while inheriting everything else. If both fields are set, disallowedTools is applied first, and any tool in both lists is always removed. For MCP servers, mcp__* removes all MCP tools, while mcp__github removes tools from that specific named server only.

What model should I assign to each subagent?

The model field accepts aliases (sonnet, opus, haiku, fable), full model IDs, or inherit. Use haiku for high-volume tasks like file search and grep, sonnet for code review and documentation, and opus for architectural decisions where a wrong call has long-range consequences. When omitted, the field defaults to inherit and uses the main conversation’s model.

How does memory isolation work between the orchestrator and subagents?

Each subagent has its own separate memory directory, invisible to other agents. The memory field accepts three scopes: user (~/.claude/agent-memory/<name>/), project (.claude/agent-memory/<name>/), and local (.claude/agent-memory-local/<name>/). At startup, the first 200 lines or 25 KB of the subagent’s MEMORY.md is injected into its system prompt — whichever limit is hit first. The orchestrator and each subagent maintain completely separate memory stores.

What are the main orchestration patterns for multi-agent Claude Code setups?

Three patterns cover most scenarios. Hub-and-spoke: one orchestrator decomposes tasks and delegates to specialist subagents, then synthesizes results. Sequential pipeline: tasks flow through a fixed sequence where each step depends on the previous — suited for design-implement-review-test workflows. Parallel fan-out: independent tasks run simultaneously across multiple subagents and results are merged — best for independent analysis tasks like running multiple linters at once.

Does a Claude Code subagent automatically inherit the parent CLAUDE.md context?

No. Subagents receive only their own system prompt (the markdown body of their definition file) plus basic environment details like the working directory. The parent conversation’s CLAUDE.md is not automatically transferred. To apply project conventions to a subagent, write those conventions directly into the subagent’s system prompt, or use the skills field to inject relevant content.


Secure Every API Key Your Subagents Touch

When multiple subagents each call different external services — a security auditor hitting a vulnerability scanner API, a doc-writer pulling from a knowledge base, an implementer pushing to CI — you end up with a sprawl of credentials that’s easy to lose track of. 1Password stores every secret in one vault and injects them at runtime via op run, so no key lives in plaintext in .env files or gets accidentally committed. As your .claude/agents/ setup grows, keeping the credential surface controlled becomes as important as keeping the tool surface controlled.

Related Articles

Explore the collection

Browse all AI coding rules — CLAUDE.md, .cursorrules, AGENTS.md, and more.

Browse Rules