I spent last weekend migrating a CLI from Click to cyclopts and fell down a research hole: what makes a CLI good for AI agents to invoke?
Three authors published independently on this in early 2026. Joel Hooks, Ugo Enyioha, and the OpenStatus team. They never cite each other. They converge on almost identical patterns. That convergence is the signal.
The first pattern is that JSON is the only output format. Not a —json flag. JSON by default, always. Humans pipe through jq. This is the most opinionated pattern and the one most existing CLIs get wrong. The flag means agents must remember to pass it, and forgetting produces unparseable output that wastes a retry.
The second is that every response is a HATEOAS envelope. The response includes ok, command, result, and a next_actions array with exact runnable commands for what the agent should do next. The agent does not need to know the full API upfront. Each response tells it where to go. Roy Fielding’s constraint, applied to CLIs.
The third is that errors include a fix field. Not just what went wrong but what to do about it. Machine-readable error codes plus human-readable fix strings plus next_actions pointing to recovery commands. The agent does not need to reason about recovery from scratch.
The fourth is that bare invocation returns the command tree. Running the tool with no arguments returns a JSON object describing every command, parameter, type, enum value, and default. One call and the agent knows the entire API surface. No help parsing required.
The fifth is semantic exit codes as a contract. Not just zero and one. A defined vocabulary: zero for ok, one for generic error, two for usage error, three for resource not found, four for permission denied, five for conflict. The agent’s control flow branches on the exit code before parsing the body.
The sixth is NDJSON for streaming. Long-running operations emit newline-delimited JSON with a type discriminator on each line. The last line is always the standard envelope. Tools that do not understand streaming just read the last line. Backwards compatible by design.
The seventh is TTY detection for dual mode. The isatty check on stdout determines behaviour. TTY means human mode with spinners, colours, and progress bars on stderr. Pipe means agent mode with clean JSON and no decoration. One binary, two audiences.
I checked the source code of six major AI coding agents: Claude Code in TypeScript with a custom framework, Codex CLI in Rust with clap, Gemini CLI in TypeScript with commander, Goose in Rust with a custom framework, Aider in Python with configargparse, and OpenCode in Go with cobra. None use Click, Typer, or cyclopts. But this is the agent harness, not the tools the agent invokes. The agent calls git, gh, rg, and your custom CLIs via subprocess. That is where the framework choice matters.
Nobody has built a framework for this because the envelope pattern is about thirty lines of helper code. Three functions. Most developers would copy-paste them rather than install a library. But the part that is genuinely framework-worthy is auto-generating the command tree and schema from type hints. My reference CLI has over two hundred lines of manually maintained JSON describing every command. That information already exists in the function signatures. A framework that introspects registered commands and generates the command tree eliminates that duplication.
The MCP angle also explains the gap. The people who care most about structured agent-tool interfaces have been building MCP servers, not CLIs. MCP gives you typed schemas, tool discovery, and structured responses by design. But as Enyioha notes, he deleted three MCP servers in favour of direct CLI usage, and switching from MCP to CLI cut token usage by roughly forty percent. The market for agent-facing CLIs is growing as people discover this cost difference.
The right abstraction is not a replacement for Click or Typer. It is a layer on top. The seven patterns do not depend on which CLI parser you use. They depend on what comes out of stdout and how the agent discovers what is available.
Sources: Joel Hooks, “CLI Design for AI Agents” (Feb 2026). Ugo Enyioha, “Writing CLI Tools That AI Agents Actually Want to Use” (Feb 2026). OpenStatus, “Building a CLI That Works for Humans and Machines” (Apr 2026). HKU, “CLI-Anything” (2026). OPENDEV, “Building Effective AI Coding Agents for the Terminal” (Mar 2026).