task-graph-basics
Foundation skill for task-graph-mcp - connection workflow, tool reference, task trees, search, and shared patterns for multi-worker coordination
SKILL.md
| Name | task-graph-basics |
| Description | Foundation skill for task-graph-mcp - connection workflow, tool reference, task trees, search, and shared patterns for multi-worker coordination |
name: task-graph-basics description: Foundation skill for task-graph-mcp - connection workflow, tool reference, task trees, search, and shared patterns for multi-worker coordination license: Apache-2.0 metadata: version: 2.0.0 suite: task-graph-mcp role: foundation
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)
CLI Agent Delegation
When running as a coordinator (MCP agent), you can spawn background CLI agents
for parallel work. CLI agents use task-graph-mcp agent subcommands instead of
MCP tool calls.
Spawning a CLI Agent
# Start a background worker
task-graph-mcp agent connect my-worker-1 --tags build,test
# or auto-generate ID:
WORKER_ID=$(task-graph-mcp agent connect --format json | jq -r '.worker_id')
CLI Agent Workflow
task-graph-mcp agent list-tasks --ready
task-graph-mcp agent claim <worker-id> <task-id>
task-graph-mcp agent update <worker-id> <task-id> --status completed
task-graph-mcp agent prompts --status working # Get state guidance
task-graph-mcp agent prompts --advisory # List advisory topics
task-graph-mcp agent disconnect <worker-id>
Coordinator Responsibilities
- Create tasks and dependencies before spawning CLI agents
- Pass the database path if not using defaults:
--database <path> - Monitor progress:
task-graph-mcp agent list-tasks --status working - CLI agents should call
thinkingperiodically for heartbeat
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 startsfollows- sequential orderingcontains- 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 |
MCP Resources
The server exposes resources that agents can read for live configuration,
documentation, and database queries. Use list_resources / read_resource (or
the equivalent MCP resource protocol) to access them.
Query Resources (live database)
| URI | Description |
|---|---|
query://tasks/all | Full task graph with dependencies |
query://tasks/ready | Tasks ready to claim (deps satisfied, unclaimed) |
query://tasks/blocked | Tasks blocked by dependencies |
query://tasks/claimed | All currently claimed tasks |
query://tasks/agent/{agent_id} | Tasks owned by a specific agent |
query://tasks/tree/{task_id} | Task with all descendants |
query://files/marks | All advisory file marks |
query://agents/all | Registered agents |
query://stats/summary | Aggregate statistics |
Config Resources (active configuration)
| URI | Description |
|---|---|
config://current | All configuration in one response (states, phases, deps, tags) |
config://states | Task state definitions and transitions |
config://phases | Work phase definitions |
config://dependencies | Dependency type definitions |
config://tags | Tag definitions and categories |
Docs Resources (reference content)
| URI | Description |
|---|---|
docs://skills/list | List all bundled skills |
docs://skills/{name} | Get a specific skill (e.g., docs://skills/basics) |
docs://workflows/list | List available workflow topologies |
docs://workflows/{name} | Workflow details (states, phases, settings) |
docs://index | List all documentation files |
docs://search/{query} | Full-text search across documentation |
docs://{path} | Read a specific doc file (e.g., docs://GATES.md) |
Tip: Read config://current early in your session to understand the active
state machine, available phases, and tag definitions without extra tool calls.
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. Before adding custom states or
phases, consult docs://WORKFLOW_CUSTOMIZATION for the decision framework.
| 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
Accounting rationale -- why you cannot skip timed states: The state machine requires tasks to pass through a timed state (e.g.,
working) before reachingcompleted. You cannot go directly frompendingtocompleted. This exists becausetime_actual_msis accumulated by measuring elapsed wall-clock time while a task sits in a timed state. Skipping the timed state would produce zero-duration records, breaking parent rollup totals, sprint velocity, and agent utilization metrics.Pattern for coordinator/bookkeeping tasks: Parent rollup tasks, umbrella tasks, and other bookkeeping items where no real work happens still need to transit through
working. The transition can be immediate:update(task=task_id, state="working", worker_id=worker_id) update(task=task_id, state="completed", worker_id=worker_id)This records a minimal (near-zero) duration while keeping the audit trail and accounting system consistent.
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 workerclaim(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_mstags,needed_tags,wanted_tagschildren- 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 |