# Breadcrumbs > Personal project manager that syncs GitHub repos and tracks coding activity through `CLAUDE.md` / `CLAUDE_LOG.md` snapshots. Ships with a Model Context Protocol (MCP) server so AI assistants can read the kanban board, attach card notes, and write project documentation directly. This file is the canonical machine-readable description of Breadcrumbs. It exists so an LLM fetching the site can answer detailed questions about how Breadcrumbs works, how to integrate with it, and what every MCP tool does, without needing to crawl the rendered SPA or the source repo. ## Overview Breadcrumbs is a self-hostable kanban + project context tool aimed at solo developers and small teams working alongside AI coding assistants. It models a project as: - One or more **GitHub repositories** that get periodically synced - A **kanban board** with columns and cards (drag-and-drop, native HTML5) - A stream of **activity** — both coding-log snapshots from `CLAUDE_LOG.md` and live entries posted by AI agents over MCP - Free-form **project documentation** pages and per-card **notes** The defining design choice: rather than scraping commit history or running an agent in your editor, Breadcrumbs ingests the markdown files (`CLAUDE.md` and `CLAUDE_LOG.md`) that Claude Code and similar tools already maintain in each repo. The cursor into `CLAUDE_LOG.md` is a line-count integer that advances on every sync, so re-runs are idempotent. Source: . Live deployment: . ## Stack - **Frontend:** React + Vite + TypeScript + Tailwind, served by nginx - **Backend:** FastAPI (Python 3.12+), SQLAlchemy async with raw SQL via `text()` - **Database:** Postgres 16 - **Auth (web):** JWT (python-jose) + bcrypt — 7-day expiry - **Auth (MCP):** user-scoped API keys with the `bcu_` prefix; project UUID is passed explicitly to project tools - **Background sync:** APScheduler, default every 6 hours - **Push notifications:** pywebpush + Web Push API - **Reverse proxy / TLS in production:** Caddy fronts nginx, auto-issues Let's Encrypt certs ## How sync works Each project has a `project_repos` table (many GitHub repos per project). On each sync tick: 1. For every repo, fetch the latest `CLAUDE.md` and `CLAUDE_LOG.md` via the GitHub API 2. Replace the stored `CLAUDE.md` snapshot wholesale (it's a snapshot, not a history) 3. Read the stored line cursor for `CLAUDE_LOG.md`, append everything from that line to the end as new activity entries, then advance the cursor to `len(all_lines)` 4. Emit `activity_changed` over the project event hub so connected web clients update in real time GitHub PATs are stored per-repo; `GITHUB_DEFAULT_PAT` in the backend `.env` is a fallback used when a repo has no project-level PAT. The settings UI never round-trips a stored PAT to the browser — it returns `has_pat: bool` only. ## Kanban model - A project has many **columns** (positioned, ordered) - A column has many **cards** (positioned within the column, ordered) - A card has: title, description (markdown), assignee (a user), and optional **structured plan** + **verification checklist** JSON blobs with `schema_version: 1` - A plan is a list of steps with `id`, `title`, `detail`, `status` (`todo`/`doing`/`done`/`blocked`), `note` - A verification checklist is a list of checks with `id`, `title`, `detail`, `status` (`pending`/`passed`/`failed`/`skipped`), `evidence` - Drag-and-drop uses native HTML5 events — no external dnd library ## Notes and documentation - **Notes** are short, threaded comments. They can be attached to a specific card (`card_id`) or live at the project level. Notes created via an MCP key can only be edited or deleted by that same key. - **Documentation** is a set of titled markdown pages scoped to a project. `(project_id, title)` is unique, so writes are upserts. Useful for runbooks, ADRs, design docs the AI agent maintains as the project evolves. ## MCP server Breadcrumbs exposes a Model Context Protocol server so AI clients (Claude Desktop, Claude Code, Codex, MCP Inspector) can read and write project data with structured tools. ### Endpoints - `GET|POST|DELETE https://breadcrumbs.dev/mcp` and `/mcp/` — Streamable HTTP transport (modern MCP clients) - `GET https://breadcrumbs.dev/mcp/sse` — Server-Sent Events transport (older clients) - `POST https://breadcrumbs.dev/mcp/messages` — JSON-RPC messages for an active SSE session ### Auth ``` Authorization: Bearer bcu_ ``` Keys are minted from **User Settings → MCP API Keys**. The full `bcu_...` value is shown once at creation time; only a hashed secret is stored afterward. Each successful MCP request updates `last_used_at` on the key. Old project-scoped `bc_...` keys are not accepted for MCP authentication. Project selection is separate from authentication. Agents should read a non-secret repo-local `.breadcrumbs/project.json` file: ```json { "project_id": "project-uuid", "project_name": "Optional display name", "app_url": "https://breadcrumbs.dev" } ``` If the file is missing, agents should call `list_projects`, ask whether to link an existing project or create one with `create_project`, then write `.breadcrumbs/project.json`. The `/mcp/messages` endpoint deliberately has no auth header — the SSE session UUID issued at connect time acts as the bearer (standard MCP behavior; adding auth here would break stock clients). ### Tool reference Project-scoped tools require a `project_id` parameter. The server verifies the authenticated user has project access on every call. **Project-level** - `list_projects` — returns projects the authenticated user can access. No inputs. - `create_project` — inputs: `name`, optional `description`. Creates a project owned by the authenticated user. - `get_project_overview` — inputs: `project_id`. Returns project name, description, kanban columns with card counts, and documentation page titles. - `get_kanban_board` — inputs: `project_id`. Returns the full board: every column with its cards (id, title, description, assignee). **Cards** - All card tools also require `project_id`. **Card plans (structured task breakdowns)** - `set_card_plan` — replace a card's plan. Inputs: `card_id`, `steps` (array of `{id?, title, detail?, status?, note?}`). Step ids are generated when omitted; status defaults to `todo`. Bumps `plan_version`. - `update_card_plan_steps` — bulk update statuses/notes by step id. Inputs: `card_id`, `updates` (array of `{step_id, status?, note?}`). Atomic — if any step id is unknown, no updates apply. **Card verification (structured QA checklists)** - `set_card_verification` — replace a card's verification checklist. Inputs: `card_id`, `checks` (array of `{id?, title, detail?, status?, evidence?}`). Check ids are generated when omitted; status defaults to `pending`. Bumps `verification_version`. - `update_card_verification_checks` — bulk update statuses/evidence by check id. Inputs: `card_id`, `updates` (array of `{check_id, status?, evidence?}`). Atomic on unknown ids. **Notes** - `list_notes` — list project notes. Inputs: optional `card_id` to filter to a specific card. - `get_note` — inputs: `note_id`. - `create_note` — inputs: `content` (required), optional `card_id` to attach to a card. - `add_note` — compatibility alias for `create_note` with a required `card_id`. Inputs: `card_id`, `content`. - `update_note` — inputs: `note_id`, `content`. Only the MCP key that created the note may update it. - `delete_note` — inputs: `note_id`. Same key-ownership rule as update. **Documentation** - `read_documentation` — inputs: `title` (case-insensitive). Returns the markdown content. Use this before `write_documentation` when amending instead of overwriting. - `write_documentation` — inputs: `title`, `content`. Upsert by `(project_id, title)`. - `delete_documentation` — inputs: `title` (case-insensitive). Cleans up obsolete pages. **Activity log** - `log_activity` — post a real-time entry to the project's coding log. Inputs: `message` (markdown), optional `tags` (array of strings, e.g. `["auth", "backend"]`). Use to record progress, decisions, or milestones while the agent is coding. ### Status enums - Plan step status: `todo` | `doing` | `done` | `blocked` - Verification check status: `pending` | `passed` | `failed` | `skipped` ## Connecting Claude Code Add to `~/.claude/settings.json` (or project-level `.claude/settings.json`): ```json { "mcpServers": { "breadcrumbs": { "url": "https://breadcrumbs.dev/mcp", "headers": { "Authorization": "Bearer bcu_" } } } } ``` For SSE-only clients, use `https://breadcrumbs.dev/mcp/sse` instead. ## Self-hosting Self-hosting is the default — there is no managed tier yet. Quick path: ```bash git clone https://github.com/xie-andy/breadcrumbs cd breadcrumbs cp backend/.env.example backend/.env # Set JWT_SECRET (any long random string) and DATABASE_URL # Optional: GITHUB_DEFAULT_PAT for sync, RESEND_API_KEY for email verification docker compose up -d --build # App is at http://localhost:8080 ``` Migrations live in `backend/migrations/` as numbered SQL files; they auto-run on a fresh Docker volume and `./scripts/migrate.sh` applies any new ones to an existing database. Production deployment notes (Hetzner + Caddy + GitHub Actions) live in `INFRA.md` and `CLAUDE.md` at the repo root. ## Useful links - Live site: - Source: - Sign in: - Sign up: