> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xynthis.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> The ~/.xynthis directory, the config.toml schema, and every supported environment variable.

Everything Xynthis persists lives under one directory, `~/.xynthis` by default. Set `XYNTHIS_HOME` to relocate the whole data directory with one lever; every path below resolves through it.

## Directory layout

```
~/.xynthis/
├── bin/                   installed binaries + skill scripts
├── bmc/                   binary memory stores (the brain's persistent state)
├── sessions/              per-session JSON + working-memory ledgers
├── skills/                skill library (one SKILL.md per directory)
├── skill/                 per-user skill model checkpoint
├── llm/                   on-device model state (state.json, train_config.json, checkpoints)
├── extensions/            external MCP/webhook extension manifests
├── recipes/               task templates (<name>.yaml)
├── archive/               archived sessions (xynthis sessions archive)
├── pids/                  service PID files
├── logs/                  daemon stdout/stderr
├── brain.sock             unix socket — the brain's only API
├── config.toml            model + provider config
├── auth.json              API keys (mode 0600)
├── lessons.json           the agent's failure-to-correction store
├── learned_actions.json   cached successful tool patterns
├── tool_policy.json       per-tool allow / deny / ask-always policy
├── cortex.json            situation bulletin (when built)
└── persona.txt            condensed user persona (when built)
```

Inside `bmc/`, alongside the memory store itself, the brain also keeps
`identity.ed25519` (the local signing identity for witnessed memory,
mode 0600) and `witness.log` (the append-only Merkle log of confirmed
facts).

The brain is the only process that writes `bmc/`. Everything else (the CLI, the daemon, the app, MCP clients) goes through `brain.sock`.

## config.toml

Two sections: `[models]` selects what runs, `[providers.<name>]` defines how to reach each backend. Missing files are replaced by defaults, so a brand-new machine works without any config.

```toml theme={null}
[models]
active = "anthropic/claude-sonnet-4-5"
fast = "anthropic/claude-haiku-4-5"      # optional

[providers.anthropic]
kind = "anthropic-messages"
base_url = "https://api.anthropic.com/v1/messages"
default_model = "claude-sonnet-4-5"

[providers.ollama]
kind = "openai-chat"
base_url = "http://localhost:11434/v1"
default_model = "llama3.3"
```

### \[models]

| Field    | Type   | Default  | Meaning                                                                                                                                                               |
| -------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `active` | string | `"echo"` | Active target: `"<provider>/<model>"`, or `"<provider>"` to use its `default_model`                                                                                   |
| `fast`   | string | unset    | Optional cheaper target the agent uses for easy turns (post-tool summaries, short acknowledgements). Same format as `active`. Unset means every turn goes to `active` |

### \[providers.\<name>]

| Field            | Type         | Default  | Meaning                                                                                                                                                              |
| ---------------- | ------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `kind`           | string       | required | One of `anthropic-messages`, `openai-chat`, `subprocess`, `codex-oauth`, `claude-oauth`, `xynthis-llm`, `echo`                                                       |
| `base_url`       | string       | unset    | HTTP backends: for `openai-chat`, the root without `/chat/completions`; for `anthropic-messages`, the full `/messages` endpoint                                      |
| `default_model`  | string       | unset    | Model id used when the target doesn't name one                                                                                                                       |
| `command`        | string       | unset    | `subprocess` only: the CLI to spawn (e.g. `"claude"`)                                                                                                                |
| `args`           | string array | `[]`     | `subprocess` only: fixed arguments                                                                                                                                   |
| `model_arg`      | string       | unset    | `subprocess` only: flag used to pass the model name (e.g. `"--model"`)                                                                                               |
| `lite`           | bool         | `false`  | Lite mode for small local models: plain chat with no tool schemas, a short system prompt, and no pre-turn memory injection. Set this for models that can't tool-call |
| `launch_command` | string       | unset    | Local providers only: shell command that starts the provider's server when it isn't running                                                                          |

