Every model-provider family ZeroClaw ships with. For each: config shape, notes on auth and endpoint behavior, and the slot key to use under [providers.models.<type>.<alias>].
See Configuration for universal fields (api_key, uri, model, ...) and resolution order.
Examples below use
homeas the alias to underline that the alias half is operator-chosen, pick whatever name fits (work,personal,cn,prod, ...). Reference it from an agent viamodel_provider = "<type>.<alias>".
Supports Console API keys and tokens generated by claude setup-token for Claude Max. Both credential forms live on the canonical anthropic slot's api_key field; Quickstart exposes them as api_key and setup_token choices. Streaming, tool calls, vision, and reasoning all supported. Custom endpoints (Anthropic-compatible proxies, e.g. Z.AI's Anthropic API) go on this slot too: set uri to override.
GPT-4o, GPT-5, o-series reasoning models. When reasoning is streamed, it is carried in the optional reasoning field of a StreamChunk wrapped by TextDelta; see Streaming.
OpenAI Codex subscription auth lives on the openai slot. Set wire_api = "responses" to route through POST /v1/responses and requires_openai_auth = true to use the Codex subscription login (from the Codex CLI's own ~/.codex/auth.json) instead of an api_key field on the entry. The subscription path does not read OPENAI_API_KEY; that variable applies only to the metered openai API-key mode. See Provider Configuration → OAuth and subscription auth for the credential model.
Local inference via Ollama's native /api/chat. Schema-based structured output via format. No API key.
Google's Gemini API. Supports vision and pre-executed grounded search (see Streaming for PreExecutedToolCall events).
Shells out to the gemini CLI; uses the CLI's existing auth.
Shells out to the Grok Build CLI through the documented grok agent stdio
ACP surface and uses the CLI's login cache by default. Run grok login, or use
the explicit API-key bridge shown below. The typed alias api_key is not used,
and ambient XAI_API_KEY is not inherited unless the alias opts in, so the Grok
CLI remains the authentication owner. This is the only transport: initialize →
authenticate → session/new → session/prompt over newline-delimited JSON-RPC.
Small and large prompts both travel on stdin and never appear in argv or a
prompt file.
The documented ACP integration and default argument profile are validated
against Grok Build CLI 0.2.118 (ACP advertise/live probes) with earlier baseline 0.2.111. Treat upgrades of the external CLI as a
compatibility change and revalidate grok agent stdio before deploying them.
Grok Build CLI (checked through 0.2.118) still advertises
promptCapabilities.image = false on ACP initialize. That is not an env-var
override on either side: ZeroClaw never rewrites Grok's advertisement. The
only ZeroClaw control is the shared per-alias config field vision.
| Layer | Behavior on 0.2.118 |
|---|---|
| ACP advertise | promptCapabilities.image = false |
Default grok_cli |
vision unset → ZeroClaw treats the alias as non-vision; image markers stay text |
vision = true |
ZeroClaw reports vision on the alias and sends ACP {type: image, data, mimeType} blocks (does not change Grok's advertise) |
| Model recognition | Live probe: image blocks are accepted by session/prompt (no protocol error) but the agent answered as if no image was received |
[providers.models.grok_cli.default]
model = "grok-4.5"
working_directory = "/srv/zeroclaw/grok-workspace"
# Optional experiment only: send ACP image blocks despite image=false advertise.
# Does not make Grok Build 0.2.118 reliably see or describe the image.
# vision = trueLeave vision unset for production grok_cli aliases. Do not route channel
attachments that require real image understanding to grok_cli until a deployed
CLI both advertises image = true and a live smoke shows the model using the
image content. When that holds, drop any temporary vision = true opt-in and
revisit whether ZeroClaw should follow the advertise bit instead of a local
override (GrokCliModelProvider::acp_prompt_content).
When deploying Grok Build 0.2.112 or later, verify ACP initialization on the
target host. On Ubuntu 24.04 hosts with
kernel.apparmor_restrict_unprivileged_userns=1, Grok can exit before ACP
initialization with bwrap: setting up uid map: Permission denied. This is a
host sandbox setup failure, not an ACP, stdout, or authentication failure.
Keep the ZeroClaw default --sandbox strict (or an explicit workspace
profile) and grant only the actual Grok executable permission to create a user
namespace. This is a host-administrator change; it preserves the global user
namespace restriction and does not turn off Grok's sandbox.
readlink -f "$(command -v grok)"Create /etc/apparmor.d/grok-build-userns, replacing the placeholder with that
absolute path:
abi <abi/4.0>,
include <tunables/global>
profile grok-build-userns /absolute/path/to/grok flags=(unconfined) {
userns,
}
Then load it and verify the profile is active:
sudo apparmor_parser -r /etc/apparmor.d/grok-build-userns
sudo aa-status | grep grok-build-usernsflags=(unconfined) is Ubuntu's per-executable AppArmor exception mechanism:
it grants userns to the named Grok binary but does not add AppArmor file
rules to it. Grok's own requested sandbox remains enabled, and the host-wide
user-namespace restriction remains enabled. Use a fully confined
organization-specific profile if Grok also needs AppArmor file restrictions.
Because self-updates can change the downloaded executable path, resolve the
path and reload this profile after each Grok update.
Do not use --sandbox off merely to avoid this error: it disables Grok's
sandbox. Do not disable kernel.apparmor_restrict_unprivileged_userns
system-wide. xAI documents Landlock for normal Linux sandboxing
and documents bubblewrap only for custom read-deny profiles;
if this occurs without a custom non-empty deny list, report the version,
exact error, sandbox profile, and non-secret host/AppArmor diagnostics to xAI.
max_acp_stdout_bytes bounds all stdout read from the Grok ACP child during
one request, including protocol frames and native-tool updates. It defaults to
4 MiB; set it per alias when a reviewed tool-enabled workload needs a larger
bounded budget.
[providers.models.grok_cli.default]
model = "grok-4.5"
working_directory = "/srv/zeroclaw/grok-workspace"
env_passthrough = ["XAI_API_KEY"]
# Optional: 4 MiB by default; accepted range is 1-64 MiB.
max_acp_stdout_bytes = 8388608Export XAI_API_KEY into the daemon environment before starting ZeroClaw. The
ACP client selects xai.api_key only when that name is listed in
env_passthrough and a non-empty value is present in the process environment at
child spawn (not snapshotted into the long-lived provider handle). Otherwise
it falls back to the CLI login cache. Typed alias api_key remains rejected:
this is an intentional process-env bridge rather than a second Config secret
field. Values are not written to provider TOML; a future typed Config bridge
may load the same name at config time without changing the operator surface.
An existing absolute working_directory is required. It is canonicalized and
used for both the child cwd and ACP session boundary, so the provider never
falls back to the daemon cwd. Optional binary_path selects a non-PATH
binary. Alias timeout_secs bounds protocol reads and writes (default 600s).
The child environment is cleared before spawn. Process-runtime, locale, proxy,
and CA variables on the built-in allowlist remain available; all other names
are blocked unless that provider alias lists them in env_passthrough. This
field is for the explicit XAI_API_KEY authentication bridge and environment
variables required by explicitly enabled Grok tools, such as cloud CLI
credentials. Values are read from the ZeroClaw process environment at spawn
time and are not stored in provider config. The default list is empty. Keep it
narrow because every listed secret is exposed to Grok and any tools enabled for
that alias. Other provider-owned XAI_* names and all GROK_* names are
rejected. Grok's discovered user and project configuration, together with alias
extra_args, owns Grok tool policy.
The default argv adds --no-auto-update, --no-plan, --sandbox strict,
--permission-mode dontAsk, and --tools "". By default, the ACP client fails
permission requests closed. When the request supplies a reject_once option,
the client selects it instead of cancelling the complete agent turn; otherwise
it cancels the request. The requested tool still fails closed, while Grok can
consume the rejection and produce a final answer or retry with an operation its
policy allows.
An alias explicitly configured with --always-approve,
--dangerously-skip-permissions, --yolo, or
--permission-mode=bypassPermissions changes the headless ACP response policy:
the client selects the request's allow_once option. It never substitutes
allow_always, and cancels when the requested allow_once option is absent.
This approval applies only to the current permission request; Grok's permission
rules and active OS sandbox can still reject or confine the operation.
[providers.models.grok_cli.ops]
working_directory = "/path/to/agents/ops/workspace"
extra_args = [
"--tools=run_terminal_cmd",
"--permission-mode=bypassPermissions",
]Treat these bypass flags as authorization for Grok to execute every
request-supported tool on that alias without a human approval round trip. Other
permission modes, including acceptEdits, do not enable ACP auto-approval.
Grok evaluates CLI --allow / --deny rules and discovered user/project
permission configuration before asking the ACP client. Those surfaces are
trusted operator policy: a matching allow rule may pre-authorize a tool so the
ACP client never sees a permission request, and project MCP servers, plugins,
or hooks may add capabilities. Use a dedicated, reviewed working_directory
for channel agents.
When an allow rule does not pre-authorize the tool, Grok still sends
session/request_permission and ZeroClaw's default reject-once policy fails
the tool closed. In practice this matters for shell/execute tools under the
default --sandbox strict: a CLI --allow=Bash(...) rule can still escalate
to the ACP host on current Grok Build, so a tool-enabled shell alias should
either set an explicit bypass flag (--always-approve /
--permission-mode=bypassPermissions) or pair allow rules with a sandbox
profile that Grok will pre-authorize without host approval (for example
--sandbox=workspace). Read-only tool grants such as --tools=Read,Grep with
matching --allow remain the narrower opt-in.
Operators can also grant tools or relax sandbox/permission policy with alias
extra_args; both surfaces are explicit opt-ins to a wider subprocess boundary.
Transport, prompt, model, session, cwd, and update flags remain provider-owned
and are rejected in extra_args. Positional and short arguments are also
rejected. Known value-taking options accept either ["--flag", "value"] or
--flag=value; unknown option shapes require the inline form so they cannot
consume the trailing ACP command.
Grok may emit progress as an agent_message_chunk before a plan, tool call, or
permission request. The provider discards the preceding message segment at
those ACP boundaries and returns only the latest answer segment, so planning
or tool-gathering narration is not delivered as the channel reply. Explicit
--no-plan also keeps the default one-shot channel alias out of Grok's plan
mode; tool/MCP configuration remains an operator-controlled capability.
ACP stdout frames, aggregate stdout, assistant text, and stderr processing are bounded while the child is running. Stderr is drained but its content is never stored, logged, or returned. Public provider errors stay stable and do not echo child-controlled protocol free-text. After every one-shot request (success, timeout, cancellation, or protocol error), ZeroClaw terminates the child process group on Unix or the Job Object on Windows and reaps the direct child. That covers ordinary descendants; a process that creates a new session or process group can escape group kill on Unix. Windows Job Object coverage is compile-covered in CI and not fully executed on every Linux developer host.
Use a dedicated provider alias for the messaging agent (for example
agents.default). The default alias grants no Grok built-in tools. Grok still
loads its normal user and project configuration, so use a dedicated workspace
whose permission rules, MCP servers, plugins, and hooks have been reviewed for
the channel trust boundary. Use a separate alias and workspace for an
operator-approved coding/ops agent.
Reply-intent precheck (classifier): ZeroClaw runs a short REPLY /
NO_REPLY[*] classification before the full agent loop. Prefer a stable
chat-completions API for that precheck (for example the HTTP/OAuth
xai slot, or any other non-CLI model alias), and keep grok_cli only for
model_provider (the full answer). CLI agent backends often emit planning
prose instead of a single sentinel token; that prose can be delivered as the
channel message (“staying silent” / “no Slack reply”). Empty
classifier_provider reuses model_provider: fine for API models, not for
CLI channel bots. ACP channels skip the classifier entirely.
# Full answers: ACP, strict sandbox, no built-in tools, reviewed Grok config
[providers.models.grok_cli.default]
model = "grok-4.5"
binary_path = "/home/you/.grok/bin/grok"
working_directory = "/path/to/agents/default/workspace"
# REPLY / NO_REPLY precheck - API (format-stable). Reuse an existing xAI
# HTTP alias if you already have one; do not point this at grok_cli.
[providers.models.xai.default]
model = "grok-4.5"
# uri / auth as for the normal xAI provider (OAuth session or api_key)
# Ops / coding agents: explicit policy and tool opt-in
[providers.models.grok_cli.ops]
model = "grok-4.5"
binary_path = "/home/you/.grok/bin/grok"
working_directory = "/path/to/agents/ops/workspace"
env_passthrough = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
# Read-only tools: matching --allow can pre-authorize without ACP approval.
extra_args = ["--tools=Read,Grep", "--allow=Read", "--allow=Grep"]
# Shell-capable ops alias: either bypass ACP approval, or pair allow with a
# sandbox profile that Grok pre-authorizes (workspace is the common choice).
[providers.models.grok_cli.ops_shell]
model = "grok-4.5"
binary_path = "/home/you/.grok/bin/grok"
working_directory = "/path/to/agents/ops/workspace"
extra_args = [
"--tools=run_terminal_cmd",
"--allow=Bash(printf *)",
"--sandbox=workspace",
]
[agents.default]
model_provider = "grok_cli.default"
classifier_provider = "xai.default"
channels = ["slack.default"] # example
[agents.dependabot]
model_provider = "grok_cli.ops"| Layer | Where | Purpose |
|---|---|---|
| Reply precheck | classifier_provider → API alias (e.g. xai.default) |
REPLY / NO_REPLY[*] only; avoids CLI thinking text as the message body |
| Full answer | model_provider → grok_cli.default |
Grok Build ACP; prompt only on stdin |
| OS sandbox | Default --sandbox strict (or extra_args override) |
Read CWD + system paths; write CWD + ~/.grok + tmp; child network blocked on Linux. Built-ins are not a permanent credential boundary - use custom deny for secrets |
| App permissions | Empty built-in tool set + fail-closed ACP default | Explicit bypass flags select allow_once; discovered Grok rules may also pre-authorize configured tools |
| Channel delivery | ZeroClaw thread_replies / channel config |
Single in-thread reply path |
| Optional gate | Slack mention_only + strict_mention_in_thread |
Drop unmentioned group/thread traffic before the agent (see Slack); independent of the classifier |
Keep channel-facing aliases at the defaults and give them dedicated, reviewed
workspaces. Permission rules, MCP servers, plugins, and hooks discovered by
Grok, along with permission/sandbox/tool flags in extra_args, are trusted
operator policy and can widen the subprocess boundary.
This is Grok Build’s process sandbox (Landlock / Seatbelt / seccomp on the
grok subprocess). It is not ZeroClaw’s tool sandbox on
[risk_profiles.*.sandbox_*]: that wraps ZeroClaw tools after native tool
calls. If an operator opts a provider alias into Grok tools, Grok's
--sandbox is the effective confinement for that work. See also
Sandboxing for ZeroClaw’s risk-profile sandbox.
ZeroClaw always supplies an explicit sandbox flag. The default is strict.
Set --sandbox=<profile> in that provider alias's extra_args to choose a
different profile; ambient Grok config or GROK_SANDBOX cannot silently relax
the provider-owned default.
Project .grok/config.toml can hold MCP / plugins / [permission]. Grok
loads that file as trusted operator policy; matching allow rules may authorize
tools without an ACP permission request. It does not select the active
sandbox profile by itself. Profile names and custom profile bodies can
live in project <workspace>/.grok/sandbox.toml; pass
--sandbox=<name> through extra_args to turn that profile on.
Built-in profiles (from Grok’s sandbox docs):
| Profile | FS read | FS write | Child process network (Linux) | Typical use |
|---|---|---|---|---|
off (default) |
unrestricted | unrestricted | unrestricted | Full access |
workspace |
everywhere | CWD + ~/.grok + tmp |
allowed | Everyday coding |
read-only |
everywhere | ~/.grok + tmp only |
blocked | Review when broad reads are OK |
strict |
CWD + system paths | CWD + ~/.grok + tmp |
blocked | Default channel chatbot (recommended) |
devbox |
everywhere | most of the tree | allowed | Disposable VMs |
Child-network blocking applies to shell children on Linux only; in-process
Grok tools (LLM, built-in web search) still need network. Prefer strict
for messaging bots to narrow the default filesystem write surface to the agent
workspace plus Grok runtime paths. Built-in profiles are not a permanent
credential boundary: xAI's sandbox docs
warn that paths such as ~/.ssh are not guaranteed protected by built-ins, and
recommend a custom profile with a kernel-enforced deny list for secrets.
Use read-only only when the agent must read outside the workspace without
writing project files.
Custom profile example (define in workspace, select from ZeroClaw):
# <agent-workspace>/.grok/sandbox.toml
[profiles.channel-bot]
extends = "strict"
# Optional kernel deny paths (needs bubblewrap on Linux when non-empty):
# deny = ["**/.env", "**/*.pem"]# ZeroClaw config.toml
[providers.models.grok_cli.default]
working_directory = "/path/to/agents/default/workspace"
extra_args = ["--sandbox=channel-bot"]Per-agent sandbox: use separate provider aliases with different,
explicit extra_args and dedicated working directories. Keep channel aliases
on the strict/no-built-in-tools default, review the Grok configuration
discovered for each workspace, and point each agent at the matching
model_provider alias.
resource, deployment, and api_version live in this typed config, they are not read from environment variables.
Uses a GitHub Copilot subscription for agent inference. Authentication uses a Copilot OAuth token obtained from GitHub.
Voice-oriented AI endpoint. Pair with the clawdtalk channel for real-time SIP calls.
Local inference via KiloCLI.
[providers.models.kilo.home]
model = "anthropic/claude-sonnet-4-6"
api_key = "..."
# endpoint = "gateway" # default → https://api.kilo.ai/api/gatewayCloud API via Kilo AI Gateway. Bearer-token auth with multiple model tiers (free, balanced, pro).
The /models endpoint is public (PUBLIC_MODEL_LISTING), so model listing works without a credential. Because it is queried live, it is the source that carries pricing into the cost-rates editor. The shared models.dev catalog (kilo key) is only a fallback for when the live endpoint is unreachable, and it does not include pricing.
Naming migration:
kilonow refers to this gateway provider. The KiloCLI subprocess provider keeps itskiloclislot (synonymkilo-cli). If you previously configured the CLI provider under thekiloshorthand, switch tokilocli.
[providers.models.zerorouter.gateway]
model = "anthropic/claude-sonnet-5"
api_key = "..." # a ZeroRouter key (prefix `zcr_`); or inject from the env
# uri = "https://zerorouter.ai/v1" # a hosted or remote router; omit for the localhost defaultSelf-hosted, OpenAI-compatible LLM gateway; Bearer-token auth. ZeroRouter is a
family of independently operated routers, so there is no canonical hosted
default: the slot points at a locally running router at http://localhost:8080/v1.
To reach the public deployment at https://zerorouter.ai, or any other remote
router, set uri explicitly.
The /v1/models endpoint is public (PUBLIC_MODEL_LISTING), so model listing
and its prompt/completion pricing come live from the router itself without a
credential; because it is queried live, it is the source that carries pricing
into the cost-rates editor (this family has no models.dev or OpenRouter
fallback). Inference does require a key: set api_key directly, or inject it
from the environment the same way as any other provider key (see
Configuration for api_key resolution order).
No built-in login. This preset configures the provider through the standard typed
api_keypath only; it does not add a device-flow login, OAuth, or provider-specific credential storage. Setapi_key(or its env injection) to run inference.
Every canonical slot, its default endpoint, whether it runs locally, and its
full config field set, generated from the provider registry and the config
schema. Click a slot to expand its fields; click a field to see how to set it.
Fixed entries show canonical defaults. operator required means the alias needs
endpoint input, such as an Azure resource and deployment or a custom uri.
dynamic / resolved at runtime endpoints may depend on credentials, region,
discovery, or runtime state and do not necessarily require uri. CLI-backed
providers use their local command.
{{#model-provider-fields}}
For a worked example per family, see Configuration. If your vendor isn't listed, use the custom slot (Custom providers).
Each of these is a standard OpenAI-compatible slot: set model and api_key, leave
uri off (the typed endpoint supplies it). None of them ship a public model index,
so the model picker stays empty until you paste a credential. Once a key is set,
ZeroClaw lists models from the provider's live /models endpoint. The model IDs
below are illustrative; confirm the current catalog in the vendor dashboard.
Morph: slot morph. Fast apply-edits models (morph-v3-large, morph-v3-fast, or
auto). Key from the Morph dashboard.
GitHub Models: slot github_models (alias github-models). OpenAI / Meta /
Microsoft models behind a single GitHub Personal Access Token. Create a PAT with the
models permission (fine-grained); a Copilot token is not the same credential.
Model IDs are publisher-prefixed (e.g. openai/gpt-4o).
Upstage: slot upstage. Solar Pro / Solar Mini (e.g. solar-pro2). Key from the
Upstage console.
Featherless: slot featherless. Serverless open-weight models, addressed by their
Hugging Face repo IDs (e.g. meta-llama/Meta-Llama-3.1-8B-Instruct). Key from
featherless.ai.
Arcee: slot arcee. Native models include conductor, maestro,
virtuoso-large, coder-large, and blitz. Key from the
Arcee platform. Arcee's Platform API uses the non-standard
/api/v1 base path; the typed endpoint already accounts for this, so still leave
uri off.
Lambda AI: slot lambda_ai (alias lambda-ai). Lambda's hosted inference (e.g.
hermes3-405b). Key from the Lambda Cloud API-keys page.
Inception: slot inception. The Mercury diffusion-LLM family (mercury-coder and
the newer mercury-2). Key from the
Inception platform.
Atlas Cloud: slot atlascloud. OpenAI-compatible endpoint
https://api.atlascloud.ai/v1 with bearer-token auth. Use the canonical
atlascloud slot only; atlas, atlas-cloud, and atlas_cloud are not
runtime aliases.
[providers.models.atlascloud.home]
model = "..."
api_key = "..."Credentials come only from config (
api_key) or the--credentialoverride at run time, these slots do not read a per-provider*_API_KEYenvironment variable.
NEAR AI Cloud example:
[providers.models.nearai.tee]
model = "..." # pick a modelId from https://cloud-api.near.ai/v1/model/list
api_key = "..."The nearai slot uses https://cloud-api.near.ai/v1 by default and sends
Authorization: Bearer <api_key>. To bridge an existing NEARAI_API_KEY
shell variable into ZeroClaw's schema-mirror env surface, set
ZEROCLAW_providers__models__nearai__tee__api_key="$NEARAI_API_KEY".
Several Chinese vendors expose distinct regional endpoints with different default models. Use one canonical slot and pick the region with the typed endpoint field on the alias entry.
Variants: cn, intl, code.
OAuth-backed Qwen accounts use the same slot with auth_mode = "o_auth".
[providers.models.minimax.intl]
model = "MiniMax-M3" # or MiniMax-M2.7, MiniMax-M2.7-highspeed
api_key = "..."
endpoint = "intl" # variants: cn, intlFor MiniMax's Anthropic-compatible API, use [providers.models.anthropic.minimax] with uri = "https://api.minimax.io/anthropic" (Global) or uri = "https://api.minimaxi.com/anthropic" (China) instead.
For Z.AI's Anthropic-compatible API, use [providers.models.anthropic.zai] with uri = "https://api.z.ai/api/anthropic" instead.
The remaining Chinese-region slots (yi, hunyuan, qianfan, baichuan) appear in the all-slots table above; select the region with the typed endpoint field on the alias entry.
OpenRouter is treated as a single first-class provider, not a meta-router. The runtime sees one endpoint; OpenRouter handles vendor fan-out behind that endpoint.
For per-task routing, run multiple agents and let channels pick which agent handles which traffic, see Routing. For a narrower in-config hint mechanism, use [[model_routes]].
- If the endpoint is OpenAI-compatible, use the
customslot withuriset. - If it has its own canonical slot above, use that, even if you only see one of its regions, the slot's
endpointenum covers the rest. - If it speaks a non-OpenAI wire format and needs its own implementation, see Custom providers.