Local-first, lightweight issue tracker. Single binary, SQLite-backed, MCP-native.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent — or use 1-click editor setup below.
💡 Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
Issue tracking for the agentic coding era.
One binary. One SQLite database (plus an attachments dir). MCP built in.
Your agent can write the code. What it can't do is remember: the plan dies with the context window, the TODO list rots in a markdown file, and the next session starts from zero. Lific is the missing memory: a self-hosted, single-binary issue tracker whose primary user is often an agent rather than a person.
Three numbers instead of adjectives:
tools/list response at v2.2.1 (o200k tokenizer). Your entire tracker costs about as much context as one long file read.attachments/ dir beside it (both covered by the automatic backups). No Docker, no Postgres, no reverse proxy, no daemon farm. Copy it to a server, point your agents at it, done.lific connect writes correct MCP config into OpenCode, Claude Code, Cursor, VS Code, Codex, Zed, and more. No hand-edited JSON.Identifiers are human-readable everywhere: APP-42, never a UUID. They survive being spoken, logged, grepped, and pasted into a prompt.
That's the whole thing. lific init sets everything up in your OS's standard locations (config in ~/.config/lific/, data in ~/.local/share/lific/ on Linux; macOS and Windows equivalents) so it works the same from any directory - use lific init --here if you'd rather keep a directory-local instance (./lific.toml + ./lific.db). It registers the server with your OS service manager (a systemd user unit on Linux, a LaunchAgent on macOS), so it isn't a process tied to your terminal - it's still running tomorrow. lific connect then detects the AI tools installed on your machine, lets you pick, mints a per-tool API key, and merges correct MCP config into each one without overwriting existing config. Restart your client and the Lific tools are there.
Manage the service anytime with lific service status | restart | stop | uninstall. Prefer a foreground process (containers, supervisors, debugging)? lific init --no-service skips the service and lific start runs the server in your terminal.
The web UI is at http://localhost:3456. Sign up there to create your account, then grant it admin rights from the CLI: lific user promote --username <username>.
Verify any setup with:
doctor exits nonzero if anything is actually broken, so agents and CI can gate on it.
list_issues(project="APP", workable=true) returns only issues with every blocker resolved. Dependency-aware triage without a graph query.get_plan and resumes exactly where the last one left off. No MEMORY.md, no re-priming ritual.blocks, relates_to, duplicate), group them into modules, and mirror plan steps to real issues with two-way done/close sync.get_activity answers "what changed while I was gone": who changed what, when, and through which tool. Every agent's work is attributed (more below).edit_issue / edit_page do targeted find-and-replace, so updating one line of a long description doesn't cost the whole document in tokens.export turns an issue, a page, or a whole project into portable markdown, no lock-in.lific connect mints a separate bot identity per tool, owned by your account (opencode-blake, cursor-blake, ...). When several agents work the same project, provenance is the primitive that keeps you sane:
This is the recommended way to connect agent harnesses.
lific connect is the front door. It supports eleven clients out of the box:
opencode · claude-code · claude-desktop · cursor · vscode · codex · zed · gemini · windsurf · goose · crush
Each client gets its native schema (mcpServers vs servers vs mcp, Codex TOML with an env-var token, Goose YAML; the quirks are handled). JSON configs are merged non-destructively; a file connect can't parse safely is left untouched and you get the exact snippet to paste instead.
Lific implements the full MCP authorization spec (RFC 9728 protected-resource metadata, dynamic client registration, PKCE), so OAuth-capable clients can connect with just the URL and complete auth in the browser:
The trade-off: an OAuth token is you. Changes made through it are indistinguishable from your own edits in the audit log, with no per-harness attribution. Fine for personally browsing your tracker from an editor; for agents doing real work, prefer the per-tool bot identities above.
Headless / SSH / agents. No browser on the box? The device flow has you covered:
Tokens are stored in your OS keyring (Secret Service / Keychain / Credential Manager), falling back to a 0600 file with a loud warning when no keyring exists.
Remote (Streamable HTTP):
Local (stdio, no server):
Create keys anytime with lific key create --name my-key.
Go to Settings > Connected tools in the web UI. Pick your tool, click Connect, and paste the generated config snippet.
Each connection creates a bot identity tied to your account (the CLI's connect does the same). Changes show up attributed to you, tagged with which tool made them.
An agent's plan shouldn't die when its context does. A plan is an ordered, arbitrarily-nestable tree of steps that persists across sessions and compaction. Start a new session, call get_plan, and it's still there, ready to resume.
create_plan builds a full nested tree at once; edit_plan_step and update_plan_step keep it current.Issues stay flat and lateral; the hierarchy lives on the plan. It's the difference between an issue tracker and a project planner.
lific agents-md writes an idempotent, marker-delimited block into your repo's AGENTS.md telling every agent that this project uses Lific: project identifier, CLI examples, and the workflow conventions. lific connect offers to do this automatically in project context.initialize response, so connected agents know how Lific wants to be used without you explaining it.create a project first: manage_resource(...)) instead of returning an empty list.lific issue list --project APP | jq just works, no --json needed (though it's there). Prompts never hang a non-interactive caller; they fail fast and name the bypass flag.lific completion fish | source (bash, zsh, fish, powershell, elvish).The CLI works directly against the database, with no server or auth required. Data commands also support an HTTP backend when you want the CLI to operate on a remote Lific instance:
--backend http can read the URL and bearer key from LIFIC_URL and LIFIC_API_KEY. If no API key is supplied, it also uses the credential from lific login (LIFIC_TOKEN, keyring, or credential file). The default backend remains direct SQL; HTTP mode never opens the local database for data commands. Its human-readable output is currently pretty-printed JSON. A remote project export downloads one archive file from the server rather than individual Markdown files.
All 27, in 5,641 tokens:
| Family | Tools |
|---|---|
| Issues | list_issues · get_issue · create_issue · update_issue · bulk_update · edit_issue · get_board |
| Relations | link_issues · unlink_issues |
| Pages | get_page · create_page · update_page · edit_page |
| Plans | create_plan · get_plan · edit_plan_step · update_plan_step |
| Comments | add_comment · list_comments · edit_comment · delete_comment |
| Search & history | search · get_activity |
| Structure | list_resources · manage_resource · delete |
| Export | export (issue, page, or whole project by ID) |
Everything takes human-readable identifiers (project="APP", not project_id=7). The behaviors worth knowing about are covered in "What your agent can now do" above; for exact schemas, connect a client and read tools/list.
| Category | What you get |
|---|---|
| Issue tracking | Status, priority, modules with icons, labels, relations, comments, board view, fuzzy search, sort by recent activity |
| Plans | Persisted, nestable step trees that outlive a session; steps mirror issues with two-way done/close sync |
| Documentation | Markdown pages in recursive folders, with comments, labels, lifecycle status, full-text search, and Mermaid diagrams |
| MCP interface | 27 tools, human-readable identifiers, compact schema, session instructions |
| Onboarding | One-command setup (lific init installs a background service), lific connect (11 clients), lific doctor, lific agents-md, shell completions |
| REST API | Resource endpoints, search, board view, and relationship/planning operations |
| Web UI | Markdown editing with live preview, drag-and-drop board, Mermaid and code-copy, dark/light theme |
| User accounts | Individual auth, per-tool bot identities, project membership and roles |
| Auth | OAuth 2.1 (PKCE, dynamic client registration, RFC 9728 discovery), RFC 8628 device flow, API keys, token revocation |
| Backups | lific dump / lific restore single-archive backups, plus automatic interval archives with retention |
| CLI | Scriptable issue/project/page/plan commands, TTY-aware JSON output, works with no server running |
| Single binary | No runtime dependencies, embedded SQLite, ~25 MB |
Honesty is cheaper than churn:
git diff on your task list, a markdown-native tracker fits better.For one human directing several agents across personal projects (the thing it's built for), none of those trade-offs bite.
Lific has project-scoped, default-deny authorization: viewer / maintainer / lead membership is enforced on project-scoped REST and MCP calls, including reads. Instance administrators and operator-trusted credentials intentionally bypass project membership checks, while instance-scoped endpoints have their own rules. Fresh installs (created on 2.0+) enforce it by default; instances upgraded from an earlier version keep it off until you opt in - nothing changes under you on upgrade. Toggle it at runtime:
With enforcement on, a newly created user sees nothing until they're granted membership. Manage access from the CLI (or the web UI's project members page):
Forgotten password? The operator can reset one from the shell (this signs out all of that user's sessions):
Auth can be turned off entirely for a private, local instance with required = false under [auth] in lific.toml. Credential-less requests then get admin-equivalent access; a presented-but-invalid token still fails loudly. The web UI signs you in automatically as the first admin (the single-user auto-login flow) instead of showing a login form - if no account exists yet, the signup screen still appears so there's an identity to attribute work to. This is a config-file key on purpose (flipping it requires shell access, like minting an operator key), and it comes with guard rails: the server refuses to start if server.public_url points anywhere but localhost, and logs a prominent warning otherwise - the default bind is 0.0.0.0, so keep an auth-less instance loopback-only or firewalled.
Unbound API keys bypass authorization by design. A key with no user binding - the one lific start auto-mints on a keyless DB, and the ones lific key create and connect's fresh-install path produce - is operator-trusted: it can only be created by someone with shell access to the server, so it's treated as admin-equivalent even in enforced mode. That's what keeps the zero-user init → start → connect flow working with enforcement on. The threat the default guards against is a web-signup stranger's session/OAuth token, not the operator's own shell-minted key. Audit these keys any time with:
Prefer per-tool bot identities (what lific connect mints when you have a user account) over unbound keys: a bot inherits its owner's project access and shows up in the audit log by name.
lific.tomllific init generates this:
CLI flags (--db, --port, --host) override config values. Set server.public_url when exposing Lific beyond localhost; it becomes the OAuth issuer and the URL lific connect writes into client configs. server.trusted_proxies controls which peers may supply X-Forwarded-For or X-Real-IP; it defaults to loopback for Tailscale Funnel. Add only proxy IPs/CIDRs you operate.
Config is discovered in standard locations, first match wins:
--config <path> (used alone, no fallback)./lific.toml (current directory)~/.config/lific/lific.toml on Linux ($XDG_CONFIG_HOME respected), ~/Library/Application Support/lific/ on macOS, %APPDATA%\lific\ on Windows/etc/lific/lific.toml on Linux/BSD, /Library/Application Support/Lific/ on macOS, %ProgramData%\lific\ on WindowsA relative database.path always resolves against the config file's own directory, so the same config works no matter where the process starts. lific init --config /path/to/lific.toml and lific service install --config ... root the whole instance (config, database, service working directory) at that path.
The data set is the database plus a content-addressed attachments/ dir beside it. lific dump packages both into one self-contained archive, taking a consistent DB snapshot via VACUUM INTO that is safe while the server is running:
Each archive contains the DB snapshot, every attachment blob, and a manifest.json (Lific version, schema version, sizes). Restoring is the mirror image. Stop the server first:
Restores are staged (a failure leaves the original data dir untouched) and refuse archives created by a newer Lific; older archives are fine, and pending migrations apply on next start.
The automatic interval backups ([backup] in config) write the same .tar.gz artifact to the backup dir with rotation. External backup harnesses (restic, borg, cron) can either scoop up that dir or call lific dump as a pre-backup hook:
SQLite is bundled via rusqlite and compiled into the binary. No system SQLite required.
The mkdir -p web/dist creates the empty directory that rust-embed expects at compile time. The resulting binary has full functionality (MCP, REST API, CLI, OAuth, backups) but visiting the web UI will return a message pointing you to build the frontend.
The frontend is a Svelte 5 SPA built with Vite. bun run build outputs static files to web/dist/, which cargo build embeds into the binary. The final binary is fully self-contained with no runtime dependencies.
You don't need Docker to run Lific; it's one binary. The Dockerfile in the repo exists mainly so MCP directory indexers can build and verify the server, but it produces a working image (full web UI, distroless runtime) if a container fits your setup:
Questions, feedback, or a setup worth showing off? Join the Lific Discord. Release announcements land there too, and support questions get answered fastest in #support.
Issues and PRs welcome. If you're planning something big, open an issue first so we can talk about it before you put in the work.
Lific ships a registry manifest (server.json) for the official MCP Registry. Its canonical registry name:
mcp-name: io.github.VoidNullable/lificShowcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/lific)<a href="https://allmcps.com/mcp/lific"><img src="https://allmcps.com/api/badge/lific?style=directory" alt="Lific on AllMCPs" /></a>