Board-mediated multi-agent coordination in ~500 lines of Python
Project description
marcus-mini
Board-mediated multi-agent coordination in ~500 lines of Python.
Multiple AI agents work in parallel on a shared task board. They never talk to each other — they coordinate exclusively through a SQLite kanban board. This minimal implementation proves that board-mediated coordination works before adding any production complexity.
Demo
mini build "a snake game in Python" — 3 agents decompose, coordinate, and ship.
The idea
Most multi-agent frameworks let agents talk to each other directly. marcus-mini
does the opposite: agents are blind to each other and coordinate only through
a shared board.
Three invariants hold in every run:
- Agents self-select work. The board assigns nothing — agents pull the next available task whose dependencies are all complete.
- Agents make all implementation decisions. The board says what to build, never how.
- Agents communicate only through the board. Artifacts and decisions logged to a task become context for downstream agents. No direct messages, no shared memory outside the board.
This mirrors how distributed teams actually work: a shared backlog, async handoffs, no mandatory standups.
Quickstart
Requirements: Python 3.11+, Claude Code CLI, tmux
pip install marcus-mini
export MINI_API_KEY=sk-ant-... # your Anthropic key — for decomposition only
mini build "a snake game in Python"
Why
MINI_API_KEYand notANTHROPIC_API_KEY? Claude Code agents inherit your shell environment. IfANTHROPIC_API_KEYis set, agents use it for every API call — even if you have a Claude subscription — and you get charged.MINI_API_KEYis only read by the decomposer (one call permini build). Agents run under your subscription key, not this one.
mini build will:
- Call Claude to decompose the goal into a parallel task DAG
- Persist all tasks to a local SQLite board
- Spawn N agents in a tmux session (N = DAG width)
- Each agent loops: claim task → implement → log artifacts → mark done
Watch the board live:
mini watch # live-refreshing kanban
mini status # per-agent activity
mini bench # coordination metrics
Install
pip install marcus-mini
Or from source:
git clone https://github.com/lwgray/marcus-mini
cd marcus-mini
pip install -e .
Commands
| Command | Description |
|---|---|
mini build "goal" |
Decompose goal, spawn agents |
mini watch |
Live kanban board (auto-exits on completion) |
mini board |
Static kanban snapshot |
mini status |
Per-agent activity with staleness warnings |
mini bench |
Wall time, utilization, coordination tax |
mini dag |
ASCII dependency graph |
mini tasks |
Task list with dependency info |
mini progress |
Completion percentage |
mini time |
Project elapsed time |
mini logs |
Tail agent log files |
mini projects |
All known projects |
mini open |
Print output directory (cd $(mini open)) |
mini config |
View/set API key env var |
Key flags
mini build "goal" --agents 4 # override agent count
mini build "goal" --output-dir ~/myproject
mini watch --interval 5 # refresh every 5s
mini bench --project my-project-1200
How it works
mini build "snake game"
│
▼
┌─────────────┐
│ decomposer │ Claude call → flat task list + dependency DAG
└──────┬──────┘
│
▼
┌─────────────┐
│ board │ SQLite (WAL mode) — the shared environment
└──────┬──────┘
│ MCP server exposes 5 tools to each agent
│
┌────┴────┐
│ │
agent-1 agent-2 ... agent-N (tmux panes)
│ │
└─────────┘
read/write the same board, never each other
Board MCP tools (what agents see)
| Tool | Purpose |
|---|---|
request_next_task |
Claim next task whose deps are all DONE |
log_artifact |
Store output (API spec, schema, file path) |
log_decision |
Record an architectural choice |
get_task_context |
Read artifacts from dependency tasks |
report_done |
Mark task complete, unblock dependents |
Task assignment (atomic SQL)
A task is claimable when status = 'TODO' and every dependency has
status = 'DONE'. The claim runs inside BEGIN EXCLUSIVE with a
json_each() dependency check — no race conditions, no external lock manager.
Coordination tax
mini bench measures the gap between theoretical and actual parallelism:
agent utilization = total task work / (n_agents × wall_time)
coordination tax = 1 − utilization
A tax of 0 % means every agent was always working. Typical software projects land at 30–60 % due to the critical path.
Project structure
marcus-mini/
├── marcus_mini/
│ ├── board.py # SQLite board + async API
│ ├── board_server.py # MCP server (5 tools)
│ ├── cli.py # mini CLI (Click)
│ ├── decomposer.py # Claude → task DAG
│ ├── models.py # Task dataclass
│ ├── monitor.py # tmux monitor pane
│ └── spawn.py # tmux agent spawner
├── prompts/
│ └── agent_prompt.md # agent loop instructions
├── tests/
└── pyproject.toml
The evolution: Marcus
marcus-mini proves the concept. Marcus
is the production system built on the same coordination primitives, adding:
- Contract-first decomposition — agents agree on APIs before building, enabling coordination beyond software (any domain with specifiable contracts)
- Full observability — structured logging, experiment tracking, run comparison
- Enterprise resilience — circuit breakers, retry strategies, error framework
- Multi-provider support — agent-agnostic board protocol
If marcus-mini is the proof, Marcus is the product.
Why not CrewAI / AutoGen / LangGraph?
Those frameworks route messages between agents. marcus-mini does not. Agents
in this system are genuinely autonomous — they pull work, they decide how to do
it, they post results. The board is the only channel.
This means: parallelism is structural (DAG-derived), not programmed. You don't write agent communication logic. You write a goal, and the board handles the rest.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file marcus_mini-0.1.0.tar.gz.
File metadata
- Download URL: marcus_mini-0.1.0.tar.gz
- Upload date:
- Size: 41.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
330a645900ca101b97cfe4dfe6e169b4be5cdbd4e9d1657dda5a1150715170b2
|
|
| MD5 |
0d687ef73580d47fa61996e8bbd2cc47
|
|
| BLAKE2b-256 |
2ed2600c7ff88d538c7ca3f598326bf52aaed5f76b5948b9fffc5b68bac511b4
|
Provenance
The following attestation bundles were made for marcus_mini-0.1.0.tar.gz:
Publisher:
publish.yml on lwgray/marcus-mini
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
marcus_mini-0.1.0.tar.gz -
Subject digest:
330a645900ca101b97cfe4dfe6e169b4be5cdbd4e9d1657dda5a1150715170b2 - Sigstore transparency entry: 1417002970
- Sigstore integration time:
-
Permalink:
lwgray/marcus-mini@a9a67ae1f875ed99c34155d7a168dc276c569c31 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/lwgray
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a9a67ae1f875ed99c34155d7a168dc276c569c31 -
Trigger Event:
push
-
Statement type:
File details
Details for the file marcus_mini-0.1.0-py3-none-any.whl.
File metadata
- Download URL: marcus_mini-0.1.0-py3-none-any.whl
- Upload date:
- Size: 35.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a66d63039bcfd5b10fdda004e364a577020226fd5a3d2b38331b8106f8ad6fed
|
|
| MD5 |
fbeaf8e87e423f914a73d5f1408465be
|
|
| BLAKE2b-256 |
2bf422b19ff75d9a5b06db60f554515247f434b17cc28351b1785bfc2c1e5e09
|
Provenance
The following attestation bundles were made for marcus_mini-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on lwgray/marcus-mini
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
marcus_mini-0.1.0-py3-none-any.whl -
Subject digest:
a66d63039bcfd5b10fdda004e364a577020226fd5a3d2b38331b8106f8ad6fed - Sigstore transparency entry: 1417003029
- Sigstore integration time:
-
Permalink:
lwgray/marcus-mini@a9a67ae1f875ed99c34155d7a168dc276c569c31 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/lwgray
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a9a67ae1f875ed99c34155d7a168dc276c569c31 -
Trigger Event:
push
-
Statement type: