.agents/skills/cli-for-agent/SKILL.md
Design and build CLI tools optimized for AI agent consumption. Use this skill when creating a new CLI command, refactoring an existing CLI for agent compatibility, or reviewing whether a CLI follows agent-friendly design principles.
npx skillsauth add agentlyhq/use-agently cli-for-agentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill when:
Agents are not humans. They cannot see colors, navigate interactive menus, interpret spinner animations, or respond to TTY prompts. A CLI built for agents must communicate entirely through structured text on stdout, clear error messages on stderr, and meaningful exit codes. If an agent can't parse your output or recover from your errors in one retry, your CLI has failed.
Never use interactive prompts, confirmation dialogs, readline, cursor movement, or progress spinners. Every command must run unattended in scripts, CI pipelines, and agent tool-call chains without a terminal.
# Bad — blocks waiting for input
Are you sure? [y/N]
# Good — flag-driven, no interaction
$ my-cli delete --confirm resource-id
If a command is destructive, require an explicit --confirm or --yes flag instead of prompting.
TTY-only decoration. Colors, boxes (boxen), tables, spinners, and progress bars are fine — but only when stdout is a TTY. When piped, output must be plain. Check isatty(stdout) (or your language's equivalent) and strip all decoration when it returns false. Never use box-drawing libraries like boxen in non-TTY mode — they break grep and head.
Your output will be piped through head, tail, grep, jq, awk, and wc. Every design decision flows from this.
One record per line. Each line must be a self-contained unit of meaning. This is the single most important rule — it makes every standard Unix tool work for free.
For a single object response, emit one compact JSON line:
$ my-cli status --output json
{"name":"my-service","status":"running","uptime_seconds":13320}
Use NDJSON when printing arrays or large collections. When a command returns a list, array, or any potentially large collection of records, use NDJSON (Newline-Delimited JSON) — one JSON object per line, no wrapping array. This lets consumers stream, grep, and slice without buffering or parsing the entire output.
# NDJSON — each line is independently parseable
$ my-cli list --output json
{"id":"svc-1","name":"api","status":"running"}
{"id":"svc-2","name":"worker","status":"stopped"}
{"id":"svc-3","name":"gateway","status":"running"}
# Standard tools just work:
$ my-cli list --output json | head -1 # first record
$ my-cli list --output json | tail -5 # last 5 records
$ my-cli list --output json | grep '"running"' # filter without jq
$ my-cli list --output json | wc -l # count records
Avoid wrapping collections in a JSON array ([{...},{...}]). An array forces the consumer to load and parse the entire output before accessing any single record.
When to use NDJSON vs a single JSON object:
stdout is for data only — no banners, tips, decorative boxes, or log messages. stderr is for diagnostics — progress info, warnings, and debug messages go to stderr. Mixing the two corrupts pipelines.
Consistent shape — the same command should always return the same JSON schema, using null for missing fields rather than omitting keys. Agents hardcode parsers against your schema.
Error messages must include enough context for the caller to succeed on the next attempt. A third attempt means your error message failed.
Every error should include:
# Bad
Error: invalid argument
# Good
Error: <uri> must be a URL (e.g. https://api.example.com/agents/echo)
or a registered short name (e.g. echo-agent).
Run 'my-cli list' to see available agents.
The CLI must describe itself without external documentation:
my-cli, my-cli --help, and my-cli help should all print the full command listing--help output$ my-cli --help
Usage: my-cli <command> [options]
Lifecycle:
init Initialize configuration
doctor Run health checks
whoami Show current identity
Resources:
list List available resources
get <id> Get a resource by ID
create Create a new resource
Run 'my-cli <command> --help' for details on a specific command.
Use exit codes so agents can detect success or failure without parsing output:
| Code | Meaning |
| ---- | ------------------------------------------- |
| 0 | Success |
| 1 | General error (bad input, failed operation) |
| 2 | Usage error (missing argument, bad flag) |
Always exit non-zero on failure. Never print "error" to stdout and exit 0.
Agents may retry commands. Design commands to be safe to re-run:
create should succeed or return the existing resource if it already exists (or offer --if-not-exists)delete should succeed even if the resource is already goneconfig set should be a no-op if the value is already setUse consistent patterns across all commands:
my-cli <noun> <verb> [arguments] [--flags]
# or
my-cli <verb> <noun> [arguments] [--flags]
Pick one pattern and stick with it. Common flag conventions:
--output <format> or -o <format> — output format (json, text, csv)--yes or --confirm — skip confirmation for destructive actions--quiet or -q — suppress non-essential output--verbose or -v — increase log detail (to stderr)Centralize output formatting so every command behaves consistently. Create a shared helper that all commands call:
--output json, emit one JSON object per line (NDJSON) to stdout--output text (default), write human-readable key-value lines to stdoutOptimize cold-start time. Agents invoke CLIs hundreds of times in a session — a 500ms startup penalty compounds fast.
Wrap errors in a consistent format that agents can parse and act on. Every error path should:
# Example error output (on stderr):
Error: "foobar" is not a valid URI.
Hint: Provide a full URL (e.g. https://example.com/api) or a short name
(e.g. my-agent). Run 'my-cli list' to see available options.
Never crash on missing config. Return sensible defaults so commands work out of the box:
--help output| Anti-Pattern | Why It Breaks Agents |
| ------------------------------ | --------------------------------------------------------- |
| Interactive prompts | Agents cannot type into stdin on demand |
| Box drawing (boxen, borders) | Breaks grep, head, tail — unparseable decoration |
| Colors/ANSI when piped | Pollutes parsed output; only use when stdout is a TTY |
| Spinners and progress bars | Interfere with stdout parsing |
| Paging (less, more) | Blocks execution waiting for keypress |
| Mixed data and logs on stdout | Agents can't separate data from noise |
| JSON arrays for collections | Forces loading entire output; use NDJSON for lists/arrays |
| Multi-line pretty-printed JSON | Breaks grep and wc -l; one record = one line |
| Inconsistent JSON shape | Agents hardcode parsers against your schema |
| Exit 0 on error | Agents assume success and proceed with bad state |
| Vague error messages | Agents waste retries guessing what went wrong |
| Slow startup (heavy imports) | Compounds across hundreds of agent invocations |
| Required env vars without docs | Agents can't discover implicit dependencies |
When reviewing or testing an agent-facing CLI, verify:
echo "" | my-cli command doesn't hang)my-cli list --output json | head -1 returns a valid, self-contained JSON objectmy-cli list --output json | grep "keyword" returns valid JSON lines--help includes at least one usage example per commandtools
Discover (by searching) to use thousands of AI agents, MCP, tools, data sources, and APIs on the use-agently.com AI Agent Marketplace/Directory. You can get more effective "Web Search", "Web Fetch" or "Social Search" with use-agently. Sending messages via the A2A protocol, calling MCP tools, making HTTP/Web requests, or interacting with paid agents supporting x402 micropayments.
tools
Create a new CLI command for the use-agently CLI. Use this skill when implementing a new command, subcommand, or protocol handler in the packages/use-agently package following the CLI design specification.
tools
Build, run, and deploy an AI agent using the aixyz framework. Use this skill when creating a new agent, adding tools, wiring up A2A/MCP protocols, configuring x402 micropayments, or deploying to Vercel.
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.