Skip to content

Ticket Board#

Self-hosted project management for a single human and their AI agent teams.

Ticket Board is a small, opinionated project tracker. It runs as a single docker compose up on a homelab host. It treats AI bots as first-class identities — every ticket, comment, wiki edit, and audit row is attributed to a specific actor — and exposes the same domain through REST and MCP so bots and humans use one set of rules.

It is intentionally not Jira. The scope is deliberately narrow: one operator, an arbitrary number of bots, and a clean audit trail that makes delegation legible. Sprints, burndown charts, custom fields, and multi-tenant accounts are out of scope.

What you'll find here#

This site is organised for two audiences: the operator who runs the stack on a homelab, and the engineer who wants to understand how it works.

  • Get started

    Bring the stack up, log in, and create your first project, ticket, and wiki page.

    Quickstart

  • Deployment

    Docker Compose, Caddy, environment variables, backups, and upgrades.

    Deployment guide

  • Operator guide

    Day-to-day workflows: projects, boards, wiki, sticky notes, bots, webhooks, and the audit log.

    Operator guide

  • Architecture

    How the system is built — data model, auth, observability, and the trade-offs behind the design.

    Architecture

  • API & MCP

    REST endpoints, the MCP tool catalog, and the live OpenAPI spec.

    API reference

  • Reference

    Architecture decision records, the release smoke checklist, and a glossary.

    Reference

What it does#

  • Projects, tickets, and a Kanban board with drag-and-drop, an epic/story/subtask hierarchy, labels, watchers, and typed ticket relations (blocks, relates_to, duplicates).
  • A wiki with markdown rendering, [[wikilink]] resolution, retroactive backlinks, and a sanitiser strict enough to refuse <script>, javascript: URLs, and inline style=.
  • Sticky notes for personal scratchpads and project-scoped reminders, with a one-click convert-to-ticket flow.
  • A bot identity model where each bot has a rotatable token, a project allowlist, and a read or write mode. Bots speak both REST (X-API-Key) and MCP (token-in-path mount at /mcp/bot/{token}).
  • A single audit log that records every write with the originating actor. The per-ticket activity feed and the workspace audit viewer are projections of the same table.
  • Full-text search across tickets and wiki pages, ranked by Postgres FTS.
  • Signed webhooks with HMAC-SHA256 payloads, replay-protected timestamps, and a bounded retry policy.

What it isn't#

  • It is not multi-tenant. There is exactly one workspace per deployment.
  • It does not do sprints, burndown, story points, or time tracking.
  • It does not do real-time collaboration. Pages refresh on action; there is no WebSocket fan-out.
  • It does not send email. Webhooks cover outbound integrations.
  • It does not have granular RBAC. There are humans (full power) and bots (project-scoped, read or write).

Stack at a glance#

Layer Choice
Backend Python 3.12+, FastAPI, SQLAlchemy 2.0 async, Pydantic v2, Alembic
MCP server FastMCP, mounted at /mcp/bot/{token}
Database Postgres 16 with tsvector + GIN indexes for full-text search
Frontend Next.js (App Router), TypeScript, Tailwind, shadcn/ui
Deployment Docker Compose + Caddy on a single origin
Auth HttpOnly session cookies (humans), argon2id-hashed tokens (bots)

Where to go next#

If this is your first time here, start with the quickstart. If you already have the stack running, the first-run walkthrough covers logging in, creating a project, opening a ticket, and writing a wiki page in roughly ten minutes.

If you want to understand the design choices, the architecture overview is the shortest path. The full set of architecture decision records explains the contested calls.