04. Models and Effort
Custom endpoints
Point Matcha CLI at an OpenAI-compatible gateway or a local Ollama daemon, store the key in the vault or an environment variable, and keep model ids exactly as that server names them.
You can attach extra models in ~/.matcha/config.toml under [model.<name>], share gateway settings under [model_providers.<id>], or override the catalog/inference base URL with [endpoints].models_base_url / MATCHA_MODELS_BASE_URL.
API backends
api_backend chooses the wire protocol for a custom [model.*] row:
| Value | Protocol | When you need it |
|---|---|---|
chat_completions | OpenAI Chat Completions (/v1/chat/completions) | Default if you omit the field |
responses | OpenAI Responses (/v1/responses) | Newer OpenAI-style gateways; built-in xAI uses this |
messages | Anthropic Messages (/v1/messages) | Direct Anthropic |
Omitting api_backend on a [model.*] row defaults to chat_completions. That is a custom-row default, not a claim that every built-in Provider uses Chat Completions. The built-in xAI descriptor uses responses; Anthropic uses messages.
Credential resolution
For each request Matcha CLI resolves the API key in this order:
api_keyon the[model.*]rowenv_key— a string or an array of names; first set, non-empty value wins (useful for SSHLC_*forwarding)- The Credential Vault secret for the selected Provider (
matcha login --provider …) - That Provider's official environment variable (
XAI_API_KEY,OPENAI_API_KEY,ANTHROPIC_API_KEY, …)
Catalog vs inference URL
The catalog fetch uses {base_url}/models (or MATCHA_MODELS_LIST_URL / [endpoints].models_list_url when the list URL differs). Inference uses the same base unless a [model.*] row sets its own base_url. If the live list fails, a local disk cache may serve an origin-and-auth-matched copy labeled (cached).
Setting models_base_url selects a custom OpenAI-compatible slot and uses API-key auth. There is no browser login.
OpenAI-compatible gateway
matcha login --provider openai_compatibleThen add a model row (the Provider id has no default URL):
[model.together-mixtral]
model = "mistralai/Mixtral-8x7B-Instruct-v0.1"
base_url = "https://api.together.xyz/v1"
name = "Mixtral 8x7B"
env_key = "TOGETHER_API_KEY"Or share the gateway once and point models at it:
[model_providers.gateway]
base_url = "https://gateway.example/v1"
# extra_headers / query_params / env_http_headers inherit onto models
# that set model_provider = "gateway" and omit their own copiesA key that also appears in the base_url query string is overridden (last value wins), not duplicated.
Ollama (local)
ollama serve
ollama pull codellama
matcha login --provider ollama[model.ollama-codellama]
model = "codellama"
base_url = "http://127.0.0.1:11434/v1"
name = "CodeLlama (Ollama)"Official Providers with an explicit row
You can also write a [model.*] row that talks to Anthropic or OpenAI directly. This is useful when you need extra headers, a context-window override, or the Responses API:
[model.claude-opus]
model = "claude-opus-4-6"
base_url = "https://api.anthropic.com/v1"
name = "Claude Opus 4.6"
api_backend = "messages"
context_window = 200000
env_key = "ANTHROPIC_API_KEY"
extra_headers = { "anthropic-version" = "2023-06-01" }[model.gpt-4o]
model = "gpt-4o"
base_url = "https://api.openai.com/v1"
name = "GPT-4o"
env_key = "OPENAI_API_KEY"[model.gpt-4o-responses]
model = "gpt-4o"
base_url = "https://api.openai.com/v1"
name = "GPT-4o (Responses)"
api_backend = "responses"
env_key = "OPENAI_API_KEY"Or store the key in the vault and skip env_key:
matcha login --provider anthropic
matcha login --provider openai --from-envCustom `/models` base URL
When every request should hit one gateway:
export MATCHA_MODELS_BASE_URL="https://api.acme.com/v1"
# Provider key as that gateway expects, for example:
export XAI_API_KEY="xai-..."
matchaGROK_MODELS_BASE_URL is read only when the Matcha name is unset. Optional MATCHA_MODELS_LIST_URL overrides {base_url}/models.
Config equivalent:
[endpoints]
models_base_url = "https://api.acme.com/v1"
[model.grok-4.5]
env_key = "XAI_API_KEY"With [endpoints].models_base_url set, partial [model.*] overrides inherit that base URL. Using XAI_API_KEY here is an example of whatever key that gateway expects — not a claim that inference defaults to xAI.
Common `[model.*]` fields
[model.my-model]
model = "model-id"
base_url = "https://api.example.com/v1"
name = "Display Name"
description = "Optional description"
env_key = "GATEWAY_API_KEY"
api_backend = "chat_completions"
temperature = 0.7
top_p = 0.95
max_completion_tokens = 8192
context_window = 128000
extra_headers = { "X-Request-Tags" = "team=example" }
query_params = { api-version = "2026-07-22" }
env_http_headers = { "X-Tenant-Token" = "GATEWAY_TENANT_TOKEN" }context_window drives auto-compaction. A new model that omits it defaults to 200,000 tokens — set it to match the server.
Global defaults that apply to every catalog row (built-in, prefetched, or custom) live under [models]. A per-model value always wins:
[models]
default = "my-model"
temperature = 0.7
top_p = 0.95
max_completion_tokens = 8192
max_retries = 8
inference_idle_timeout_secs = 600
stream_tool_calls = true
extra_headers = { "X-Request-Tags" = "team=example,env=prod" }stream_tool_calls changes request shape. If a BYOK gateway rejects a global true, set stream_tool_calls = false on that [model.<id>].
Settings that identify a specific model (model, base_url, api_key, context_window, …) cannot be defaulted under [models]. Reasoning effort stays at [models].default_reasoning_effort.
Override a catalog id by writing only the fields you want to change. Priority: your [model.*] > prefetched /v1/models > hardcoded Provider defaults.
Use the custom id
matcha models/model my-modelmatcha -p "Hello" -m my-modelIf the list is empty or a call fails
matcha modelsConfirm the selected Provider actually serves that id. Check [model.*] typos. Probe the gateway with the Provider's header scheme (Bearer vs x-api-key); do not paste keys into tickets.
RUST_LOG=debug MATCHA_LOG_FILE=/tmp/matcha.log matchaLook for model / sampling lines. Logs must not contain API keys.
What Matcha CLI does not do
- No MatchaCode product inference URL, no browser OAuth, no device-code login.
- Product web search, image generation, and video generation are unavailable.
[models] web_searchdoes not enable them. Use a local MCP server if you need search-like tools. - Ollama is not a remote GPU marketplace; the built-in Provider requires loopback.