An AI agent does not read a GUI. It runs commands, reads stdout, checks the exit code, and decides what to do next. That loop only works when its tools behave predictably: structured output, no interactive prompts, and reliable success or failure signals.
The useful question is not “which CLI is most powerful?” It is “which CLI can an agent safely automate?” A CLI that prints a human-friendly table, asks Are you sure? (y/n), or exits 0 after a failed operation will cause brittle agent workflows.
This guide covers two categories:
- Agent runtimes: coding CLIs that run the agent loop, including Claude Code, Codex CLI, Gemini CLI, and Cursor CLI.
-
Tool CLIs: commands agents use to interact with repositories, files, JSON, HTTP APIs, and API projects:
gh, ripgrep, jq, HTTPie, and apidog-cli.
For API automation, see the Apidog CLI complete guide for a full setup walkthrough.
What makes a CLI good for AI agents?
Before adding a CLI to an agent workflow, verify these three properties.
1. Structured output
Agents should parse fields, not infer meaning from formatted text.
Prefer:
tool --json
tool --output-format json
Over output such as:
NAME STATUS UPDATED
api-prod healthy 2 minutes ago
JSON lets an agent access stable values by key:
command --json | jq -r '.status'
2. Non-interactive execution
A command that pauses for confirmation can hang a headless process indefinitely.
Look for flags such as:
--non-interactive
--yes
--force
--print
--exec
Your automation should pass every required input up front.
3. Deterministic exit codes
Use the shell exit code as the primary success signal:
if command --run-task; then
echo "Task succeeded"
else
echo "Task failed"
exit 1
fi
A reliable CLI exits 0 on success and a non-zero value on failure. Parse output for details, but branch on exit codes.
Some tools also provide actionable metadata for the next command. That is uncommon, and it is where apidog-cli differs from most general-purpose CLIs.
Claude Code
Claude Code is Anthropic’s terminal coding agent. Use -p for print mode to run the agent without its terminal UI.
npm install -g @anthropic-ai/claude-code
claude -p "summarize the failing tests in this repo" \
--output-format json
Use JSON output when another process needs the result:
claude -p "list likely causes of the build failure" \
--output-format json \
| jq -r '.result'
The JSON payload includes the result, a session_id, and total_cost_usd, which can help a calling script track runs and spend. For streaming events, use stream-json with --verbose.
You can also pipe context into Claude Code:
cat build-error.txt | claude -p "explain this error"
Best for: Multi-step coding tasks where an agent plans, executes, and returns machine-readable output.
Implementation note: Capture the exit code and persist the session_id if your workflow needs to correlate retries or follow-up work.
Limits: Claude Code uses a paid, closed model behind an API. Costs can grow during long autonomous runs.
Codex CLI
Codex CLI is OpenAI’s open-source terminal agent. Use codex exec (or codex e) for non-interactive runs.
npm install -g @openai/codex
codex exec --json "add input validation to the signup handler"
Its --json output is JSONL: each command, file change, and agent message is emitted as a structured event.
Extract only the events you need:
codex exec --json "inspect the test failures" \
| jq 'select(.type == "item.completed")'
For jobs that need a stable final payload, provide an output schema:
codex exec \
--json \
--output-schema ./job-summary.schema.json \
"fix the failing tests and return a summary"
Best for: CI-driven code changes that need typed or schema-validated output.
Implementation note: Treat the event stream as an event log. Use jq to filter it before passing results to another command.
Limits: JSONL is verbose, and schema-constrained output should be tested against the prompts your automation actually sends.
Gemini CLI
Gemini CLI is Google’s open-source terminal agent. It runs headlessly in non-TTY environments and also supports explicit non-interactive mode.
npm install -g @google/gemini-cli
gemini --non-interactive \
--output-format json \
-p "list the public endpoints in this service"
Parse the response field in a pipeline:
gemini --non-interactive \
--output-format json \
-p "summarize the API authentication flow" \
| jq -r '.response'
Use --non-interactive in CI even if the command appears to work without it. This makes the intent explicit and prevents future prompts from blocking the job.
Best for: Google-stack environments and read-heavy codebase inspection tasks.
Implementation note: Pin the Gemini CLI version in CI and verify its JSON flags during upgrades.
Limits: Structured JSON output arrived later than in some alternatives, so validate behavior before depending on it in production workflows.
Cursor CLI
Cursor’s cursor-agent runs its coding agent independently of the editor. Use -p or --print to run it headlessly.
curl https://cursor.com/install -fsS | bash
cursor-agent -p "refactor utils/date.js to use date-fns" \
--output-format json
Choose an output format based on how your pipeline consumes results:
# One final JSON object
cursor-agent -p "review the changed files" --output-format json
# Stream structured events
cursor-agent -p "review the changed files" --output-format stream-json
In headless environments, use --trust only when the agent should be allowed to write files or run shell commands without pausing.
cursor-agent --trust \
-p "update the failing unit tests" \
--output-format json
Best for: Teams already using Cursor that want editor-to-CI agent parity.
Implementation note: Run this in a disposable branch or worktree, use least-privilege credentials, and review diffs before merging.
Limits: Some users have reported hangs in headless -p mode on specific builds or platforms. Test on your target OS and pin a known-good version.
gh (GitHub CLI)
gh is the primary CLI for agent workflows that touch GitHub repositories, issues, pull requests, and releases.
brew install gh
gh pr list --json number,title,author \
--jq '.[].author.login'
Request only the fields your agent needs:
gh issue list \
--json number,title,state,labels \
--jq '.[] | select(.state == "OPEN") | {number, title}'
For API operations not covered by a built-in command, use gh api:
gh api repos/OWNER/REPO/pulls \
--jq '.[] | {number, title, state}'
You can discover supported JSON fields by running a compatible command with --json and no field list.
Best for: GitHub operations such as reading PR state, creating issues, and querying release metadata.
Implementation note: Request narrow field lists to reduce parsing work and avoid relying on human-formatted output.
Limits: gh is GitHub-specific, and available --json fields vary by subcommand.
ripgrep
ripgrep (rg) is a fast code-search tool. Use --json when an agent needs to identify exact paths, lines, and match contents safely.
brew install ripgrep
rg --json "TODO" src/ \
| jq 'select(.type == "match") | .data.path.text'
Extract match metadata without splitting file:line:text strings:
rg --json "deprecated" src/ \
| jq -r '
select(.type == "match") |
"\(.data.path.text):\(.data.line_number):\(.data.lines.text)"
'
Each match is a typed JSON event. This is safer than parsing plain grep output, especially when file paths or source text contain colons.
Best for: Fast structured code search before an agent decides what to inspect or edit.
Implementation note: Filter for .type == "match" because ripgrep also emits begin, end, and summary events.
Limits: JSON output is verbose. Use plain text mode for quick human-driven searches.
jq
jq is the JSON transformation layer for the rest of the toolchain.
brew install jq
curl -s https://api.github.com/repos/cli/cli \
| jq '{name, stars: .stargazers_count}'
Use it to reshape one tool’s output into the next tool’s input:
gh pr list --json number,title \
| jq -r '.[] | "\(.number): \(.title)"'
Use strict shell behavior when jq is part of a deployment or CI gate:
set -euo pipefail
gh pr list --json number,title \
| jq -e 'length > 0'
The -e flag makes jq return a non-zero exit code when the final result is false or null.
Best for: Filtering, validating, and reshaping JSON between commands.
Implementation note: Use jq -e when a JSON condition should control whether the pipeline succeeds.
Limits: jq processes JSON only, so pair it with JSON-capable tools rather than raw log output.
HTTPie
HTTPie (http) is useful when an agent needs to call an HTTP API directly. It defaults to JSON-friendly request handling.
brew install httpie
http --print=b POST httpbin.org/post \
name=apidog \
role=cli
Use --print=b to send only the response body to stdout:
http --print=b GET https://api.github.com/repos/cli/cli \
| jq '{name, stars: .stargazers_count}'
HTTPie converts key=value arguments into JSON request fields, avoiding hand-built JSON strings:
http --print=b POST https://example.com/api/users \
name="Ada" \
role="developer"
Best for: Scriptable JSON API calls where readability matters.
Implementation note: Use --print=b when another command will parse the response. This avoids mixing headers and body content.
Limits: curl is more universally installed and remains the better fallback for streaming or uncommon protocols.
apidog-cli
Most CLIs were designed for humans first and added JSON later. apidog-cli is designed around structured JSON output and includes agentHints.nextSteps in responses, giving a calling agent explicit suggestions for what it can do next.
It manages API endpoints, schemas, mocks, environments, imports, exports, documentation, test scenarios, and branches.
Install and authenticate:
npm install -g apidog-cli
apidog login --with-token <YOUR_TOKEN>
apidog run --help
Use the command exit code as a test gate:
if apidog run; then
echo "All API tests passed"
else
echo "API tests failed"
exit 1
fi
apidog run exits 0 when every test passes and non-zero when any test fails. That lets an agent or CI job branch without trying to infer test status from formatted output.
The structured response can also include next-step hints, which is useful when chaining API lifecycle tasks. See:
For safer write operations, create an isolated AI branch:
apidog branch --type ai
An AI Branch keeps agent edits separate from the source branch until you approve a merge request. This helps prevent an agent with write access from accidentally overwriting live endpoints or schemas.
For implementation patterns, see:
Best for: A single JSON-native CLI for API lifecycle work, including testing, documentation, mocks, and isolated agent edits.
Implementation note: Give agents isolated branches and require a review step before merging changes into a shared API project.
Limits: Apidog is a commercial product with a free tier and is not open source. It also does not provide an OpenAPI linter, so use Spectral or Redocly when style enforcement is required.
How to choose
Use one agent runtime to plan and execute work, then give it a focused toolkit.
| Tool | Best for | Install | Open source? | Agent-fit feature |
|---|---|---|---|---|
| Claude Code | Multi-step coding and planning | npm i -g @anthropic-ai/claude-code |
No |
-p and --output-format json
|
| Codex CLI | Schema-typed CI code changes | npm i -g @openai/codex |
Yes |
codex exec --json, --output-schema
|
| Gemini CLI | Google-stack and read-heavy tasks | npm i -g @google/gemini-cli |
Yes | --non-interactive --output-format json |
| Cursor CLI | Cursor teams and editor-to-CI workflows | `curl cursor.com/install \ | bash` | No |
| gh | GitHub operations | brew install gh |
Yes |
--json and built-in --jq
|
| ripgrep | Structured code search | brew install ripgrep |
Yes |
--json typed match events |
| jq | JSON reshaping and validation | brew install jq |
Yes | Deterministic pipeline transformations |
| HTTPie | Scriptable JSON API calls | brew install httpie |
Yes | JSON-first requests and --print
|
| apidog-cli | API lifecycle automation | npm i -g apidog-cli |
No, free tier | Native JSON and agentHints.nextSteps
|
A practical baseline for a coding agent looks like this:
# Search code
rg --json "TODO|FIXME" src/ | jq 'select(.type == "match")'
# Read GitHub state
gh pr list --json number,title,state
# Run API checks
apidog run
# Let the agent summarize or plan the next change
claude -p "review the command output and propose the next action" \
--output-format json
For API workflows, stitching together curl, a mock server, and a test runner can work. A JSON-native CLI that manages the project lifecycle and exposes next-step hints reduces the glue code an agent must maintain.
Wrapping up
Agent-friendly CLIs have three concrete properties:
- Structured output that software can parse.
- Non-interactive execution that cannot block on prompts.
- Reliable exit codes that automation can branch on.
The runtimes—Claude Code, Codex CLI, Gemini CLI, and Cursor CLI—provide reasoning and execution. The tool CLIs—gh, ripgrep, jq, HTTPie, and apidog-cli—give them reliable ways to interact with repositories, code, JSON, HTTP, and APIs.
apidog-cli is notable for API workflows because it starts with structured JSON, provides deterministic test exit codes, and can expose agentHints.nextSteps for chained automation. If your agent touches APIs, download Apidog and try the CLI, or begin with the Apidog CLI complete guide. Then wire it into CI, where machine-readable output is most valuable.
Top comments (0)