Task Graph Basics
Foundation skill providing shared patterns, tool reference, and connection workflow for task-graph-mcp.
This skill is automatically referenced by all other task-graph skills.
Coordination patterns (roles, phases, states, gates) are defined by workflow configs (
workflow-solo.yaml,workflow-hierarchical.yaml, etc.) loaded at connect time. This skill covers the tools and patterns that are common across all workflows.
Quick Start
# First thing in any session - connect as a worker connect(tags=["code", "image-in"]) Returns worker_id (SAVE THIS for all subsequent calls) # Find work list_tasks(ready=true, worker_id=worker_id) # Claim and work claim(worker_id=worker_id, task=task_id) thinking(worker_id=worker_id, thought="Working on X...") update(worker_id=worker_id, task=task_id, state="completed")
Connection Workflow
Every worker MUST connect before using task-graph tools:
1. CONNECT
connect(
worker_id="worker-17", # Only if assigned!
tags=["code", "audio-out"], # Capabilities
)
Returns: worker_id
SAVE THIS ID for all subsequent calls
2. WORK (use worker_id in all calls)
list_tasks, claim, thinking, update, etc.
3. DISCONNECT (when done)
disconnect(worker_id=worker_id)
Releases all claims and locks
Choosing a worker_id:
- •Only provide a worker_id if you've been assigned one that seems unique
- •
"claude"-> BAD (too generic, will collide) - •
"coordinator"-> Likely OK (role-based, probably unique) - •
"worker-17"-> Good (explicitly assigned) - •If you don't have an assigned name, omit worker_id entirely -- a unique petname will be generated for you automatically
Tags enable task affinity:
- •
agent_tags_allon tasks: Worker must have ALL (AND logic) - •
agent_tags_anyon tasks: Worker must have AT LEAST ONE (OR logic)
Tool Reference
Worker Management
| Tool | Purpose | Key Parameters |
|---|---|---|
connect | Register as worker | worker_id (optional ID), tags[], force |
disconnect | Unregister, release all | worker_id |
list_workers | See all workers | format |
Task CRUD
| Tool | Purpose | Key Parameters |
|---|---|---|
create | Single task | title, description, parent, priority, blocked_by[], agent_tags_all[], agent_tags_any[] |
create_tree | Nested structure | tree, parent, child_type, sibling_type |
get | Fetch task | task, children, format |
list_tasks | Query tasks | status, ready, blocked, owner, parent, worker_id, format |
update | Modify task & state | worker_id, task, state, title, description, priority, force |
delete | Remove task | task, cascade |
Claiming & Ownership
| Tool | Purpose | Key Parameters |
|---|---|---|
claim | Take ownership (shortcut) | worker_id, task, force |
Ownership via update:
- •
update(state="working")-> Claims task (sets owner) - •
update(state="pending")-> Releases task (clears owner) - •
update(state="completed")-> Completes task (clears owner) - •Use
force=trueto take from another worker
Dependencies
| Tool | Purpose | Key Parameters |
|---|---|---|
link | Add dependency | from, to, type |
unlink | Remove dependency | from, to, type |
relink | Atomic move dependencies | prev_from, prev_to, from, to, type |
Dependency types:
- •
blocks- blocker must complete before blocked starts - •
follows- sequential ordering - •
contains- parent-child relationship
File Coordination
| Tool | Purpose | Key Parameters |
|---|---|---|
mark_file | Mark file | worker_id, file, reason |
unmark_file | Unmark file | worker_id, file, reason |
list_marks | Current marks | worker_id, files[] |
mark_updates | Poll changes | worker_id, files[], timeout |
Progress & Metrics
| Tool | Purpose | Key Parameters |
|---|---|---|
thinking | Live status | worker_id, thought, tasks[] |
get_state_history | Audit trail | task |
log_cost | Track usage | worker_id, task, tokens_in, tokens_out, cost_usd |
Attachments
| Tool | Purpose | Key Parameters |
|---|---|---|
attach | Add content | task, name, content, mime, file, store_as_file |
attachments | List/get | task, content |
detach | Remove | task, index |
Search
| Tool | Purpose | Key Parameters |
|---|---|---|
search | Full-text search | query, limit, include_attachments, status_filter |
Search features:
- •FTS5-based relevance ranking
- •Searches task titles, descriptions, and optionally attachments
- •Returns snippets with highlighted matches
- •Filter by task status (e.g.,
status_filter="pending")
Workflows
| Tool | Purpose | Key Parameters |
|---|---|---|
list_workflows | Available workflow configs | |
check_gates | Check gate requirements | task |
Task States
States and transitions are defined by the active workflow config. The default state machine (present in all workflows) is:
pending --> working --> completed | | | +--> failed --> pending (retry) | +--> cancelled
Workflows may add additional states (e.g., assigned, consult). See the
loaded workflow for the full state machine.
| Common State | Timed | Typical Exits |
|---|---|---|
pending | No | working, cancelled |
working | Yes | completed, failed, pending |
completed | No | (terminal or pending) |
failed | No | pending |
cancelled | No | (terminal) |
Timed states (like working) automatically:
- •Set owner when entering
- •Track
time_actual_ms - •Clear owner when leaving
Unified Update Behavior
The update tool handles ownership based on state transitions:
Transition to TIMED state (e.g., working) CLAIMS task: validates tags, checks limit, sets owner Transition to NON-TIMED state (e.g., pending) RELEASES task: clears owner Transition to TERMINAL state (e.g., completed) COMPLETES task: checks children, releases file locks
Force parameter:
- •
update(force=true)takes ownership from another worker - •
claim(force=true)same behavior (claim is shortcut for update)
Task Trees
Use create_tree for hierarchical task structures:
{
"tree": {
"title": "Feature X",
"children": [
{"title": "Design", "points": 3},
{"title": "Implement", "points": 5},
{"title": "Test", "points": 2}
]
},
"sibling_type": "follows"
}
Top-level params:
- •
child_type- Dependency from parent to children (default: "contains") - •
sibling_type- Dependency between siblings ("follows" for sequential, null for parallel)
Tree node fields:
- •
title- Task title (required for new tasks) - •
ref- Reference existing task by ID (other fields ignored) - •
id- Custom task ID (UUID7 generated if omitted) - •
description,priority,points,time_estimate_ms - •
tags,needed_tags,wanted_tags - •
children- Nested child nodes
Reference existing tasks:
{ "ref": "existing-task-id" }
Parallel Workstreams with Cross-Branch Dependencies
For complex patterns with parallel tracks, build the tree then add links:
{
"tree": {
"title": "Sprint 5",
"children": [
{
"title": "Backend Track",
"children": [
{"title": "API endpoints", "id": "api", "needed_tags": ["backend"]},
{"title": "Database migrations", "id": "db", "needed_tags": ["database"]}
]
},
{
"title": "Frontend Track",
"children": [
{"title": "Component library", "id": "comp", "needed_tags": ["frontend"]},
{"title": "Page integration", "id": "page", "needed_tags": ["frontend"]}
]
}
]
}
}
# Sequential deps within each track: link(from="api", to="db", type="follows") link(from="comp", to="page", type="follows") # Cross-branch deps: link(from="api", to="page", type="blocks")
Scope Expansion via Relink
When a task's scope grows, move children atomically with relink:
# Task "Backend" has children A, B, C, D # Split: keep A, B in Backend; move C, D to new "Database" sibling # 1. Create new sibling task create(title="Database", parent=grandparent_id) new_task_id # 2. Atomic move relink( prev_from="backend-task-id", prev_to=["child-c", "child-d"], from=new_task_id, to=["child-c", "child-d"], type="contains" )
Why relink vs unlink+link?
- •Single transaction: all changes succeed or none do
- •No intermediate state where children are orphaned
- •Validates constraints (single parent, no cycles) before committing
Query Patterns
Find available work
list_tasks(ready=true, worker_id=worker_id) # Returns: unclaimed tasks with satisfied deps matching worker's tags
Find blocked tasks
list_tasks(blocked=true) # Returns: tasks waiting on dependencies
Find my tasks
list_tasks(owner=worker_id) # Returns: tasks I've claimed
Get root tasks only
list_tasks(parent="null") # Returns: top-level tasks
Get formatted output
list_tasks(format="markdown") get(task=task_id, children=true, format="markdown")
Search tasks
search(query="authentication") # Returns: ranked results with highlighted snippets search(query="auth", include_attachments=true, status_filter="pending") # Returns: pending tasks matching "auth" in title, description, or attachments
Search vs list_tasks
| Use Case | Tool |
|---|---|
| Find ready tasks for your tags | list_tasks(ready=true) |
| Find tasks by keyword | search(query="keyword") |
| Filter by status only | list_tasks(status="pending") |
| Find tasks with specific content | search(query="...") |
| Check your claimed tasks | list_tasks(owner=worker_id) |
| Find tasks mentioning a topic | search(query="topic") |
Best Practices
Always Do
- •Save your
worker_idafter connecting - •Use
thinking()frequently to show progress - •Mark files before editing (
mark_file) - •Check
mark_updatesbefore editing shared files or when seeing edit conflicts - •Log costs with
log_costfor tracking
Never Do
- •Claim tasks without checking dependencies
- •Edit files without advisory locks
- •Leave tasks in limbo (always update state)
- •Ignore tag requirements on tasks
Error Handling
| Error | Cause | Solution |
|---|---|---|
| "Task already claimed" | Another worker owns it | Use force=true or pick another |
| "Dependencies not satisfied" | Blockers incomplete | Wait or help complete blockers |
| "Worker ID already registered" | Name collision | Omit worker_id to get a unique petname |
| "Worker not found" | Invalid/expired worker_id | Reconnect (let stale reaping clean up old) |
| "Tag mismatch" | Worker lacks required tags | Check agent_tags_all/agent_tags_any |
Related Skills
| Skill | Purpose |
|---|---|
task-graph-reporting | Analyze metrics and progress |
task-graph-migration | Import from other systems |
task-graph-repair | Fix orphaned/broken tasks |