Comparing harnesses
Every harness runs the same loop. What separates them is where they run, what they will let the model do before asking you, and what you can bolt onto them. A demo will not tell you any of that. It comes out three weeks later, when the tool has to run in a pipeline, or point at a model the vendor did not sell you, or explain what it did to a file nobody expected it to touch.
The tabs at the foot of this page describe four of them: Claude Code, Codex, Gemini CLI, and Cursor. The summary table above the tabs adds Muse Code. What follows is the set of axes to compare any of them on, with what a difference on each axis costs.
Interface surface
Where the harness runs decides what is cheap.
A terminal program is one process with your shell, your credentials, and your repository already around it. Piping into it and out of it is free, so it composes with everything else you run. Reviewing a 400 line diff in a terminal is unpleasant.
An extension inside an editor trades that away. Diffs are reviewable, the file you have open is context the harness gets for nothing, and clicking through a change is fast. Running it from a cron job is not a thing you do.
A background or cloud runner has no terminal at all. It takes a task, works on a copy of the repository somewhere else, and hands back a branch or a pull request. That is the only surface that survives you closing your laptop. It is also the one where you cannot lean over and correct it mid-run.
A web surface removes the install. It also removes your local environment, so anything that needed your credentials or your unpushed branch is not there.
Most vendors now ship several of these against one engine, so the real question is which surface holds the configuration, and whether the others read the same files.
Model coupling
Model couplinghow tightly a harness is bound to one vendor's models, and whether you can point it at another endpoint. It decides whether an LLM gateway can sit in front of it.Full glossary entryIntroduced in Comparing harnesses is how tightly the harness is bound to one vendor's models. There are three positions. A harness may call only its own vendor's models. It may call its vendor's models through several endpoints, such as a cloud marketplace or a base URL you set. Or it may point at any endpoint speaking a supported wire format.
This is the axis to check before any of the others, because it decides whether an LLM gateway is usable in front of the harness at all. A gateway exists to centralise keys, cap spend per team, and log every request. It works by being the endpoint the client calls. A harness with no way to change its endpoint cannot be put behind one, so the gateway you bought for governance covers everything except the tool your engineers use all day.
Coupling also decides your exit cost. Prompts, skills and permission rules written against one harness do not move to another, but the choice of model underneath is reversible if the harness lets you set the endpoint.
The permission model
The permission model runs from confirm-everything, through a sandbox with an allowlist of pre-approved commands, to fully unattended. Most harnesses offer a named mode at two or three points on that line, plus an allowlist and a denylist you configure.
The middle position matters most and is the hardest to build. Confirming every call is safe and slow enough that people stop using it. Unattended is fast and gives a language model shell access to your machine. The workable answer is an operating system sandbox around tool execution plus a list of commands that skip the prompt inside it, so npm test runs silently and curl to an unknown host does not.
This axis is what decides whether the harness can run in CI. A pipeline has nobody to confirm anything. If the only unattended mode is "skip all checks", then running it in CI means running it in a throwaway container, and if the harness cannot be sandboxed you are trusting the model with whatever credentials that container holds.
Extensibility
Which of skills, plugins, hooks, subagents and MCP the harness supports, and where that configuration lives. Nearly all of them speak MCP now. The rest vary a great deal.
Ask of each mechanism where the configuration lives. In the repository, so a new joiner gets it from a clone, or in a user directory, so everybody sets it up themselves? And can an administrator pin a setting so a project file cannot override it? Where it lives in a user directory, what the team really has is an onboarding document that each new joiner has to follow.
The instructions file
Several harnesses read a markdown file from the repository root at the start of every session and prepend it to the context. The industry has mostly settled on the name AGENTS.md for this, and a few harnesses read their own filename as well or instead. The generic term is an Agent instructions filea markdown file in a repository that a harness reads into the context at the start of every session, holding build commands, conventions, and standing instructions.Full glossary entryIntroduced in Comparing harnesses.
The file is the closest thing to a portable asset in this whole subject. Build commands, the test runner, directory conventions, things the last three people got wrong. Written in ordinary markdown, in the repository, under review like any other file. Switch harness and it carries over unchanged.
Context management
Whether the harness compacts automatically when the window fills, whether you can inspect what is in the window right now, and what it does at the limit.
Automatic compaction keeps a long run alive at the cost of detail you cannot get back. Where you can see the breakdown of the window, you can find out that an MCP server's tool definitions are eating 20,000 tokens of every request. A harness that stops dead at the limit instead is annoying, and honest about it.
Headless operation
Headless moderunning a harness non-interactively. One prompt in, a result out, an exit code set, and nothing to confirm. It is what makes a harness usable in a pipeline.Full glossary entryIntroduced in Comparing harnesses is running the harness with no interactive session: one prompt in, a result out, exit code set, nothing to confirm. Usually a flag such as a print or exec mode, sometimes an SDK.
Without it the harness cannot go in a pipeline, which rules out the whole class of work that makes these things pay for themselves. Automated code review on every pull request, a nightly pass over failing tests, translating new strings when they land. Check what the output format is as well as whether the mode exists. A mode that emits structured output can be piped into something that decides what to do next; one that emits prose for a human cannot.
Checkpointing and undo
An agentic run edits files, which is the point of it and also the problem. Checkpointinga harness snapshotting the working tree as a run proceeds, so the files can be rolled back to an earlier point in the conversation.Full glossary entryIntroduced in Comparing harnesses is the harness snapshotting the working tree before each step so you can roll back to a point in the conversation.
Read the limits carefully, because they are usually narrower than the feature name suggests. A harness that snapshots edits made through its own file-editing tools has not captured the file a shell command deleted, or the edits a subagent made in a separate context. Version control has none of those gaps. Commit before you start a long run.
The transcript
Every message, every tool call, every result, written somewhere you can read it afterwards. Ask whether it is on disk or only in the scrollback, whether it survives a resume, and whether you can search it.
A run that went wrong is unreviewable without one. So is a run that went right and now has to be explained to somebody else. Some harnesses also expose the transcript as a structured event log, which is the version an automated policy check can read.
Match the surface to where the work already lives.
- Check model coupling first. Confirm the harness can call the endpoint you intend to use.
- Reject a harness that no gateway can sit in front of, if you need central spend control.
- Check that the unattended mode is safe enough for a pipeline before you plan any pipeline work.
- Put the instructions file in the repository. Keep it under review.
- Never grant unattended permissions in a workspace you cannot roll back.
- Commit your work before you start a long unattended run.
How to choose in one pass
Start from the shape of the work. It picks the surface, and the surface rules out more candidates than any feature list.
Terms introduced
- Model coupling: how tightly a harness is bound to one vendor's models, and whether you can point it at another endpoint.
- Agent instructions file: a markdown file in the repository that a harness reads into context at the start of every session.
- Headless mode: running a harness non-interactively, one prompt in and a result out, with nothing to confirm.
- Checkpointing: snapshotting the working tree as a run proceeds so a later step can be rolled back.
How providers do it
Five harnesses against the axes the page teaches. Four of them have a tab below; Muse Code, Meta's terminal coding agent, does not, so its rows carry an open question rather than a full answer.
| Harness | Surfaces | Model coupling | Unattended mode |
|---|---|---|---|
| Claude Code | Terminal, VS Code, JetBrains, desktop, web | Claude models, over five endpoints, base URL settable for a gateway | bypassPermissions, documented for isolated environments |
| Codex | CLI, IDE extension, desktop, ChatGPT web, cloud | Any provider you define, with a base_url and a wire protocol | codex exec, with --sandbox workspace-write recommended |
| Gemini CLI | Terminal | Gemini models. Custom endpoint not documented | --approval-mode=yolo |
| Cursor | Editor, CLI, web, mobile | Many vendors, plus its own models. Own key for four of them | Run Everything, no sandbox and no classifier |
| Muse Code | Terminal and CI | muse-spark-1.2 by default, --model to change it. Whether a non-Meta endpoint is reachable is unstated | muse exec, with --disable-approval and --yolo as flags |
Every row is confirmed against the vendor's own documentation except Muse Code, which is unconfirmed: the pages read document the flags and the default model but do not say whether the harness can call any model other than Meta's own, which is the question that decides whether a gateway can sit in front of it.
| Harness | Instructions file | Compacts automatically | Checkpoint or undo |
|---|---|---|---|
| Claude Code | CLAUDE.md | Yes, plus /compact | /rewind, last 100 checkpoints |
| Codex | AGENTS.md | Yes, at model_auto_compact_token_limit | None. The docs tell you to use git |
| Gemini CLI | GEMINI.md, filename configurable | /compress on demand. Automatic behaviour unstated | --checkpointing and /restore |
| Cursor | .cursor/rules/*.mdc or AGENTS.md | Not documented on the pages read | Checkpoints, restored from the timeline |
| Muse Code | AGENTS.md, then CLAUDE.md, then .agents/AGENTS.md, then .claude/CLAUDE.md | Not stated on the pages read | Rewind a conversation, plus a replayable event log |
Rows marked "not documented" or "unstated" are open questions. The rest is confirmed against the documentation named in each tab. Muse Code has no tab, so its rows were read on 2026-09-09 against https://dev.meta.ai/docs/muse-code/ and https://dev.meta.ai/docs/muse-code/configuration.
Only Codex documents pointing the harness at an endpoint you choose, so it is the one an LLM gateway sits in front of without argument. Every harness here reads a markdown file from the repository root, three of them under the same name, which makes that file the only asset that survives changing your mind about the rest of the table.
- Anthropic
- OpenAI
- Cursor
What this maps to: Claude Code. One engine behind several surfaces, with the repository's configuration shared across all of them.
| Question | Answer | Status |
|---|---|---|
| What surfaces does it run on? | Terminal CLI, VS Code and JetBrains extensions, a desktop app, and the web at claude.ai/code, plus the Claude mobile app | confirmed |
| Does the configuration follow the surface? | Yes. Each surface connects to the same engine, so CLAUDE.md, settings and MCP servers work across all of them | confirmed |
| Which models can it call? | Claude models, through the Anthropic API, Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform, or Microsoft Foundry | confirmed |
| Can it point at a custom endpoint? | Yes, for an LLM gateway: ANTHROPIC_BASE_URL, plus ANTHROPIC_BEDROCK_BASE_URL, ANTHROPIC_AWS_BASE_URL, ANTHROPIC_VERTEX_BASE_URL and ANTHROPIC_FOUNDRY_BASE_URL. /status shows which one a session used | confirmed |
| Can it call another vendor's model? | Not documented on the pages read. Open question | unconfirmed |
| How do permissions work? | allow, ask and deny rules in settings files, plus a mode: default, acceptEdits, plan, auto, dontAsk, bypassPermissions | confirmed |
| What is the unattended mode? | bypassPermissions, documented for isolated environments only. permissions.disableBypassPermissionsMode blocks it from managed settings | confirmed |
| Is there an enforced sandbox? | Yes, operating system level filesystem and network isolation for Bash commands, merged with the permission rules | confirmed |
| Which extension mechanisms? | Skills, plugins, hooks, subagents, slash commands, MCP | confirmed |
| Where does that configuration live? | ~/.claude/settings.json, .claude/settings.json, .claude/settings.local.json, managed-settings.json for an administrator, and .mcp.json in the repository | confirmed |
| Instructions file | CLAUDE.md at the repository root, read at the start of every session. Organisation-wide copies can also be deployed to system directories | confirmed |
| Does it compact automatically? | Yes. /compact forces it, /context shows what is in the window | confirmed |
| Headless mode | claude -p with --output-format json, or the Claude Agent SDK for Python and TypeScript | confirmed |
| Checkpointing and undo | /rewind, or double Escape. Snapshots taken before every user prompt, the 100 most recent kept per session | confirmed |
| What checkpointing misses | Files changed by Bash commands, most subagent edits, external edits, and symlinked or hard-linked paths | confirmed |
| Transcript | Sessions saved to disk and resumable, swept after cleanupPeriodDays, 30 days by default | confirmed |
Their vocabulary
| Standard term | Their term |
|---|---|
| Agent instructions file | CLAUDE.md, plus auto memory |
| Permission model | Permission modes and permission rules |
| Headless mode | Print mode, -p |
| Checkpointing | Checkpoints, restored with /rewind |
Where to look
/status names the provider, base URL and proxy in force for the current session, which is the fastest way to check whether a gateway is actually in the path. /permissions shows the rules that are live.
Last verified: 2026-09-09 against https://code.claude.com/docs/en/overview and https://code.claude.com/docs/en/permissions and https://code.claude.com/docs/en/checkpointing and https://code.claude.com/docs/en/third-party-integrations and https://code.claude.com/docs/en/costs.
What this maps to: Codex. A CLI with an IDE extension, a desktop app, a ChatGPT surface and a cloud environment beside it, configured from one TOML file.
| Question | Answer | Status |
|---|---|---|
| What surfaces does it run on? | CLI, IDE extension, desktop app, ChatGPT on the web, and a cloud environment | confirmed |
| Which models can it call? | Set by the model key, for example gpt-5.5, with review_model overriding it for /review | confirmed |
| Can it point at a custom endpoint? | Yes. [model_providers.<id>] takes a base_url, an env_key for the API key, and a wire protocol, and model_provider selects it | confirmed |
| How do permissions work? | approval_policy, set to on-request, never, or a granular policy that keeps chosen prompt categories interactive. untrusted is no longer supported | confirmed |
| Approval and sandbox flags | --ask-for-approval <mode> or -a, and --sandbox <mode> | confirmed |
| Is there an enforced sandbox? | Yes. sandbox_mode is read-only, workspace-write (the default) or danger-full-access. [sandbox_workspace_write] sets network_access and writable_roots | confirmed |
| What is the unattended mode? | codex exec. --dangerously-bypass-approvals-and-sandbox, aliased --yolo, removes both protections. --full-auto is deprecated | confirmed |
| Recommended CI invocation | codex exec --sandbox workspace-write | confirmed |
| Which extension mechanisms? | MCP, added with codex mcp and configured under [mcp_servers.<id>] | confirmed |
| Skills, plugins, hooks, subagents | Not covered on the pages read. Open question | unconfirmed |
| Where does the configuration live? | ~/.codex/config.toml, with .codex/config.toml overriding it inside a trusted project | confirmed |
| Instructions file | AGENTS.md, which /init writes for you. model_instructions_file points at another file | confirmed |
| Does it compact automatically? | Yes, at model_auto_compact_token_limit | confirmed |
| Checkpointing and undo | No built-in checkpoint. The quickstart tells you to create git checkpoints before and after a task so the work can be reverted | confirmed |
| Transcript | history.persistence controls whether it is saved | confirmed |
Their vocabulary
| Standard term | Their term |
|---|---|
| Agent instructions file | AGENTS.md |
| Permission model | Approval policy |
| Sandbox | Sandbox mode |
| Headless mode | codex exec |
Where to look
~/.codex/config.toml is the whole configuration surface, so read it before trusting a CI job. The pairing that matters is approval_policy = "never" with a sandbox_mode other than danger-full-access: the first stops it asking, the second is what still stops it.
Last verified: 2026-09-09 against https://learn.chatgpt.com/docs/config-file/config-reference.md and https://learn.chatgpt.com/docs/agent-approvals-security and https://learn.chatgpt.com/docs/codex/cli.
What this maps to: Gemini CLI. A terminal-first, open source harness, configured from settings.json files at three levels.
| Question | Answer | Status |
|---|---|---|
| What surface does it run on? | The terminal. The documentation describes it as terminal-first | confirmed |
| Which models can it call? | Gemini models. The overview read names Gemini 2.5 Pro as the default and gemini -m gemini-2.5-flash as the way to pick another | confirmed |
| Can it point at a custom endpoint? | Not documented on the pages read. Authentication is by GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_LOCATION, GOOGLE_API_KEY and GOOGLE_APPLICATION_CREDENTIALS. Open question | unconfirmed |
| How do permissions work? | --approval-mode <mode>, one of default, auto_edit, yolo. Trusted folders control execution policy per folder | confirmed |
| What is the unattended mode? | --approval-mode=yolo, which approves every tool call. The older --yolo flag still works | confirmed |
| Is there an enforced sandbox? | Yes, switched on with "tools.sandbox": true or --sandbox. A project can supply .gemini/sandbox.Dockerfile for a custom image | confirmed |
| Which extension mechanisms? | MCP servers, extensions listed by /extensions, and custom commands | confirmed |
| Subagents | Not mentioned in the command reference or the overview read. Open question | unconfirmed |
| Where does the configuration live? | ~/.gemini/settings.json, .gemini/settings.json in the project, and a system file at /etc/gemini-cli/settings.json on Linux, C:\ProgramData\gemini-cli\settings.json on Windows, /Library/Application Support/GeminiCli/settings.json on macOS | confirmed |
| Instructions file | GEMINI.md. The filename is configurable with "context.fileName", which also accepts a list | confirmed |
| Does it compact automatically? | /compress replaces the chat context with a summary on demand. Whether it also happens automatically is not stated on the pages read | unconfirmed |
| Headless mode | gemini -p "prompt", with --output-format json for structured output in scripts | confirmed |
| Checkpointing and undo | Yes. "general.checkpointing.enabled": true or --checkpointing, and /restore puts the project files back to the state they were in just before a tool ran | confirmed |
| Transcript | /chat saves and resumes conversation history, including branching to an earlier state | confirmed |
Their vocabulary
| Standard term | Their term |
|---|---|
| Agent instructions file | Context file, GEMINI.md |
| Permission model | Approval mode, plus trusted folders |
| Compaction | /compress |
| Checkpointing | Checkpointing, restored with /restore |
Where to look
The three settings.json levels merge, and the system-level file is the one an administrator can use to hold a setting down. Check which level supplied a value before assuming a project can change it.
Last verified: 2026-09-09 against https://google-gemini.github.io/gemini-cli/ and https://google-gemini.github.io/gemini-cli/docs/get-started/configuration.html and https://google-gemini.github.io/gemini-cli/docs/cli/commands.html.
What this maps to: Cursor. An editor first, with a CLI, a web surface and cloud agents beside it, and the widest model list of the four.
| Question | Answer | Status |
|---|---|---|
| What surfaces does it run on? | The editor, a CLI, the web at cursor.com/agents for cloud agents, and mobile | confirmed |
| Which models can it call? | Models from several vendors, including Anthropic, OpenAI and Google, alongside Cursor's own Composer models | confirmed |
| Can a user bring an API key? | Yes, for OpenAI, Anthropic, Azure and AWS Bedrock. An administrator can block it from Team Settings, Models | confirmed |
| Can it point at an arbitrary base URL? | Not documented on the pages read. Open question | unconfirmed |
| How do permissions work? | Run modes: Auto-review (the default), Allowlist, and Run Everything. Auto-review runs allowlisted calls, sandboxes shell commands where it can, and sends the rest to a classifier that returns allow or block | confirmed |
| What is the unattended mode? | Run Everything. Every tool call runs, with no sandbox and no classifier | confirmed |
| Is there an enforced sandbox? | Yes, as a layer on top of run modes for shell commands | confirmed |
| Where does that configuration live? | ~/.cursor/permissions.json and ~/.cursor/sandbox.json, with per-project copies in <project>/.cursor/ that take priority when merged | confirmed |
| What does each file control? | permissions.json steers which calls Auto-review runs and which it reviews. sandbox.json sets what a sandboxed command can reach, such as network domains and extra readable or writable paths | confirmed |
| Which extension mechanisms? | MCP tools are covered by run modes alongside shell commands and fetches, so MCP is supported. Custom subagents appear in the Cloud Agents API. Hooks and plugins are not covered on the pages read | unconfirmed |
| Instructions file | Project rules at .cursor/rules/*.mdc, version-controlled, and AGENTS.md in the project root or a subdirectory as the simpler alternative. Precedence runs Team Rules, then Project Rules, then User Rules | confirmed |
| Does it compact automatically? | Not documented on the pages read. Open question | unconfirmed |
| Headless mode | Print mode in the CLI: -p "<prompt>" with --model and --output-format, for scripts and CI pipelines. A TypeScript SDK is also published | confirmed |
| Checkpointing and undo | Yes. Snapshots of the modified files, created automatically before a significant change, restored from the chat timeline or the Restore Checkpoint button | confirmed |
| What checkpointing misses | Restoring reverts files only and leaves the messages in the conversation. Checkpoints are stored locally and separately from git, and are documented for undoing agent changes only | confirmed |
Their vocabulary
| Standard term | Their term |
|---|---|
| Permission model | Run modes, with Auto-review, Allowlist and Run Everything |
| Agent instructions file | Project rules, or AGENTS.md |
| Headless mode | Print mode |
| Checkpointing | Checkpoints, with Restore Checkpoint |
Where to look
Run modes and sandboxing are two separate controls, and reading only one of them gives the wrong answer about what a command can do. Check the merged permissions.json and sandbox.json together.
Last verified: 2026-09-09 against https://cursor.com/docs/agent/security/run-modes and https://cursor.com/docs/cli/overview and https://cursor.com/docs/context/rules and https://cursor.com/docs/enterprise/model-and-integration-management, https://cursor.com/docs/agent/chat/checkpoints and https://cursor.com/docs.