What is an agent-native CLI?
An agent-native CLI is a command-line tool for coding agents and people, with structured output, clear exit codes, and no prompts without a terminal. The term describes a command-line interface (CLI) that agents call, not a coding agent that runs in a terminal, e.g. Claude Code. One binary serves a person at a terminal and an agent's shell tool.
Most of these properties are older than coding agents, because scripts, and teams that test a command-line application, need them too. The Command Line Interface Guidelines advise JSON output behind a --json flag, and prompts only when stdin is a terminal. What changes with an agent is the reader. Each result goes into the model's context, where long tables and color codes take up space, and the model generates its next command from that text.
Some tool makers use the term agent experience (AX) for how well a product works when an AI agent is its user. A CLI that prompts, or that exits 0 after an error, can stall an agent's run or let it report success after a failure.
How does an agent use a CLI?
A coding agent runs a CLI through a shell tool in its harness, the program that runs the model and its tools. Each command moves through four steps:
- The model generates a tool call to the shell tool with a command, e.g.
acme orders list --json. - The harness usually runs the command with no terminal and reads its stdout and stderr through pipes.
- The command exits, or the tool's timeout stops it.
- The harness returns the output and the exit code, and the model generates its next call from them.
An agent-native CLI puts everything a caller needs into those three outputs, with these properties:
- Structured output. A flag, e.g.
--json, prints results as JSON on stdout with the same field names in each release, and keeps messages on stderr. - Meaningful exit codes. The command exits 0 only on success, in JSON mode too.
- Errors that name the fix. The message says what failed and which flag or value to change. Anthropic's guide to writing tools for agents asks for "specific and actionable improvements, rather than opaque error codes or tracebacks."
- No prompts without a terminal. A prompt appears only when stdin is a TTY, and a flag, e.g.
--yes, supplies each answer. Sign-in accepts a token from an environment variable, because an agent cannot finish a browser login. - Short, plain output. Colors and spinners appear only on a terminal, and the tool honors NO_COLOR. Filters, e.g.
--limit, keep results short. - Help that leads with examples. The
--helpoutput shows examples above its list of subcommands and flags. An agent often runs--helpto find a flag it lacks. - A dry run for changes. A
--dry-runflag prints what a command would change without changing it.
In the GitHub CLI (gh), GH_PROMPT_DISABLED turns off prompts, and a token in GH_TOKEN skips the login prompt, per its environment manual.
An agent-native CLI checks for a terminal, NO_COLOR, and explicit flags, not for the name of its caller, because no environment variable identifies an agent reliably. Claude Code's environment variable reference says it sets CLAUDECODE to 1 in the commands it starts. Its editor extensions set the same variable in terminals where people type, so a CLI that checks it can change the output a person sees.
What is an example of an agent-native CLI?
Here is an illustrative example. Acme Co. sells furniture online, and its command-line tool, acme, manages orders. A developer at Acme asks a coding agent to "Cancel the failed orders." The run takes six steps:
- The agent runs
acme orders list --status failed --json, which prints a JSON array and exits 0. - The array holds one order, and the model takes its ID
A-1042from theorder_idfield. - The agent runs
acme orders cancel A-1042, which printsCancel order A-1042? [y/N]and reads a line from stdin. - The shell tool passes no input, so the command takes the default "N" answer, cancels nothing, and exits 0.
- The command exited 0, so the agent reports the order as canceled. The developer finds it still open and changes
cancelso that it never prompts without a terminal. - The agent runs the command again, gets an error that names the flag to pass, and reruns it with
--yes --json.
In a shell, < /dev/null gives the command the same empty input:
$ acme orders cancel A-1042 < /dev/null
error: no terminal to confirm. Pass --yes to cancel A-1042.
$ echo $?
2
$ acme orders cancel A-1042 --yes --json
{"order_id": "A-1042", "status": "canceled"}
At a terminal, the prompt still appears for a person. This example is simplified. A real CLI would also need a --dry-run flag for canceling many orders at once.
What changes when a coding agent writes the code?
When a coding agent writes a CLI, the agent is also the CLI's first caller. It can run each command it adds through its shell tool, so JSON output and exit codes give it exact results to check.
Those checks cover only the commands the agent ran. An agent that adds commands in separate sessions can give one a --json flag and another a --format json option. It can rename a JSON field between edits, because nothing records the old name. An error message can also name a flag, e.g. --yes, that the parser does not accept.
A team can write the output contract as tests. One test runs each subcommand with --json and parses stdout, and another compares the field names with a saved list. A third runs each command with stdin from /dev/null and a time limit, and fails if the command waits for input. A fourth reruns each failing command with the flag its error names.
The flags that help an agent also help these tests, which is the idea behind design for testability. The same tests help verify a CLI that a coding agent built.
What are the limits of agent-native design?
Agent-native design helps an agent call a CLI correctly. It does not make the CLI's results correct, and it has these limits:
- Valid output can still be wrong. A command can exit 0 with valid JSON that lists the wrong orders. An agent's report of "done" then rests on what the CLI printed, not on a check of the result.
- JSON output becomes a contract. Once agents and scripts parse a field, renaming it breaks them. The guidelines accept changes to output for people, but tell authors to encourage
--plainor--jsonin scripts "to keep output stable." - Fewer prompts remove a human check. A
--yesflag skips the confirmation that a person would have read. The list of commands an agent may run belongs in its permission settings, which harness engineering sets up. - Some software has no CLI. A team can write a CLI around the software's API. Software with only a graphical interface can call for a computer-use agent, which operates the screen instead of a command line.
How is an agent-native CLI different from an MCP server?
An MCP server is a program that offers named tools, each with an argument schema, over the Model Context Protocol. An MCP server fits an AI application that has no shell tool, or a task that keeps state between calls, e.g. an open browser session. It can also limit an agent to chosen actions, while a shell tool usually runs with the user's permissions.
An agent-native CLI needs no server. An MCP server's tool names enter the model's context when a session starts, and some agents load each tool's full schema then too. A CLI's help enters it only when the agent runs --help. Claude Code's best practices recommend CLI tools for external services as the option that uses the least context. An MCP server or an agent skill can also wrap a CLI.
FAQs
What is agent experience?
Agent experience, often shortened to AX, is how well a product or tool works when an AI agent is the one using it. For a CLI, agent experience depends on structured output, clear exit codes, errors that name the fix, and prompts that appear only for a person at a terminal.
What should a JSON output flag guarantee?
A JSON output flag should keep stdout to valid JSON only, with field names that stay the same between releases. Warnings and progress lines go to stderr, and the exit code still reports a failure, so a caller does not parse an error as data.
Should a CLI detect that an agent is running it?
A CLI usually should not detect an agent by name, because no environment variable identifies an agent reliably. One agent's variable also appears in terminals where people type. A check for a terminal gives agents and scripts the same plain output.
Do coding agents read a CLI's help text?
Coding agents often run a CLI's help flag to find a flag they lack, and the help text then enters the model's context. Examples near the top of the help show the model a complete command, flags included.