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.
| Flag | Equivalent |
|---|---|
| -b, --backend <value> | explicit backend name (claude, codex, opencode) |
| --claude | shortcut for --backend claude |
| --codex | shortcut for --backend codex |
| --opencode | shortcut 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 Value | Binary | Project Dir | Instructions File |
|---|---|---|---|
| claude | claude | .claude | CLAUDE.md |
| codex | codex | .agents | AGENTS.md |
| opencode | opencode | .opencode | AGENTS.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.
| Placeholder | Resolves 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" }
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.
| Backend | skills/ | rules/ | commands/ | agents/ |
|---|---|---|---|---|
| claude | yes | yes | yes | yes |
| codex | yes | — | — | — |
| opencode | yes | — | yes | yes |
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:
| Command | Equivalent |
|---|---|
| ace auto | shortcut for ace config set trust auto |
| ace yolo | shortcut 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.
| Flag | Layer | File |
|---|---|---|
| --local (default for trust) | per-machine, gitignored | ace.local.toml |
| --project | repo-wide, committed | ace.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
per-backend mapping
| Backend | auto | yolo | CLI Flags |
|---|---|---|---|
| claude | yes | yes | --permission-mode auto / --permission-mode bypassPermissions |
| codex | yes | yes | --ask-for-approval on-request --sandbox danger-full-access / --dangerously-bypass-approvals-and-sandbox |
| opencode | — | — | interactive mode has no trust flags; --dangerously-skip-permissions is one-shot only |
MCP registration
ACE registers [[mcp]] entries from school.toml into the active backend. All entries are remote HTTP endpoints.
| Backend | Method | OAuth |
|---|---|---|
| claude | CLI: claude mcp add -t http -s user | auto on 401 |
| codex | CLI-first: codex mcp add | in-session via /mcp |
| opencode | writes opencode.json directly (mcpServers key) | in-session |
readiness check
ACE verifies the backend is authenticated before launching a session.
| Backend | Check |
|---|---|
| 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
| Backend | Notes |
|---|---|
| claude | Default 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. |
| codex | MCP registration is CLI-first. MCP auth and ongoing management happen inside Codex via /mcp. Only skills/ is linked. |
| opencode | Session 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. |