Configuration
Exocortex reads three layers of configuration. They’re applied in this order — later sources override earlier ones:
- Bundled defaults —
exocortex/_bundled/config/*.example.yaml, shipped inside the wheel - User config —
config/*.yamlin the working directory (created byexocortex initfrom the matching*.example.yaml) - Environment variables —
DATABASE_URL,OPENAI_API_KEY, etc. override individual settings at process start
First run
# Inside the repo (dev) or any working directory (pip-installed):exocortex initexocortex init copies every *.example.yaml that isn’t already
present, leaves existing user-customised files alone, and creates a
.env skeleton. It is idempotent — re-running on an initialised
directory is a no-op.
The env file
.env (and /etc/exocortex.env for systemd-managed installs) holds
secrets and infrastructure URLs:
# Database — psycopg-style URL. Exocortex parses it via Pydantic# Settings; individual PG_* overrides are also honoured.DATABASE_URL=postgresql://postgres:postgres@localhost:5432/exocortex
# Tenant — Exocortex is multi-tenant-aware at the row level. Pick any# stable UUID; you only need to change this if you run multiple# logically separated knowledge bases against one Postgres.TENANT_ID=00000000-0000-0000-0000-000000000001
# LLM providers — llm_router fan-out. At least one is required for the# `ask` MCP tool to return a synthesised answer.ANTHROPIC_API_KEY=sk-ant-...OPENAI_API_KEY=sk-...
# Optional — fallback router behaviour. Default is on; set to `off` to# fail hard instead of cascading providers.LLM_ROUTER_FALLBACK=on
# Vault root — used by the wiki compiler for output and by the vault# watcher for ingest. Defaults to ./vault/ relative to the working# directory. Canonical name across systemd units, docker-compose, and# the bootstrap script.EXOCORTEX_VAULT_PATH=./vaultThe YAML files
config/ holds opinionated, project-specific configuration. None of
these are required for the engine to start, but most plugins assume
at least projects.yaml exists.
| File | Purpose | Example shipped at |
|---|---|---|
projects.yaml | Client/project registry, person tag mapping | _bundled/config/projects.example.yaml |
tag_taxonomy.yaml | Five-axis tag taxonomy used by the synthesiser | _bundled/config/tag_taxonomy.example.yaml |
sources.yaml | RSS feeds + vault watch rules | _bundled/config/sources.example.yaml |
integrations.yaml | Notion / Gmail / Telegram integration settings | _bundled/config/integrations.example.yaml |
graph_rag.yaml | GraphRAG retrieval tuning (top-k, hop count, weights) | _bundled/config/graph_rag.example.yaml |
All user-edited files in config/ are gitignored by default — your
secrets and project names never end up in version control unless you
explicitly stage them.
Plugins
Plugins discover configuration through the same config/ directory,
either by reading a file directly or by registering a Pydantic Settings
class against an EXOCORTEX_PLUGIN_<NAME>__* prefix. See
Writing a plugin for the patterns.
Verifying the setup
# Show resolved settings (secrets redacted)exocortex query --diag settings
# Show registered pluginsexocortex query --diag plugins
# Show database connectivity + migration stateexocortex migrate statusIf any of these fail, the error message points at the missing variable or file.
Next steps
- Quickstart — five-minute end-to-end smoke
- Writing a plugin — extend the engine for your domain
- Architecture overview — L1/L2/L3