Kanbaroo
A kanban-style issue tracker with a TUI, REST + WebSocket API, CLI, and MCP server. Designed to be useful standalone, and to integrate with trusty-cage for AI-driven workflows.
Status: Phase 2 complete. Single-user, terminal + web + AI.
What it does
Kanbaroo exposes the same data through five surfaces:
- TUI (Textual) for terminal-centric humans: workspace list, kanban board, story detail, fuzzy search, audit feed.
- Web UI (React SPA, served by the API at
/ui): workspace list, kanban board with drag-to-transition, story detail, comments, tags, live WebSocket updates, keyboard shortcuts. - CLI (Typer + Rich): scriptable access to every resource, JSON output for pipelines.
- REST + WebSocket API (FastAPI): the source of truth. WebSocket feeds live change events; REST is always authoritative.
- MCP server: lets AI agents (outer Claude in particular) read and write the board through the Model Context Protocol.
The data model is intentionally Jira-shaped but simpler. Workspaces contain optional Epics which contain Stories. Stories carry comments, tags, typed linkages, priority, and a standard kanban lifecycle. Every mutation is attributed to a human, claude, or system actor and recorded in an immutable audit log.
Architecture
flowchart TB
subgraph clients["Clients"]
TUI["TUI<br/>(Textual)"]
CLI["CLI<br/>(Typer + Rich)"]
MCP["MCP Server<br/>(mcp SDK)"]
WEB["Web UI<br/>(React SPA)"]
end
subgraph server["Kanbaroo Server"]
REST["FastAPI<br/>REST endpoints"]
WS["WebSocket<br/>event stream"]
CORE["kanbaroo-core<br/>(business logic)"]
end
subgraph storage["Storage"]
DB[("SQLite (local)<br/>Postgres (cloud)")]
end
subgraph external["External Consumers"]
DUCK["DuckDB / Snowflake<br/>(read-only)"]
GHA["GitHub Actions<br/>(read-only scripts)"]
end
TUI -->|HTTP + WS| REST
TUI -->|HTTP + WS| WS
CLI -->|HTTP| REST
MCP -->|HTTP| REST
WEB -->|HTTP + WS| REST
REST --> CORE
WS --> CORE
CORE --> DB
DB -.->|direct read| DUCK
DB -.->|direct read| GHA
style DUCK stroke-dasharray: 5 5
style GHA stroke-dasharray: 5 5
Installation
Requires Python 3.12 or newer.
# Everything (server + TUI + CLI + MCP)
pip install 'kanbaroo[all]'
# Or pick and choose:
pip install kanbaroo-api # Just the server (no web UI)
pip install 'kanbaroo-api[web]' # Server + bundled web UI at /ui
pip install kanbaroo-cli # CLI only (pulls in core)
pip install kanbaroo-tui # TUI only
pip install kanbaroo-mcp # MCP server only
Contributors working from a checkout should use the uv workspace instead:
uv sync --all-packages --dev
Quickstart
For a human walking up cold, all the way from install to a running board:
# 1. Install
pip install 'kanbaroo[all]'
# 2. Initialize config dir, apply migrations, mint your first token
kb init
# 3. Start the server (docker compose under the hood)
kb server start
# 4. Create your first workspace
kb workspace create --key KAN --name "My Work"
# 5. File a story
kb story create --workspace KAN --title "First task"
# 6. In another terminal, open the TUI on the board
kanbaroo-tui
Press ? on any TUI screen for the keybinding cheatsheet. Press / from the workspace list or board for fuzzy search. a opens the global audit feed.
Configuration
Kanbaroo reads settings from $KANBAROO_CONFIG_DIR/config.toml (default ~/.kanbaroo/config.toml), which kb init creates for you. Environment variables override the TOML values when set.
| Variable | Consumed by | Default / note |
|---|---|---|
KANBAROO_DATABASE_URL |
core, api, kb init, kb backup |
Required for the API to start. Docker supplies sqlite:////data/kanbaroo.db inside the container. |
KANBAROO_API_URL |
cli, tui, mcp | Overrides api_url in config.toml. Example: http://localhost:8080. |
KANBAROO_TOKEN |
cli, tui | Bearer token for API auth. Overrides token in config.toml. |
KANBAROO_MCP_TOKEN |
mcp | MCP-specific token; falls back to KANBAROO_TOKEN. |
KANBAROO_CONFIG_DIR |
cli, tui, mcp, kb init |
Override for the config directory. Default: ~/.kanbaroo. |
KANBAROO_WORKSPACE |
cli | Default workspace key so you can omit --workspace on every command. Example: KAN. |
KANBAROO_API_HOST |
api server | Uvicorn bind host. Default: 0.0.0.0. |
KANBAROO_API_PORT |
api server | Uvicorn bind port. Default: 8080. |
KANBAROO_COMPOSE_FILE |
kb server |
Path to a non-default docker-compose.yml (useful for CI). |
KANBAROO_MCP_LOG_LEVEL |
mcp | INFO by default; DEBUG for verbose MCP logs. |
For a long-lived single-user setup with per-project token attribution, host-bind-mounted SQLite, and nightly snapshots, see docs/deployment-dogfood.md. The fastest path to wire a single project up to a running Kanbaroo server is kb project init, which creates the workspace, mints a per-project claude token, and writes a project-root .mcp.json in one shot.
Web UI
The kanbaroo-web package ships a Vite + React SPA that kanbaroo-api serves at /ui. Once the API is running, visit http://localhost:8080/ui in a browser.
First-boot inside the container
kb server start runs docker compose up -d; the API runs inside the kanbaroo-api container with its SQLite DB on a named volume. The volume is blank on first boot, so migrations and the initial token have to happen inside the container:
# Bring the stack up
kb server start
# Apply migrations
docker compose exec -e KANBAROO_DATABASE_URL="sqlite:////data/kanbaroo.db" \
kanbaroo-api \
uv run --no-dev alembic -c /app/packages/kanbaroo-core/alembic.ini upgrade head
# Mint the first token (print it once; save it)
docker compose exec -e KANBAROO_DATABASE_URL="sqlite:////data/kanbaroo.db" \
kanbaroo-api \
uv run --no-dev kb init
Copy the kbr_ token that kb init prints and paste it into the /ui login form. The token is stored in browser localStorage under kanbaroo.token; press "Log out" to clear it.
You can also mint additional tokens later with kb token create --actor-type human --actor-id you --name "web" (inside the container, same docker compose exec wrapper).
Shipped in v0.2.0:
- Workspace list with inline create.
- Kanban board with drag-to-transition, illegal-move rejection, optimistic updates.
- Story detail: markdown description, metadata, comments (with one-level replies), tags, audit trail.
- Live updates via the existing
/api/v1/eventsWebSocket. - Story creation modal (
non the board). - In-board search (
/on the board; matches on human id prefix and title substring). - Keyboard shortcuts:
nnew story,/search,eedit story,?shortcut help,Escapeclose modal / clear search / exit edit mode.
The release wheel auto-includes the built bundle, so pipx install --include-deps 'kanbaroo[all]' picks up the UI. Node 20+ is only required at build time for maintainers publishing a new release.
Developing the web UI
make web-build # Build the SPA into packages/kanbaroo-web/src/kanbaroo_web/dist/
make web-dev # Vite dev server on :5173, proxies /api and /api/v1/events to :8080
make web-test # vitest, single-shot
MCP setup
Let an AI agent drive Kanbaroo through the Model Context Protocol. The MCP server is a thin translator between the MCP tool protocol and the Kanbaroo REST API; every mutation routes through the API and is attributed to the MCP token's actor.
First create a dedicated claude-typed token so AI mutations are audited correctly:
kb token create --actor-type claude --actor-id outer-claude --name "claude"
Copy the plaintext that kb token create prints into KANBAROO_MCP_TOKEN in your shell, then add this to Claude's mcpServers block:
{
"mcpServers": {
"kanbaroo": {
"command": "kanbaroo-mcp",
"args": ["--api-url", "http://localhost:8080", "--token-env", "KANBAROO_MCP_TOKEN"]
}
}
}
See docs/mcp-setup.md for the full walkthrough, the smoke test, and the tool reference.
Docs
docs/spec.md: authoritative design intent. Start here if you want the why.docs/api-reference.md: generated REST API reference.docs/mcp-setup.md: MCP setup guide for AI agents.docs/future-skill-draft.md: draft workflow skill for AI agents using Kanbaroo via MCP.CLAUDE.md: guidance for Claude Code when working in this repo.CHANGELOG.md: release notes.
Development
This is a uv workspace monorepo with six packages in packages/ (kanbaroo-core, -api, -cli, -tui, -mcp, -web) and a top-level meta-package with an [all] extra. Before committing anything:
uv run ruff format .
uv run ruff check --fix .
uv run mypy packages/
uv run pytest
License
MIT. See LICENSE.
Release files for kanbaroo 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| kanbaroo-0.3.0.tar.gz | 696.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kanbaroo-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 702.6 kB
Release files / kanbaroo-0.3.0.tar.gz
| Download URL | kanbaroo-0.3.0.tar.gz |
|---|---|
| Size | 696.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4226d3b649a642f4c877c88330e7a81709ebe03a2f731a1eccc204fec414f3e5
|
|
BLAKE2b-256 checksum How to use checksums |
664cb07e80ae8e9fe24e167d538149fed69dff1074acf9e67f6c7c77107ca786
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / kanbaroo-0.3.0-py3-none-any.whl
| Download URL | kanbaroo-0.3.0-py3-none-any.whl |
|---|---|
| Size | 6.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
746944faf93dda275a87324767f71e1ed7c17d03dd6ae29832080ad54caa537a
|
|
BLAKE2b-256 checksum How to use checksums |
23770aa49c06186dc67a0a00732b4937598c05ef48edd34f722f84326b394036
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|