ai-friendly-cli
AI-Friendly CLI
Overview
Human DX optimizes for discoverability and forgiveness. Agent DX optimizes for predictability and defense-in-depth. These require fundamentally different design approaches.
This skill provides 8 principles for building or refactoring command-line interfaces so that AI agents can invoke them reliably, safely, and efficiently. The core insight: agents hallucinate inputs, pay per token, and can't read interactive prompts. Your CLI must defend against all three.
When to Use
Use this skill when:
- Adding AI/agent support to an existing CLI tool
- Building a new CLI that agents will invoke
- Wrapping an API as a CLI tool (REST, GraphQL, gRPC)
- Designing MCP servers alongside CLI interfaces
- Hardening inputs against hallucinated or malformed agent inputs
- Reducing token cost by limiting response sizes
- Adding structured output (JSON, NDJSON) to human-oriented CLIs
The 8 Principles
1. Structured JSON I/O
Support --json for structured input payloads and --output json for machine-readable output. When stdout is not a TTY, default to NDJSON.
Why: Agents parse structured data. Tabular or prose output requires brittle regex parsing that breaks across versions.
Example -- instead of 10 separate flags:
# Human-friendly (many flags)
cli create-issue --title "Bug" --assignee alice --priority high --label bug
# Agent-friendly (single structured payload)
cli create-issue --json '{"title":"Bug","assignee":"alice","priority":"high","labels":["bug"]}'
Both should produce structured output:
cli create-issue --json '{"title":"Bug"}' --output json
# {"id":"ISS-42","title":"Bug","status":"open","url":"https://..."}
2. Schema Introspection
Make the CLI self-documenting with machine-readable method signatures. Add a schema subcommand or --describe flag that returns parameters, types, and constraints as JSON.
Why: Agents need to know what parameters exist, what types they accept, and what values are valid -- without parsing --help prose.
Example:
cli schema issues.create
# {
# "method": "issues.create",
# "params": {
# "title": {"type": "string", "required": true},
# "assignee": {"type": "string", "enum": ["alice","bob"]},
# "priority": {"type": "string", "enum": ["low","medium","high"]}
# }
# }
The CLI becomes the canonical source of truth, eliminating stale documentation.
3. Context Window Discipline
Agents pay per token. API responses can be massive. Support field masks and streaming pagination to keep responses lean.
Key patterns:
--fields "id,name,status"-- return only specified fields--page-all-- stream all pages as NDJSON instead of buffering entire arrays--limit N-- cap result count
Example:
# Without field mask: 50 fields per issue, 100 issues = thousands of tokens
cli issues list --output json
# With field mask: 3 fields per issue = fraction of tokens
cli issues list --output json --fields "id,title,status"
4. Input Hardening
Agents hallucinate. The CLI is the last line of defense before bad data reaches your API or filesystem.
Validate and reject:
- Path traversals:
../../etc/passwd,../.ssh/id_rsa - Control characters: bytes 0x00-0x1F in any string input
- Malformed resource IDs: values containing
?,#,% - URL injection: always percent-encode path segments; never use string interpolation
Example:
# Agent hallucinates a path traversal
cli files get --path "../../.ssh/id_rsa"
# {"error":"invalid_path","code":"PATH_TRAVERSAL","message":"path must not contain '..'"}
# Agent hallucinates control characters
cli issues create --json '{"title":"test\x00inject"}'
# {"error":"invalid_input","code":"CONTROL_CHAR","message":"input contains control characters"}
5. Safety Rails
Provide mechanisms for agents to validate operations before executing them, and for defending against prompt injection in response data.
Key patterns:
--dry-run-- validate inputs and show what would happen, without executing--sanitize-- strip or escape potentially dangerous content from responses (prompt injection defense)- Always confirm with the user before mutations
Example:
# Dry-run: validate and preview without side effects
cli issues delete ISS-42 --dry-run
# {"action":"delete","target":"ISS-42","status":"valid","would_delete":true}
# Sanitize: defend against prompt injection in response data
cli issues get ISS-42 --sanitize template
# Strips sequences like "IGNORE ALL PREVIOUS INSTRUCTIONS" from response fields
6. Structured Errors
Return JSON errors with codes and reasons on stdout. Print human-friendly hints on stderr. Agents parse stdout; humans read stderr. Never mix prose with JSON on the same stream.
Example:
cli issues get NONEXISTENT --output json
# stdout: {"error":"not_found","code":"ISSUE_NOT_FOUND","message":"Issue NONEXISTENT does not exist"}
# stderr: Hint: Run `cli issues list` to see available issues.
# exit code: 1
Error JSON structure:
{
"error": "category_name",
"code": "SPECIFIC_ERROR_CODE",
"message": "Human-readable description",
"details": {}
}
7. Agent Documentation
Ship documentation alongside the CLI that encodes invariants an agent cannot discover from --help alone.
Key files:
SKILL.md-- Activation triggers and common workflowsAGENTS.mdorCONTEXT.md-- Non-obvious rules, gotchas, required sequences- Schema introspection (Principle 2) for runtime discovery
What to document:
- "Always use
--dry-runbefore any mutation" - "Always use
--fieldsfor list operations to control token cost" - "Never pass user-provided strings directly as
--jsonwithout escaping" - Required ordering of operations (e.g., authenticate before query)
- Rate limits and retry semantics
8. Multi-Surface Architecture
One core binary, multiple interfaces: CLI for humans, MCP (JSON-RPC over stdio) for agents, environment variables for headless authentication.
Architecture:
+------------------+
| Core Library |
+------------------+
/ | \
CLI MCP Server REST API
(humans) (agents) (services)
Key patterns:
- CLI and MCP share the same validation, business logic, and error handling
- CLI reads flags/args; MCP reads JSON-RPC params; both call the same core
- Auth via
CLI_TOKENenv var (headless) or interactive OAuth (human) - MCP enables richer agent integration (streaming, tool registration)
Implementation Priority
Start here, in order. Each step builds on the previous:
- Add
--output jsonfor machine-readable output on all commands - Validate all inputs -- reject control characters, path traversals, embedded query params
- Add
schemaor--describecommand for runtime introspection - Support
--fieldsto limit response size and token cost - Add
--dry-runfor validation before any mutation - Ship
CONTEXT.mdor skill files encoding non-obvious invariants - Expose MCP surface for API-wrapping CLIs
Quick Reference
| Flag / Pattern | Purpose | Example |
|---|---|---|
--output json |
Machine-readable output | cli list --output json |
--json '{...}' |
Structured input payload | cli create --json '{"title":"Bug"}' |
--fields |
Field masks (limit response) | cli list --fields "id,name" |
--dry-run |
Validate without executing | cli delete --dry-run |
--page-all |
Stream all pages as NDJSON | cli list --page-all |
schema / --describe |
Schema introspection | cli schema method.name |
--sanitize |
Response sanitization | cli get --sanitize template |
--limit N |
Cap result count | cli list --limit 50 |
Anti-Patterns
Avoid these when building agent-friendly CLIs:
- Mixing prose with JSON on stdout -- agents cannot reliably parse mixed output
- Trusting agent inputs -- validate everything; agents hallucinate paths, IDs, and parameters
- String interpolation for URLs -- use URL builders to prevent injection
- Auto-executing destructive operations -- always require confirmation or
--dry-runfirst - Outputting secrets to stdout -- tokens, keys, and passwords should never appear in structured output
- Creating alias-only helpers -- wrappers must add real value (validation, structured output), not just alias existing commands
- Unbounded responses -- always support field masks and pagination; agents pay per token
- Interactive prompts -- agents cannot respond to interactive stdin; use flags or
--jsoninstead
Advanced Reference
For detailed patterns and implementation guidance, see:
- Output Patterns -- JSON, NDJSON, field masks, dual-channel (stdout/stderr)
- Input Hardening -- Path safety, URL encoding, control character validation
- Safety Patterns -- Dry-run implementation, sanitization, confirmation flows
- Architecture -- Multi-surface design, schema introspection, MCP integration
Attribution
- Blog: "Rewrite your CLI for AI Agents" by Justin Poehnelt
- Reference implementation: Google Workspace CLI (gws)
More from dashed/claude-marketplace
playwright
Browser automation with Playwright for Python. Use when testing websites, taking screenshots, filling forms, scraping web content, or automating browser interactions. Triggers on browser, web testing, screenshots, selenium, puppeteer, or playwright.
22tmux
Remote control tmux sessions for interactive CLIs (python, gdb, git add -p, etc.) by sending keystrokes and scraping pane output. Use when debugging applications, running interactive REPLs (Python, gdb, ipdb, psql, mysql, node), automating terminal workflows, interactive git commands (git add -p, git stash -p, git rebase -i), or when user mentions tmux, debugging, or interactive shells.
11zellij
Terminal workspace and multiplexer for interactive CLI sessions. Use when managing terminal sessions, running interactive REPLs, debugging applications, automating terminal workflows, or when user mentions zellij, terminal multiplexer, floating panes, or session layouts. Simpler alternative to tmux with native session management.
2chrome-cdp
Interact with local Chrome browser session via Chrome DevTools Protocol. Use when asked to inspect, debug, or interact with a page open in Chrome, take screenshots of browser tabs, read accessibility trees, evaluate JavaScript, click elements, navigate pages, or automate browser interactions in a live Chrome session.
2mermaid-cli
Generate, validate, and fix diagrams from Mermaid markup using the mermaid-cli (mmdc) tool. Use when creating flowcharts, sequence diagrams, class diagrams, state diagrams, ER diagrams, Gantt charts, pie charts, mindmaps, or any Mermaid-supported diagram type. Also use when validating, verifying, or fixing Mermaid diagram syntax. Triggers on mentions of mermaid, mmdc, diagram generation, diagram validation, or converting .mmd files to images/SVG/PDF.
2design-principles
Guide AI-assisted UI generation toward enterprise-grade, intentional design. Use when building user interfaces, creating dashboards, designing enterprise software or SaaS applications, generating frontend code with styling, or when the user asks for design help. Enforces principles inspired by Linear, Notion, Stripe, and Vercel.
2