Providers
The models, speech services and channels Nestor works with today, what is planned, and how to set each one up.
Nestor needs a language model for the agent, and speech services only to talk aloud.
People reach it through channels: Telegram, satellites (in writing, aloud or both), or all of
them. Everything is set in nestor.yaml, with the keys in the .env next to it. nestor init
asks for the model server and the model, and writes satellites with Telegram, or satellites with
their voice on ElevenLabs when the voice extra is installed. To change a provider later, paste its blocks below over the matching ones, then
run nestor check.
Language model
The agent talks to any server that speaks the OpenAI Chat Completions API, with streaming. The adapter is tested against OpenRouter; the others speak the same API and are expected to work. Pick a model that supports tool calls: the agent acts through them.
The model’s key is MODEL_API_KEY, in .env, whatever the provider. Local servers need none:
leave it empty. OpenRouter, OpenAI, Mistral and Anthropic refuse an empty key, and nestor check
names the variable to fill.
One key for models from many vendors, Claude and Gemini included. It is the default, and the provider the adapter is tested against.
MODEL_API_KEY=sk-or-...model:
kind: openai-compatible
base_url: https://openrouter.ai/api/v1
api_key: ${MODEL_API_KEY}
model: anthropic/claude-haiku-5.5MODEL_API_KEY=sk-...model:
kind: openai-compatible
base_url: https://api.openai.com/v1
api_key: ${MODEL_API_KEY}
model: gpt-5-miniMODEL_API_KEY=...model:
kind: openai-compatible
base_url: https://api.mistral.ai/v1
api_key: ${MODEL_API_KEY}
model: mistral-small-latestMODEL_API_KEY=gsk_...model:
kind: openai-compatible
base_url: https://api.groq.com/openai/v1
api_key: ${MODEL_API_KEY}
model: openai/gpt-oss-120bThrough Google’s OpenAI-compatible endpoint.
MODEL_API_KEY=...model:
kind: openai-compatible
base_url: https://generativelanguage.googleapis.com/v1beta/openai/
api_key: ${MODEL_API_KEY}
model: gemini-flash-latestThrough Anthropic’s OpenAI compatibility layer, which Anthropic intends for testing, not for production. OpenRouter is the tested way to Claude.
MODEL_API_KEY=sk-ant-...model:
kind: openai-compatible
base_url: https://api.anthropic.com/v1/
api_key: ${MODEL_API_KEY}
model: claude-haiku-5-5No key: leave MODEL_API_KEY empty. model is one the server has pulled.
model:
kind: openai-compatible
base_url: http://localhost:11434/v1
model: qwen3Start LM Studio’s server. No key: leave MODEL_API_KEY empty. model is the identifier LM Studio shows for the loaded model.
model:
kind: openai-compatible
base_url: http://localhost:1234/v1
model: qwen3-8bLeave MODEL_API_KEY empty, unless you started vLLM with --api-key. model is the name vLLM
serves.
model:
kind: openai-compatible
base_url: http://localhost:8000/v1
model: Qwen/Qwen3-8BNo key: leave MODEL_API_KEY empty. llama-server serves the one model it loaded, whatever model says.
model:
kind: openai-compatible
base_url: http://localhost:8080/v1
model: localThe model names are examples: any model of the provider’s catalogue that supports tool calls will do, and any other OpenAI-compatible host works the same way. On most home hardware a local model answers more slowly than a hosted one, and speech feels it first.
With Docker, localhost is the container itself. A model server running on the host is
http://host.docker.internal:<port>/v1: http://host.docker.internal:11434/v1 for Ollama,
http://host.docker.internal:1234/v1 for LM Studio. On Linux, that address is not the host’s
loopback, so the model server must listen beyond it: OLLAMA_HOST=0.0.0.0 for Ollama,
--host 0.0.0.0 for llama.cpp.
model also takes extra_body, merged into every request (OpenRouter’s routing, reasoning
settings…), connect_timeout_s (5) and read_timeout_s (30). A triage_model with the same keys
gives the sorting of incoming items to a smaller model.
Speech
The satellites’ voice transcribes the person and speaks the answer. ElevenLabs is the one provider today, for both; a new one ships once it holds up on reproducible measurements (latency, turn ends, interruptions).
Scribe v2 Realtime transcribes, v4 Turbo speaks; one key covers both.
ELEVENLABS_API_KEY=sk_...channels:
- kind: satellites
host: 0.0.0.0
voice:
speech:
api_key: ${ELEVENLABS_API_KEY}
voice_id: GPAQQPp9dazaB2bl4zg9voice_id is any voice of your ElevenLabs library. The voice follows the language of the text;
the transcription listens for English unless speech sets another language (see
below).
Gradium is planned: Nestor does not support it yet.
Deepgram is planned: Nestor does not support it yet.
Cartesia is planned: Nestor does not support it yet.
OpenAI is planned: Nestor does not support it yet.
Whisper is planned: Nestor does not support it yet.
Kokoro is planned: Nestor does not support it yet.
Piper is planned: Nestor does not support it yet.
Channels
Each channel is an entry of channels, and several can run side by side with the same memory.
Telegram and satellites come with the package. Satellites talk in writing
out of the box; their voice is the voice extra (see Install), with the speech
services above.
Create a bot with Telegram’s @BotFather and put its token in .env:
TELEGRAM_BOT_TOKEN=123456:ABC-...channels:
- kind: telegram
token: ${TELEGRAM_BOT_TOKEN}Add "telegram:<your chat id>" to your accounts in household so the bot knows you. It reads
text messages; voice notes and pictures are ignored.
Devices people type on, talk to, or both. In writing, nothing more is needed:
channels:
- kind: satellites
host: 0.0.0.0To talk to them too, install the voice extra (the Docker image has it) and add a voice with its
speech provider:
channels:
- kind: satellites
host: 0.0.0.0
voice:
speech:
api_key: ${ELEVENLABS_API_KEY}
voice_id: GPAQQPp9dazaB2bl4zg9host: 0.0.0.0 lets satellites on your network reach the server, on port 8471 (set by port);
then pair them as Satellites explains. Each satellite talks in the room it was
paired in. Add "satellites:*" to your accounts in household.
WhatsApp is planned: Nestor does not support it yet.
Signal is planned: Nestor does not support it yet.
Discord is planned: Nestor does not support it yet.
Matrix is planned: Nestor does not support it yet.
In French
nestor init asks for the household’s language. Without it, Nestor speaks English, on UTC. To
switch an existing configuration to French, set the persona’s locale (the fixed phrases and the
admin), the language the model writes in, the household’s timezone and, with the satellites’
voice, the transcription’s language:
persona:
locale: fr
language: French
timezone: Europe/Paris
channels:
- kind: satellites
voice:
speech:
language: fr
Where keys live
.env, next tonestor.yaml, referred to as${NAME}: whatnestor initwrites and the blocks above use. Nestor reads it at each start. A variable already set in the environment (the shell, a service manager, Docker) wins over the file.- The vault, encrypted in the data folder, referred to as
${secret:name}: set withnestor secrets set <name>(asked without echo) or from the admin, listed withnestor secrets list. Move keys there once the installation settles: none sits in clear on disk, and the admin can change them.
nestor secrets set openrouter # then, in nestor.yaml: api_key: ${secret:openrouter}
NESTOR_SECRET_KEY, in .env, opens the vault. nestor init generates it: never change it, or the
secrets already stored can no longer be read. Restart Nestor after changing a key.