@protomaze/kanban
v0.1.15
Published
A simple, useful Kanban board with a React web UI and a first-class API for AI agents (REST + SSE + CLI + MCP).
Downloads
1,705
Maintainers
Readme
@protomaze/kanban
A small, self-hosted Kanban board: a React web UI for people, and a REST/CLI/MCP API built so an AI agent can read the board, get notified when it changes, and manage cards and columns without any special handling.
- Web UI — drag-and-drop board, live updates (no refresh needed), card detail with comments, WIP limits, search.
- REST API — full CRUD on cards/columns, plus
/api/changes(long-poll) and/api/stream(SSE) so nothing has to busy-poll. - CLI (
kanban) — script it from anywhere, or use it as your own agent's hands when MCP isn't available. - MCP server (
kanban-mcp) — drop-in tools for Claude/other MCP clients: read the board, add/move/comment on cards, watch for changes. - Single JSON file as the source of truth (
.kanban/board.json) — easy to back up, diff, or hand-edit; the running server picks up external edits. - Ships with the repo — a plain-text
TODO.mdsnapshot is regenerated on every change, so the current board state is readable on GitHub with nothing running. See Shipping the board with your project. - One dashboard for every board on your machine —
kanban hublists every board you'vekanban init'd orkanban serve'd, across every project, and launches any of them on click. See Hub.
This repo tracks its own work with it — see TODO.md or npm run
board.
Install
npm install -g @protomaze/kanbanQuick start
kanban serveThis starts the web UI + API at http://127.0.0.1:4300 (opens your browser)
and creates ./.kanban/board.json with five default columns (Backlog, Todo,
In Progress, Review, Done). Leave it running while you work — the CLI and any
agent will talk to it automatically.
If you're setting this up inside a project you'll come back to (rather than
just trying it out), use kanban init instead — see the next section.
CLI
kanban add "Fix login redirect" --column todo --priority high --labels bug,auth
kanban ls --label bug
kanban mv KAN-3 "In Progress"
kanban comment KAN-3 "Reproduced on staging"
kanban show # whole board as text
kanban changes --since 12 # what happened after seq 12
kanban watch # stream changes until ctrl-cRun kanban help for the full command list. A card <ref> can be its id, a
key like KAN-3 (or just 3), or its exact title.
Every command works two ways:
- Server running — talks to it over HTTP, so the web UI updates instantly.
- No server — falls back to reading/writing
.kanban/board.jsondirectly (pass--localto force this even if a server is up).
For AI agents
Three ways in, pick whichever fits the harness:
1. MCP (recommended for MCP-capable agents)
{
"mcpServers": {
"kanban": {
"command": "kanban-mcp",
"args": ["--url", "http://127.0.0.1:4300"]
}
}
}Ten tools: kanban_board, kanban_changes, kanban_list_cards,
kanban_get_card, kanban_add_card, kanban_update_card,
kanban_move_card, kanban_comment_card, kanban_remove_card,
kanban_manage_columns. Each returns plain text meant to be read directly,
and errors come back as tool output (Error: ...) rather than a protocol
failure, so the model can self-correct.
Getting notified of changes, without polling in a loop: call
kanban_changes with the last seq you saw and a waitSeconds — the call
blocks server-side and returns the instant something happens (or after the
timeout, whichever is first).
2. CLI
Any agent that can run shell commands can just use kanban ... as above.
kanban changes --since N --wait 30 --json is the scriptable version of the
same long-poll.
3. REST, directly
GET /api self-describing index of every endpoint
GET /api/board full board (columns + cards)
GET /api/summary the board as compact plain text
GET /api/changes?since=N&wait=30 long-poll for changes after seq N
GET /api/stream Server-Sent Events, one message per change
POST /api/cards {title, body?, column?, labels?, assignee?, priority?}
POST /api/cards/:ref/move {column, position?}
POST /api/cards/:ref/comments {text, author?}Set X-Kanban-Actor: <name> on write requests so the activity log (and the
web UI) show who made the change. See GET /api for the complete list.
Shipping the board with your project
The board is designed to travel with a repo, not live off to the side on one person's machine:
cd your-project
npm install -D @protomaze/kanban
npx kanban initkanban init creates .kanban/board.json (if it doesn't exist yet), writes
its TODO.md snapshot, and adds "board": "kanban serve" to your
package.json scripts if one isn't already there. It's safe to run again
later — it won't touch an existing board or overwrite a script you've
customised.
Commit .kanban/board.json and TODO.md. From then on:
- Anyone who clones the repo can see the current state by opening
TODO.md— no install, no running server. It's regenerated on every change (checkbox lists per column,Donecards checked off), so it's never stale for long once someone's had the board open. - Anyone who wants to actually use the board runs
npm install && npm run board, which starts the same server the last person used.
Two things worth knowing:
TODO.mdis a derived file — edit the board, not the markdown. Hand edits toTODO.mdget overwritten on the next change and never feed back in.- Committing
board.jsonmeans concurrent edits on different branches can conflict like any other JSON file (card ids and timestamps make the diff noisy but git will still show you exactly what moved). For a single active board this is rarely an issue in practice.
Hub
Once you've set up a few boards across a few projects, you don't want to
remember which port each one runs on. kanban init and kanban serve both
register the board in a small machine-local registry (~/.kanban/registry.json
by default, or $KANBAN_HOME/registry.json). kanban hub serves one page
listing every board that's ever been registered:
kanban hubEach board is read straight off its board.json — no need for its server to
be running — so the list is accurate even if nothing else is. Clicking a
board that isn't running launches it on demand (in-process, no extra CLI
window) and takes you straight there; clicking a running one just opens it.
Boards launched this way stay up for as long as the hub does.
Data model
- Board → columns (ordered, optional WIP limit) → cards (ordered within their column).
- Cards have a title, body, labels, assignee, priority
(
low/medium/high/urgent), and comments. - Every mutation appends an event (
card.created,card.moved, ...) with a monotonicseq. That log is the changefeed the web UI, CLIwatch, and MCPkanban_changesall read from — it's the one primitive that makes "did anything change?" a cheap question to ask.
Development
npm install
npm run dev:server # API on :4300
npm run dev:web # Vite dev server on :4301, proxies /api to :4300
npm test # node --test test/
npm run build # bundles the web UI into dist/web (served by kanban serve)Publishing
Releases go out via .github/workflows/publish.yml
using npm's Trusted Publishing: no token lives anywhere, in CI or on any
laptop. GitHub Actions proves its identity to npm with a short-lived OIDC
credential, scoped to this exact repo + workflow file.
One-time setup (needs the npm account owner, done once on npmjs.com — see Trusted Publishers):
- Push this repo to GitHub.
- On the package's npmjs.com settings, add a Trusted Publisher: GitHub
Actions, this repo, workflow file
.github/workflows/publish.yml.
After that, a release is just:
npm version patch # or minor / major — bumps package.json and tags it
git push --follow-tagsThe tag push triggers the workflow, which runs the test suite and publishes.
workflow_dispatch is also enabled, so a release can be re-run by hand from
the Actions tab if needed.
For local iteration without touching the public registry, point npm at a local Verdaccio instance instead:
verdaccio --listen 4873 &
npm publish --registry http://localhost:4873
# consumers: npm install @protomaze/kanban --registry http://localhost:4873