{
  "markdown": "<p align=\"center\">\n  <img src=\"LificHero.png\" alt=\"Lific Issue tracking built for AI-driven development\" width=\"800\">\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/VoidNullable/lific/actions/workflows/ci.yml\"><img src=\"https://github.com/VoidNullable/lific/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"></a>\n  <a href=\"https://crates.io/crates/lific\"><img src=\"https://img.shields.io/crates/v/lific\" alt=\"crates.io\"></a>\n  <a href=\"https://github.com/VoidNullable/lific/releases\"><img src=\"https://img.shields.io/github/v/release/VoidNullable/lific\" alt=\"Release\"></a>\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/github/license/VoidNullable/lific\" alt=\"License\"></a>\n  <a href=\"https://discord.gg/uWvaFC4f7D\"><img src=\"https://img.shields.io/discord/1516612377196363889?logo=discord&logoColor=white&label=discord&color=5865F2\" alt=\"Discord\"></a>\n</p>\n\n<p align=\"center\">\n  <strong>Issue tracking for the agentic coding era.</strong><br>\n  One binary. One SQLite database (plus an attachments dir). MCP built in.\n</p>\n\n<p align=\"center\">\n  <a href=\"https://lific.dev\"><strong>lific.dev</strong></a>\n  &nbsp;·&nbsp;\n  <a href=\"https://lific.dev/docs\">Docs</a>\n  &nbsp;·&nbsp;\n  <a href=\"https://discord.gg/uWvaFC4f7D\">Discord</a>\n</p>\n\n---\n\nYour 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.\n\nThree numbers instead of adjectives:\n\n- **30 MCP tools in 6,335 tokens.** That's the measured size of the full `tools/list` response (o200k tokenizer). Your entire tracker costs about as much context as one long file read.\n- **One ~25 MB binary.** Embedded SQLite, embedded web UI, backups built in. The data set is just the database and a content-addressed `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.\n- **11 AI clients configured by one command.** `lific connect` writes correct MCP config into OpenCode, Claude Code, Cursor, VS Code, Codex, Zed, and more. No hand-edited JSON.\n\nIdentifiers are human-readable everywhere: `APP-42`, never a UUID. They survive being spoken, logged, grepped, and pasted into a prompt.\n\n## 60-second setup\n\n```bash\ncargo install lific     # or grab a binary from the releases page\n\nlific init              # config + database + your API key, printed once -\n                        # then installs a background service and starts it.\n                        # The server is now on :3456 and survives reboot.\nlific connect           # writes MCP config into your AI clients\n```\n\nThat'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.\n\nManage 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.\n\nThe 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>`.\n\nVerify any setup with:\n\n```bash\nlific doctor            # green/yellow/red checks: config, database, server,\n                        # OAuth discovery, and a real MCP round-trip\n```\n\n`doctor` exits nonzero if anything is actually broken, so agents and CI can gate on it.\n\n## What your agent can now do\n\n- **Ask \"what can I work on right now?\" in one call.** `list_issues(project=\"APP\", workable=true)` returns only issues with every blocker resolved. Dependency-aware triage without a graph query.\n- **Keep a plan alive across sessions.** Plans are persistent, nestable step trees. A fresh session calls `get_plan` and resumes exactly where the last one left off. No `MEMORY.md`, no re-priming ritual.\n- **Break work down and wire it up.** Create issues, link blockers (`blocks`, `relates_to`, `duplicate`), group them into modules, and mirror plan steps to real issues with two-way done/close sync.\n- **Leave a real audit trail.** `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).\n- **Write docs where the issues live.** Markdown pages in folders, with comments, labels, lifecycle status, and Mermaid diagrams. Design decisions stay next to the work they justify.\n- **Edit without resending.** `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.\n- **Take everything with you.** `export` turns an issue, a page, or a whole project into portable markdown, no lock-in.\n\n## Every tool gets its own identity, and that's the point\n\n`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:\n\n- **The audit log shows which harness made every change.** \"OpenCode closed APP-42\", \"Cursor edited the design page\". All attributed to you, never blurred together.\n- **Revoke one tool without touching the others.** Cursor misbehaving? Disconnect just its key and OpenCode keeps working.\n- **Scoped authority.** Each bot inherits its owner's project access and nothing more.\n\nThis is the recommended way to connect agent harnesses.\n\n## Connecting AI tools\n\n**`lific connect`** is the front door. It supports eleven clients out of the box:\n\n`opencode` · `claude-code` · `claude-desktop` · `cursor` · `vscode` · `codex` · `zed` · `gemini` · `windsurf` · `goose` · `crush`\n\n```bash\nlific connect                                    # interactive picker\nlific connect --client opencode --client cursor --yes   # non-interactive\nlific connect --client claude-code --scope project      # repo-local .mcp.json\nlific connect --client zed --stdio               # no server: direct SQLite over stdio\nlific connect --dry-run --client vscode          # preview without writing\n```\n\nEach 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.\n\n<details>\n<summary>OAuth, if you'd rather auth as yourself</summary>\n\nLific 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:\n\n```bash\nlific connect --oauth --client opencode   # writes a header-less config, mints nothing\nopencode mcp auth lific                   # browser opens → sign in → approve\n\n# or with any client's native command:\nclaude mcp add --transport http lific http://localhost:3456/mcp\n```\n\nThe 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.\n\n**Headless / SSH / agents.** No browser on the box? The device flow has you covered:\n\n```bash\nlific login                     # prints a URL + short code; approve on any device\nlific login --non-interactive   # agent mode: prints JSON {verification_uri, user_code,\n                                #   device_code, next_step} and exits immediately\nlific login --complete <code>   # finish later, from a script or a second session\n```\n\nTokens 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.\n\n</details>\n\n<details>\n<summary>Manual configuration (any MCP client)</summary>\n\n**Remote (Streamable HTTP):**\n\n```json\n{\n  \"lific\": {\n    \"type\": \"remote\",\n    \"url\": \"http://localhost:3456/mcp\",\n    \"headers\": { \"Authorization\": \"Bearer your-api-key\" }\n  }\n}\n```\n\n**Local (stdio, no server):**\n\n```json\n{\n  \"lific\": {\n    \"type\": \"local\",\n    \"command\": [\"lific\", \"--db\", \"path/to/lific.db\", \"mcp\"]\n  }\n}\n```\n\nCreate keys anytime with `lific key create --name my-key`.\n\n</details>\n\n<details>\n<summary>Web UI setup (if you prefer clicking)</summary>\n\nGo to **Settings > Connected tools** in the web UI. Pick your tool, click Connect, and paste the generated config snippet.\n\nEach 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.\n\n</details>\n\n## Plans: state that outlives the session\n\nAn 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.\n\n- **Steps can mirror issues.** Link a step to an issue and the two stay in sync: close the issue and the step checks itself; mark the step done and the issue closes. Reopen the issue and the step reopens, with a note of why.\n- **Authored in one call.** `create_plan` builds a full nested tree at once; `edit_plan_step` and `update_plan_step` keep it current.\n- **First-class in the UI.** A Plans tab sits alongside Issues, Board, Modules, and Pages: a real tree view with done toggles, per-step markdown notes, issue chips, and an activity timeline.\n- **Fully tracked.** Every plan and step change lands in the audit log, including the issue-driven cascades.\n\nIssues stay flat and lateral; the hierarchy lives on the plan. It's the difference between an issue tracker and a project planner.\n\n## Built for agents, not just reachable by them\n\n- **`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.\n- **Session instructions.** The MCP server ships its conventions in the `initialize` response, so connected agents know how Lific wants to be used without you explaining it.\n- **Self-onboarding.** On a fresh database, the MCP tools tell the agent exactly how to bootstrap (`create a project first: manage_resource(...)`) instead of returning an empty list.\n- **Pipe-native CLI.** Output auto-upgrades to JSON when piped, so `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.\n- **Shell completions:** `lific completion fish | source` (bash, zsh, fish, powershell, elvish).\n\nThe 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:\n\n```bash\nlific project list\nlific issue list --project APP\nlific issue create --project APP --title \"Fix login bug\" --priority high\nlific issue update APP-42 --status done\nlific search \"authentication\" --project APP\n\n# Remote mode (the same commands use the server API)\nlific --backend http --url https://lific.example.com --api-key \"$LIFIC_API_KEY\" issue list --project APP\nlific --backend http --url https://lific.example.com --api-key \"$LIFIC_API_KEY\" issue update APP-42 --status done\n```\n\n`--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.\n\n## MCP tools\n\nAll 30, in 6,335 tokens:\n\n| Family | Tools |\n|--------|-------|\n| Issues | `list_issues` · `get_issue` · `create_issue` · `update_issue` · `bulk_update` · `edit_issue` · `get_board` |\n| Relations | `link_issues` · `unlink_issues` |\n| Pages | `get_page` · `create_page` · `update_page` · `edit_page` |\n| Plans | `create_plan` · `get_plan` · `edit_plan_step` · `update_plan_step` |\n| Comments | `add_comment` · `list_comments` · `edit_comment` · `delete_comment` |\n| Attachments | `upload_attachment` · `get_attachment` · `list_attachments` |\n| Search & history | `search` · `get_activity` |\n| Structure | `list_resources` · `manage_resource` · `delete` |\n| Export | `export` (issue, page, or whole project by ID) |\n\nEverything 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`.\n\n## Features\n\n| Category | What you get |\n|----------|-------------|\n| **Issue tracking** | Status, priority, modules with icons, labels, relations, comments, board view, fuzzy search, sort by recent activity |\n| **Plans** | Persisted, nestable step trees that outlive a session; steps mirror issues with two-way done/close sync |\n| **Documentation** | Markdown pages in recursive folders, with comments, labels, lifecycle status, full-text search, and Mermaid diagrams |\n| **MCP interface** | 30 tools, human-readable identifiers, compact schema, session instructions |\n| **Onboarding** | One-command setup (`lific init` installs a background service), `lific connect` (11 clients), `lific doctor`, `lific agents-md`, shell completions |\n| **REST API** | Resource endpoints, search, board view, and relationship/planning operations |\n| **Web UI** | Markdown editing with live preview, drag-and-drop board, Mermaid and code-copy, dark/light theme |\n| **User accounts** | Individual auth, per-tool bot identities, project membership and roles |\n| **Auth** | OAuth 2.1 (PKCE, dynamic client registration, RFC 9728 discovery), RFC 8628 device flow, API keys, token revocation |\n| **Backups** | `lific dump` / `lific restore` single-archive backups, plus automatic interval archives with retention |\n| **CLI** | Scriptable issue/project/page/plan commands, TTY-aware JSON output, works with no server running |\n| **Single binary** | No runtime dependencies, embedded SQLite, ~25 MB |\n\n## When Lific is the wrong tool\n\nHonesty is cheaper than churn:\n\n- **You need enterprise team features.** SSO/SAML isn't here, and neither is the sprint-estimate-gantt layer of project management. If you're coordinating forty humans, use Linear or Plane.\n- **You want issues as files in the repo.** Lific is a database with an API, not markdown-in-git. If you want `git diff` on your task list, a markdown-native tracker fits better.\n- **You need distributed multi-writer sync.** One Lific instance is one SQLite file: a single source of truth that's trivially backed up, not a CRDT. Multiple agents talk to one server; the server doesn't merge with other servers.\n\nFor one human directing several agents across personal projects (the thing it's built for), none of those trade-offs bite.\n\n## Authorization\n\nLific 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:\n\n```bash\nlific instance set --authz-enforced true    # or false\n```\n\nWith 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):\n\n```bash\nlific member add --project LIF --user sam              # viewer by default\nlific member add --all --user sam --role maintainer    # every project at once\nlific member role -p LIF -u sam -r lead                # change a role\nlific member remove -p LIF -u sam\nlific member list --project LIF\n```\n\nForgotten password? The operator can reset one from the shell (this signs out all of that user's sessions):\n\n```bash\nlific user set-password --username sam\n```\n\n**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.\n\n**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:\n\n```bash\nlific key list\n```\n\nPrefer 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.\n\n## Configuration\n\n<details>\n<summary><code>lific.toml</code></summary>\n\n`lific init` generates this:\n\n```toml\n[server]\nhost = \"0.0.0.0\"\nport = 3456\ncors_origins = []\ntrusted_proxies = []\n\n[database]\npath = \"lific.db\"\n\n[backup]\nenabled = true\ndir = \"backups\"\ninterval_minutes = 60\nretain = 24\n\n[log]\nlevel = \"info\"\n\n[auth]\nallow_signup = true\nrequired = true\n```\n\nCLI 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 none. Add only isolated proxy IPs/CIDRs you operate, and prevent direct clients from reaching that ingress.\n\nConfig is discovered in standard locations, first match wins:\n\n1. `--config <path>` (used alone, no fallback)\n2. `./lific.toml` (current directory)\n3. User config dir: `~/.config/lific/lific.toml` on Linux (`$XDG_CONFIG_HOME` respected), `~/Library/Application Support/lific/` on macOS, `%APPDATA%\\lific\\` on Windows\n4. System config dir: `/etc/lific/lific.toml` on Linux/BSD, `/Library/Application Support/Lific/` on macOS, `%ProgramData%\\lific\\` on Windows\n\nA 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.\n\n</details>\n\n## Backup and restore\n\nThe 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:\n\n```bash\nlific dump                      # → ./lific_20260703_141500.tar.gz\nlific dump --out /mnt/backups   # directory → default filename inside it\n```\n\nEach 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:\n\n```bash\nlific restore lific_20260703_141500.tar.gz          # refuses to overwrite an existing db\nlific restore lific_20260703_141500.tar.gz --force  # moves the current db aside to lific.db.pre-restore-<ts>\n```\n\nRestores 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.\n\nThe 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:\n\n```bash\n# e.g. restic pre-hook\nlific dump --out /srv/backup-staging/lific.tar.gz && restic backup /srv/backup-staging\n```\n\n## Building from source\n\n### Requirements\n\n- **Rust 1.88+** required\n- **Bun** optional, only needed if you want the web UI\n\nSQLite is bundled via `rusqlite` and compiled into the binary. No system SQLite required.\n\n### API-only build (no web UI)\n\n```bash\ngit clone https://github.com/VoidNullable/lific\ncd lific\nmkdir -p web/dist\ncargo build --release\n```\n\nThe `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.\n\n### Full build (with web UI)\n\n```bash\ngit clone https://github.com/VoidNullable/lific\ncd lific\ncd web && bun install && bun run build && cd ..\ncargo build --release\n```\n\nThe 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.\n\n### Docker (optional)\n\nYou 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:\n\n```bash\ndocker build -t lific .\ndocker run -p 3456:3456 -v lific-data:/data lific\n```\n\n## Community\n\nQuestions, feedback, or a setup worth showing off? Join the [Lific Discord](https://discord.gg/uWvaFC4f7D). Release announcements land there too, and support questions get answered fastest in #support.\n\n## Contributing\n\nIssues 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.\n\n## MCP Registry\n\nLific ships a registry manifest (`server.json`) for the official [MCP Registry](https://registry.modelcontextprotocol.io). Its canonical registry name:\n\n- `mcp-name: io.github.VoidNullable/lific`\n\n## License\n\n[Apache-2.0](LICENSE)\n",
  "bytes": 23737,
  "sha": "11007491249aef74f53ec559ef0e68381ab824bab02cad5c094ba3088ad29c57",
  "repo_slug": "voidnullable/lific",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_voidnullable_lific_b5178fc1/readme"
}