Skip to content

Orchestrating

Master multi-agent orchestration using Claude Code’s agent teams and task system.

Experimental: Agent teams are disabled by default. Enable with CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS in your settings.json or environment.


PrimitiveWhat It IsFile Location
AgentA Claude instance that can use tools. You are an agent. Subagents are agents you spawn.N/A (process)
TeamA named group of agents working together. One leader, multiple teammates.~/.claude/teams/{name}/config.json
TeammateAn agent that joined a team. Has a name, color, inbox. Spawned via Task with team_name + name.Listed in team config
LeaderThe agent that created the team. Receives teammate messages, approves plans/shutdowns.First member in config
TaskA work item with subject, description, status, owner, and dependencies.~/.claude/tasks/{team}/N.json
InboxJSON file where an agent receives messages from teammates.~/.claude/teams/{name}/inboxes/{agent}.json
MessageA JSON object sent between agents. Can be text or structured (shutdown_request, idle_notification, etc).Stored in inbox files
BackendHow teammates run. Auto-detected: in-process (same Node.js, invisible), tmux (separate panes, visible), iterm2 (split panes in iTerm2). See Spawn Backends.Auto-detected based on environment
ModePermission mode for spawned agents. Set mode: "plan" to require plan approval before the agent acts. See Plan Approval pattern.Task parameter
IsolationSet isolation: "worktree" to give an agent an isolated git worktree copy. Cleaned up if no changes; returns worktree path/branch if changes are made. Recommended for agents making code changes.Task parameter
flowchart TB
    subgraph TEAM[TEAM]
        Leader[Leader - you]
        T1[Teammate 1]
        T2[Teammate 2]

        Leader <-->|messages via inbox| T1
        Leader <-->|messages via inbox| T2
        T1 <-.->|can message| T2
    end

    subgraph TASKS[TASK LIST]
        Task1["#1 completed: Research<br/>owner: teammate1"]
        Task2["#2 in_progress: Implement<br/>owner: teammate2"]
        Task3["#3 pending: Test<br/>blocked by #2"]
    end

    T1 --> Task1
    T2 --> Task2
    Task2 -.->|unblocks| Task3
flowchart LR
    A[1. Create Team] --> B[2. Create Tasks]
    B --> C[3. Spawn Teammates]
    C --> D[4. Work]
    D --> E[5. Coordinate]
    E --> F[6. Shutdown]
    F --> G[7. Cleanup]
sequenceDiagram
    participant L as Leader
    participant T1 as Teammate 1
    participant T2 as Teammate 2
    participant Tasks as Task List

    L->>Tasks: TaskCreate (3 tasks)
    L->>T1: spawn with prompt
    L->>T2: spawn with prompt

    T1->>Tasks: claim task #1
    T2->>Tasks: claim task #2

    T1->>Tasks: complete #1
    T1->>L: SendMessage (findings)

    Note over Tasks: #3 auto-unblocks

    T2->>Tasks: complete #2
    T2->>L: SendMessage (findings)

    L->>T1: SendMessage (shutdown_request)
    T1->>L: SendMessage (shutdown_response, approve)
    L->>T2: SendMessage (shutdown_request)
    T2->>L: SendMessage (shutdown_response, approve)

    L->>L: TeamDelete

SkillWhat It Covers
Team ManagementCreate teams, spawn teammates, delegate mode, permissions, shutdown, cleanup
Task SystemTaskCreate, TaskList, TaskGet, TaskUpdate, dependencies, file locking
Agent TypesBuilt-in agents (Bash, Explore, Plan, general-purpose), plugin agents, selection guide
MessagingSendMessage (all types), message formats, automatic delivery, direct interaction
Orchestration Patterns7 patterns (parallel, pipeline, swarm, research, plan approval, refactoring, RLM)
RLM PatternContent-aware chunked analysis of large files and directories using RLM pattern
Spawn Backendsin-process, tmux, iTerm2, teammateMode setting, auto-detection
Error HandlingCommon errors, hooks (TeammateIdle, TaskCompleted), limitations, debugging

