29 KiB
summary, read_when, title, sidebarTitle
| summary | read_when | title | sidebarTitle | |||
|---|---|---|---|---|---|---|
| Tools config (policy, experimental toggles, provider-backed tools) and custom provider/base-URL setup |
|
Configuration — tools and custom providers | Tools and custom providers |
tools.* config keys and custom provider / base-URL setup. For agents, channels, and other top-level config keys, see Configuration reference.
Tools
Tool profiles
tools.profile sets a base allowlist before tools.allow/tools.deny:
| Profile | Includes |
|---|---|
minimal |
session_status only |
coding |
group:fs, group:runtime, group:web, group:sessions, group:memory, cron, image, image_generate, video_generate |
messaging |
group:messaging, sessions_list, sessions_history, sessions_send, session_status |
full |
No restriction (same as unset) |
Tool groups
| Group | Tools |
|---|---|
group:runtime |
exec, process, code_execution (bash is accepted as an alias for exec) |
group:fs |
read, write, edit, apply_patch |
group:sessions |
sessions_list, sessions_history, sessions_send, sessions_spawn, sessions_yield, subagents, session_status |
group:memory |
memory_search, memory_get |
group:web |
web_search, x_search, web_fetch |
group:ui |
browser, canvas |
group:automation |
heartbeat_respond, cron, gateway |
group:messaging |
message |
group:nodes |
nodes |
group:agents |
agents_list, update_plan |
group:media |
image, image_generate, music_generate, video_generate, tts |
group:openclaw |
All built-in tools (excludes provider plugins) |
tools.allow / tools.deny
Global tool allow/deny policy (deny wins). Case-insensitive, supports * wildcards. Applied even when Docker sandbox is off.
{
tools: { deny: ["browser", "canvas"] },
}
write and apply_patch are separate tool ids. allow: ["write"] also enables apply_patch for compatible models, but deny: ["write"] does not deny apply_patch. To block all file mutation, deny group:fs or list each mutating tool explicitly:
{
tools: { deny: ["write", "edit", "apply_patch"] },
}
tools.byProvider
Further restrict tools for specific providers or models. Order: base profile → provider profile → allow/deny.
{
tools: {
profile: "coding",
byProvider: {
"google-antigravity": { profile: "minimal" },
"openai/gpt-5.4": { allow: ["group:fs", "sessions_list"] },
},
},
}
tools.elevated
Controls elevated exec access outside the sandbox:
{
tools: {
elevated: {
enabled: true,
allowFrom: {
whatsapp: ["+15555550123"],
discord: ["1234567890123", "987654321098765432"],
},
},
},
}
- Per-agent override (
agents.list[].tools.elevated) can only further restrict. /elevated on|off|ask|fullstores state per session; inline directives apply to single message.- Elevated
execbypasses sandboxing and uses the configured escape path (gatewayby default, ornodewhen the exec target isnode).
tools.exec
{
tools: {
exec: {
backgroundMs: 10000,
timeoutSec: 1800,
cleanupMs: 1800000,
notifyOnExit: true,
notifyOnExitEmptySuccess: false,
applyPatch: {
enabled: false,
allowModels: ["gpt-5.5"],
},
},
},
}
tools.loopDetection
Tool-loop safety checks are disabled by default. Set enabled: true to activate detection. Settings can be defined globally in tools.loopDetection and overridden per-agent at agents.list[].tools.loopDetection.
{
tools: {
loopDetection: {
enabled: true,
historySize: 30,
warningThreshold: 10,
criticalThreshold: 20,
globalCircuitBreakerThreshold: 30,
detectors: {
genericRepeat: true,
knownPollNoProgress: true,
pingPong: true,
},
},
},
}
tools.web
{
tools: {
web: {
search: {
enabled: true,
apiKey: "brave_api_key", // or BRAVE_API_KEY env
maxResults: 5,
timeoutSeconds: 30,
cacheTtlMinutes: 15,
},
fetch: {
enabled: true,
provider: "firecrawl", // optional; omit for auto-detect
maxChars: 50000,
maxCharsCap: 50000,
maxResponseBytes: 2000000,
timeoutSeconds: 30,
cacheTtlMinutes: 15,
maxRedirects: 3,
readability: true,
userAgent: "custom-ua",
},
},
},
}
tools.media
Configures inbound media understanding (image/audio/video):
{
tools: {
media: {
concurrency: 2,
asyncCompletion: {
directSend: false, // deprecated: completions stay agent-mediated
},
audio: {
enabled: true,
maxBytes: 20971520,
scope: {
default: "deny",
rules: [{ action: "allow", match: { chatType: "direct" } }],
},
models: [
{ provider: "openai", model: "gpt-4o-mini-transcribe" },
{ type: "cli", command: "whisper", args: ["--model", "base", "{{MediaPath}}"] },
],
},
image: {
enabled: true,
timeoutSeconds: 180,
models: [{ provider: "ollama", model: "gemma4:26b", timeoutSeconds: 300 }],
},
video: {
enabled: true,
maxBytes: 52428800,
models: [{ provider: "google", model: "gemini-3-flash-preview" }],
},
},
},
}
- `provider`: API provider id (`openai`, `anthropic`, `google`/`gemini`, `groq`, etc.)
- `model`: model id override
- `profile` / `preferredProfile`: `auth-profiles.json` profile selection
**CLI entry** (`type: "cli"`):
- `command`: executable to run
- `args`: templated args (supports `{{MediaPath}}`, `{{Prompt}}`, `{{MaxChars}}`, etc.; `openclaw doctor --fix` migrates deprecated `{input}` placeholders to `{{MediaPath}}`)
**Common fields:**
- `capabilities`: optional list (`image`, `audio`, `video`). Defaults: `openai`/`anthropic`/`minimax` → image, `google` → image+audio+video, `groq` → audio.
- `prompt`, `maxChars`, `maxBytes`, `timeoutSeconds`, `language`: per-entry overrides.
- `tools.media.image.timeoutSeconds` and matching image model `timeoutSeconds` entries also apply when the agent calls the explicit `image` tool.
- Failures fall back to the next entry.
Provider auth follows standard order: `auth-profiles.json` → env vars → `models.providers.*.apiKey`.
**Async completion fields:**
- `asyncCompletion.directSend`: deprecated compatibility flag. Completed async media tasks stay requester-session mediated so the agent receives the result, decides how to tell the user, and uses the message tool when source delivery requires it.
tools.agentToAgent
{
tools: {
agentToAgent: {
enabled: false,
allow: ["home", "work"],
},
},
}
tools.sessions
Controls which sessions can be targeted by the session tools (sessions_list, sessions_history, sessions_send).
Default: tree (current session + sessions spawned by it, such as subagents).
{
tools: {
sessions: {
// "self" | "tree" | "agent" | "all"
visibility: "tree",
},
},
}
tools.sessions_spawn
Controls inline attachment support for sessions_spawn.
{
tools: {
sessions_spawn: {
attachments: {
enabled: false, // opt-in: set true to allow inline file attachments
maxTotalBytes: 5242880, // 5 MB total across all files
maxFiles: 50,
maxFileBytes: 1048576, // 1 MB per file
retainOnSessionKeep: false, // keep attachments when cleanup="keep"
},
},
},
}
tools.experimental
Experimental built-in tool flags. Default off unless a strict-agentic GPT-5 auto-enable rule applies.
{
tools: {
experimental: {
planTool: true, // enable experimental update_plan
},
},
}
planTool: enables the structuredupdate_plantool for non-trivial multi-step work tracking.- Default:
falseunlessagents.defaults.embeddedPi.executionContract(or a per-agent override) is set to"strict-agentic"for an OpenAI or OpenAI Codex GPT-5-family run. Settrueto force the tool on outside that scope, orfalseto keep it off even for strict-agentic GPT-5 runs. - When enabled, the system prompt also adds usage guidance so the model only uses it for substantial work and keeps at most one step
in_progress.
agents.defaults.subagents
{
agents: {
defaults: {
subagents: {
allowAgents: ["research"],
model: "minimax/MiniMax-M2.7",
maxConcurrent: 8,
runTimeoutSeconds: 900,
archiveAfterMinutes: 60,
},
},
},
}
model: default model for spawned sub-agents. If omitted, sub-agents inherit the caller's model.allowAgents: default allowlist of target agent ids forsessions_spawnwhen the requester agent does not set its ownsubagents.allowAgents(["*"]= any; default: same agent only).runTimeoutSeconds: default timeout (seconds) forsessions_spawnwhen the tool call omitsrunTimeoutSeconds.0means no timeout.- Per-subagent tool policy:
tools.subagents.tools.allow/tools.subagents.tools.deny.
Custom providers and base URLs
OpenClaw uses the built-in model catalog. Add custom providers via models.providers in config or ~/.openclaw/agents/<agentId>/agent/models.json.
{
models: {
mode: "merge", // merge (default) | replace
providers: {
"custom-proxy": {
baseUrl: "http://localhost:4000/v1",
apiKey: "LITELLM_KEY",
api: "openai-completions", // openai-completions | openai-responses | anthropic-messages | google-generative-ai
models: [
{
id: "llama-3.1-8b",
name: "Llama 3.1 8B",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
contextTokens: 96000,
maxTokens: 32000,
},
],
},
},
},
}
Provider field details
- `models.mode`: provider catalog behavior (`merge` or `replace`). - `models.providers`: custom provider map keyed by provider id. - Safe edits: use `openclaw config set models.providers. '' --strict-json --merge` or `openclaw config set models.providers..models '' --strict-json --merge` for additive updates. `config set` refuses destructive replacements unless you pass `--replace`. - `models.providers.*.api`: request adapter (`openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai`, etc). For self-hosted `/v1/chat/completions` backends such as MLX, vLLM, SGLang, and most OpenAI-compatible local servers, use `openai-completions`. A custom provider with `baseUrl` but no `api` defaults to `openai-completions`; set `openai-responses` only when the backend supports `/v1/responses`. - `models.providers.*.apiKey`: provider credential (prefer SecretRef/env substitution). - `models.providers.*.auth`: auth strategy (`api-key`, `token`, `oauth`, `aws-sdk`). - `models.providers.*.contextWindow`: default native context window for models under this provider when the model entry does not set `contextWindow`. - `models.providers.*.contextTokens`: default effective runtime context cap for models under this provider when the model entry does not set `contextTokens`. - `models.providers.*.maxTokens`: default output-token cap for models under this provider when the model entry does not set `maxTokens`. - `models.providers.*.timeoutSeconds`: optional per-provider model HTTP request timeout in seconds, including connect, headers, body, and total request abort handling. - `models.providers.*.injectNumCtxForOpenAICompat`: for Ollama + `openai-completions`, inject `options.num_ctx` into requests (default: `true`). - `models.providers.*.authHeader`: force credential transport in the `Authorization` header when required. - `models.providers.*.baseUrl`: upstream API base URL. - `models.providers.*.headers`: extra static headers for proxy/tenant routing. `models.providers.*.request`: transport overrides for model-provider HTTP requests.- `request.headers`: extra headers (merged with provider defaults). Values accept SecretRef.
- `request.auth`: auth strategy override. Modes: `"provider-default"` (use provider's built-in auth), `"authorization-bearer"` (with `token`), `"header"` (with `headerName`, `value`, optional `prefix`).
- `request.proxy`: HTTP proxy override. Modes: `"env-proxy"` (use `HTTP_PROXY`/`HTTPS_PROXY` env vars), `"explicit-proxy"` (with `url`). Both modes accept an optional `tls` sub-object.
- `request.tls`: TLS override for direct connections. Fields: `ca`, `cert`, `key`, `passphrase` (all accept SecretRef), `serverName`, `insecureSkipVerify`.
- `request.allowPrivateNetwork`: when `true`, allow HTTPS to `baseUrl` when DNS resolves to private, CGNAT, or similar ranges, via the provider HTTP fetch guard (operator opt-in for trusted self-hosted OpenAI-compatible endpoints). Loopback model-provider stream URLs such as `localhost`, `127.0.0.1`, and `[::1]` are allowed automatically unless this is explicitly set to `false`; LAN, tailnet, and private DNS hosts still require opt-in. WebSocket uses the same `request` for headers/TLS but not that fetch SSRF gate. Default `false`.
- `models.providers.*.models`: explicit provider model catalog entries.
- `models.providers.*.models.*.input`: model input modalities. Use `["text"]` for text-only models and `["text", "image"]` for native image/vision models. Image attachments are only injected into agent turns when the selected model is marked image-capable.
- `models.providers.*.models.*.contextWindow`: native model context window metadata. This overrides provider-level `contextWindow` for that model.
- `models.providers.*.models.*.contextTokens`: optional runtime context cap. This overrides provider-level `contextTokens`; use it when you want a smaller effective context budget than the model's native `contextWindow`; `openclaw models list` shows both values when they differ.
- `models.providers.*.models.*.compat.supportsDeveloperRole`: optional compatibility hint. For `api: "openai-completions"` with a non-empty non-native `baseUrl` (host not `api.openai.com`), OpenClaw forces this to `false` at runtime. Empty/omitted `baseUrl` keeps default OpenAI behavior.
- `models.providers.*.models.*.compat.requiresStringContent`: optional compatibility hint for string-only OpenAI-compatible chat endpoints. When `true`, OpenClaw flattens pure text `messages[].content` arrays into plain strings before sending the request.
- `plugins.entries.amazon-bedrock.config.discovery`: Bedrock auto-discovery settings root.
- `plugins.entries.amazon-bedrock.config.discovery.enabled`: turn implicit discovery on/off.
- `plugins.entries.amazon-bedrock.config.discovery.region`: AWS region for discovery.
- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`: optional provider-id filter for targeted discovery.
- `plugins.entries.amazon-bedrock.config.discovery.refreshInterval`: polling interval for discovery refresh.
- `plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow`: fallback context window for discovered models.
- `plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens`: fallback max output tokens for discovered models.
Interactive custom-provider onboarding infers image input for common vision model IDs such as GPT-4o, Claude, Gemini, Qwen-VL, LLaVA, Pixtral, InternVL, Mllama, MiniCPM-V, and GLM-4V, and skips the extra question for known text-only families. Unknown model IDs still prompt for image support. Non-interactive onboarding uses the same inference; pass --custom-image-input to force image-capable metadata or --custom-text-input to force text-only metadata.
Provider examples
The bundled `cerebras` provider plugin can configure this via `openclaw onboard --auth-choice cerebras-api-key`. Use explicit provider config only when overriding defaults.```json5
{
env: { CEREBRAS_API_KEY: "sk-..." },
agents: {
defaults: {
model: {
primary: "cerebras/zai-glm-4.7",
fallbacks: ["cerebras/gpt-oss-120b"],
},
models: {
"cerebras/zai-glm-4.7": { alias: "GLM 4.7 (Cerebras)" },
"cerebras/gpt-oss-120b": { alias: "GPT OSS 120B (Cerebras)" },
},
},
},
models: {
mode: "merge",
providers: {
cerebras: {
baseUrl: "https://api.cerebras.ai/v1",
apiKey: "${CEREBRAS_API_KEY}",
api: "openai-completions",
models: [
{ id: "zai-glm-4.7", name: "GLM 4.7 (Cerebras)" },
{ id: "gpt-oss-120b", name: "GPT OSS 120B (Cerebras)" },
],
},
},
},
}
```
Use `cerebras/zai-glm-4.7` for Cerebras; `zai/glm-4.7` for Z.AI direct.
```json5
{
env: { KIMI_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "kimi/kimi-code" },
models: { "kimi/kimi-code": { alias: "Kimi Code" } },
},
},
}
```
Anthropic-compatible, built-in provider. Shortcut: `openclaw onboard --auth-choice kimi-code-api-key`.
See [Local Models](/gateway/local-models). TL;DR: run a large local model via LM Studio Responses API on serious hardware; keep hosted models merged for fallback.
```json5
{
agents: {
defaults: {
model: { primary: "minimax/MiniMax-M2.7" },
models: {
"minimax/MiniMax-M2.7": { alias: "Minimax" },
},
},
},
models: {
mode: "merge",
providers: {
minimax: {
baseUrl: "https://api.minimax.io/anthropic",
apiKey: "${MINIMAX_API_KEY}",
api: "anthropic-messages",
models: [
{
id: "MiniMax-M2.7",
name: "MiniMax M2.7",
reasoning: true,
input: ["text"],
cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 },
contextWindow: 204800,
maxTokens: 131072,
},
],
},
},
},
}
```
Set `MINIMAX_API_KEY`. Shortcuts: `openclaw onboard --auth-choice minimax-global-api` or `openclaw onboard --auth-choice minimax-cn-api`. The model catalog defaults to M2.7 only. On the Anthropic-compatible streaming path, OpenClaw disables MiniMax thinking by default unless you explicitly set `thinking` yourself. `/fast on` or `params.fastMode: true` rewrites `MiniMax-M2.7` to `MiniMax-M2.7-highspeed`.
```json5
{
env: { MOONSHOT_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "moonshot/kimi-k2.6" },
models: { "moonshot/kimi-k2.6": { alias: "Kimi K2.6" } },
},
},
models: {
mode: "merge",
providers: {
moonshot: {
baseUrl: "https://api.moonshot.ai/v1",
apiKey: "${MOONSHOT_API_KEY}",
api: "openai-completions",
models: [
{
id: "kimi-k2.6",
name: "Kimi K2.6",
reasoning: false,
input: ["text", "image"],
cost: { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 },
contextWindow: 262144,
maxTokens: 262144,
},
],
},
},
},
}
```
For the China endpoint: `baseUrl: "https://api.moonshot.cn/v1"` or `openclaw onboard --auth-choice moonshot-api-key-cn`.
Native Moonshot endpoints advertise streaming usage compatibility on the shared `openai-completions` transport, and OpenClaw keys that off endpoint capabilities rather than the built-in provider id alone.
```json5
{
agents: {
defaults: {
model: { primary: "opencode/claude-opus-4-6" },
models: { "opencode/claude-opus-4-6": { alias: "Opus" } },
},
},
}
```
Set `OPENCODE_API_KEY` (or `OPENCODE_ZEN_API_KEY`). Use `opencode/...` refs for the Zen catalog or `opencode-go/...` refs for the Go catalog. Shortcut: `openclaw onboard --auth-choice opencode-zen` or `openclaw onboard --auth-choice opencode-go`.
```json5
{
env: { SYNTHETIC_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "synthetic/hf:MiniMaxAI/MiniMax-M2.5" },
models: { "synthetic/hf:MiniMaxAI/MiniMax-M2.5": { alias: "MiniMax M2.5" } },
},
},
models: {
mode: "merge",
providers: {
synthetic: {
baseUrl: "https://api.synthetic.new/anthropic",
apiKey: "${SYNTHETIC_API_KEY}",
api: "anthropic-messages",
models: [
{
id: "hf:MiniMaxAI/MiniMax-M2.5",
name: "MiniMax M2.5",
reasoning: true,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 192000,
maxTokens: 65536,
},
],
},
},
},
}
```
Base URL should omit `/v1` (Anthropic client appends it). Shortcut: `openclaw onboard --auth-choice synthetic-api-key`.
```json5
{
agents: {
defaults: {
model: { primary: "zai/glm-4.7" },
models: { "zai/glm-4.7": {} },
},
},
}
```
Set `ZAI_API_KEY`. `z.ai/*` and `z-ai/*` are accepted aliases. Shortcut: `openclaw onboard --auth-choice zai-api-key`.
- General endpoint: `https://api.z.ai/api/paas/v4`
- Coding endpoint (default): `https://api.z.ai/api/coding/paas/v4`
- For the general endpoint, define a custom provider with the base URL override.
Related
- Configuration — agents
- Configuration — channels
- Configuration reference — other top-level keys
- Tools and plugins