Integration Config
MCP config
Two layers; session overrides global. Manage servers with /mcp in the TUI or the /v1/mcp* endpoints. See MCP Client for the full schema and ${VAR} expansion behavior.
Provider config
There are no static provider catalogs — model lists come from each provider's API when a model is added. Registered models live in config.json; credentials never do, they live in the OS keychain under service agenvoy.
Compat provider URL storage split
compat provider URLs use a two-storage model:
| What | Where | Why |
|---|---|---|
URL (e.g. http://host:8000/v1) |
~/.config/agenvoy/config.json compats[].URL |
Non-secret, user-editable |
API key (COMPAT_<NAME>_API_KEY) |
OS keychain | Secret |
URL convention follows Zed: the user enters the URL up to /v1 (e.g. http://localhost:11434/v1) and the router appends /chat/completions. The URL is read from config, not the keychain — there is no COMPAT_<NAME>_URL keychain key (intentionally removed: a historical bug had the TUI writing to config while the runtime read the keychain, always falling back to localhost).
KuraDB
Enabled state is kuradb_enabled: bool in config.json. Toggle via /kuradb in the TUI; POST /v1/kuradb can enable, disable, start, stop, and restart an already-installed instance, while install and uninstall stay TUI-only (install.sh + sudo need a real TTY). See KuraDB RAG for the full lifecycle.
| Key | Location |
|---|---|
kuradb_enabled |
config.json |
OPENAI_API_KEY |
keychain (agenvoy service) — shared with semantic search |
| Endpoint URL (runtime) | ~/.config/kuradb/endpoint (plaintext, random port per spawn) |
| Binary | /usr/local/bin/kura (hardcoded in install.sh) |
Telegram / Discord enablement
| Key | Location |
|---|---|
telegram_enabled / discord_enabled |
config.json |
TELEGRAM_TOKEN / DISCORD_TOKEN |
keychain (agenvoy service) |
| Authorized chat IDs | ~/.config/agenvoy/.telegram and ~/.config/agenvoy/.discord (one ID per line, written after 6-digit OTP verification succeeds) |
| Verification-code relay | admin_channel in config.json — /admin-channel in the TUI picks an authorized chat or a raw tg@<id> / dc@<id> target |
| Voice replies | enable_voice in config.json, toggled with /voice (Gemini TTS; Telegram only) |
Both channels can also be enabled or disabled through POST /v1/channel/telegram and POST /v1/channel/discord, which store the token and flip the flag; the daemon's config watcher reconnects the bot and fills in its username. Platform formatting rules are embedded in the channel system prompts — there is no format_chatbot tool.
Where things deliberately do not live
Some intentional non-locations:
- Provider API keys — Never in
config.json; always in keychain - MCP credentials — Use
${VAR}placeholders inmcp.jsonand put the actual values in env vars (or keychain via your shell init) - Secrets captured by
store_secret— Land in keychain only; never in LLM context, history, action.log, or tool args - Session history — In ToriiDB and the SQLite archive, never spread across per-session JSON files
- Tool call results — Deduped in memory per run, plus a 30-minute ToriiDB cache for
fetch_page/search_web/search_google_news; nothing else survives a restart