A self-hosted kanban board with a built-in MCP server — purpose-built for LLM-assisted project management.
ABoard is a lightweight, self-hosted kanban board that exposes all its operations as an MCP (Model Context Protocol) server, letting LLM agents create projects, manage sprints, move tasks, and search for work items — all through a standard AI tool interface.
The web UI provides a full drag-and-drop kanban experience. The backend runs on ASP.NET Core with SQLite, and ships as a single Docker image.
| Category | Details |
|---|---|
| Board | Multi-project kanban boards with sprints; 4-column workflow |
| Tasks | Priorities (Low / Medium / High / Critical), tags, subtasks (1 level), comments, acceptance criteria |
| Drag & Drop | Move tasks between columns and reorder within a column |
| Semantic Search | Vector search via sqlite-vec — find similar tasks using natural language (optional) |
| MCP Server | 22 tools covering all board operations, available to any MCP-compatible LLM agent |
| Authentication | JWT for the web UI; API key (X-Api-Key) for MCP clients |
| User Management | Admin-managed users; per-user API keys with regeneration |
| Theme | Dark / Light / System theme toggle |
| Zero dependencies | Single container, SQLite — no external database required |
| Layer | Technology |
|---|---|
| Backend | ASP.NET Core (.NET 10), vertical slice architecture |
| Frontend | React 19 + TypeScript, Vite, MUI v7 |
| Database | SQLite + sqlite-vec for vector search |
| ORM | EF Core 10 |
| MCP | ModelContextProtocol.AspNetCore 1.3 |
| Auth | BCrypt password hashing, JWT Bearer tokens |
| Container | Multi-stage Docker build (Node → .NET SDK → .NET Runtime) |
| Testing | xUnit (unit), Playwright (E2E) |
# Clone the repository
git clone https://github.com/your-org/ABoard.git
cd ABoard
# Build and start
docker-compose up --build
# Open http://localhost:5040
# Default credentials: admin / changeme
Change
JWT_KEY,BOARD_ADMIN_PASSWORDbefore exposing to a network.
Copy the relevant environment variables from docker-compose.yml into a docker-compose.override.yml file:
services:
aboard:
environment:
- BOARD_ADMIN_USER=myadmin
- BOARD_ADMIN_PASSWORD=s3cr3t
- JWT_KEY=a-very-long-random-string-at-least-32-chars
- EMBEDDING_API_KEY=sk-...
All configuration is done via environment variables.
| Variable | Default | Required | Description |
|---|---|---|---|
JWT_KEY | — | Yes | JWT signing key (≥ 32 characters). Change in production. |
DATABASE_PATH | /app/data/aboard.db | No | SQLite database file path inside the container |
BOARD_ADMIN_USER | admin | First run | Username for the initial admin account |
BOARD_ADMIN_PASSWORD | changeme | First run | Password for the initial admin account |
BOARD_FORCE_ADMIN_PASSWORD | — | No | Force-resets the admin password on next startup, then clears itself |
When EMBEDDING_API_KEY is set the app generates embeddings for every task and enables the FindSimilarTasks MCP tool and vector search.
| Variable | Default | Description |
|---|---|---|
EMBEDDING_API_KEY | — | OpenAI-compatible API key |
EMBEDDING_BASE_URL | https://api.openai.com/v1 | Base URL for the embedding API |
EMBEDDING_MODEL | text-embedding-3-small | Embedding model name |
EMBEDDING_DIMENSIONS | 1536 | Vector dimensions |
SQLite is stored at /app/data/aboard.db. The default docker-compose.yml mounts ./data to that path on the host. Back up the ./data directory to preserve all data.
volumes:
- ./data:/app/data
ABoard exposes an HTTP Streamable MCP endpoint at /mcp.
URL: http://your-host:5040/mcp
Header: X-Api-Key: <your-user-api-key>
Retrieve your API key from the Users page in the web UI (admin view) or via GET /api/auth/me.
| Category | Tools |
|---|---|
| Projects | ListProjects GetProject CreateProject UpdateProject DeleteProject |
| Sprints | ListSprints GetSprint CreateSprint UpdateSprint |
| Tasks | ListTasks GetTask CreateTask UpdateTask DeleteTask SetTaskStatus AssignTask |
| Comments | ListComments AddComment |
| Tags | AddTag RemoveTag |
| Users | ListUsers |
| Search | FindSimilarTasks (requires embedding API key) |
{
"mcpServers": {
"aboard": {
"url": "http://localhost:5040/mcp",
"headers": {
"X-Api-Key": "your-api-key-here"
}
}
}
}
Add to your project's .mcp.json (or ~/.claude/settings.json for user-level access):
{
"mcpServers": {
"aboard": {
"type": "http",
"url": "http://localhost:5040/mcp",
"headers": {
"X-Api-Key": "your-api-key-here"
}
}
}
}
Add to .vscode/mcp.json in your workspace:
{
"servers": {
"aboard": {
"type": "http",
"url": "http://localhost:5040/mcp",
"headers": {
"X-Api-Key": "your-api-key-here"
}
}
}
}
ABoard.slnx
├── src/
│ ├── ABoard.Api/ # ASP.NET Core host; vertical slices in Features/
│ │ └── Features/
│ │ ├── Auth/ # JWT login, /me endpoint
│ │ ├── Users/ # User CRUD, API key management
│ │ ├── Projects/ # Project CRUD, member management
│ │ ├── Sprints/ # Sprint CRUD
│ │ ├── Tasks/ # Task CRUD, comments, tags, embeddings
│ │ ├── Mcp/ # MCP tool handlers
│ │ └── Health/ # GET /health
│ ├── ABoard.Core/ # Domain entities, enums (no EF references)
│ └── ABoard.Infrastructure/ # EF Core DbContext, migrations, MigrationService
├── tests/
│ ├── ABoard.Tests.Unit/ # xUnit (53 tests)
│ └── ABoard.Tests.E2E/ # Playwright
└── frontend/ # Vite + React 19 + MUI v7
└── src/
├── features/board/ # Kanban board (dnd-kit)
├── pages/ # Route-level pages
├── providers/ # Auth, theme context
└── lib/api.ts # Typed API client
users ──< project_members >── projects ──< sprints ──< tasks
├── task_tags
├── task_comments
└── tasks (subtasks, 1 level)
Todo ←→ In Progress ←→ In Verification ←→ Complete
Free movement between any status is allowed.
All development cycles go through Docker. Do not run the app outside
docker-compose.
docker-compose up --build
dotnet ef migrations add <MigrationName> \
--project src/ABoard.Infrastructure \
--startup-project src/ABoard.Api
Then rebuild with docker-compose build to verify the migration applies cleanly.
src/ABoard.Api/Features/{FeatureName}/dotnet test tests/ABoard.Tests.Unit
Covers: JWT generation & claims, admin seeding, embedding service, project / sprint / task database logic, MCP tool handlers — 53 tests.
Requires the app to be running first:
docker-compose up -d
Then:
cd tests/ABoard.Tests.E2E
npm install
npx playwright install chromium
npx playwright test
| Environment variable | Default | Description |
|---|---|---|
BASE_URL | http://localhost:5040 | Target host |
ADMIN_USER | admin | Admin username |
ADMIN_PASS | changeme | Admin password |
Test suites: auth.spec.ts · users.spec.ts · projects.spec.ts · sprints.spec.ts · board.spec.ts
docker-compose builddotnet test tests/ABoard.Tests.UnitSee PLAN.md for the full architecture reference and TODO.md for the current task list.
Content type
Image
Digest
sha256:f82af149b…
Size
111.2 MB
Last updated
5 months ago
docker pull jncchds/aboard