CLI Backends
CLI backends (fallback runtime)
Section titled “CLI backends (fallback runtime)”OpenClaw can run local AI CLIs as a text-only fallback when API providers are down, rate-limited, or temporarily misbehaving. This is intentionally conservative:
- Tools are disabled (no tool calls).
- Text in → text out (reliable).
- Sessions are supported (so follow-up turns stay coherent).
- Images can be passed through if the CLI accepts image paths.
This is designed as a safety net rather than a primary path. Use it when you want “always works” text responses without relying on external APIs.
Beginner-friendly quick start
Section titled “Beginner-friendly quick start”You can use Claude Code CLI without any config (the bundled Anthropic plugin registers a default backend):
openclaw agent --message "hi" --model claude-cli/opus-4.6Codex CLI also works out of the box (via the bundled OpenAI plugin):
openclaw agent --message "hi" --model codex-cli/gpt-5.4If your gateway runs under launchd/systemd and PATH is minimal, add just the command path:
{ agents: { defaults: { cliBackends: { "claude-cli": { command: "/opt/homebrew/bin/claude", }, }, }, },}That’s it. No keys, no extra auth config needed beyond the CLI itself.
If you use a bundled CLI backend as the primary message provider on a
gateway host, OpenClaw now auto-loads the owning bundled plugin when your config
explicitly references that backend in a model ref or under
agents.defaults.cliBackends.
Using it as a fallback
Section titled “Using it as a fallback”Add a CLI backend to your fallback list so it only runs when primary models fail:
{ agents: { defaults: { model: { primary: "anthropic/claude-opus-4-6", fallbacks: ["claude-cli/opus-4.6", "claude-cli/opus-4.5"], }, models: { "anthropic/claude-opus-4-6": { alias: "Opus" }, "claude-cli/opus-4.6": {}, "claude-cli/opus-4.5": {}, }, }, },}Notes:
- If you use
agents.defaults.models(allowlist), you must includeclaude-cli/.... - If the primary provider fails (auth, rate limits, timeouts), OpenClaw will try the CLI backend next.
Configuration overview
Section titled “Configuration overview”All CLI backends live under:
agents.defaults.cliBackendsEach entry is keyed by a provider id (e.g. claude-cli, my-cli).
The provider id becomes the left side of your model ref:
<provider>/<model>Example configuration
Section titled “Example configuration”{ agents: { defaults: { cliBackends: { "claude-cli": { command: "/opt/homebrew/bin/claude", }, "my-cli": { command: "my-cli", args: ["--json"], output: "json", input: "arg", modelArg: "--model", modelAliases: { "claude-opus-4-6": "opus", "claude-sonnet-4-6": "sonnet", }, sessionArg: "--session", sessionMode: "existing", sessionIdFields: ["session_id", "conversation_id"], systemPromptArg: "--system", systemPromptWhen: "first", imageArg: "--image", imageMode: "repeat", serialize: true, }, }, }, },}How it works
Section titled “How it works”- Selects a backend based on the provider prefix (
claude-cli/...). - Builds a system prompt using the same OpenClaw prompt + workspace context.
- Executes the CLI with a session id (if supported) so history stays consistent.
- Parses output (JSON or plain text) and returns the final text.
- Persists session ids per backend, so follow-ups reuse the same CLI session.
Sessions
Section titled “Sessions”- If the CLI supports sessions, set
sessionArg(e.g.--session-id) orsessionArgs(placeholder{sessionId}) when the ID needs to be inserted into multiple flags. - If the CLI uses a resume subcommand with different flags, set
resumeArgs(replacesargswhen resuming) and optionallyresumeOutput(for non-JSON resumes). sessionMode:always: always send a session id (new UUID if none stored).existing: only send a session id if one was stored before.none: never send a session id.
Images (pass-through)
Section titled “Images (pass-through)”If your CLI accepts image paths, set imageArg:
imageArg: "--image",imageMode: "repeat"OpenClaw will write base64 images to temp files. If imageArg is set, those
paths are passed as CLI args. If imageArg is missing, OpenClaw appends the
file paths to the prompt (path injection), which is enough for CLIs that auto-
load local files from plain paths (Claude Code CLI behavior).
Inputs / outputs
Section titled “Inputs / outputs”output: "json"(default) tries to parse JSON and extract text + session id.output: "jsonl"parses JSONL streams (Codex CLI--json) and extracts the last agent message plusthread_idwhen present.output: "text"treats stdout as the final response.
Input modes:
input: "arg"(default) passes the prompt as the last CLI arg.input: "stdin"sends the prompt via stdin.- If the prompt is very long and
maxPromptArgCharsis set, stdin is used.
Defaults (plugin-owned)
Section titled “Defaults (plugin-owned)”The bundled Anthropic plugin registers a default for claude-cli:
command: "claude"args: ["-p", "--output-format", "json", "--permission-mode", "bypassPermissions"]resumeArgs: ["-p", "--output-format", "json", "--permission-mode", "bypassPermissions", "--resume", "{sessionId}"]modelArg: "--model"systemPromptArg: "--append-system-prompt"sessionArg: "--session-id"systemPromptWhen: "first"sessionMode: "always"
The bundled OpenAI plugin also registers a default for codex-cli:
command: "codex"args: ["exec","--json","--color","never","--sandbox","workspace-write","--skip-git-repo-check"]resumeArgs: ["exec","resume","{sessionId}","--color","never","--sandbox","workspace-write","--skip-git-repo-check"]output: "jsonl"resumeOutput: "text"modelArg: "--model"imageArg: "--image"sessionMode: "existing"
The bundled Google plugin also registers a default for google-gemini-cli:
command: "gemini"args: ["--prompt", "--output-format", "json"]resumeArgs: ["--resume", "{sessionId}", "--prompt", "--output-format", "json"]modelArg: "--model"sessionMode: "existing"sessionIdFields: ["session_id", "sessionId"]
Override only if needed (common: absolute command path).
Plugin-owned defaults
Section titled “Plugin-owned defaults”CLI backend defaults are now part of the plugin surface:
- Plugins register them with
api.registerCliBackend(...). - The backend
idbecomes the provider prefix in model refs. - User config in
agents.defaults.cliBackends.<id>still overrides the plugin default. - Backend-specific config cleanup stays plugin-owned through the optional
normalizeConfighook.
Limitations
Section titled “Limitations”- No OpenClaw tools (the CLI backend never receives tool calls). Some CLIs may still run their own agent tooling.
- No streaming (CLI output is collected then returned).
- Structured outputs depend on the CLI’s JSON format.
- Codex CLI sessions resume via text output (no JSONL), which is less
structured than the initial
--jsonrun. OpenClaw sessions still work normally.
Troubleshooting
Section titled “Troubleshooting”- CLI not found: set
commandto a full path. - Wrong model name: use
modelAliasesto mapprovider/model→ CLI model. - No session continuity: ensure
sessionArgis set andsessionModeis notnone(Codex CLI currently cannot resume with JSON output). - Images ignored: set
imageArg(and verify CLI supports file paths).