Introduction
In January 2026, Anthropic released a fundamental change to how Claude Code manages work: Tasks. Released alongside the Opus 4.5 model, Tasks replace the simpler Todos system with a more powerful primitive designed for longer projects spanning multiple sessions and coordinated subagents.
If you've been using Claude Code for complex projects, you've probably hit the limitations of Todos. They were simple checklists that didn't persist well, couldn't express dependencies, and had no way to coordinate work across multiple Claude instances. Tasks solve all of these problems.
This guide covers everything you need to know about Tasks: what changed, how the four Task tools work, how to build dependency chains, and how to coordinate work across sessions and subagents. By the end, you'll be equipped to manage complex, multi-phase projects with confidence.
What Changed: Tasks vs Todos
Understanding what Tasks replaced helps you appreciate why they matter. Here's how the two systems compare:
The Old Way: Todos
Todos were essentially simple checklists. Claude could create them, mark them done, and that was about it. They lived only in the current session's memory, which meant:
- Starting a new conversation meant losing your todo list
- No way to express "Task B depends on Task A"
- No visibility into what other Claude sessions were working on
- No structured way to track complex, multi-step projects
The New Way: Tasks
Tasks are a proper data structure with persistence, dependencies, and coordination features:
- Persistent storage: Tasks are stored in the file system at
~/.claude/tasks, surviving across sessions - Dependencies: Tasks can block other tasks, creating execution pipelines
- Status tracking: Tasks have explicit states (pending, in_progress, completed, blocked)
- Ownership: Tasks can be claimed by specific sessions or agents
- Broadcasting: Updates propagate to all sessions watching the same task list
The Four Task Tools
Tasks are managed through four dedicated tools. Each has a specific purpose in the task lifecycle.
TaskCreate
Creates a new task with a subject, description, and active form. The active form is particularly important: it describes what "doing" this task looks like, helping Claude understand when to work on it.
TaskCreate:
subject: "Implement user authentication"
description: "Add login and signup flows with JWT tokens"
activeForm: "Building the auth module with login, signup, and token management"
The activeForm field is what Claude shows when actively working on the task. It should be a present-tense description of the work being done.
TaskGet
Retrieves the full details of a specific task by its ID. Use this when you need to see all task metadata including dependencies, blockers, and full description.
TaskGet:
id: "task_abc123"
Returns:
id: "task_abc123"
subject: "Implement user authentication"
description: "Add login and signup flows with JWT tokens"
status: "in_progress"
owner: "session_xyz"
blockedBy: []
blocks: ["task_def456", "task_ghi789"]
TaskUpdate
Modifies an existing task. You can update status, set the owner, add dependencies, or modify the description. This is how tasks progress through their lifecycle.
TaskUpdate:
id: "task_abc123"
status: "completed"
TaskUpdate:
id: "task_def456"
addBlockedBy: ["task_abc123"]
owner: "session_xyz"
Common status values:
pending- Task is waiting to be startedin_progress- Task is actively being worked onblocked- Task is waiting on dependenciescompleted- Task is finished
TaskList
Returns all tasks with summary information. Essential for understanding the current state of a project and finding tasks to work on.
TaskList returns:
- id: "task_abc123"
subject: "Implement user authentication"
status: "completed"
- id: "task_def456"
subject: "Build user profile page"
status: "in_progress"
owner: "session_xyz"
- id: "task_ghi789"
subject: "Add email notifications"
status: "blocked"
blockedBy: ["task_abc123"]
Task Dependencies
Dependencies are what make Tasks powerful for complex projects. They let you express relationships between pieces of work and automatically track what's ready to be done.
Using addBlockedBy and addBlocks
There are two ways to express dependencies:
addBlockedBy: "This task cannot start until these other tasks complete"addBlocks: "These other tasks cannot start until this task completes"
Both achieve the same result from different directions. Use whichever makes more sense for your workflow:
# When creating the blocked task:
TaskUpdate:
id: "task_profile_page"
addBlockedBy: ["task_auth", "task_database_schema"]
# Or when updating the blocking task:
TaskUpdate:
id: "task_auth"
addBlocks: ["task_profile_page", "task_settings_page"]
How Downstream Tasks Auto-Unblock
When a task is marked as completed, all tasks that were blocked by it automatically update. If a blocked task has no remaining blockers, its status changes from blocked to pending, signaling it's ready for work.
# Initial state:
task_auth: status=in_progress
task_profile: status=blocked, blockedBy=[task_auth]
task_settings: status=blocked, blockedBy=[task_auth, task_database]
# After completing auth:
TaskUpdate: id="task_auth", status="completed"
# Resulting state:
task_auth: status=completed
task_profile: status=pending, blockedBy=[] # Auto-unblocked!
task_settings: status=blocked, blockedBy=[task_database] # Still blocked
Building Pipelines with Dependencies
For complex projects, you can create entire execution pipelines:
# Phase 1: Foundation (no dependencies)
task_schema: "Design database schema"
task_auth_design: "Design authentication flow"
# Phase 2: Implementation (depends on Phase 1)
task_database: blockedBy=[task_schema]
task_auth_impl: blockedBy=[task_auth_design]
# Phase 3: Integration (depends on Phase 2)
task_api: blockedBy=[task_database, task_auth_impl]
# Phase 4: Frontend (depends on Phase 3)
task_ui: blockedBy=[task_api]
# Phase 5: Testing (depends on everything)
task_tests: blockedBy=[task_ui]
Cross-Session Collaboration
One of the most powerful features of Tasks is the ability to share them across multiple Claude sessions. This enables parallel development workflows where different terminals work on different parts of a project.
The CLAUDE_CODE_TASK_LIST_ID Environment Variable
By default, each Claude session has its own task list. To share tasks across sessions, set the CLAUDE_CODE_TASK_LIST_ID environment variable to the same value in each terminal:
# Terminal 1: Start Claude with a shared task list
CLAUDE_CODE_TASK_LIST_ID=myproject claude
# Terminal 2: Join the same task list
CLAUDE_CODE_TASK_LIST_ID=myproject claude
# Terminal 3: Also joins
CLAUDE_CODE_TASK_LIST_ID=myproject claude
All three terminals now see the same tasks and receive updates when any session modifies them.
Broadcasting Updates to All Sessions
When a session updates a task, the change broadcasts to all other sessions watching that task list. This means:
- When Terminal 1 marks a task complete, Terminal 2 sees it immediately
- When Terminal 2 claims a task, Terminal 1 knows not to work on it
- Blocked tasks auto-unblock for all sessions simultaneously
Practical Workflow: Parallel Development
Here's a workflow for a team working on different parts of a feature:
# Session 1: Create the task list with dependencies
TaskCreate: subject="Design API endpoints", activeForm="Designing REST API"
TaskCreate: subject="Build backend", blockedBy=[api_design_task]
TaskCreate: subject="Build frontend", blockedBy=[api_design_task]
TaskCreate: subject="Integration tests", blockedBy=[backend_task, frontend_task]
# Session 1: Works on API design
TaskUpdate: id="api_design_task", owner="session_1", status="in_progress"
# ... does the work ...
TaskUpdate: id="api_design_task", status="completed"
# Backend and frontend tasks auto-unblock
# Session 2: Claims backend
TaskUpdate: id="backend_task", owner="session_2", status="in_progress"
# Session 3: Claims frontend (in parallel!)
TaskUpdate: id="frontend_task", owner="session_3", status="in_progress"
# Both complete, integration tests unblock automatically
Using Tasks with Subagents
Tasks become even more powerful when combined with Claude's subagent capabilities. Subagents can claim tasks, report progress, and mark work complete just like top-level sessions.
How Subagents Claim and Update Tasks
When spawning a subagent for specific work, you can pass it a task ID to work on:
# Main agent creates tasks
TaskCreate: subject="Build auth service", activeForm="Implementing authentication"
TaskCreate: subject="Build user service", activeForm="Implementing user management"
# Main agent spawns subagents for each task
Spawn subagent:
task: "Work on task_auth_123. Claim it, implement authentication, mark complete."
Spawn subagent:
task: "Work on task_user_456. Claim it, implement user service, mark complete."
# Subagents work in parallel, each updating their assigned task
Coordinating Work Across Multiple Agents
The ownership system prevents conflicts when multiple agents are active:
# Agent checks for unowned, unblocked tasks
TaskList
# Finds: task_xyz is pending with no owner
# Agent claims it
TaskUpdate: id="task_xyz", owner="agent_abc", status="in_progress"
# Other agents see the task is claimed and skip it
TaskList
# Shows: task_xyz is in_progress, owned by agent_abc
Best Practices for Parallel Execution
- Always set owner before starting: Prevents duplicate work
- Use fine-grained tasks: Smaller tasks enable more parallelism
- Design for independence: Tasks that can run in parallel should have no shared dependencies
- Check TaskList before claiming: Another agent might have just claimed it
- Update status immediately: Don't leave tasks in misleading states
Going Further: Specialist Agents
Tasks solve the problem of tracking what needs to be done. But for complex projects, who does the work matters just as much.
Consider a multi-platform project with iOS, web, and backend components. Tasks can track that you need to "build the login screen," but which agent should do it? A generic Claude session might not know your iOS conventions, your CSS patterns, or your Firebase security rules.
The Specialist Agent Pattern
The most effective Claude Code workflows pair Tasks with specialist agents, each pre-configured with domain expertise:
- Frontend Designer: Knows your design system, CSS patterns, accessibility requirements
- iOS Developer: Understands SwiftUI, your app architecture, platform conventions
- Web Developer: Knows your JavaScript patterns, framework quirks, API contracts
- Firebase Developer: Understands security rules, Cloud Functions, Firestore patterns
Instead of telling a generic Claude session everything it needs to know, you spawn the right specialist for each task. The specialist already has the context baked in.
Ready for Specialist Agents?
Claude Architect provides pre-built specialist agents with deep domain expertise. Stop repeating instructions and start delegating to experts.
Join the Waitlist