A local-first, single-user sales CRM in one self-contained Go binary. Capture Leads, convert the good ones into Contacts, and track opportunities as Deals through a pipeline — all stored in a single embedded bbolt file, no server and no network.
The same data is reachable through two surfaces, selected at launch:
- a tview terminal UI for the human operator, and
- an MCP stdio server so an AI assistant can read and update the CRM.
The two modes can run concurrently as separate local processes against the same file: persistence
opens bbolt per operation so no process holds the lock
while idle, and the TUI auto-refreshes when the MCP process writes. The full design lives in
docs/SPECIFICATIONS.md — the source of truth for what this app is.
Requires Go 1.26+. Two dev tools are used for formatting and linting:
go install mvdan.cc/gofumpt@latest
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latestmake build # go build ./...
make run # go run . (defaults to -mode tui)
go run . -mode mcp # start the MCP stdio server
make test # go test ./... -race -cover
make fmt # gofumpt -w .
make lint # golangci-lint run
make check # fmt + tidy + lint + testmake check (fmt + tidy + lint + test) mirrors CI and is the gate to run before pushing.
Both surfaces resolve the bbolt file the same way, so the TUI and the MCP server share one database no matter which directory you start them from:
- the
-dbflag —go run . -db /path/to/leadzaar.db - the
LEADZAAR_DBenvironment variable - the default
~/.local/leadzaar/default.db
The parent directory is created on first run.
main.go flag parsing; dispatches to the selected surface
internal/models plain domain structs (Lead, Contact, Deal) + enums — no persistence imports
internal/db the Store — the only bbolt-aware package; all CRUD, validation, indexes,
and cross-entity use-cases (lead conversion, contact cascade-delete)
internal/server (planned) MCP stdio server, consuming internal/db
internal/tui (planned) tview TUI, consuming internal/db
docs/ SPECIFICATIONS.md — the source of truth
.claude/rules/ layer conventions (bbolt, MCP, tview, testing, spec) read by Claude Code
The layering rule: only internal/db touches bbolt; every other layer works with plain models.
Both surfaces consume the same Store, so business logic lives in one place. See
CLAUDE.md for the full architecture and contributor guidance.