Skip to content

Configuration

How shunt loads configuration — files, environment variables, and routing.

Updated View as Markdown

shunt loads configuration from, in increasing precedence:

  1. Built-in defaults — every provider (anthropic, openai, codex, …) is preconfigured.

  2. A TOML or YAML file. The format is chosen by extension — .toml is TOML, .yaml/.yml is YAML (any other extension is parsed as TOML). With --config <path> that exact file is used (a missing file is an error). Otherwise shunt probes each directory for shunt.toml, then shunt.yaml, then shunt.yml, and takes the first file found:

    • ./
    • $XDG_CONFIG_HOME/shunt/ (default ~/.config/shunt/)
    • $HOMEBREW_PREFIX/etc/ (default /opt/homebrew and /usr/local prefixes)

    A local shunt.yaml therefore still wins over a config file in a later directory, while an existing shunt.toml alongside it takes priority within the same directory. Boot logs report which file was loaded, or that defaults are in use.

  3. Environment variables prefixed SHUNT_, using __ for nested keys — e.g. SHUNT_SERVER__BIND=0.0.0.0:3001.

Because the defaults already define every provider, your config only needs the parts you want to change. Start from shunt.toml.example for TOML or shunt.yaml.example for YAML.

Annotated example

[server]
bind = "127.0.0.1:3001"        # address shunt listens on
default_provider = "anthropic" # provider for any model with no route (pass-through)

# Each provider is a [providers.<name>] table.
[providers.anthropic]
kind = "anthropic"             # forward Claude Code's own credential unchanged
base_url = "https://api.anthropic.com"

[providers.openai]
kind = "responses"             # translate Anthropic Messages -> OpenAI Responses
base_url = "https://api.openai.com/v1"
auth = "api_key"
api_key_env = "OPENAI_API_KEY" # env var the OpenAI key is read from
# effort = "high"              # optional default reasoning effort for this provider

[providers.codex]
kind = "responses"
base_url = "https://chatgpt.com/backend-api"
auth = "chatgpt_oauth"         # reuses ~/.codex/auth.json
# effort = "high"
# service_tier = "fast"        # optional: opt in to Codex's "Fast" mode

# --- Routing: how a request's `model` id picks a provider ---

# A matching [models.upstream_model] entry wins first. [[routes]] is the legacy exact-match form checked next.
[[routes]]
model = "gpt-5.6-sol"
provider = "codex"
# upstream_model = "gpt-5.6-sol"
# effort = "high"
# service_tier = "priority"    # optional: pin service_tier for this route

# Then prefix match.
[[route_prefixes]]
prefix = "gpt-"
provider = "openai"

# Optional: expose Claude-named aliases in the /model picker via discovery.
# The id MUST start with "claude" or "anthropic" or Claude Code ignores it.
# [[models]]
# id = "claude-opus-via-codex"
# display_name = "Opus (via Codex)"

YAML equivalent

The same schema in YAML — save as shunt.yaml or shunt.yml. Tables become mappings and [[...]] arrays become lists:

server:
  bind: "127.0.0.1:3001"
  default_provider: anthropic

providers:
  openai:
    kind: responses
    base_url: https://api.openai.com/v1
    auth: api_key
    api_key_env: OPENAI_API_KEY

routes:
  - model: gpt-5.6-sol
    provider: codex

route_prefixes:
  - prefix: gpt-
    provider: openai

Routing precedence

  1. Matching [models.upstream_model] entry on the request’s model id.
  2. Exact [[routes]] match on the request’s model id.
  3. [[route_prefixes]] prefix match.
  4. server.default_provider — by default anthropic, so a model with no match falls through to Anthropic unchanged.

A route can override the forwarded model id (upstream_model), the reasoning effort (effort), and the response service_tier (Codex’s “Fast” mode) per model.

Partial overrides

Config maps are deep-merged, so a partial override of a built-in provider keeps the rest of its defaults:

# Only raise codex's default effort; everything else stays at the built-in values.
[providers.codex]
effort = "high"

Validate

shunt check
# -> prints "config ok", or a specific error (bad bind address, unknown provider, …)

See the Configuration Reference for every key, and Providers for adding new backends.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close