Stop AI agents from overwriting each other's work.
CoordinationHub is a lightweight MCP server that coordinates multiple AI coding agents working on the same codebase. It tracks which agent owns which files, prevents two agents from editing the same file at once, and gives you a live view of who is doing what.
Built for Claude Code, compatible with any MCP client. Zero third-party dependencies. Python stdlib only.
When you spawn multiple AI agents on the same project, they can silently overwrite each other's changes. There's no way to know which agent is editing which file, no protection against two agents touching the same code, and no visibility into what's happening across your swarm.
CoordinationHub fixes this by acting as a shared coordination layer — a single source of truth for file ownership, agent identity, and work status.
- File locking — Agents lock files before editing. If another agent tries to edit the same file, it gets blocked (or warned). Supports retry with exponential backoff for cooperative lock acquisition.
- Scope enforcement — Agents can declare a scope (list of path prefixes). Lock acquisitions outside the declared scope are denied. Supports both absolute and project-relative paths.
- Boundary detection — Warns when an agent crosses into another agent's assigned territory.
- Agent tracking — Every spawned agent gets an ID. See the full hierarchy, who's alive, who's stale.
- Change notifications — Agents report what they changed. Others poll to stay in sync.
- Inter-agent messaging — Direct message passing between agents with payload support.
- Agent dependency tracking — Wait for an agent or task to complete before proceeding. Dependencies auto-satisfy when the depended-on task completes.
- Contention hotspots — Identifies files that cause the most conflicts between agents.
- Cascade cleanup — When an agent dies, its children get re-parented and its locks get released. Nothing is orphaned.
- Region locking — Two agents can edit different sections of the same file simultaneously.
- Dashboard — Live CLI or JSON view of all agents, locks, and file assignments.
pip install coordinationhub# One-time setup: creates DB, configures Claude Code hooks
coordinationhub init
# Verify everything is working
coordinationhub doctor
# Start the coordination server
coordinationhub serve
# In another terminal — see what's happening
coordinationhub dashboard
coordinationhub agent-tree
coordinationhub watch # live-refresh agent tree
coordinationhub contention-hotspotsCoordinationHub hooks into Claude Code automatically via project-level hooks. Once configured:
- Agents are registered on session start
- Files are locked before every write
- Changes are broadcast after every edit
- Subagents are tracked in the agent tree
- Everything is cleaned up on session end
See coordinationhub/hooks/claude_code.py and .claude/settings.json for the hook configuration.
Define your agent roles and handoff rules in a coordination_spec.yaml at your project root:
agents:
- id: planner
role: decompose tasks
responsibilities:
- break down user stories
- assign subtasks
- id: executor
role: implement
responsibilities:
- write code
- run tests
handoffs:
- from: planner
to: executor
condition: task_size < 500 && no_blockersEvery agent in the swarm sees the same live hierarchy. Call coordinationhub agent-tree from any agent:
hub.cc.main [active] — "observing..."
├── hub.cc.main.0 [Agent A] — service consolidation
│ ├─ ◆ src/services/mcpProbes.js [exclusive]
│ └─ ◆ mcpChallengeRoutes.js [exclusive] ⚠ owned by hub.cc.main.1
├── hub.cc.main.1 [Agent B] — "route simplification"
│ ├─ ◆ routeLoader.js [exclusive L325-360]
│ └─ ◆ vcsRoutes.js [exclusive]
└── hub.cc.main.2 [Agent C] — data layer
├── hub.cc.main.2.0 [CA] — "working on fileStore.js"
│ └─ ◆ fileStore.js [exclusive]
└── hub.cc.main.2.1 [CB] — "working on BaseModel"
├─ ◆ BaseModel.js [exclusive]
└─ ◆ baseModel.test.js [shared]
Each node shows: agent ID, role/task, active file locks with type and region, and boundary warnings when an agent locks a file owned by another.
Root Agent (project manager)
├── Agent A (team leader)
│ ├── Agent A.0 (writes code)
│ └── Agent A.1 (writes tests)
├── Agent B (team leader)
│ └── Agent B.0 (refactoring)
└── Agent C (documentation)
Every agent gets a unique ID. Files are locked by agent ID. The root agent (your main Claude Code session) acts as project manager — it spawns child agents and can see the full tree at any time.
Agents don't message each other directly. Instead they communicate through the shared database: lock a file, write to it, notify that it changed, release the lock. Other agents poll for notifications to see what happened.
| Category | Tools |
|---|---|
| Identity | register_agent, heartbeat, deregister_agent, list_agents, get_lineage, get_siblings |
| Locking | acquire_lock, release_lock, refresh_lock, get_lock_status, list_locks, release_agent_locks, reap_expired_locks, reap_stale_agents |
| Coordination | broadcast, wait_for_locks, await_agent |
| Handoffs | acknowledge_handoff, complete_handoff, cancel_handoff, get_handoffs, await_handoff_acks, await_handoff_completion |
| Messaging | send_message, get_messages, mark_messages_read |
| Changes | notify_change, get_notifications, prune_notifications, wait_for_notifications |
| Audit | get_conflicts, get_contention_hotspots, status |
| Visibility | load_coordination_spec, validate_graph, scan_project, get_agent_status, get_file_agent_map, update_agent_status, run_assessment, assess_current_session, get_agent_tree |
| Tasks | create_task, assign_task, update_task_status, get_task, get_child_tasks, get_tasks_by_agent, get_all_tasks, create_subtask, get_subtasks, get_task_tree, wait_for_task, get_available_tasks, suggest_task_assignments, retry_task, get_dead_letter_tasks, get_task_failure_history |
| Dependencies | declare_dependency, check_dependencies, satisfy_dependency, wait_for_dependency, get_blockers, assert_can_start, get_all_dependencies |
# Setup & diagnostics
coordinationhub init # one-time: create DB, configure hooks
coordinationhub doctor # validate setup, detect venv issues
# Server
coordinationhub serve --port 9877
coordinationhub serve-mcp # stdio mode (requires: pip install coordinationhub[mcp])
# See what's happening
coordinationhub status
coordinationhub dashboard # full view (also: --json, --minimal)
coordinationhub agent-tree # agent hierarchy
coordinationhub agent-status <id> # single agent detail
coordinationhub contention-hotspots # files with most conflicts
coordinationhub watch # live agent tree (Ctrl+C to stop)
# Agent lifecycle
coordinationhub register <id> [--parent-id <parent>]
coordinationhub heartbeat <id>
coordinationhub deregister <id>
coordinationhub list-agents
coordinationhub lineage <id>
coordinationhub siblings <id>
# File locking
coordinationhub acquire-lock <path> <id> [--region-start N --region-end N]
coordinationhub release-lock <path> <id>
coordinationhub refresh-lock <path> <id>
coordinationhub lock-status <path>
coordinationhub list-locks [--agent-id <id>]
coordinationhub release-agent-locks <id>
coordinationhub reap-expired-locks
coordinationhub reap-stale-agents
# Coordination & changes
coordinationhub broadcast <id> [--document-path <path>]
coordinationhub wait-for-locks <id> <paths...>
coordinationhub notify-change <path> <type> <id>
coordinationhub get-notifications
coordinationhub prune-notifications
coordinationhub wait-for-notifications <id> [--timeout S] [--exclude-agent <agent>]
coordinationhub get-conflicts
# Graph & assessment
coordinationhub load-spec
coordinationhub validate-spec
coordinationhub scan-project
coordinationhub assess --suite <file> # score a hand-authored trace suite
coordinationhub assess-session # score the current live session (no suite file needed)
# Tasks
coordinationhub create-task <task_id> <parent_agent_id> <description> [--depends-on <task_id>...]
coordinationhub assign-task <task_id> <agent_id>
coordinationhub update-task-status <task_id> <status> [--summary <text>]
coordinationhub get-task <task_id>
coordinationhub get-all-tasks
coordinationhub wait-for-task <task_id> [--timeout S] # poll until terminal state
coordinationhub get-available-tasks [--agent-id <id>] # tasks with satisfied deps
# coordinationhub suggest-task-assignments # suggest ready tasks for idle agents (API only)coordinationhub retry-task <task_id>
coordinationhub dead-letter-queuehub.12345.0 — root agent (namespace.PID.sequence)
hub.12345.0.0 — child of root
hub.12345.0.1 — sibling
hub.12345.0.0.0 — grandchild
SQLite-backed, thread-safe, WAL mode. Each module is under 500 LOC with single responsibility. Zero internal cross-dependencies between sub-modules — they all receive a connect callable from the caller.
coordinationhub/
core.py — CoordinationEngine (identity, change, audit, graph/visibility)
core_locking.py — LockingMixin (all lock + coordination methods)
_storage.py — SQLite pool, path resolution, thread-safe ID generation
db.py — Schema, versioning, perf pragmas, ConnectionPool
lock_ops.py — Lock primitives + region overlap detection
agent_registry.py — Agent lifecycle (register, heartbeat, deregister, lineage)
notifications.py — Change notification storage
conflict_log.py — Conflict recording and querying
scan.py — File ownership scan
agent_status.py — Agent status, file map, agent tree
graphs.py — Coordination graph loading + validation
assessment.py — Assessment runner (5 metric scorers)
messages.py — Inter-agent messaging primitives
mcp_server.py — HTTP server (stdlib only)
mcp_stdio.py — Stdio server (optional mcp package)
cli.py — CLI parser + dispatch
cli_setup.py — doctor, init, watch commands
hooks/claude_code.py — Claude Code session hooks
tests/ — <!-- GEN:test-count -->393<!-- /GEN --> tests across 16 files
Core uses only the Python standard library. The mcp package is optional (stdio transport only). Air-gapped install: pip install coordinationhub --no-deps.
| Server | Port |
|---|---|
| Stele | 9876 |
| CoordinationHub | 9877 |
| Chisel | 8377 |
| Trammel | 8737 |