TestRelic AI
Go to App
CLI

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

ModeWhat it means
Cloud (default)The standard experience: queries and results flow to and from TestRelic Cloud.
LocalNothing is uploaded. Every mutation is approval-gated, and cloud memory is read-only.

Switch modes either way:

testrelic --mode local

Or 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:

EngineSelector
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-code

Or open the picker in the interactive UI:

❯ /engine

CloudAgent 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.

Terminalshop-e2e · main

$ tr

> /engine

Engine
TestRelic CloudTestRelic cloud agent · default, no deps
Claude Codeyour local Claude Code · installed
Codexyour local OpenAI Codex · installed
Ollamayour local Ollama model · not installed

engine: Claude Code — your local Claude Code (runs on your own auth)

~/shop-e2e · Claude Code · CLOUDenter send · @ context · ! shell · shift+tab → mode · /commands

> @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.

~/shop-e2e · Codex · CLOUDenter send · @ context · ! shell · shift+tab → mode · /commands

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:

EngineHow it receives MCP servers
ClaudeCodeInline --mcp-config JSON, with an allowlist covering every merged server.
Codex-c mcp_servers.<name>.{command,args,env} TOML dotted-path overrides.
CursorMirrored 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.
OllamaThe 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
ValueBehavior
planPlan the work without making changes.
defaultPrompt for confirmation on each gated action.
acceptEditsAuto-accept edits while still gating other actions.
bypassPermissionsRun 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

Authentication · MCP host

Was this page helpful?

On this page