Building CLIs for AI Agents
|
This content was generated with the assistance of AI and should be verified against the official documentation of each tool and framework before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
A command-line tool that an AI agent can drive is the same kind of tool a careful engineer would want anyway: predictable streams, honest exit codes, structured output, no surprise prompts and safe defaults. This sub-section collects those practices, shows them on one running example, and then shows how to wrap the finished tool as an MCP server or an agent tool. The versions used are listed in Version baseline, all checked on 2026-09-30, and every page repeats the subset it needs in its own lead paragraph.
Why CLIs work well with agents
An agent that can run a shell command can already use a very large tool ecosystem, and a CLI has properties that suit that style of work:
-
Nothing to load up front. A command costs context only when it is run, and only its output is paid for. Claude Code’s own guidance treats command-line tools as a context-efficient way to reach external services (see Claude Code — Best practices). Tool schemas, by contrast, are usually loaded before the first call.
-
Models already know the common ones.
git,gh,curlandjqappear throughout training data, so little description is needed; an unfamiliar tool costs one--helpcall, which is why Self-Describing Help matters. -
Composition is built in. Pipes, redirection and exit codes let an agent chain steps without a bespoke integration, which only works when the tool respects Streams & Exit Codes.
-
Humans and CI use the same interface. One implementation serves a terminal, a script and an agent, and the same contract can later be exposed as an MCP tool (see CLI vs. MCP for the honest trade-offs, including where MCP is the better fit).
-
Guardrails already exist. Hosts gate shell access with permission rules and sandboxes, described for Claude Code on Permissions & Settings; a well-designed CLI adds dry-runs, confirmations and least-privilege credentials on top.
The price is that a CLI written only for people is hostile to agents: colour codes and spinners in captured output, prompts that hang, human-only error text, unbounded output and unparseable tables. The pages below remove each of those problems in turn. The tool-design ideas behind them are the ones in Tool Design and Designing Good MCP Servers, applied to a process instead of a protocol.
Three audiences, one tool
A command-line tool has three kinds of caller, and a good design serves all of them from one implementation.
terminal, TTY"]) --> CLI S(["Script or CI job
pipes, exit codes"]) --> CLI A(["AI agent
shell tool, MCP or agent-framework tool"]) --> CLI CLI["docsctl
one command line, one contract"] --> SVC[("Service
documentation site, credentials, gh-pages")] CLI -.->|"stdout: data (text or JSON)
stderr: messages
exit code: outcome"| H CLI -.-> S CLI -.-> A
| Audience | Needs | Where it is covered |
|---|---|---|
Humans |
Readable text, colour and progress on a terminal, helpful errors, examples in |
TTY, Colour & Interactivity, Self-Describing Help, TUIs vs. CLIs |
Scripts and CI |
Stable stdout, nothing on stdout but data, meaningful exit codes, no prompts, configuration through flags and environment variables, predictable installation. |
Streams & Exit Codes, Configuration & Auth, Packaging & Distribution |
AI agents |
Everything scripts need, plus JSON with a stable schema, small default outputs with pagination, errors that say what to do next, dry-run and confirmation for anything destructive, a machine-readable description of the commands, and input validation that assumes the arguments came from a model. |
Machine-Readable Output, Agent Ergonomics, Safety & Idempotency, Security |
The reading map
The pages can be read in any order, but this route works for most readers:
-
Start with CLI Design Fundamentals and Streams & Exit Codes; they are the foundation of everything else.
-
Read the agent-specific pages: Machine-Readable Output, Agent Ergonomics and Safety & Idempotency.
-
Pick your language on the framework pages, from Python to Swift & .NET.
-
Decide how the tool reaches the agent: CLI vs. MCP, wrapping as an MCP server or as an agent tool, and the Security rules that apply either way.
-
Ship it with Packaging & Distribution, Testing CLIs and Documenting CLIs, and review it against the Agent-Readiness Checklist.
Readers who only need a reminder can use the Cheat Sheet, which has a printable one-page PDF.
The docsctl running example
Every page uses the same small, fictional tool, docsctl, a command-line client for the documentation of this site. It exists only on these pages, its behaviour is illustrative, and its contract is repeated identically wherever it is used so that snippets in different languages stay comparable.
| Command | What it does | Safety |
|---|---|---|
|
Full-text search over the documentation; supports |
Read-only, idempotent |
|
Returns one page such as |
Read-only, idempotent |
|
Lists the documented components and their versions. |
Read-only, idempotent |
|
Checks a documentation tree for broken references and reports problems with a code, a line and a hint. |
Read-only, idempotent |
|
Publishes a component; |
Destructive, needs confirmation, idempotent with the same key |
|
Credentials, the machine-readable command tree, and shell completion. |
Credentials only, or read-only |
Every command accepts --json (or --format json|jsonl|text), --no-input, --yes, --timeout and --no-color,
writes data to stdout and messages to stderr, and ends with one of a small set of documented exit codes. A search looks
like this from a script or an agent:
docsctl search kalman --component irurueta-statistics --limit 3 --json --fields id,title,score
Output (illustrative):
{"nextCursor":null,"query":"kalman","results":[{"id":"irurueta-statistics::kalman.adoc","score":0.91,"title":"Kalman filter"}],"schemaVersion":1,"total":1,"truncated":false}
The primary implementations are in Python with Typer (Python CLI Frameworks)
and in Java with picocli, compiled to a native binary with GraalVM Native Image
(Java CLI Frameworks). Shorter equivalents cover
Node.js (commander),
Go and Rust (Cobra; clap, with a Ratatui interface and a Rig agent) and
Swift and .NET (swift-argument-parser with SwiftTUI;
System.CommandLine). The finished tool is then wrapped three ways: as an MCP server (Python FastMCP, the TypeScript SDK and
Spring AI @McpTool) on Wrapping a CLI as an MCP Server, and as a
LangChain @tool, a Spring AI @Tool and a LangChain4j @Tool on
Wrapping a CLI as an Agent Tool, which also shows using the CLI
directly from Claude Code and from Copilot agent mode.
Version baseline
Every version below was read from PyPI, npm, Maven Central, crates.io, the Go module proxy, NuGet, the projects' release pages and their official documentation on 2026-09-30. Each page repeats the subset it uses in its own lead paragraph, and facts that could not be confirmed, or snippets that could not be run in the environment used to write the pages (Go, Rust, .NET and GraalVM native compilation), are said so on the page that uses them. If a page and this baseline disagree after a later update, trust this baseline.
| Area | Versions |
|---|---|
Python |
Python 3.12 (the AI-section baseline); Typer 0.27.2, Click 8.5.0, Rich 15.0.0, Textual 8.2.8; |
Java |
Java 21; picocli and |
Node.js and TypeScript |
Node.js 24 LTS; commander 15.0.0, oclif 6.0.2, Ink 7.1.1; |
Go |
Go 1.27.1; Cobra v1.10.2 with pflag v1.0.10. |
Rust |
clap 4.6.7, |
Swift |
Swift 6.4; swift-argument-parser 1.8.2; SwiftTUI 0.1.0, whose repository has seen no push since 2024-07-09, so treat it as dormant. |
.NET |
System.CommandLine 2.0.12 (a 3.0.0 release candidate exists and is not used); Spectre.Console and Spectre.Console.Cli 0.57.2; .NET snippets were not compiled for these pages. |
Agents and MCP |
MCP specification revision 2026-07-28; the official Python |
What’s covered
The pages are grouped the same way as the navigation.
Fundamentals
-
CLI Design Fundamentals — the clig.dev principles, POSIX and GNU conventions, the 12 Factor CLI Apps checklist, subcommand design and naming, flags versus positional arguments and why ambiguous prefix matching is a trap.
-
Streams & Exit Codes — stdout for data and stderr for messages, piping, crash-only design and the exit-code taxonomy, including 126, 127 and 128+N.
-
TTY, Colour & Interactivity —
isatty,NO_COLOR, prompting only on a TTY,--no-inputand--yes, and progress output only on a terminal. -
Configuration & Auth — flag, environment, project, user and system precedence, XDG directories, and the token file, keychain and environment-variable trade-off.
Designing for agents
-
Machine-Readable Output —
--json, JSON Lines, field projection, deterministic ordering,schemaVersionand published JSON Schemas. -
Agent Ergonomics — token budgets, pagination with small defaults, truncation markers, errors that carry remediation, timeouts and fast startup.
-
Safety & Idempotency — read-only defaults,
--dry-runplans, the confirmation envelope,--forceand idempotency keys. -
Self-Describing Help —
--helpwritten for LLMs, a machine-readable command tree, completion, man pages and a bundled agent skill. -
CLI vs. MCP — an even-handed comparison, the
ghplus GitHub MCP server case study and when to ship both.
Frameworks by language
-
Python CLI Frameworks — argparse, Click, Typer, Rich and Textual.
-
Java CLI Frameworks — picocli, GraalVM Native Image, Spring Shell and JLine.
-
Node.js CLI Frameworks — commander, yargs, oclif and Ink.
-
Go & Rust CLI Frameworks — Cobra and Bubble Tea; clap, Ratatui and Rig.
-
Swift & .NET CLI Frameworks — swift-argument-parser and SwiftTUI; System.CommandLine and Spectre.Console.
-
TUIs vs. CLIs — when a full-screen interface helps and why agents still need a non-interactive mode.
Integration
-
Wrapping a CLI as an MCP Server — subcommands to tools, exit codes to
isError, JSON stdout tostructuredContent, in Python, TypeScript and Spring AI. -
Wrapping a CLI as an Agent Tool — narrow LangChain, Spring AI and LangChain4j tools versus a generic shell tool, and direct use from Claude Code and Copilot.
-
Security — argument injection, argv discipline, allowlists, least privilege, sandboxing and output sanitisation.
Shipping
-
Packaging & Distribution — pipx, Homebrew, npm, JBang, native binaries,
cargo install, winget, .NET tools, GoReleaser, containers, signing and checksums. -
Testing CLIs — golden tests of JSON output, no-TTY and exit-code tests, bats-core, framework test runners and agent evals.
-
Documenting CLIs — man pages and reference docs generated from the command tree, kept in sync from one source.
-
Agent-Readiness Checklist — a one-page review list linking every concept page.
-
Cheat Sheet — a grouped index of quick back-links and the printable one-page PDF.
Bibliography
The following sources were consulted while preparing this sub-section’s pages. Every command, flag, environment variable, package name, API name and version was checked against the projects' official documentation, specifications and package registries on 2026-09-30 — never copied from a book. Where something could not be confirmed or run, the page that cites it says so. Every URL cited on any page of this sub-section appears in this list.
Requester-provided books, consulted for tool-design principles only and never the source of an example:
-
Albada, Michael. Building Applications with AI Agents: Designing and Implementing Multiagent Systems. O’Reilly Media, 1st ed., Sep 2025. ISBN 978-1-098-17650-1. Publisher page: https://www.oreilly.com/library/view/building-applications-with/9781098176495/ . Official code repository: https://github.com/michaelalbada/BuildingApplicationsWithAIAgents . Consulted (Chapter 4) for stateful tools with least privilege, narrow parameterised operations, validation and logging, which inform the safety, security and agent-ergonomics pages.
-
Lanham, Micheal. AI Agents in Action. Manning Publications, 2025. ISBN 978-1-63343-634-3. Publisher page: https://www.manning.com/books/ai-agents-in-action . Official code repositories: https://github.com/cxbxmxcx/GPT-Agents , https://github.com/cxbxmxcx/GPTAssistantsPlayground and https://github.com/cxbxmxcx/Nexus . Consulted (Chapter 5) for designing semantic service layers that a model can consume, which inform the machine-readable-output and wrapping pages. Its Assistants-API code no longer runs.
oreilly.com answers automated fetches with an HTTP 403 response, but the publisher page above is a live page when
opened in a browser.
Official documentation
Guidelines for command-line tools:
-
Command Line Interface Guidelines (clig.dev), with the sections Help, Output and Interactivity (confirmation,
--force,--dry-run) -
12 Factor CLI Apps (an engineering article) and The Twelve-Factor App — Config
-
Microsoft — Console virtual terminal sequences and Microsoft — Console.IsOutputRedirected
Agent hosts and guidance:
-
Claude Code — Best practices, Claude Code — Run programmatically, Claude Code — MCP (output limits), Claude Code — Permissions, Claude Code — Sandboxing and Claude Code — Skills
-
Anthropic — Writing effective tools for agents, Anthropic — Building effective agents and Anthropic — Code execution with MCP
-
GitHub CLI manual, with formatting, environment variables and
gh auth login
MCP and tool wrapping:
Python:
-
argparse, json, signal (with the note on SIGPIPE), tomllib and urllib.request
-
Typer, with autocompletion, prompts, terminating and testing
-
Rich, with Console, Console reference and Progress display
Java:
Node.js:
-
commander.js, yargs, oclif (with Commands) and Ink
Go and Rust:
-
Cobra, with shell completion and documenting CLIs for LLMs; Bubble Tea
-
clap, clap_complete and clap_mangen
-
Ratatui, Rig and Rig on GitHub
Swift and .NET:
Packaging, signing and containers:
Testing and documentation:
Specifications and standards
-
POSIX — Utility Conventions and POSIX — Shell Command Language
-
GNU Coding Standards — Command-Line Interfaces and GNU
--help -
sysexits (FreeBSD manual; marked deprecated, used as vocabulary only)
-
RFC 8628 — OAuth 2.0 Device Authorization Grant and IETF Internet-Draft (expired, not an RFC) — The Idempotency-Key HTTP Header Field
-
MCP specification — Tools (latest), the 2026-07-28 revision and its Tools page
-
CWE-88 — Improper Neutralization of Argument Delimiters in a Command (Argument Injection)
Papers and engineering articles
-
Engineering blogs, practitioners' accounts rather than standards, cited as such: Arcjet — Designing a CLI for AI agents and Speakeasy — Engineering an agent-friendly CLI
-
Vendor articles, cited only as vendor claims and never restated as numbers here: Firecrawl — MCP vs. CLI and CircleCI — MCP vs. CLI
These books are consulted references, not the primary source of any example on this sub-section’s pages. On any discrepancy between a book and a tool’s own official documentation, that documentation is authoritative.