Fabled Grimoire

A self-hosted system of record for the work you do with Claude Code.

Claude records what it learned, decided and built in Grimoire, and that record reaches the next session, so a solution is recalled instead of reinvented. Notes, tasks, plans, rules, lessons and reusable code live in one place. Claude reaches them through a built-in MCP endpoint and the bundled Claude Code plugin, and people read and edit the same records in the web UI. There is no language model inside Grimoire: Claude is the only assistant. ## Deploy You need Docker with Compose. Save this as `docker-compose.yml` (it is the [`docker-compose.yml`](docker-compose.yml) in this repository), then run `docker compose up -d` beside it: ```yaml # Fabled Grimoire: the app and its database. # docker compose up -d # Then open http://localhost:5000. The first account registered becomes admin. # # Keep both volumes. app_data holds the instance's own SECRET_KEY, which seals # saved credentials; pgdata holds everything else. services: app: image: git.fabledsword.com/bvandeusen/fabledgrimoire:latest ports: - "5000:5000" environment: DATABASE_URL: "postgresql+asyncpg://${POSTGRES_USER:-grimoire}:${POSTGRES_PASSWORD:-grimoire}@db:5432/${POSTGRES_DB:-grimoire}" LOG_LEVEL: "${LOG_LEVEL:-INFO}" # Behind an HTTPS reverse proxy: # BASE_URL: "https://grimoire.example.com" # SECURE_COOKIES: "true" # TRUST_PROXY_HEADERS: "true" volumes: - app_data:/data depends_on: - db restart: unless-stopped db: # Postgres 17 with the vector extension Grimoire needs. image: pgvector/pgvector:pg17 stop_grace_period: 120s volumes: - pgdata:/var/lib/postgresql/data environment: POSTGRES_USER: ${POSTGRES_USER:-grimoire} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-grimoire} POSTGRES_DB: ${POSTGRES_DB:-grimoire} restart: unless-stopped volumes: app_data: pgdata: ``` Open `http://localhost:5000`. The first account you register becomes the admin. Nothing has to be set first. On its first start Grimoire makes its own `SECRET_KEY` and keeps it in the `app_data` volume, so restarts, reboots and updates all use the same key. To connect Claude, create an API key under **Settings → MCP Access**, then in Claude Code: ``` /plugin marketplace add https://git.fabledsword.com/bvandeusen/FabledGrimoire.git /plugin install grimoire@grimoire-plugin ``` The plugin asks for your Grimoire URL and the API key. Settings → MCP Access shows the exact commands for your instance. ## Configuration Everything is optional. Set these in the environment or in a `.env` file beside the compose file: | Variable | When | What it does | |----------|------|--------------| | `BASE_URL` | Behind a proxy | The public URL, used in email links and SSO redirects | | `SECURE_COOKIES` | Over HTTPS | `true` when Grimoire is served over HTTPS | | `TRUST_PROXY_HEADERS` | Behind a proxy | `true` to read the client address from the proxy's headers | | `POSTGRES_PASSWORD` | Before the first start | The database password (defaults to `grimoire`; the database is reachable only inside the compose network). Postgres takes it once, when the volume is created | | `SECRET_KEY` | Rarely | A key you manage yourself, instead of the one Grimoire keeps. It wins over the kept key; remove it to go back | Everything else (registration, email, SSO, git forge connections, retrieval tuning, backups) is in **Settings**, or listed in [Configuration](docs/configuration.md). ## Setup pitfalls - **Keep both volumes.** `pgdata` holds everything Grimoire stores. `app_data` holds the instance's key, and forge tokens and the backup bucket's secret are sealed under it. If the key is lost, Settings asks you to enter those credentials again; nothing else is lost. - **The embedding model downloads on first use**, into the `app_data` volume. Without internet access, semantic search falls back to keyword search until the model is in place. - **Behind a reverse proxy, turn off response buffering** for `/mcp`, because MCP responses stream. [Configuration](docs/configuration.md#behind-a-reverse-proxy) has an Nginx example. ## Updating and backups ```bash docker compose pull docker compose up -d ``` Database migrations run when the app starts, and the key stays in its volume. Claude Code updates the plugin from its marketplace; run `/reload-plugins` after an update. **Settings → Data → Scheduled backups** writes a daily backup of the database to a folder or an S3-compatible bucket, and `python -m grimoire.restore` brings a fresh instance back from one. See [Backups](docs/backups.md). ## Features **Working with Claude** - Claude enters a project and gets a short primer: its goal, current plans, open tasks and areas. - Your rules reach Claude when its work matches them, or at a moment of work such as finishing a task or pushing code. - Before Claude writes a file or runs a command, the plugin shows it the rules, lessons and reusable code that may apply. - Stored procedures, such as a drift audit, become Claude Code skills. **Recording the work** - Notes in a Markdown editor, with wikilinks, tags and version history. - Tasks, issues and time-boxed investigations, with work logs that the next session reads first. - Plans as milestones: a design plus ordered steps. - Lessons learned the hard way, linked to the rules they illustrate. - Duplicate checks, so a new record that matches an existing one updates it instead. **Reusing code** - Snippets of reusable code, each with when to reach for it and where it lives in the repo. - With a git forge connected, Grimoire tracks every function and style in your repos and shows which ones are still unaccounted for. - Ideas shared across projects on the same platform, with each project's answer recorded. - Design systems with tokens, inheritance and a generated stylesheet. **For people** - A web UI to browse, search and edit everything, plus a graph of how notes connect. - Sharing with users and groups, as viewer, editor or admin. - Email and password sign-in, optional SSO through OIDC, and invite links. - Personal export to Markdown or JSON, and admin backup and restore. The full list is in [Features](docs/features.md). ## Troubleshooting | What you see | Why | Fix | |--------------|-----|-----| | `SECRET_KEY is set to the public placeholder` at startup | `SECURE_COOKIES=true` while `SECRET_KEY` is `dev-secret-change-me` | Remove `SECRET_KEY`, or set a real one | | Settings asks for forge tokens or the backup secret again | The instance's key changed: the `app_data` volume was replaced, or `SECRET_KEY` was set or removed | Enter them again, or restore the previous key | | `Can't locate revision identified by '…'` at startup | An older image is running against a database a newer one has already migrated | Run the newer image; migrations only move forward | | The plugin's tools are missing in Claude Code | The plugin isn't installed, or Claude Code hasn't reloaded it | `/plugin` to install or update it, then `/reload-plugins` | | Search finds only exact words | The embedding model hasn't downloaded yet | Give the app internet access once, or wait for the first download to finish | ## Development ```bash docker compose -f docker-compose.dev.yml up --build ``` [Development](docs/development.md) covers checks, migrations, the plugin and CI. [Architecture](docs/architecture.md) describes how it is built, and the [API reference](docs/api-reference.md) lists every REST endpoint. ## Licence Fabled Grimoire is free software under the [GNU Affero General Public License v3.0 only](LICENSE) (`AGPL-3.0-only`). If you run a modified version for other people over a network, the licence requires you to offer them its source.