TeamCreate({ team_name: "my-team", description: "Working on feature X" })
Task({ team_name: "my-team", name: "worker", subagent_type: "general-purpose", prompt: "...", run_in_background: true })
Task({ subagent_type: "Explore", description: "Find files", prompt: "..." })
// With isolated worktree (for agents making code changes)
Task({ subagent_type: "general-purpose", description: "Apply patch", prompt: "...", isolation: "worktree" })
SendMessage({ to: "worker-1", message: "...", summary: "Brief update" })
TaskCreate({ subject: "Step 1", description: "...", activeForm: "Working on step 1..." })
TaskCreate({ subject: "Step 2", description: "...", activeForm: "Working on step 2..." })
TaskUpdate({ taskId: "2", addBlockedBy: ["1"] })
Task({ team_name: "my-team", name: "planner", subagent_type: "general-purpose", prompt: "...", mode: "plan", run_in_background: true })
// Teammate works read-only, sends plan_approval_request, you approve/reject
SendMessage({ to: "worker-1", message: { type: "shutdown_request", reason: "All done" } })
// Wait for approval...
TeamDelete()

Every skill’s SKILL.md starts with YAML frontmatter. name and description are required; all other fields are optional.

FieldTypeDescription
namestringRequired. Identifier used to invoke the skill
descriptionstringRequired. Shown in autocomplete and used by Claude to select the skill
argument-hintstringHint shown during autocomplete (e.g. "[file path or query]")
user-invocablebooleanWhen false, hides from the / menu; skill is background knowledge for Claude only (default: true)
disable-model-invocationbooleanWhen true, Claude won’t auto-load this skill; user must invoke via / menu
allowed-toolsstringRestrict tool access when skill is active (e.g. "Read, Grep, Glob")
modelstringModel override when skill is active (e.g. "haiku", "sonnet")
contextstringSet to "fork" to run skill in an isolated subagent context
agentstringSubagent type to use when context: fork (e.g. "Explore", "general-purpose")
hooksobjectLifecycle hooks scoped to this skill

Use these placeholders in your skill content to inject runtime values:

SubstitutionValue
$ARGUMENTSFull user input passed to the skill
$ARGUMENTS[N] / $NNth space-separated argument (1-indexed)
${CLAUDE_SESSION_ID}Current Claude session ID
${CLAUDE_SKILL_DIR}Absolute path to the directory containing this skill’s SKILL.md

Security: Do not interpolate $ARGUMENTS into !`command` expressions — treat it as untrusted user input. Use $ARGUMENTS in skill body text only, never in shell command substitutions.

Add a context field in frontmatter with the bang-backtick syntax to execute a shell command and inject its output when the skill loads. For example, setting context to bang-backtick cat ${CLAUDE_SKILL_DIR}/extra-context.md backtick will read that file into context at load time.

Security: Commands execute locally when the skill loads. Use only safe, read-only commands (e.g., cat, git log, date). Avoid network calls or mutations. Review bang-backtick expressions in third-party plugins before loading.

Note: Do not put the bang-backtick syntax inside code blocks in skill content — the skill loader will attempt to execute it even within fenced code blocks.

---
name: my-explorer
description: Explore codebase for patterns
user-invocable: true
argument-hint: "[pattern or question]"
context: fork
agent: Explore
---

When context: fork is set, Claude spawns a fresh subagent of type agent to handle the skill invocation, keeping the main context clean.

The agent: type determines the tool access scope of the forked subagent:

  • Explore — read-only (no Edit, Write, or Bash)
  • Plan — read-only, thoughtful analysis
  • Bash — shell commands only
  • general-purpose — full tool access (*)

Choose the most restrictive agent type that meets the skill’s needs.


Based on Claude Code agent teams documentation - Updated 2026-03-18