Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

217 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Kanban

A self-hosted, real-time project management board with built-in MCP server — so AI assistants like Claude can read and write your tasks directly.

Built with AI tools: This project was developed using Claude Code, RTK-AI, and code-review-graph.


Table of Contents


Features

Authentication & Security

  • Email + password registration with email verification (SMTP or console fallback in dev)
  • Two-factor authentication (TOTP) — Google Authenticator, Authy, 1Password, any TOTP app
  • Two-step login — email/password then TOTP code when 2FA is enabled
  • JWT access tokens (short-lived) + HTTP-only refresh token cookies (rotated on each use)
  • Rate Limiting — brute-force protection on sensitive routes (login, register, forgot-password)
  • Account Lockout — accounts are temporarily locked after 5 failed attempts
  • API keys — long-lived bearer tokens for MCP / programmatic access

Organizations & Members

  • Create multiple organizations per account
  • Invite members via single-use invitation links (shareable URL)
  • Role system: owner and member
  • Owner can transfer ownership to any member
  • Owner can delete the organization (requires at least one other org)
  • Rename organization and set optional website

Projects

  • Multiple projects per organization
  • Create, rename, and delete projects
  • All members of the org have access to all projects

Kanban Board

  • Four columns: Ideas → To Do → Doing → Done
  • Tasks sorted by due date ascending (overdue first)
  • Drag-and-drop tasks between columns
  • Ideas column collapsible to save horizontal space
  • Color-coded task cards — set a custom background colour per task
  • Auto-assign the moving user as doer when dragging a task to Doing (no doer set)
  • Auto-clear doer when moving back to Todo (drag-and-drop only — MCP move_task never touches the doer, and refuses a move to Doing without one)
  • Stacking task panels — open multiple tasks side-by-side; inactive panels collapse to vertical title strips
  • Side-by-side comparison — hover any task card and click the ⊞ split icon to pin it as a comparison panel alongside your current task

Project Wiki

  • Integrated Wiki — Keep documentation right alongside your projects
  • Collaborative Markdown Editor — Custom-built real-time editor with live sync (no heavy libraries like TipTap/Yjs)
  • Split View — Work on two pages side-by-side; perfect for cross-referencing documentation
  • Tabbed Interface — Keep multiple pages open and switch between them instantly
  • Page Metadata (Properties) — Add frontmatter-style JSON properties to any page for structured data
  • Revision History — View previous versions of any page to track changes over time
  • Intelligent Markdown Links — Link to other wiki pages or tasks directly in your content
  • Unified Search — Find wiki pages and tasks from the same bottom search bar (Cmd+K)

See the Wiki Documentation for more details.

Task Detail

Each task has a rich detail sidebar with:

  • Title and description (multi-line)
  • Objective — group tasks under a goal
  • Global subject — cross-cutting label
  • Start date and end date
  • Reporter, Doer, Validator — assignable to any org member
  • Watchers and Advisors — additional stakeholders
  • Tags — free-form, with autocomplete from existing tags
  • Linked tasks — bidirectional links between tasks
  • Custom background colour — colour picker
  • History log — every field change recorded with who changed it and when, ordered newest-first deterministically (ties broken by insertion order)
  • Conflict detection — if two users edit the same field simultaneously, the second user gets a warning with merge options

Filtering

  • Filter by tag — click any tag chip on a card
  • Filter by objective
  • Filter by doer — click an avatar
  • Multiple active filters combine (AND)
  • Active filters shown as removable chips with "Clear all"

Archive

  • Multi-select Done tasks with checkboxes
  • Archive in bulk with one click
  • Resizable archive panel at the bottom — drag to resize
  • Search archived tasks by title
  • Paginated results
  • Restore archived tasks back to Todo

CSV Import

  • Upload a .csv file to bulk-create tasks
  • Columns: title, description, startDate, endDate, column
  • Invalid rows are skipped and reported; valid rows are imported atomically

Real-Time Collaboration

  • WebSocket connection per board — live dot indicator (green = connected)
  • Task creates, updates, deletes, moves, and reorders pushed to all connected users instantly
  • Conflict-aware editing — if you are typing in a field and a remote update arrives, the change is held until you blur, then you are shown a diff and asked to choose

