Local-first task tracking and coordination for humans and agents, built on Automerge CRDTs (tasks, comments, mentions, activity, timeline / patchwork, and optional git commit attribution).
This section describes product intent. The Current implementation section below describes what this repository runs today.
- One workspace of tasks, comments, activity, and history—usable offline on any device that holds a replica of the data.
- Multiple replicas (for example laptop + cloud) should catch up automatically when a network path exists. If something cannot be merged safely, the system should surface that clearly and offer a manual / explicit fallback.
- Many humans and agents contribute. Concurrent structured edits should merge without requiring Google Docs–style live co-editing of the same field.
- Coarse access control for now: a shared workspace secret, effectively flat permissions for everyone who has it.
- Attribution should be hard to mess up by accident (for example multiple agent personas in the same shell or wrong git metadata) and should move toward self-verifying actor identity over time.
- A larger mix of humans and agents across many sites; optional relays (any node may opt in to help routing). Intelligent routing is expected to lean on the sync ecosystem / dependencies, not this repo alone.
- Presence: see who is “around” in the work—including across replicas—before or alongside deeper collaboration features.
- Capabilities-style authorization (for example UCAN / Keyhive-shaped ideas) with cryptographically bound identity. Reads remain broadly available to everyone admitted to the workspace (no emphasis on filtered / constrained read replicas).
- Rich real-time co-editing should feel continuous with the same local-first model. Live editing may assume a shared session or live network path between editors, while the underlying data layer still tolerates offline work and partitions elsewhere.
- Replica-aware authorship: part of identity is which replica produced a change. Replicas have identity and metadata (for example where they run—region, host—and form factor: phone, laptop, cloud VM).
- Replicas are the unit of storage, sync, and partition tolerance.
- Actors (humans and agents) are not bound to a single replica; they should be able to act from different places, with state converging across replicas.
- Holding a full replica is opt-in: for local-first authoring, backup / stewardship, or running infrastructure—not a requirement for every participant.
What ships in this repository today is a hub-and-spoke deployment: a sync server holds the Automerge document, applies mutations, and broadcasts document snapshots to connected WebSocket clients. The CLI and daemon talk to that server over HTTP only (no offline CLI path).
This topology is the current supported runtime. Peer-to-peer replica sync (with partitions and automatic merge between replicas) is a product goal—not yet implemented here.
┌──────────────────────────────────────────────────────────────────────┐
│ MISSION CONTROL │
│ Activity Feed · Task Board · Comments · Timeline · Patchwork │
└──────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────┐
│ AUTOMERGE STORE │
│ (CRDT: tasks, comments, activity) │
└────────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌─────────┐ ┌───────────┐ ┌──────────┐
│ mc CLI │ │ Sync Srv │ │ UI Dev │
└─────────┘ └───────────┘ └──────────┘
| Component | Location | Purpose |
|---|---|---|
| mc CLI | bin/mc.js |
Primary interface for task management (HTTP client to sync server) |
| Automerge Store | lib/automerge-store.js |
Persistence + CRDT document logic (used by the sync server) |
| Sync Server | automerge-sync-server.js |
HTTP + WebSocket hub for the current deployment |
| Notification Daemon | daemon/index.js |
Mention-delivery worker (OpenClaw-oriented) |
| UI Dev Client | ui-prototype/src/MissionControlSync.jsx |
Supported development UI client |
- Start
automerge-sync-server.js(HTTP + WebSocket). - Point CLI and daemon at that server (
MC_SYNC_SERVERorMC_HTTP_PORT). - Run the UI through the Vite dev server proxy (
/mc-api+/mc-ws).
Note: Anything that bypasses the sync server—including direct AutomergeStore access from CLI workflows—is not a supported runtime path for the shipped CLI.
mc tasks [--status <s>] [--assignee <name>] # List tasks
mc show <task-id> # Show task details
mc task create "title" [options] # Create task
--priority <p0-p3> # Set priority
--assignee <name> # Assign to someone
--tag <tag> # Optional tag
mc update <task-id> [options] # Update task
--status <s> # todo/in-progress/completed
--assignee <name> # Reassign
--title "text" # Rename
--description "text" # Body
--priority <p0-p3> # Priority
--agent <name> # Actor (defaults to MC_AGENT or "unknown")mc comment <task-id> "message" # Add comment (use @name to mention)
mc comments <task-id> # List task comments
mc comment-delete <comment-id> # Delete a comment by ID
mc mentions pending [--agent <name>] # Pending @mentions (optional filter)
mc mentions <agent> # Same pool, filter by agent (positional)
mc activity [--limit <n>] # Activity feed
mc agents list # List registered agentsmc timeline [options] # Rich timeline view
--agent <name> # Filter by actor
--task <id> # Filter by task
--limit <n> # Limit entries
mc diff <task-id> # Show task changes over time
mc branch <task-id> <name> # Create experimental branch
mc branches <task-id> # List branches
mc merge <branch-task-id> # Merge branch task back into parentmc commit -m "message" # Commit with agent attribution
--task <id> # Link to Mission Control task
mc trace list [--limit <n>] # List recent traced commits
mc trace show <hash> # Show trace details
mc trace task <task-id> # Commits linked to a taskSee docs/AGENT-TRACE.md for full documentation.
# Install
cd /path/to/mission-control
npm install
# Symlink for easy access
ln -s $(pwd)/bin/mc.js ~/bin/mc
# Start the sync server
export MC_API_TOKEN="$(openssl rand -hex 32)"
MC_API_TOKEN="$MC_API_TOKEN" npm run sync
# Use the CLI with the same token
MC_API_TOKEN="$MC_API_TOKEN" mc tasks
# Create a task
MC_API_TOKEN="$MC_API_TOKEN" mc task create "Fix the thing" --priority p1
# Add a comment
MC_API_TOKEN="$MC_API_TOKEN" mc comment <task-id> "Working on this now"
# Check activity
MC_API_TOKEN="$MC_API_TOKEN" mc activity --limit 10
# Optional workers/clients
MC_API_TOKEN="$MC_API_TOKEN" npm run daemon
VITE_MC_API_TOKEN="$MC_API_TOKEN" npm run dev --prefix ui-prototypeBy default the sync server stores data under the current working directory. To pin a data root (for example a dedicated folder), set MC_STORAGE_PATH when starting the server and use the same layout described under Data Storage below.
Binary CRDT data lives under a .mission-control/ directory.
- Default (no
MC_STORAGE_PATH):./.mission-control/in the directory from which you start the sync server, with the document handle in./.mission-control-url. - With
MC_STORAGE_PATHset:$MC_STORAGE_PATH/.mission-control/for binary data, and$MC_STORAGE_PATH/.mission-control/document-urlfor the document handle (not.mission-control-urlin the cwd).
{
tasks: { [id]: Task }, // Task objects
comments: { [id]: Comment }, // Comment threads
mentions: { [id]: Mention }, // @mention tracking
agents: { [name]: Agent }, // Agent registry
activity: Activity[], // Activity feed
taskHistory: { [id]: Change[] } // Patchwork history
}See Automerge Document above for where the document URL file lives (.mission-control-url by default, or document-url under .mission-control when using MC_STORAGE_PATH). The sync server defaults to HTTP 8004 and WebSocket 8005 and can be configured with environment variables.
The sync server requires an API token by default.
# Generate a token once per shell/session
export MC_API_TOKEN="$(openssl rand -hex 32)"
# Start server (binds to 127.0.0.1 by default)
MC_API_TOKEN="$MC_API_TOKEN" npm run sync
# Use CLI/daemon with the same token
MC_API_TOKEN="$MC_API_TOKEN" mc tasks
MC_API_TOKEN="$MC_API_TOKEN" npm run daemonOptional environment settings:
MC_ALLOWED_ORIGINS(comma-separated CORS allowlist, defaults to localhost dev origins; wildcard*is not supported)MC_BIND_HOST(default127.0.0.1)MC_HTTP_PORT(default8004)MC_WS_PORT(default8005)MC_SYNC_SERVER(CLI/daemon API base URL override, e.g.http://127.0.0.1:9000)MC_STORAGE_PATH(optional directory; store uses$MC_STORAGE_PATH/.mission-controland nesteddocument-urlas above)MC_ALLOW_INSECURE_LOCAL=1(disables auth; local testing only)
For the Vite UI, set VITE_MC_API_TOKEN in ui-prototype/.env.local. The UI exchanges that token for a short-lived one-time WebSocket ticket via /mc-api/automerge/ws-ticket, so long-lived tokens are not placed in WS URLs.
Optional compatibility setting:
MC_ALLOW_LEGACY_WS_QUERY_TOKEN=1(temporarily allow?token=WebSocket auth for old clients; disabled by default)
Behavior notes:
- Browser requests with an
Originheader must matchMC_ALLOWED_ORIGINS. Allowed preflightOPTIONSrequests receive the same allowlisted CORS headers; disallowed origins are rejected with403. - Originless non-browser requests (for example CLI and daemon traffic) are allowed and still require auth unless
MC_ALLOW_INSECURE_LOCAL=1is set. - CLI and daemon commands fail fast when the sync server is unreachable; they do not fall back to direct local-store access.
- The sync server logs rejected auth/origin checks with a
[security]prefix and keeps in-memory counters for HTTP and WebSocket rejections. Those counters are available on the server instance (used by integration tests and any embedder); they are not exposed as a public HTTP API.
# Supported passing suites
npm test
# Opt-in roadmap/gap specs (may fail until the product catches up)
npm run test:gaps
# Install UI dependencies once, then verify the Vite build from repo root
npm install --prefix ui-prototype
npm run ui:buildGAP:-prefixed suites under test/ are reserved for intentionally failing roadmap/specification checks. They remain runnable through npm run test:gaps, but npm test excludes them by default.
Same as Quick Start: MC_API_TOKEN="$MC_API_TOKEN" npm run sync (HTTP 8004, WebSocket 8005 by default). Run from the repo root (or set MC_STORAGE_PATH) so .mission-control lands where you expect.
- Automerge CRDT storage (
lib/automerge-store.js) - Task migration from beans (historical migration phase)
- CLI with full task management (
bin/mc.js) - Comments with @mentions
- Activity feed and timeline
- Agent registry
- WebSocket sync server (
automerge-sync-server.js) - Multi-session document sync over WebSockets
- Conflict-free concurrent structured edits at the CRDT layer (server-side)
- Timeline view with rich context
- Task history tracking
- Branch/merge for task experimentation
- Diff visualization
- React dashboard dev client (
ui-prototype/) - Task board with sync
- Activity feed view
Also shipped: Agent Trace (mc commit / mc trace) — see docs/AGENT-TRACE.md.
Aligned with Direction above, plus practical polish:
- Replica registry and identity; replica-aware attribution in the document model
- Peer-to-peer replica sync and partition-tolerant workflows (beyond hub-and-spoke)
- Presence across replicas
- Capability-gated mutations with cryptographically bound identity
- Richer co-editing (staged after presence); likely layered on top of local-first state
- Productionize UI deployment (repo ships a development client)
--jsonoutput for CLI scripting- Timestamp tracking for stale task detection
- Backup / export
- UI timeline visualization, diff viewer, branch management
- Optional automation (digests, alerts)—out of core scope unless prioritized
- Original design was a companion layer to beans; the project pivoted to a full Automerge-backed system.
- Tasks were imported during migration; original IDs were preserved as
clawd-<hash>. Beans is deprecated. - 2026-02-02: Initial multi-agent coordination features landed.
- 2026-02-08: Operating deployment was consolidated around a single-operator workflow; multi-agent infrastructure may still exist in the data model and code paths.
MIT