Skip to main content
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.
[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]

FieldTypeDefaultMeaning
activestring"echo"Active target: "<provider>/<model>", or "<provider>" to use its default_model
faststringunsetOptional 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>]

FieldTypeDefaultMeaning
kindstringrequiredOne of anthropic-messages, openai-chat, subprocess, codex-oauth, claude-oauth, xynthis-llm, echo
base_urlstringunsetHTTP backends: for openai-chat, the root without /chat/completions; for anthropic-messages, the full /messages endpoint
default_modelstringunsetModel id used when the target doesn’t name one
commandstringunsetsubprocess only: the CLI to spawn (e.g. "claude")
argsstring array[]subprocess only: fixed arguments
model_argstringunsetsubprocess only: flag used to pass the model name (e.g. "--model")
liteboolfalseLite 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_commandstringunsetLocal 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

VariableDefaultEffect
XYNTHIS_HOME~/.xynthisRelocate the entire data directory. Blank values are treated as unset
XYNTHIS_BRAIN_SOCKET$XYNTHIS_HOME/brain.sockOverride the brain socket path
XYNTHIS_LLM_OVERRIDEunsetForce an LLM target for one invocation (same as the global --llm flag); does not write config
XYNTHIS_NO_APPunset1 stops xynthis chat from launching the macOS app
XYNTHIS_API_KEYunsetNon-interactive key for xynthis models add
XYNTHIS_SKILLS_DIR~/.xynthis/skillsOverride the skill library root
XYNTHIS_CORTEXoffon injects the cortex bulletin into the system prompt
XYNTHIS_CORTEX_REFRESH_SECS900Bulletin staleness threshold in seconds
XYNTHIS_LEXICAL_FLOORon0 disables the lexical floor in memory retrieval (re-scoring stage that guarantees strong keyword matches rank)
XYNTHIS_LLM_PORT8080Model server listen port
XYNTHIS_LLM_BIND127.0.0.1Model server bind address. 0.0.0.0 listens on all interfaces; only do that behind a tunnel or VPN
XYNTHIS_LLM_SMALLunsetSet to serve the smaller backbone preset
XYNTHIS_LLM_MODEL_IDxynthis-localModel id advertised on /v1/models
XYNTHIS_LLM_TRAINunsetFirst-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_JSPACEoffSet to capture workspace readouts; responses carry xynthis_jspace
XYNTHIS_JSPACE_TOPK5Concepts captured per generated token (minimum 1)
XYNTHIS_JSPACE_TO_BRAINoffAlso submit each reply’s readout summary to the brain as short-lived working-memory context. Requires XYNTHIS_JSPACE; inert without it