Profile

  • View and update display name
  • Manage TOTP 2FA — enable with QR code scan, disable with code confirmation
  • Resend email verification link
  • Generate and revoke MCP API keys with labels

MCP Server (Model Context Protocol)

  • Exposes your board as an MCP server for AI tools
  • Streamable HTTP transport
  • Authenticated via API key (Authorization: Bearer <key>)
  • Tools available to AI:
    • list_organizations, create_organization, list_members
    • list_projects, create_project
    • get_board
    • list_tasks, get_task, get_task_history, create_task, update_task, append_task_note, move_task, delete_task
    • list_wiki_pages, get_wiki_page, create_wiki_page, update_wiki_page, delete_wiki_page
    • get_wiki_history, search_wiki
    • set_wiki_page_property
    • search_knowledge, audit_knowledge_freshness, create_capture, promote_capture_to_task, promote_capture_to_wiki_page

Screenshots

Sign in

Sign in

Organizations

Organizations

Projects

Projects

Kanban Board

Tasks sorted by due date, colour-coded, with tags and assignees visible at a glance. The Ideas column is expanded on the left.

Kanban Board

Task Detail Sidebar

Click any card to open the full detail panel — description, dates, assignees, tags, linked tasks, colour picker, and history.

Task Detail

Stacking Task Panels

Open multiple tasks simultaneously. Inactive panels stack to the right as thin 48px vertical title strips for quick switching. The board remains accessible via horizontal scrolling.

Stacking Panels

Side-by-side Task Comparison

Hover any task card and click the ⊞ split icon to open it as a pinned comparison panel alongside your current task. Clicking other cards replaces only the right panel. Close the comparison with the dashed-split icon in the left panel header.

Compare Panels

Tag Filtering

Click any tag chip to filter the board. Active filters shown as removable chips.

Filtering

Archive Panel

Archived tasks are searchable and restorable from the collapsible panel at the bottom.

Archive

Profile & MCP API Keys

Set up 2FA, generate API keys, copy the MCP config snippet for Claude.

Profile

Registration

Register


Tech Stack

Layer Technology
API Hono on Node.js
Database SQLite via Drizzle ORM + better-sqlite3
Real-time WebSockets (@hono/node-ws)
Web Next.js 16 App Router (Server Components + Server Actions)
Auth JWT access tokens, HTTP-only refresh cookies, Argon2 password hashing
2FA otplib (TOTP) + qrcode
Email nodemailer (SMTP)
Drag & Drop @dnd-kit
MCP @modelcontextprotocol/sdk
Monorepo pnpm workspaces + Turborepo
Tests Vitest + in-memory SQLite

Getting Started

Environment Configuration

The application uses an agnostic approach to configuration. Copy .env.example to .env and configure your secrets.

The core of the "Plug & Play" setup is the URL configuration:

  • API_URL: Base URL for the API (server-side).
  • WS_URL: WebSocket URL for the browser.

Zero-Config Switching

The project is designed so you never have to change your .env when switching between Docker and Local development:

  1. Set your .env for Local Dev (localhost, relative paths).
  2. docker-compose.yml automatically overrides these values with specific container-internal addresses (api:3001, absolute paths) when running in Docker.

Local Development

Prerequisites: Node.js ≥ 22, pnpm ≥ 10

# Clone and install
git clone https://github.com/sherault/kanban
cd kanban
./scripts/setup.sh    # Initialize .env and generate secrets
pnpm install

# Start all apps via Turborepo
pnpm dev

Open http://localhost:3000 (Web) and the API will be available on http://localhost:3010.

Docker for Deployment (Local)

The primary docker-compose.yml is used for "production-like" deployments on your local machine.

# Initialise environment
./scripts/setup.sh

