backends

Run the same ACE workflow on whichever AI coding tool your team prefers. Set the backend in ace.toml or ace.local.toml with backend = "value". Default: claude.

cli override

Override the configured backend for a single invocation without editing config. Flags are global — they work on any ace subcommand.

FlagEquivalent
-b, --backend <value>explicit backend name (claude, codex, opencode)
--claudeshortcut for --backend claude
--codexshortcut for --backend codex
--opencodeshortcut for --backend opencode
$ ace --codex # launch Codex for this session only
$ ace --claude -- --continue # resume with Claude, passing --continue through
$ ace mcp --codex # check MCP against Codex without switching config
Config ValueBinaryProject DirInstructions File
claudeclaude.claudeCLAUDE.md
codexcodex.agentsAGENTS.md
opencodeopencode.opencodeAGENTS.md

custom backends

Schools, users, or projects can register additional backend entries via [[backends]]. A custom backend aliases a built-in (claude, codex, and opencode) and may override its launch cmd and env. The MCP, instructions file, and linked-folder behavior are inherited from the aliased kind.

# Override env on the built-in claude backend
[[backends]]
name = "claude"
env = { ANTHROPIC_BASE_URL = "https://proxy.example.com" }

# Custom name aliasing claude
[[backends]]
name = "bailer"
kind = "claude"
env = { ANTHROPIC_BASE_URL = "https://bailer.example.com" }

# Wrap the claude binary through a process wrapper
[[backends]]
name = "claude-wrapped"
kind = "claude"
cmd = ["wrapper", "claude"]

templated cmd and env

cmd[] and env values support {{ placeholder }} substitution, rendered at bind time. A school can pre-roll a backend that points at a launcher script under its own clone without knowing the absolute path.

PlaceholderResolves to
{{ school_dir }}Active school root.
{{ project_dir }}Project working directory.
{{ backend_dir }}project_dir joined with the kind's backend dir (.claude, .agents, .opencode).
{{ home }}$HOME.
# School-relative launcher script
[[backends]]
name = "codex-ace"
kind = "codex"
cmd  = ["{{ school_dir }}/skills/ace-connect/scripts/codex.sh"]

# Path-valued env var
[[backends]]
name = "claude-scoped"
kind = "claude"
env  = { XDG_CONFIG_HOME = "{{ project_dir }}/.config" }
Substitution is a closed set of named placeholders — no shell-style $VAR or ~ expansion. Unknown placeholders render to empty strings.

Selectable via backend = "bailer" in any config layer or -b bailer on the CLI. Layer order for merging [[backends]] decls is school → user → project → local; later layers may add new entries or partially override earlier ones. A custom backend cannot introduce new behavior beyond its aliased kind — that requires a source change.

linked folders

ACE links school folders into the project's backend directory. skills/ becomes a real directory with per-skill symlinks (driven by skills/include_skills/exclude_skills in ace.toml); the rest are whole-directory symlinks. Not all backends support every folder.

Backendskills/rules/commands/agents/
claudeyesyesyesyes
codexyes
opencodeyesyesyes

trust modes

Trust modes change how the backend handles permission prompts: default uses the backend's standard handling, auto lets the model decide what needs approval, and yolo disables prompts entirely. Three equivalent ways to set the mode:

CommandEquivalent
ace autoshortcut for ace config set trust auto
ace yoloshortcut for ace config set trust yolo
ace config set trust <value>accepts default, auto, or yolo

scope

Without a scope flag, trust writes to ace.local.toml (per-machine, gitignored — safe for personal preference). Add a global flag to target a different layer.

FlagLayerFile
--local (default for trust)per-machine, gitignoredace.local.toml
--projectrepo-wide, committedace.toml
--user (alias: --global)per-user, applies everywhere~/.config/ace/ace.toml
# Per-machine yolo for the current project (default scope)
$ ace yolo

# Project-wide auto — every clone of this repo picks this up
$ ace auto --project

# User-wide auto across every project on this machine
$ ace config set trust auto --user

# Inspect which layer is winning and why
$ ace config explain trust
--user, --project, and --local are mutually exclusive and global — they work on any ace config set key, not just trust. Most keys default to --project; trust and resume default to --local.

per-backend mapping

BackendautoyoloCLI Flags
claudeyesyes--permission-mode auto / --permission-mode bypassPermissions
codexyesyes--ask-for-approval on-request --sandbox danger-full-access / --dangerously-bypass-approvals-and-sandbox
opencodeinteractive mode has no trust flags; --dangerously-skip-permissions is one-shot only
Each backend maps ACE trust modes to its own CLI flags. The mappings differ between backends.

MCP registration

ACE registers [[mcp]] entries from school.toml into the active backend. All entries are remote HTTP endpoints.

BackendMethodOAuth
claudeCLI: claude mcp add -t http -s userauto on 401
codexCLI-first: codex mcp addin-session via /mcp
opencodewrites opencode.json directly (mcpServers key)in-session

readiness check

ACE verifies the backend is authenticated before launching a session.

BackendCheck
claude~/.claude.json exists
codex~/.codex/auth.json exists, or CODEX_API_KEY / OPENAI_API_KEY set
opencode~/.local/share/opencode/auth.json exists and is non-empty ($XDG_DATA_HOME respected)

quirks

BackendNotes
claudeDefault backend. Full feature support. MCP servers registered at user scope (-s user), not project scope. Auto-resume via --continue fails when no prior session exists; ACE prints a hint suggesting ace new to start fresh.
codexMCP registration is CLI-first. MCP auth and ongoing management happen inside Codex via /mcp. Only skills/ is linked.
opencodeSession prompt is written to .opencode/agents/ace.md and selected with --agent ace. ACE supports opencode.json only — an existing opencode.jsonc is rejected with a hint to rename. No structured MCP health check; ace mcp check is a no-op.