Modes & engines
The CLI has two orthogonal axes — Mode (the data boundary, Cloud vs Local) and Engine (which agent backend runs a turn) — plus permission modes. They compose freely.
The CLI has two orthogonal axes. Mode controls the data boundary; Engine controls which agent backend runs a turn. They are independent and compose — any mode works with any engine.
Mode — the data boundary
| Mode | What it means |
|---|---|
| Cloud (default) | The standard experience: queries and results flow to and from TestRelic Cloud. |
| Local | Nothing is uploaded. Every mutation is approval-gated, and cloud memory is read-only. |
Switch modes either way:
testrelic --mode localOr press Shift+Tab in the interactive UI to toggle the mode for the current session.
When to use Local mode
Local mode is for working against sensitive repos or in environments where you don't want anything written back to the cloud. You can still read cloud memory and context; you just can't change it without an explicit approval.
Engine — which agent backend runs a turn
The engine decides which agent backend actually executes a turn:
| Engine | Selector |
|---|---|
| CloudAgent | --engine cloud |
| ClaudeCode | --engine claude-code (alias claude) |
| Codex | --engine codex |
| Cursor | --engine cursor (alias cursor-agent) |
| Ollama | --engine ollama |
| (auto-select) | --engine auto |
testrelic --engine claude-codeOr open the picker in the interactive UI:
❯ /engineCloudAgent is the default (auto resolves to it) and needs no local install. ClaudeCode,
Codex, Cursor, and Ollama are local engines — always opt-in, and each runs on
your own auth or model, never silently substituted for the cloud agent. Claude Code drives your
installed claude CLI headless; Codex drives codex exec; Cursor drives cursor-agent; Ollama
talks directly to a local POST /api/chat (default llama3.1 @ localhost:11434, override with
OLLAMA_MODEL / OLLAMA_HOST or config ollamaModel). /engine shows each local engine's
install status; if the CLI it needs is missing or unauthenticated, the turn falls back to
CloudAgent.
$ tr
> /engine
engine: Claude Code — your local Claude Code (runs on your own auth)
> @tests/checkout.spec.ts why does this keep flaking on CI?
✻ TestRelic
⏺ 3 tools · ctrl+o
The last 6 CI runs fail on the same step — waiting on [data-testid="place-order"]before the cart total re-renders. It's a race with the debounced price recalculation, not a selector problem.
I can add a wait on the total text settling before the click. Want me to open a fix?
> /engine codex
engine: Codex — your local OpenAI Codex (runs on your own auth)
> same fix, now open a PR
✻ TestRelic
⏺ 5 tools · ctrl+o
Opened fix/checkout-total-race — waits for the cart total to stop mutating before the place-order click, same MCP Playwright server Claude Code just used. PR #482 is up for review.
The turn header always reads ✻ TestRelic, no matter which engine is running
underneath — switching engines with /engine changes who executes the turn (and the status
chip below the composer), not the identity you're talking to. The same conversation, the same
MCP tools, a different backend.
MCP tools follow you across every engine
Whichever engine you pick, it gets the same MCP server composition — your configured harness
servers (Playwright/Appium/Maestro), any user-added servers, scoped entries, and the injected
testrelic server — not a cut-down set. Each engine receives it through the only channel it
actually has:
| Engine | How it receives MCP servers |
|---|---|
| ClaudeCode | Inline --mcp-config JSON, with an allowlist covering every merged server. |
| Codex | -c mcp_servers.<name>.{command,args,env} TOML dotted-path overrides. |
| Cursor | Mirrored into the workspace's .cursor/mcp.json (Cursor's only MCP channel), merge-preserving anything already there; --approve-mcps is used for headless approval when the installed cursor-agent supports it. |
| Ollama | The session's MCP host rides directly into TestRelic's own tool loop — host tools are advertised and dispatched the same way as the Cloud engine's client tools. A model that can't take a tools array degrades to a tool-less chat with an in-chat note, rather than failing the turn. |
Cross-app confinement is engine-agnostic: it lives in the server's own command
(tr mcp app-proxy --app <slug>), not in engine-specific config, so a cross-app call is refused
in plain English no matter which engine spawned the entry. The testrelic MCP token is never
written into a repo file — Cursor's .cursor/mcp.json entries that need it are fronted by the
tr mcp app-proxy relay, which resolves the token from ~/.testrelic/token at spawn time.
Known gap: Codex and Cursor have no --disallowedTools equivalent
Claude Code disallows interactive-only tools per turn; Codex and Cursor don't expose that knob, so in Local mode those two engines rely on the MCP capability gate (read-only caps) alone for the data boundary.
Permission mode
Independently of mode and engine, choose how the agent asks before acting:
testrelic --permission-mode plan|default|acceptEdits|bypassPermissions| Value | Behavior |
|---|---|
plan | Plan the work without making changes. |
default | Prompt for confirmation on each gated action. |
acceptEdits | Auto-accept edits while still gating other actions. |
bypassPermissions | Run without confirmation prompts. |
Each local engine maps this onto its own controls: Claude Code disallows its interactive-only
tools so a headless turn never stalls on them; Codex maps to its sandbox flags (plan = read-only,
otherwise full access); Cursor maps to --mode plan (read-only) for plan and --force
(the turn has already been approved) otherwise. Ollama runs TestRelic's own built-in tools, which
stay gated by Local mode's standard write/delete/run approval regardless of --permission-mode.
How they compose
Mode and engine are set separately and combine freely — for example, Local mode with the
ClaudeCode engine keeps every mutation approval-gated and nothing uploaded, while running
the turn on Claude Code. Pick the data boundary you need with --mode, the backend you want
with --engine, and the confirmation behavior with --permission-mode.
Next steps
TestRelic CLI authentication
Authenticate the CLI with a session login for full parity or a personal access token for headless and CI use, and point it at a different backend.
Using the CLI as an MCP host
Run local MCP servers from the CLI so the cloud Ask AI agent can call your tools during a turn, with Claude-Code-compatible .mcp.json config.