Integration Config
MCP config
One file: ~/.config/agenvoy/mcp.json. The session-scoped layer was removed. Manage servers with /mcp in the TUI, the web dashboard, 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, or a local endpoint's GET /models, when a model is added. Registered models live in config.json under models (their order is the fallback priority), tiers under model_tag, and custom endpoint URLs under compats; credentials never do, they live in the OS keychain under service agenvoy. A write to config.json reloads the agent registry without a restart.
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[] — {"provider": "<NAME>", "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://host:8000/v1) and the router appends /chat/completions. Local Ollama (http://localhost:11434/v1) and llama.cpp (http://localhost:8080/v1) are built in through configs/jsons/local_compat.json and need no compats entry. 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
There is no kuradb_enabled flag and no /v1/kuradb endpoint. KuraDB is registered as an ordinary MCP server — one entry in mcp.json — so its tools arrive under mcp__kura__* and vanish when it is unregistered or disconnected. The /kuradb TUI wizard was removed in v0.35.0: run kuradb.sh yourself (it needs a real TTY for sudo), then register through /mcp. See KuraDB RAG for the full picture.
| Key | Location |
|---|---|
kura server entry |
~/.config/agenvoy/mcp.json — {"command": "kura", "args": ["mcp"]} |
OPENAI_API_KEY |
keychain (agenvoy service) — shared with semantic search |
| Binary | kura on PATH (/usr/local/bin/kura, from kuradb.sh) |
| KuraDB's own config / data | ~/.config/kuradb/, managed entirely by KuraDB |
Telegram / Discord enablement
| Key | Location |
|---|---|
telegram_enabled / discord_enabled |
config.json (bot usernames are filled into telegram_username / discord_username) |
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 — /channel → admin in the TUI, or POST /v1/channel/admin, picks an authorized chat or a raw tg@<id> / dc@<id> target. The /admin-channel command was removed; use /channel |
| Inbound voice messages | Transcribed with whichever model stt_model in config.json names (/model → stt in the TUI). With none selected the bot answers that no speech-to-text model is set instead of transcribing |
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.
Both bots connect outbound from the daemon, so the host needs no inbound port, public hostname, or reverse proxy — a bot token is the whole setup. That is also the bar for adding another platform: one is considered only when it improves on this, not merely to widen the list.
Voice output was removed from both channels. [SEND_VOICE:<text>] no longer exists and replies are never synthesized into a chat; speech synthesis is the generate_audio tool, which writes a .wav to the download directory and is gated on tts_model.
Where things deliberately do not live
Some intentional non-locations:
- Provider API keys — Never in
config.json; always in keychain (config.jsonkeyslists only the key names) - 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, andhttp_requestGETcalls; nothing else survives a restart