Docs
Jan Agent
Providers

Providers

Jan Agent ships no inference engine, so a model always runs somewhere else. A provider is how it gets there.

Adding one


jan config set --provider anthropic --api-key sk-ant-...

Full form:


jan config set \
--provider openai \
--api-key sk-... \
--base-url https://api.openai.com/v1 \
--model gpt-4o \
--model gpt-4o-mini \
--api-type openai

FlagDescription
--providerProvider id, e.g. openai, anthropic, groq. Required
--api-keyAPI key
--base-urlEndpoint base URL
--modelModel to expose. Repeatable, and replaces any existing list
--api-typeWire protocol, openai or anthropic. Defaults to OpenAI-compatible

Inspecting


jan config list # configured providers as JSON, keys redacted
jan config path # where that file lives
jan cli models list

jan config list can report no providers while jan cli models list returns plenty. That isn't a bug - the second includes providers inherited from Jan Desktop, which aren't stored in ~/.jan/config.toml.

Inside the console, /config shows the same thing read-only, and /model switches model on the spot.

From the console

/settings > providers manages the same ~/.jan/config.toml entries interactively:

  • a opens an add form (name, base url, api key, space-separated models)
  • Enter edits the highlighted provider, prefilled - except the API key, which shows (unchanged) and is kept as stored unless you type into the field. Typing replaces the key; blanking the field out clears it (for an endpoint that dropped auth)
  • d pressed twice deletes the highlighted provider

The name is read-only while editing, so an entry can never be orphaned. Inside a form, arrow keys move between fields and k/j type as ordinary characters (API keys contain them). The base URL must be https://, or http:// for a localhost endpoint, so a key is never sent over a plaintext remote connection.

A provider saved with no models is queried for its GET /models the next time you open /model, and the discovered ids are persisted - so a bare provider becomes selectable immediately.

Tokamak

Signing in avoids managing a key yourself:


jan login

Or /login from inside the console. The key is saved to ~/.jan/config.toml.

Where settings come from

Four sources, each beating the ones above it:

SourceNotes
1~/.jan/config.tomlThe base, and the only file jan config set writes
2Jan Desktop's settings.jsonInherit-only. Adds providers you haven't configured here, never overwrites one you have, and is never written back to
3[provider] in a project's agent.tomlAn explicit per-project choice, so it wins over both
4--provider / --api-key, or JAN_API_KEY / <PROVIDER>_API_KEYThe most explicit and most ephemeral signal

The useful consequence: Jan Desktop fills in providers for free without ever clobbering something you set deliberately, a project can pin its own provider without touching your global setup, and a single run can override everything.

Your own hardware

Any OpenAI-compatible endpoint works, which includes a model running locally. Jan Desktop's local API server is the easy path:


jan config set \
--provider local \
--base-url http://localhost:6767/v1 \
--model my-local-model

Nothing leaves your machine in that setup - Jan Desktop runs the model, Jan Agent drives it.

Per-project override

For a project that must use a specific provider, put it in agent.toml:


[provider]
name = "openai"
api_key = "sk-..."
base_url = "https://api.openai.com/v1"
models = ["gpt-4o"]

⚠️

That file usually gets committed. Prefer leaving api_key out of it and keeping the key in ~/.jan/config.toml or the environment.

Removing one


jan config unset --provider openai