The `kind` values map to how xynthis reaches the backend: `openai-chat` covers OpenAI, Ollama, llama.cpp, Groq, DeepSeek, Gemini, xAI, LM Studio, and anything else implementing the standard. `subprocess` pipes through an external CLI like `claude` or `codex` using that CLI's own auth. `codex-oauth` and `claude-oauth` call the respective backends directly with tokens from an existing Codex or Claude Code login. `xynthis-llm` targets the local model server on `http://127.0.0.1:8080/v1`. `echo` is a deterministic network-free fallback.

Fourteen providers are pre-registered on first save: `echo`, `anthropic`, `openai`, `ollama`, `xynthis-llm`, `llamacpp`, `groq`, `deepseek`, `gemini`, `xai`, `claude-code`, `codex`, `codex-oauth`, `claude-oauth`. `xynthis models list --all` shows them.

### API keys

Keys never live in `config.toml`. Lookup order per provider: the macOS Keychain (service `com.xynthis.app`, account `<provider>-api-key`; this is where the app's Settings writes), then `~/.xynthis/auth.json` (written by `xynthis login` and `xynthis auth apply`, mode 0600).

## Environment variables

| Variable                      | Default                    | Effect                                                                                                                                                                                                                                                                                |
| ----------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `XYNTHIS_HOME`                | `~/.xynthis`               | Relocate the entire data directory. Blank values are treated as unset                                                                                                                                                                                                                 |
| `XYNTHIS_BRAIN_SOCKET`        | `$XYNTHIS_HOME/brain.sock` | Override the brain socket path                                                                                                                                                                                                                                                        |
| `XYNTHIS_LLM_OVERRIDE`        | unset                      | Force an LLM target for one invocation (same as the global `--llm` flag); does not write config                                                                                                                                                                                       |
| `XYNTHIS_NO_APP`              | unset                      | `1` stops `xynthis chat` from launching the macOS app                                                                                                                                                                                                                                 |
| `XYNTHIS_API_KEY`             | unset                      | Non-interactive key for `xynthis models add`                                                                                                                                                                                                                                          |
| `XYNTHIS_SKILLS_DIR`          | `~/.xynthis/skills`        | Override the skill library root                                                                                                                                                                                                                                                       |
| `XYNTHIS_CORTEX`              | off                        | `on` injects the cortex bulletin into the system prompt                                                                                                                                                                                                                               |
| `XYNTHIS_CORTEX_REFRESH_SECS` | `900`                      | Bulletin staleness threshold in seconds                                                                                                                                                                                                                                               |
| `XYNTHIS_LEXICAL_FLOOR`       | on                         | `0` disables the lexical floor in memory retrieval (re-scoring stage that guarantees strong keyword matches rank)                                                                                                                                                                     |
| `XYNTHIS_LLM_PORT`            | `8080`                     | Model server listen port                                                                                                                                                                                                                                                              |
| `XYNTHIS_LLM_BIND`            | `127.0.0.1`                | Model server bind address. `0.0.0.0` listens on all interfaces; only do that behind a tunnel or VPN                                                                                                                                                                                   |
| `XYNTHIS_LLM_SMALL`           | unset                      | Set to serve the smaller backbone preset                                                                                                                                                                                                                                              |
| `XYNTHIS_LLM_MODEL_ID`        | `xynthis-local`            | Model id advertised on `/v1/models`                                                                                                                                                                                                                                                   |
| `XYNTHIS_LLM_TRAIN`           | unset                      | First-run seed only: if set (any value) when `~/.xynthis/llm/train_config.json` does not exist, the model server creates that file with training enabled. Once the file exists, it governs and this variable is ignored; toggle training with the MCP `llm_train_set` tool or the app |
| `XYNTHIS_JSPACE`              | off                        | Set to capture workspace readouts; responses carry `xynthis_jspace`                                                                                                                                                                                                                   |
| `XYNTHIS_JSPACE_TOPK`         | `5`                        | Concepts captured per generated token (minimum 1)                                                                                                                                                                                                                                     |
| `XYNTHIS_JSPACE_TO_BRAIN`     | off                        | Also submit each reply's readout summary to the brain as short-lived working-memory context. Requires `XYNTHIS_JSPACE`; inert without it                                                                                                                                              |
