Skip to main content

Add a provider

You can add a language-model provider yourself — no plugin, no restart. It works for any provider that speaks one of two protocols:

ProtocolRuns throughTypical providers
Anthropicthe Claude Code CLIDeepSeek, Moonshot (Kimi), Z.ai, any Anthropic-compatible gateway
OpenAI Responsesthe Codex CLIOpenRouter, a vLLM or LM Studio server, any endpoint that serves /v1/responses

If your provider speaks neither, it needs a provider plugin instead.

Adding or removing a backend is reserved to a superadmin: a backend decides where the prompts of every mission run on it are sent.

From Settings

Open Settings → LLM backends and choose Add a backend.

FieldWhat to enter
NameHow the backend appears in the model selectors.
ProtocolAnthropic or OpenAI Responses.
Base URLFor Anthropic, the address the provider documents for ANTHROPIC_BASE_URL, without /v1. For OpenAI Responses, the address ending in /v1.
API keyStored in the secrets vault, never in a file, and never shown again. Leave it empty for a local server that asks for none.

Test makes one call to the provider's model listing and tells you which of these is true:

  • the endpoint answers and accepts the key — the models it lists are proposed alongside the ones you entered;
  • the endpoint answers but refuses the key;
  • nothing answers at this address;
  • the endpoint answers with another status (often 404: it has no model listing). The key could not be checked, which does not mean it is wrong.

Once saved, the backend is selectable immediately, in every place where you choose a model. Choose Edit to change its key, address, models or picture. Leave the key field empty to keep the saved key. Removing a backend also deletes its key from the vault.

You can also add models manually when the provider has no model listing. Enter the exact model ID, give it a label and choose which model should be the default. See backend management for disabling, reordering and editing built-in providers.

When a backend is inactive

An inactive backend is listed with its reason, for example:

  • vault entry … does not exist — the key it refers to was deleted from the vault;
  • vault entry … has no grant — the key exists but no mission may receive it; grant it to global on the Secrets page;
  • dialect … is not installed — the file names a protocol that no installed plugin provides.

From a file

Each backend is one file, ~/.timon/backends/<id>.json. The form writes that file; you can also write it, or copy one from a README. The folder is watched: a file you add, edit or delete takes effect within a second.

{
"id": "deepseek",
"dialect": "claude",
"label": "DeepSeek",
"vendor": "DeepSeek",
"env": {
"ANTHROPIC_BASE_URL": "https://api.deepseek.com/anthropic",
"ANTHROPIC_AUTH_TOKEN": { "secret": "BACKEND_DEEPSEEK_API_KEY" }
},
"defaultModel": "deepseek-v4-pro",
"models": [
{ "slug": "deepseek-v4-pro", "label": "DeepSeek V4 Pro", "contextWindow": 128000 },
{ "slug": "deepseek-v4-flash", "label": "DeepSeek V4 Flash" }
]
}

An OpenAI Responses provider also declares how the Codex CLI reaches it:

{
"id": "openrouter",
"dialect": "codex",
"label": "OpenRouter",
"env": { "BACKEND_OPENROUTER_API_KEY": { "secret": "OPENROUTER_API_KEY" } },
"providerConfig": {
"id": "timon-openrouter",
"name": "OpenRouter",
"baseUrl": "https://openrouter.ai/api/v1",
"envKey": "BACKEND_OPENROUTER_API_KEY",
"wireApi": "responses"
},
"defaultModel": null,
"models": [],
"modelsEndpoint": { "url": "https://openrouter.ai/api/v1/models", "format": "openai" }
}
FieldMeaning
idLowercase letters, digits and dashes. Must equal the file name. It cannot be the id of a built-in backend (claude, codex, …) or of one a plugin provides.
dialectclaude (Anthropic protocol) or codex (OpenAI Responses), or a dialect an installed plugin provides.
label, vendor, brandDisplay name, vendor column and logo key in the selectors.
envEnvironment of the mission process. A value is either a plain, non-secret string or a reference to a vault entry: { "secret": "NAME" }.
providerConfigcodex dialect only. Choose an id that is not one of Codex's built-in providers (openai, ollama, …). envKey names the variable of env that holds the key.
defaultModel, modelsModels offered in the selectors. models may be empty: the model field is then free text.
modelsEndpointOptional. A public, OpenAI-style model listing that replaces models while it answers.

Keys belong in the vault

Create the key on the Secrets page in inject mode, grant it to global, and reference it by name. A key without a grant is never handed to a mission, and the backend stays inactive.

A key written directly in the file works, but the backend is flagged with a warning: the file is plain text, and it is included when you export your installation.

What a file cannot do

A backend file is data. It chooses an address and a model list, nothing else, and these keys are refused:

  • cmd, requiredBinary — a file never chooses a program to run;
  • requiredEnv, envFrom — a file never reads the environment of the Timon service.

What a file may set in env

Each protocol reads its own variables, and a file may only name those:

Protocol (dialect)Names a file may set
Anthropic (claude)ANTHROPIC_* — e.g. ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY
OpenAI-Responses (codex)OPENAI_* — e.g. OPENAI_API_VERSION for Azure — and BACKEND_* for the backend's own key, as in BACKEND_OPENROUTER_API_KEY above

Any other name is refused, with the reason, and the backend stays inactive — a file can never change what an agent runs, where it looks for it, or where it reads its configuration. A protocol added by a plugin brings its own list.

A codex file written from an earlier version of this page, with OPENROUTER_API_KEY in env and envKey, is now refused: rename that variable BACKEND_OPENROUTER_API_KEY in both places. The vault entry it points at keeps its name.

If your provider genuinely needs a variable this leaves out, tell us the provider and the variable: the list is part of the product, and it grows with real ones.

A file that is refused, malformed, or named differently from its id is listed in Settings → LLM backends with the reason. It never prevents Timon from starting.