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.

~/.openinterpreter/config.toml
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"
The base URL keeps the /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.
Kunavo has not run this client against its endpoint — not this one, and not any other client on these pages. What is checked is the configuration surface: the keys below are the ones Open Interpreter's own documentation prints, read on the date at the bottom of this page, and the base URL and model ids are Kunavo's. A published setup page is not a test run. Treat the verify request as the thing that tells you it works.
Two different programs answer to the name "Open Interpreter", and this block is for the Rust one. The Python package frozen at 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.
A Claude model id makes Open Interpreter pick the 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

  1. Create a key at /app/keys and copy it — it is shown once.
  2. 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 list env_key as the source that "reads a bearer token from an environment variable".
  3. Put the block above in ~/.openinterpreter/config.toml, or in .openinterpreter/config.toml inside a trusted project when you want it to apply to one repository only. Project config outranks user config; a -c key=value flag outranks both for that run.
  4. Start interpreter and run /model. The picker asks the active provider's models route first, and Kunavo answers GET /v1/models, so the list populates itself.
  5. Run /debug-config if 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.

This is the short version. The full walkthrough — model choice, what a real session costs, and the failure modes — is in the Open Interpreter version split, pricing and alternatives.

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 idKunavo in / outWhere it fits in Open Interpreter
claude-sonnet-5$2.00 / $10.00the default working model for edit-and-run loops
claude-opus-5$2.00 / $10.00planning a large refactor, where a wrong plan is expensive
claude-haiku-4-5$0.40 / $2.00shell-heavy sessions where turn count dominates
gpt-5-6-sol$2.00 / $12.00a second opinion from a different family, same key
Billing is per token from a prepaid balance with no monthly fee — see billing. On repeated context — which is most of what an editor or a chat client sends — prompt caching moves the bill more than the model choice does.

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.