# Build and start
docker compose up -d --build
  • Unified Entry Point: http://localhost:3000
    • /ws and /mcp/* are automatically routed to the API.
    • Everything else is routed to the Web app (SSR).

Self-Hosting (Production with SSL)

For a real deployment on a server with a domain name and automatic HTTPS:

# Initialise environment
./scripts/setup.sh

# Set your domain and start with the production config
DOMAIN=kanban.example.com docker compose -f docker-compose.prod.yml up -d --build

Caddy will automatically generate and renew SSL certificates via Let's Encrypt for your domain. Ensure ports 80 and 443 are open.

The SQLite database is persisted to ./data/kanban.db on the host.

Docker for Development

If you want to run the whole stack in Docker with Hot Module Replacement (HMR) and source code volumes:

# Start in dev mode
docker compose -f docker-compose.dev.yml up --build

This setup mounts your local project directory into the containers and runs pnpm dev.


Demo Data

A seed script creates three demo users, one organization, two projects, and a realistic set of tasks across all columns.

Requirements: both pnpm dev servers must be running.

node scripts/seed.mjs

User accounts: alice@acmecorp.io, bob@acmecorp.io, carol@acmecorp.io. Password: demo1234.


MCP Integration (Claude / AI)

Connect Claude (or any other MCP client) to your board from the Profile page by generating an API key. The page provides ready-to-use config snippets that automatically use the correct URL for your environment (Local vs Docker/Hosted).

Config Snippet Example:

{
  "mcpServers": {
    "kanban": {
      "type": "http",
      "url": "http://localhost:3000/mcp/",
      "headers": { "Authorization": "Bearer <your-key>" }
    }
  }
}

Available Tools

  • list_organizations: List all organizations the current user belongs to.
  • list_members: List the members of an organization with their id, display name, and role — use the returned ids to assign tasks.
  • create_organization: Create a new organization.
  • list_projects: List all projects within an organization.
  • create_project: Create a new project.
  • get_board: Full board snapshot in one call — every column with each task's doer, deadline, tags, and colour. Use this at session start instead of several paginated list_tasks calls. Archived tasks are excluded. limitPerColumn is configurable (1–200, default 50) with an overflow indicator per column.
  • list_tasks: List tasks in a project with filtering and pagination. Filters: column, tags (a task must carry every listed tag), doerId, validatorId, search. Always ordered by due date ascending. tag remains as a deprecated single-tag alias.
  • get_task: Get a single task by ID, including tags, links, watchers, advisors, and assignments. Use it instead of list_tasks when the ID is already known; archived tasks come back with an extra archived: true field.
  • get_task_history: Get the change history of a task, newest first — who changed which field, from what to what, when, and from where (source: "mcp", "web", or null for entries recorded before source tracking). Supports a field filter and pagination; long values are truncated to 500 characters. field: "note" yields the task log book — one entry per append_task_note call, holding only the appended text.
  • create_task: Create a new task (supports tags, doer, and validator assignment).
  • update_task: Update task details. Tags can be set wholesale with tags, or edited incrementally with addTags/removeTags (mutually exclusive with tags).
  • append_task_note: Append a note to the end of a task description, atomically server-side. Use it instead of read + update_task(description) for traceability blocks: it never overwrites concurrent edits and needs no prior read. The server prefixes the note with a UTC timestamp heading naming the current doer, and records the note text alone as a note history entry (read it back with get_task_history(field: "note")).
  • move_task: Change task column. Unlike drag-and-drop, it never auto-assigns or auto-clears the doer — and because of that it rejects (422) a move to doing on a task with no doer. Assign one with update_task first.
  • delete_task: Remove a task.
  • link_tasks: Add a bidirectional link between two tasks.
  • unlink_tasks: Remove a link between two tasks.
  • archive_task: Archive a task in the 'done' column.
  • list_archived_tasks: Retrieve and search through archived tasks.
  • restore_task: Restore an archived task back to the 'todo' column.
  • list_wiki_pages: List all wiki pages in an organization.
  • get_wiki_page: Get the full content and metadata of a wiki page.
  • create_wiki_page: Create a new wiki page with markdown content and optional properties.
  • update_wiki_page: Update page title, content, parent, or properties.
  • set_wiki_page_property: Update one page metadata property without rewriting the whole page.
  • delete_wiki_page: Remove a wiki page.
  • get_wiki_history: View the full revision history of a wiki page.
  • search_wiki: Search wiki pages by title across the organization.
  • search_knowledge: Search wiki content, wiki properties, and tasks together.
  • audit_knowledge_freshness: Find stale, draft, unsourced, expired, or incomplete wiki pages and optionally create review tasks.
  • create_capture: Create a second-brain inbox capture as a wiki page, optionally with a linked triage task.
  • promote_capture_to_task: Turn a capture page into an actionable task and mark the capture triaged.
  • promote_capture_to_wiki_page: Turn a capture page into durable wiki knowledge and mark the capture triaged.

Kanban Markdown Links

Kanban supports durable interlinks in normal Markdown:

[A wiki page](wiki://<WIKI_PAGE_UUID>)
[A task](task://<TASK_UUID>)

AI clients should search or fetch the target first and then link to the returned id. They should not invent UUIDs.

Wiki page properties are the frontmatter-like details/attributes layer for structured metadata such as doc_type, jurisdiction, validation_status, source_urls, freshness, cite_required, related_wiki_ids, and related_task_ids. Use page content for human-readable Markdown.


Second-Brain Agent Installer

Kanban includes an interactive installer that can provision a personal second-brain instance and configure coding agents to use it through MCP.

Install From GitHub Without Cloning

Prerequisites:

  • Node.js 22 or newer.
  • Docker Desktop or Docker Engine if you want the installer to run Kanban locally.
  • git, or curl plus tar.
  • A workspace folder for the agent config, usually the project where you run Codex or Claude Code.

First do a dry run. The bootstrap downloads the installer source into ~/.kanban/app, but the dry run does not start containers, create Kanban data, or write agent config into your workspace:

curl -fsSL https://raw.githubusercontent.com/sherault/kanban/main/scripts/install-kanban-agent.sh \
  | sh -s -- --dry-run --mode docker --clients codex,claude --workspace "$PWD"

Then run the interactive local install:

curl -fsSL https://raw.githubusercontent.com/sherault/kanban/main/scripts/install-kanban-agent.sh \
  | sh -s -- --mode docker --clients codex,claude --workspace "$PWD"

What this does:

  1. downloads Kanban into ~/.kanban/app;
  2. writes Docker files and SQLite data under ~/.kanban;
  3. starts Kanban with Docker;
  4. asks for an MCP/skill connection name (default: Kanban) and your workspace;
  5. asks for your email, display name, organization, and project names;
  6. creates a verified user, default organization, default project, Second Brain Index, Second Brain Inbox, and triage task;
  7. shows your generated login credentials once;
  8. creates an MCP API key and stores it in the OS keychain when possible;
  9. installs agent instructions, skills, and MCP config into the workspace you passed with --workspace.

If you want to test without touching the default ~/.kanban folder, set a custom install home:

curl -fsSL https://raw.githubusercontent.com/sherault/kanban/main/scripts/install-kanban-agent.sh \
  | KANBAN_HOME="$HOME/.kanban-test" sh -s -- --mode docker --clients codex,claude --workspace "$PWD"

If you already have a hosted Kanban instance, use external mode instead:

curl -fsSL https://raw.githubusercontent.com/sherault/kanban/main/scripts/install-kanban-agent.sh \
  | sh -s -- --mode external --url https://kanban.example.com \
    --clients codex,claude --workspace "$PWD" \
    --integration-name "Personal Kanban" \
    --skip-provision --mcp-key kbk_your_existing_key

From a local checkout:

pnpm agent:install

The installer can:

  • run Kanban locally with Docker in ~/.kanban;
  • connect to an external Kanban URL;
  • create a verified default user, organization, project, inbox wiki page, and triage task for Docker installs;
  • generate an MCP API key without printing it;
  • store the key in the OS keychain when available, with lookup metadata in the connection env file (~/.kanban/agent.env by default);
  • fall back to storing the key in that private connection env file;
  • install the kanban-second-brain skill and MCP configuration for Codex and Claude Code;
  • add experimental Antigravity MCP/instruction files when requested.

Existing Installations And Existing MCP Config

The installer is conservative when files already exist:

  • Existing AGENTS.md and CLAUDE.md content is preserved; the installer adds or updates only its named managed block.
  • Existing .mcp.json and .antigravity/mcp.json keep unrelated MCP servers; the installer adds its selected connection id.
  • Existing .codex/config.toml keeps unrelated content; the installer adds its named managed MCP block.
  • All generated MCP configs use an environment-variable placeholder for the API key, never a raw key.
  • If the chosen connection name already exists, the installer stops instead of replacing it. Choose another name to keep both, or pass --replace-existing when intentionally updating that named installation.
  • If an unmanaged Codex MCP section already uses the chosen id, choose another connection name or edit the TOML manually; the installer will not create a duplicate section.
  • Docker mode stops when local Kanban Docker/config/data files already exist under KANBAN_HOME. To test separately, set KANBAN_HOME="$HOME/.kanban-test". To configure agents against an existing instance, use --mode external. Use --overwrite-local-instance only after backing up data and accepting that local configuration may be rewritten.

A name such as Personal Kanban becomes:

  • MCP config id: personal-kanban
  • skill id: personal-kanban-second-brain
  • secret environment variable: PERSONAL_KANBAN_MCP_API_KEY
  • secret metadata file: ~/.kanban/agent-personal-kanban.env

It also supports non-interactive installs:

pnpm agent:install -- --mode external --url https://kanban.example.com \
  --email you@example.com --mcp-key kbk_... --skip-provision \
  --integration-name "Personal Kanban" \
  --clients codex,claude --workspace /path/to/workspace

Useful flags:

  • --mode docker|external|native
  • --url, --api-url, --port
  • --email, --password, --display-name, --org, --project
  • --clients codex,claude,antigravity
  • --workspace /path/to/workspace
  • --integration-name "Personal Kanban" to use a distinct MCP/skill identity
  • --mcp-key kbk_... --skip-provision for an existing key
  • --replace-existing to update an already installed named connection
  • --overwrite-local-instance to allow Docker mode to reuse an existing KANBAN_HOME after backup
  • --no-start to write Docker files without starting containers
  • --no-keychain to store only in the connection env file
  • --dry-run to print the plan without writing files

Generated config files use an API-key environment variable. From a local checkout, launch agents through:

pnpm agent:env -- codex
pnpm agent:env -- claude

From a curl install, launch through the downloaded helper instead:

node ~/.kanban/app/scripts/kanban-agent-env.mjs -- codex
node ~/.kanban/app/scripts/kanban-agent-env.mjs -- claude

For a non-default name, pass its env file:

node ~/.kanban/app/scripts/kanban-agent-env.mjs \
  --env ~/.kanban/agent-personal-kanban.env -- codex

When a workspace has multiple named Kanban connections, load each env file:

node ~/.kanban/app/scripts/kanban-agent-env.mjs \
  --env ~/.kanban/agent-work-kanban.env \
  --env ~/.kanban/agent-personal-kanban.env -- codex

The env launcher resolves keys stored in macOS Keychain or Linux secret-tool.

Installer smoke test:

pnpm agent:install:smoke

The reusable skill template lives in scripts/agent-install/skills/kanban-second-brain/SKILL.md.

Second-Brain Testing

See Second-Brain Testing Guide for the full automated and manual test flow covering installer smoke tests, MCP capture/search/promote/audit tools, UI inbox triage, freshness review, and secret handling.


Architecture

  • apps/api: Hono API. Stateless domain logic and SQLite.
  • apps/web: Next.js 16. Pure BFF, no direct DB access. Handles SSR and Server Actions.
  • packages/shared: Shared DTO types between front and back.

The web layer is a pure consumer of the API. It uses API_URL for internal calls and NEXT_PUBLIC_API_URL for client-side hooks.


Environment Variables

Variable Required Description
JWT_SECRET Yes Secret for signing access tokens (≥ 32 chars)
REFRESH_SECRET Yes Secret for refresh tokens (≥ 32 chars)
DATABASE_URL No Path to SQLite file (default: ./data/kanban.db)
PORT No Internal API port (default: 3001)
APP_URL No Public URL of the frontend (for email links, CSRF, and CORS)
API_URL No API URL for server-to-server calls (Internal Docker: http://api:3001)
LOG_LEVEL No Log level: debug, info, warn, error, none (default: debug in dev, error in prod)
ENABLE_HSTS No Set to true to force HTTPS HSTS (default: true if production, false otherwise)
WS_URL Yes WebSocket URL for the browser (ws://localhost:3010)

Running Tests

Tests in apps/api use an in-memory database.

pnpm test

About

Simple multi project Kanban with wiki and more to be added later :) For now, it could be used as a simili-second-brain between wiki and Task <3

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages