kanban-agent
Kanban Agent
File-based kanban for coding-agent fleets. A PM agent writes markdown work
items into work-items/pending/, worker agents claim them with git mv, and
the folder a file sits in is its status — no database, no service, no
lock server. The repo is the queue, git is the lock, and any agent (Claude
Code or otherwise) or any human with a file manager can operate it. On top of
the convention sit a zero-dependency live dashboard (the cockpit) and an
MCP server that attaches the workflow to any project and drives the queue
through tools.

Why
When several coding agents work a backlog in parallel, the coordination layer usually becomes the hard part: a ticket API to integrate, a database to host, credentials to distribute. Kanban Agent removes that layer instead of adding to it:
Plain files — a work item is a markdown file; its folder is its status. Every agent can read and write files; no SDK required.
Git is the lock — claiming an item is
git mv pending/007-… in-progress/007-…. Two workers cannot both win the move, and history doubles as an audit log.Reviewable backlog — items travel with the code. Specs, acceptance criteria and results are diffable, greppable and PR-reviewable.
Watchable — the cockpit tails every queue on the machine over
fs.watch+ SSE, so you can watch a fleet burn down a backlog live.
Quickstart
git clone https://github.com/gak4u/kanban-agent.git
cd kanban-agent
npm start # → http://localhost:4400Requires Node ≥ 20. Zero npm dependencies, no build step. On first start the
server seeds projects.json from projects.example.json, which points at the
bundled examples/demo-project — so you get a
populated board out of the box. Edit projects.json to track your own
projects.
The convention
Each tracked project has a work-items/ directory at its root
(full spec: docs/convention.md):
work-items/
pending/ NNN-slug.md ← ready to be picked up
in-progress/ NNN-slug.md ← claimed by a worker
review/ NNN-slug.md ← on a pushed branch, awaiting human verification
blocked/ NNN-slug.md ← stuck; has a "## Blocked" note
done/ NNN-slug.md ← finished + verified (merged)
_TEMPLATE.md README.md WORKER_PROMPT.md _artifacts/ ← not work itemsFolder = status. Files carry a
status:frontmatter field but it goes stale; the folder is always authoritative.NNNordering. Items areNNN-slug.mdwith a zero-padded number that is allocated once across all four folders — it doubles as FIFO/priority order. Workers always claim the lowest-numbered pending item.Frontmatter fields (all optional, parsed leniently):
id,title,type(feature|bug|chore),priority(P1|P2|P3),created(YYYY-MM-DD),status,depends_on/stacks_on(item number),needs_migration(bool).Claim protocol. A worker claims an item by moving it:
git mv work-items/pending/NNN-slug.md work-items/in-progress/— the move is the lock; never touch a file already inin-progress/. Finished items get their## Resultsection filled and move todone/; stuck items get a## Blockednote and move toblocked/.
The cockpit
A read-only web dashboard over every queue on the machine:
Overview — one card per project: per-status counts, done-vs-total progress, what is in progress right now; blocked counts light up when > 0.
Board — four kanban columns per project, cards ordered by item number (Done newest-first) with type/priority badges, acceptance-criteria progress,
stacks_on/depends_onchips and last-activity time.Item drawer — click a card for the rendered markdown, with frontmatter as a key/value header (a stale frontmatter
statusis flagged).Live — the server watches the status folders (
fs.watch) and pushes refreshes over SSE; the UI falls back to 10-second polling if SSE fails.


