Local-first Kanban board with an MCP server for any compatible client.
Run the full stack on your machine — UI, API, Postgres, and agent tools.
Quick start · Features · MCP · Development
Harbor is a single-operator Kanban that stays on localhost. Use the web UI to manage projects and issues, or drive the same board from any MCP client (Claude, Cursor, and others) through a stdio MCP server that talks to the Nest API.
MCP client ──stdio──► Harbor MCP ──HTTP Bearer──► Nest API ──► Postgres
Browser ─────────────────────────► Harbor UI ──/api──► Nest API
| Package | Path | Role |
|---|---|---|
@kanban/api |
apps/api |
NestJS + Prisma + OpenAPI |
@kanban/web |
apps/web |
Harbor UI (Vite + React) |
@kanban/mcp |
apps/mcp |
Stdio MCP server |
- Projects & boards — multiple projects, Columns and List layouts, column colors, reorder, done columns
- Issues — create, edit, move, archive/restore, delete; priority, type, due date, effort (hours / LOC)
- Dependencies — issue links (
blocks,relates_to,duplicates) with cycle checks; blocker summaries via MCP - Labels, comments, activity — label attach/detach, threaded comments, activity history
- Attachments — multipart file upload in the issue drawer (UI/API; max 20 MB)
- Live updates — board refreshes over SSE when the API or an MCP agent changes data
- Global search —
Ctrl/Cmd+Kacross projects - MCP tools — projects, columns, issues, links, blockers, epics, labels, comments, activity
- Auth — first-run admin signup, cookie sessions for the UI, Bearer MCP tokens from Harbor
Requirements: Bun 1.3+, Docker
git clone git@github.com:Eidantz/Harbor.git
cd Harbor
bun install
bun run setup:env # copies .env.example → .env and links apps/api/.env
bun run docker:up # builds & starts db + api + web| Service | URL (defaults) |
|---|---|
| Harbor UI | http://localhost:3010 |
| API health | http://localhost:3001/health |
| OpenAPI | http://localhost:3001/api/docs |
Ports come from .env (WEB_PORT, API_PORT, POSTGRES_PORT). Defaults are 3010 / 3001 / 5433 so Harbor can sit next to stacks that already use 3000 / 5432 (e.g. Langfuse).
On a fresh database, open the UI and create the admin account. After that, the same screen is sign-in. Seed data includes sample project KAN.
Stop the stack with bun run docker:down.
Harbor exposes a stdio MCP server any compatible client can launch (Claude Desktop / Claude Code, Cursor, and others).
- Start Harbor (
bun run docker:up) and complete admin signup. - In the UI: MCP tokens → Create token (copy it once).
- Build the server:
bun run build:mcp- Point your client at the server with the same command + env:
{
"mcpServers": {
"harbor": {
"command": "node",
"args": ["/absolute/path/to/Harbor/apps/mcp/dist/index.js"],
"env": {
"KANBAN_API_URL": "http://127.0.0.1:3001",
"KANBAN_API_TOKEN": "<paste token from Harbor>"
}
}
}
}| Client | Where to put the config |
|---|---|
| Claude Desktop | Claude → Settings → Developer → Edit Config (claude_desktop_config.json) |
| Claude Code | Project or user .mcp.json (same mcpServers shape) |
| Cursor | Copy docs/mcp.example.json → .cursor/mcp.json |
Use an absolute path to apps/mcp/dist/index.js when the client does not start in the repo root. Reload MCP after changing config.
Full tool catalog: apps/mcp/README.md.
Keep Postgres in Docker; run API and web on the host:
bun run setup:env
docker compose up -d db
bun run db:migrate:deploy
bun run db:seed
bun run dev # API :3001 + web :3000Useful scripts: bun run dev:api, bun run dev:web, bun run db:studio, bun run smoke.
| Client | Mechanism |
|---|---|
| Harbor UI | First-run signup, then login → HTTP-only session cookie |
| MCP / scripts | Authorization: Bearer <token> from MCP tokens |
- Compose publishes ports on
127.0.0.1only. - Real secrets live in
.envand local MCP config files (e.g..cursor/) — gitignored. Use.env.exampleanddocs/mcp.example.jsonas templates. - Rotate
SESSION_SECRETand revoke MCP tokens for anything beyond casual local use.