Docs
Open Interpreter
Open Interpreter reads providers from a TOML table, the way its Codex ancestor does — but it kept a Chat Completions transport that upstream Codex dropped. One [model_providers.kunavo] block and the agent runs on any model the key reaches.
One [model_providers.kunavo] table in ~/.openinterpreter/config.toml — base_url, env_key, wire_api = "chat" — and the Rust terminal agent runs on any model the key reaches.
model_provider = "kunavo"
model = "claude-sonnet-5"
[model_providers.kunavo]
name = "Kunavo"
base_url = "https://api.kunavo.com/v1"
env_key = "KUNAVO_API_KEY" # the NAME of the variable, not the key
wire_api = "chat"/v1 suffix on the chat wire. Open Interpreter's docs settle this by example rather than by a stated rule: the custom-provider block on the providers page uses base_url = "https://api.example.com/v1", the configuration page's uses "https://api.acme.example/v1", and the hosted gateway they document by name uses "https://app.nz/v1". Drop the suffix and the failure arrives as a 404, not as an authentication error.0.4.3 is configured through --api_base, --api_key and --model openai/<id>, or through interpreter.llm in Python. None of those exist in the current terminal agent, which reads only the TOML table above. Run interpreter --version before you edit anything — a pip install open-interpreter from an old tutorial leaves a second binary competing for the same name.claude-code harness on its own — its documented defaults select it for "Anthropic, Claude model ids, Anthropic base URL, or any messages provider". That is a legal pairing here: the routing table lists claude-code as compatible with wire_api = "chat". Set harness explicitly if you want a different one; an explicit value always wins, and an unrecognised one falls back to chat with no built-in request builder rather than failing loudly.Step by step
- Create a key at
/app/keysand copy it — it is shown once. - Export it under the name you are about to write into
env_key:export KUNAVO_API_KEY=sk-kn-.... That field holds the variable's name, not its value — the docs listenv_keyas the source that "reads a bearer token from an environment variable". - Put the block above in
~/.openinterpreter/config.toml, or in.openinterpreter/config.tomlinside a trusted project when you want it to apply to one repository only. Project config outranks user config; a-c key=valueflag outranks both for that run. - Start
interpreterand run/model. The picker asks the active provider's models route first, and Kunavo answersGET /v1/models, so the list populates itself. - Run
/debug-configif the wrong values are in play — it prints the effective configuration and where each value came from, which settles a stale profile or a project file faster than re-reading the TOML.
Checked against Open Interpreter's Model Providers page on September 21, 2026. Third-party settings move; if a field name here no longer matches what you see, that page is the authority, not this one.
Verify before you debug the client
One request settles whether a failure is the endpoint, the key, or the configuration file. If this returns JSON, the same base URL and key work in Open Interpreter.
# Settles whether a failure is the endpoint, the key, or the client.
curl -sS https://api.kunavo.com/v1/models \
-H "Authorization: Bearer sk-kn-..."Which model id to put in the field
Every text model is reachable as a model id — the live list is GET /v1/models, and the catalog with prices is on the models page. Rates are USD per 1M tokens, input / output.
| Model id | Kunavo in / out | Where it fits in Open Interpreter |
|---|---|---|
claude-sonnet-5 | $2.00 / $10.00 | the default working model for edit-and-run loops |
claude-opus-5 | $2.00 / $10.00 | planning a large refactor, where a wrong plan is expensive |
claude-haiku-4-5 | $0.40 / $2.00 | shell-heavy sessions where turn count dominates |
gpt-5-6-sol | $2.00 / $12.00 | a second opinion from a different family, same key |
FAQ
How do I point Open Interpreter at a custom API provider?
Add a [model_providers.<id>] table to ~/.openinterpreter/config.toml with name, base_url, env_key and wire_api, then select it with the top-level model_provider key and name a model with model. For an OpenAI-compatible endpoint use wire_api = "chat" and a base URL ending in /v1 — that is the shape Open Interpreter's own providers page shows for a custom provider and for the hosted gateway it documents by name. env_key holds the name of an environment variable, so export the key rather than pasting it into the file.
Does the Open Interpreter base_url need /v1 at the end?
On the chat wire, yes. The documentation does not state a path-construction rule in prose, but every custom-provider example it prints carries the suffix: https://api.example.com/v1 on the providers page, https://api.acme.example/v1 on the configuration page, and https://app.nz/v1 for the gateway it names. The messages wire behaves differently — the Anthropic-style providers that ship with the client use an API root without /v1 — so the /v1 answer is specific to wire_api = "chat" and to wire_api = "responses".
Do the old --api_base and --model openai/... flags still work?
No. Those belong to the Python package frozen at 0.4.3, which routed through LiteLLM and therefore needed the openai/ prefix. The current terminal agent is a Rust fork of Codex with neither the flags nor the prefix convention: it reads a TOML provider table from ~/.openinterpreter/config.toml or a project-level .openinterpreter/config.toml and selects it with model_provider and model. The configuration is written from scratch, and docs.openinterpreter.com redirects to the Rust documentation, so an old tutorial's links still resolve while describing a program you do not have installed.
Why does the /model picker show no context window for a custom provider?
Because that metadata comes from the catalog bundled with the client, which is generated from models.dev plus a handful of live provider endpoints, and it is seeded only when a provider matches an entry by Anthropic identity, base URL, provider name or auth environment variable. Kunavo is not in that generated catalog — checked against the file in the repository on September 21, 2026 — so a hand-written provider gets the model list from the endpoint's own models route and nothing else. The models still run; the picker just has less to display beside them.
Can Open Interpreter reach a Claude model without an Anthropic account?
Yes, because wire_api names a transport rather than a vendor. With wire_api = "chat" the model id is passed through to whatever base_url you configured and resolved there, so the credential you hold is the endpoint's. Open Interpreter will still auto-select its claude-code harness from a Claude model id, and that harness is listed as compatible with the chat wire, so the pairing is the documented one rather than a workaround.