Files
FabledGrimoire/docs/configuration.md
T
bvandeusenandClaude Opus 5.5 47d40bffd8 docs: architecture, configuration, development and features describe Scribe as it is today
Milestone 544, step 6217 (follow-up to #1778, which rewrote features.md and
api-reference.md in July but left architecture.md and configuration.md alone).

- architecture.md, configuration.md, development.md: rewritten against the
  code. They still described Ollama, chat, SSE generation, voice, project
  summaries, image caching, Docker secrets that the compose files don't use,
  a raw-SQL migration convention the migrations no longer follow, a 27-entry
  migration list, CalVer YY.MM.DD.N tags and the removed infra/ files.
- features.md: adds what shipped since July (spikes, claims, moments, rule
  versions and verification, lessons, reply shapes, snippets and the shape
  ledger, forge integration, family canon, design systems, retrieval tuning)
  and corrects the Settings tabs and keyboard shortcuts (g g is the graph).
- api-reference.md: adds the endpoints for snippets, lessons, design
  systems, family canon, platforms, shared areas, retrieval, rule versions,
  relations and verification, forge connections, webhooks, scheduled
  backups and the newer plugin hooks.
- api-keys-and-mcp.md: Settings tab is "MCP Access"; a plugin install
  section; the tool-family table matches the tools that exist.
- design-system.md: the dated "decisions in progress" changelog (April
  PR log, chat/journal/calendar surfaces) becomes a short present-tense
  section; the stored design system is named as the authority.
- sso-oauth.md: the app is Scribe, not "Fabled Assistant".
- README: feature summary and doc table brought current.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 19:23:56 -04:00

5.7 KiB

Configuration

Scribe reads its configuration from environment variables. Most settings people change day to day (registration, SMTP, retrieval thresholds, backups, forge connections) live in Settings in the web UI instead.

Any variable marked secret can also be read from a file: set <NAME>_FILE to the path, for example a Docker secret at /run/secrets/scribe_key.

Environment variables

Core

Variable Default Description
DATABASE_URL (secret) postgresql+asyncpg://scribe:scribe@localhost:5432/scribe PostgreSQL connection string, using the asyncpg driver
SECRET_KEY (secret) dev-secret-change-me Signs sessions and seals stored credentials. Set it before first use and keep it (see below)
BASE_URL http://localhost:5000 Public URL, used in email links and OIDC redirects
SECURE_COOKIES false true when Scribe is served over HTTPS
TRUST_PROXY_HEADERS false true behind a reverse proxy, to read the client IP from X-Forwarded-For / X-Real-IP
LOG_LEVEL INFO DEBUG, INFO, WARNING or ERROR
LOG_RETENTION_DAYS 90 Days of app logs to keep
FASTEMBED_CACHE_DIR /data/fastembed-cache Where the embedding model is stored after its first download

Sign-in

Variable Default Description
LOCAL_AUTH_ENABLED true false turns off username/password login, leaving SSO only
OIDC_ISSUER — OIDC issuer URL
OIDC_CLIENT_ID — OIDC client ID
OIDC_CLIENT_SECRET (secret) — OIDC client secret
OIDC_SCOPES openid profile email Scopes to request

SSO turns on when the issuer, client ID and secret are all set. See SSO / OAuth.

Email

Admins can set SMTP in Settings; these are the defaults until they do.

Variable Default
SMTP_HOST —
SMTP_PORT 587
SMTP_USERNAME —
SMTP_PASSWORD (secret) —
SMTP_FROM_ADDRESS —
SMTP_FROM_NAME Fabled Scribe
SMTP_USE_TLS true

Integrations

Variable Default Description
PLUGIN_MARKETPLACE_URL this repo's git URL The git URL shown in the plugin install command under Settings → MCP Access. An admin can override it in Settings
FORGE_KIND, FORGE_BASE_URL, FORGE_TOKEN (secret) — A git forge connection for admins' projects, so a token can live in a Docker secret. Each user can add their own under Settings → Integrations; a stored connection for the same host wins
FORGE_WEBHOOK_SECRET (secret) — Verifies push webhooks from the forge
SEARXNG_URL — A SearXNG instance, listed as the web-search backend under Settings → Integrations

Running it

Quick start

docker-compose.quickstart.yml runs the published image with its own database:

SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex(32))') \
  docker compose -f docker-compose.quickstart.yml up -d

Open http://localhost:5000. The first account registered becomes the admin; after that, registration stays closed until an admin opens it in Settings or sends an invite.

From source

cp .env.example .env   # then set SECRET_KEY
docker compose up --build

Docker Swarm

docker-compose.prod.yml is a stack file: the app and database on a private overlay network, with SECURE_COOKIES and TRUST_PROXY_HEADERS on. Provide DB_PASSWORD and SECRET_KEY in the environment:

DB_PASSWORD=... SECRET_KEY=... docker stack deploy -c docker-compose.prod.yml scribe

The shipped files leave out healthchecks and restart policies on purpose. The app waits for its database on startup, and the orchestrator's defaults restart it if it ever exits.

Volumes

  • Database (pgdata): everything Scribe stores.
  • App data (/data): the embedding model cache and diagnostics. Losing it costs a re-download, nothing else.

Back up the database with Settings → Data → Scheduled backups (Backups).

Behind a reverse proxy

Scribe doesn't terminate TLS. Put it behind Nginx, Traefik or Caddy, forward to port 5000, and keep port 5000 off the internet. Set SECURE_COOKIES=true, TRUST_PROXY_HEADERS=true and BASE_URL.

location / {
    proxy_pass http://127.0.0.1:5000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # MCP responses can stream.
    proxy_buffering off;
    proxy_read_timeout 600s;
}

With TRUST_PROXY_HEADERS=true, make sure the proxy replaces any X-Forwarded-For the client sends.

Security checklist

  • Set a strong SECRET_KEY, and keep it. Forge tokens and the backup destination's S3 secret are sealed under a key derived from it, so a copy of the database alone can't read them. If the key changes (say, a restore onto an instance with a different key), Settings marks those credentials and asks for them again; nothing else breaks. The app logs a warning at startup while the default key is in use, and refuses to start with it when SECURE_COOKIES=true.
  • SECURE_COOKIES=true whenever Scribe is served over HTTPS.
  • Registration is open only for the first account. Invite people, or open it briefly from Settings.
  • Signing everyone else out: changing a password ends that user's other sessions; Settings → Account has a button for it too.
  • API keys are per user, shown once, and can be read-only. Revoke any you no longer use under Settings → MCP Access.