Skip to content

Providers & models

muaz separates what an agent is (its prompt, tools, and behaviour) from which model it talks to. Agents are provider-agnostic: they never hard-code a provider. The model is chosen separately, so you can say “use GPT for everything” — or point one agent at a different model — without editing the agent.

Agents never carry a provider. Everything about model routing lives in one file, ~/.muaz/models.yaml, which muaz re-reads on every resolution — so changing a model takes effect immediately, with no restart.

When an agent runs, muaz resolves its provider in this order (first match wins):

  1. Per-agent binding — an entry under agents: in models.yaml for this agent, naming a profile and optionally a model.
  2. Global default — the default: profile in models.yaml.

If neither resolves, muaz errors with a clear message telling you to set a default or bind the agent to a profile.

The single file has three parts: named connection profiles, the global default, and per-agent agents overrides. A profile is a named, reusable model connection — define it once and reference it by name everywhere.

~/.muaz/models.yaml
profiles:
anthropic-main:
type: anthropic # native Anthropic provider (prompt caching on)
default_model: claude-opus-4-8
api_key: ${ANTHROPIC_API_KEY}
openai-main:
type: openai-compatible
base_url: https://api.openai.com
default_model: gpt-4o
api_key: ${OPENAI_API_KEY}
bedrock-work:
type: bedrock
region: us-east-1
default_model: anthropic.claude-3-5-sonnet-20241022-v2:0
profile: work
local:
type: ollama
default_model: qwen3
default: anthropic-main # every unbound agent uses this profile
agents: # per-agent overrides (agent name or @plugin/agent)
coding:
profile: bedrock-work

The API-key providers (openai-compatible, gemini) authenticate with a key you get from the provider’s dashboard. Rather than reference ${OPENAI_API_KEY} and hope it’s exported in every shell that launches muaz, you can store the key with muaz — it goes to your OS keychain (macOS Keychain, Windows Credential Manager, or the Linux Secret Service), falling back to a chmod 600 ~/.muaz/secrets.json when no keychain is available (headless Linux, CI).

Keep the api_key: ${OPENAI_API_KEY} reference in the profile as-is — it names the secret. When the key is needed, muaz resolves ${OPENAI_API_KEY} from the store first, then the environment, so a stored key wins over a stale shell value.

Store a key any of these ways:

  • CLImuaz auth [profile] prompts for the key (input hidden) and saves it, without starting a chat. With no argument it targets the default binding. This is the way to authenticate before your first chat: if a profile’s key is unset, agent startup fails while resolving ${VAR}, so the REPL never reaches its prompt — run muaz auth <profile> first. It also accepts a piped key for scripting: printf %s "$KEY" | muaz auth openai-main.
  • REPL/auth [profile] does the same from inside a running chat. With no argument it targets the current session’s profile.
  • Browser UI — the Providers page shows a status pill (Key set / From environment / Not set) next to each key-based profile, a masked Set key field, and a Test button that validates the credentials with a minimal request.
  • Gateway APIPUT /api/secrets/{name} sets a value (write-only — secret values are never returned over HTTP), DELETE /api/secrets/{name} removes it, and POST /api/providers/{name}/test probes a profile’s credentials.

Bedrock uses the ambient AWS credential chain (profile/region), and local Ollama / LM Studio need no key, so neither uses the secret store.

Binding models (the default + agents sections)

Section titled “Binding models (the default + agents sections)”
# ~/.muaz/models.yaml (default + agents sections)
# Profile used by every agent that isn't bound below:
default: anthropic-main
# Bind specific agents to a different profile (and optionally a different model):
agents:
coding:
profile: bedrock-work
model: anthropic.claude-3-7-sonnet-20250219-v1:0 # optional model swap
"@web-research/researcher": # plugin agents use their qualified name
profile: openai-main

The binding key is the agent name (or a fully-qualified @plugin/agent name for a plugin agent). model is optional — omit it to use the profile’s model.

muaz supports four provider types. Each accepts only its own fields — unknown fields are rejected with a clear error.

typeNotes
openai-compatibleOpenAI, Together.ai, Groq, and any OpenAI-compatible endpoint
bedrockAWS Bedrock (uses ambient AWS credentials)
geminiGoogle Gemini (generativelanguage.googleapis.com)
ollamaLocally-running Ollama server
type: openai-compatible
base_url: "https://api.openai.com"
default_model: gpt-4o
api_key: "${OPENAI_API_KEY}"
timeout_secs: 60
reasoning_effort: "medium" # for o-series / thinking models
  • CLI — manage models.yaml without hand-editing YAML:

    Terminal window
    muaz models list # profiles, default, and bindings
    muaz models set openai-main --type openai-compatible --model gpt-4o --api-key '${OPENAI_API_KEY}'
    muaz models set-model openai-main gpt-4o-mini # change just a profile's model
    muaz models default anthropic-main # set the global default
    muaz models bind coding --profile bedrock-work --model claude-3-7-sonnet
    muaz models unbind coding
    muaz models remove openai-main

    muaz agents create also offers to bind a profile to the new agent.

  • Browser UI — the Providers page manages profiles and the default; the Agents page edits per-agent bindings. See Browser UI.

  • Gateway APIPUT /api/providers/{name} / DELETE manage profiles; PUT /api/bindings/default, PUT /api/bindings/agents/{agent}, and DELETE /api/bindings/agents/{agent} manage the mapping.

  • File — or just edit ~/.muaz/models.yaml directly.

# models.yaml — add the profile once, make it the default
profiles:
anthropic-main: { type: anthropic, default_model: claude-opus-4-8, api_key: ${ANTHROPIC_API_KEY} }
default: anthropic-main

Every agent — including the built-in default and coding agents — now uses that model. No agent files were touched.