The server binds to 127.0.0.1 only (localhost tool, no auth) and never writes
to tracked projects. API: GET /api/projects (all queues, parsed),
GET /api/item?project=&status=&file= (one item, raw + rendered),
GET /api/events (SSE refresh stream).
The MCP server
mcp/server.js is the write side: it attaches the workflow to any project and
operates queues from any MCP client (sole dependency:
@modelcontextprotocol/sdk).
cd mcp && npm install # once
claude mcp add --scope user kanban-agent -- node /path/to/kanban-agent/mcp/server.js(claude mcp list should then show kanban-agent … ✔ Connected.)
Hosted mode (one server for a team)
The same tool set can be served over the MCP Streamable HTTP transport so a
team's agents share one server: per-user Bearer tokens (roles admin /
member), server-managed projects operated by name, created_by/claimed_by
attribution with completion commits authored as the item's creator (and pushed
to the project's origin), an /admin panel for users + projects, and user
chips / an active-claims strip on the dashboard.
node server/bootstrap.js # once — creates the user store, prints the admin token
npm run mcp-http # serves http://0.0.0.0:4401/mcp (port: KANBAN_MCP_PORT)
npm run agent-runner # optional: the server works its own queues (see below)With the built-in agent runner, the server executes pending items itself:
up to N parallel agents (configurable live in /admin → Settings, 1–16)
backed by the GLM coding API, each with shell + file tools scoped to its
project tree. Runner health, active runs and per-run transcripts are on the
/admin → Agents view. Details: docs/hosted.md.
Each user registers the server with their own token (stdio one-liner above stays the local single-user path):
claude mcp add --transport http kanban-agent http://<server>:4401/mcp --header "Authorization: Bearer <token>"Reading the cockpit board stays unauthenticated — tokens gate writes and administration. Architecture, team quickstart, attribution/push flow and ops notes: docs/hosted.md.
Attach the workflow to a project
Call
attach_workflowwith the project's absolute path (optionallyverify_command, e.g.npm test && npm run build, andapp_urlfor live checks). It scaffoldswork-items/{pending,in-progress,blocked,done,_artifacts}/with the queueREADME.md,_TEMPLATE.mdand a parameterizedWORKER_PROMPT.md, and appends a## Work-item queuesection to the project'sCLAUDE.md(orAGENTS.md). Idempotent — a second run skips everything that exists.Commit the scaffold in that project.
Have a PM agent write items (
create_work_item, or by hand from_TEMPLATE.md— thepm-write-itemsprompt sets an agent up for this), then spawn workers with theworker-loopprompt: claim → implement → verify → done, polling until idle.Watch it live in the cockpit — the project auto-discovers if it sits under an
autoDiscoverRootsentry.
Tools
Tool | What it does |
| Scaffold the queue + agent instructions into a project (idempotent). |
| Per-status counts + |
| Allocate the next |
| Move the lowest- |
| Fill |
| Human verified a review item: merge its branch into base ( |
| Append a |
| Blocker resolved: record the resolution, move back to |
| Status + raw markdown, searching all folders. |
| Every tracked/discovered project with status counts (hosted mode: the server registry). |
Queue tools accept project_path (absolute path, local mode) or project
(server-managed project name, hosted mode). Admin tools — hosted mode only,
admin role required:
Tool | What it does |
| Clone or init a git tree under |
| Hide a project from lists; files are never deleted. |
| Create a user; returns the one-time API token. |
| Invalidate a user's token immediately. |
| Issue a new token (returned once), killing the old one. |
Prompt | What it returns |
| The project's |
| PM guidance: verify requests, write fully-specified items. |
All writes are confined to <project_path>/work-items/ (plus the one
instructions append); filenames are validated against NNN-*.md, ids against
\d+ — traversal is rejected.
Configuration
projects.json at the repo root (gitignored; seeded from
projects.example.json on first start):
{
"projects": [
{ "name": "Demo Project", "path": "examples/demo-project" }
],
"autoDiscoverRoots": ["/absolute/path/to/your/projects"]
}projects— explicit list;nameis what the UI shows. Paths may be absolute or relative to the config file.autoDiscoverRoots— every direct child of these directories that contains awork-items/folder with at least one status subfolder is added automatically (deduped against the explicit list). New projects appear with zero config.PROJECTS_CONFIG=/path/to/other.json— point the cockpit and the MCP server at an alternate config.PORToverrides the cockpit's port (4400).
More
docs/convention.md— the full queue convention.docs/design.md— how the cockpit and MCP server are built.CONTRIBUTING.md— dev setup and PR guidelines.
License
MIT © 2026 gak4u
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/gak4u/kanban-agent'
If you have feedback or need assistance with the MCP directory API, please join our Discord server