Complete coverage, zero effort
- Every endpoint becomes a CLI command
- Params, query strings, bodies mapped to typed
--flags - Help text auto-generated from spec descriptions
Point OnlyCLI at any OpenAPI spec. Get a native binary with every operation as a typed command -- flags, help text, pagination, and shell completion included.
go install github.com/onlycli/onlycli/cmd/onlycli@latest
$ onlycli generate --spec api.github.com.yaml --name github --auth bearer --out ./gh Generated CLI project at ./gh Groups: 43 Commands: 1107 Auth: bearer (env: GITHUB_TOKEN) $ cd gh && go build -o gh . && ./gh repos get --owner golang --repo go {"id":23096959,"name":"go","full_name":"golang/go","stargazers_count":128000,...} $ ./gh issues list-for-repo --owner golang --repo go --state open --format table ID TITLE STATE CREATED 71234 proposal: spec: add ... open 2025-12-01 71198 cmd/go: module cache ... open 2025-11-30
$ go install github.com/onlycli/onlycli/cmd/onlycli@latest
$ onlycli generate \
--spec your-api.yaml \
--name myapi --out ./cli
$ cd cli && go build -o myapi . $ ./myapi --help $ ./myapi users list --format table
Every operation in your spec becomes a command. Every parameter becomes a flag. That's it.
--flags--help to discover commandsNot just commands and flags. Generated CLIs ship with the features you'd build yourself -- so you don't have to.
--format json|yaml|table|csv|pretty|jsonl|raw -- tables, JSON, or diff-friendly YAML.
--transform "#.full_name" -- project fields inline without reaching for jq.
--page-limit 10 auto-detects Link header, cursor, offset, and page-number schemes. One flag, complete results.
--data @payload.json or --data @- for stdin. Readable commands, repeatable CI.
Device flow for login, client credentials for CI. Tokens saved per profile.
--profile staging -- switch dev, staging, and prod without re-exporting secrets.
--max-retries 3 -- exponential backoff for 429s and 5xx. Respects Retry-After.
--dry-run -- prints method, URL, headers, body without sending.
Bash, zsh, fish, PowerShell. Enums surface as completion candidates.
--template '{{.login}}' -- custom formatting beyond field projection.
--name.first John -- builds nested JSON, no heredocs needed.
Multiplexed requests, auto gzip decompression out of the box.
The full GitHub API spec has 1,107 operations across 43 groups. OnlyCLI generates a complete CLI in under 5 seconds.
# Generate from the official GitHub spec $ onlycli generate \ --spec https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.yaml \ --name github --auth bearer --out ./github-cli # Build and authenticate $ cd github-cli && go build -o gh . $ export GITHUB_TOKEN=ghp_xxx # List repos as a table $ ./gh repos list-for-user --username octocat --format table # Create an issue with flags $ ./gh issues create --owner myorg --repo myrepo --title "Bug" --body "Details here" # Search with field projection $ ./gh search repos --q "language:go stars:>1000" --sort stars --transform "#.full_name" # Paginate automatically $ ./gh repos list-for-user --username octocat --page-limit 5 --format csv
| OnlyCLI | curl | Restish | MCP tools | |
|---|---|---|---|---|
| Typed commands per endpoint | Yes | No | Yes | Varies |
| Single binary, no runtime | Yes | Yes | Yes | No |
| Table / YAML / CSV output | Yes | No | No | No |
| Auto-pagination (Link, cursor, offset) | Yes | No | No | No |
| GJSON field transforms | Yes | No | No | No |
| Works offline, no server | Yes | Yes | Yes | No |
| 35x fewer tokens than MCP | ~200 tok | Low | Low | 55K+ tok |
| Streaming (SSE / NDJSON) | Yes | Manual | No | Varies |
Detailed comparisons: vs Stainless · vs Restish · vs curl/HTTPie
A GitHub MCP server loads 55,000 tokens into every prompt. Three services eat 72% of your context window on idle. OnlyCLI generates a binary that agents call like any command -- --help costs ~200 tokens. See the full cost breakdown.
# Agent discovers available commands $ ./gh --help $ ./gh repos --help # Agent calls a specific operation $ ./gh repos get --owner golang --repo go --format json # Agent reads structured JSON from stdout {"id":23096959,"name":"go","full_name":"golang/go",...}
Stable names. Predictable flags. Structured output. The agent learns the surface once, not on every turn.
Contributions welcome -- bug reports, new features, and docs improvements all help.