Turn any OpenAPI 3.x or Swagger 2.0 spec into a fully functional CLI — instantly, no code generation required.
openapi2cli reads a spec file at runtime and dynamically generates a CLI with resource-based commands, typed flags, authentication, and formatted output.
Download the archive for your platform from the releases page, extract it, and put openapi2cli on your PATH.
go install github.com/s04/openapi2cli@latestgit clone https://github.com/s04/openapi2cli.git
cd openapi2cli
go build -o openapi2cli .# Point at any spec and explore
openapi2cli --spec petstore.json --help
# Make a request
openapi2cli --spec petstore.json --server https://petstore.io/api/v3 \
pet find-pets-by-status --status available
# Load specs from URLs
openapi2cli --spec https://petstore.swagger.io/v2/swagger.json \
store get-inventorySave connection details so you don't repeat yourself:
# Create a profile
openapi2cli config set-profile myrouter \
--spec /path/to/spec.json \
--server https://192.168.1.1/rest \
--auth-type basic \
--auth-username admin \
--auth-password "" \
--insecure
# Use it
openapi2cli --profile myrouter interface get-interface
openapi2cli --profile myrouter ip get-ip-address -o table
# Manage profiles
openapi2cli config list
openapi2cli config show myrouter
openapi2cli config delete-profile myrouterSupports API key, Bearer token, and HTTP Basic auth via flags, environment variables, or profiles:
# Basic auth
openapi2cli --spec api.json --server https://host \
--username admin --password secret resource list
# Bearer token
openapi2cli --spec api.json --server https://host \
--token eyJhbGci... resource list
# API key
openapi2cli --spec api.json --server https://host \
--api-key "MyToken=abc123" resource listResources come from the spec's tags (or the first path segment when untagged), operations from operationId, and flags from parameter names. All are converted to lowercase kebab-case, so petId becomes --pet-id and the tag Access applications becomes access-applications.
Every operation's --help lists its flags with the spec's descriptions, required markers, and allowed enum values.
If a spec parameter would collide with one of the CLI's own flags (for example a query parameter called token), it is exposed as --param-token.
# Raw JSON body
openapi2cli --profile myapi resource create \
--data '{"name": "example", "enabled": true}'
# Body from file
openapi2cli --profile myapi resource create \
--data-file ./payload.json
# Individual body property flags
openapi2cli --profile myapi resource create \
--body-name example --body-enabled true
# Array properties: repeat the flag, comma-separate, or pass a JSON array
openapi2cli --profile myapi resource create \
--body-tags a,b --body-tags c
openapi2cli --profile myapi resource create \
--body-items '[{"id": 1}, {"id": 2}]'
# Object properties take a JSON object
openapi2cli --profile myapi resource create \
--body-category '{"id": 1, "name": "dogs"}'--data and --data-file take precedence over --body-* flags.
openapi2cli --profile myapi resource list -o json # default, pretty-printed
openapi2cli --profile myapi resource list -o yaml # YAML
openapi2cli --profile myapi resource list -o table # ASCII table
openapi2cli --profile myapi resource list -o raw # raw response body# See the HTTP request without sending it
openapi2cli --profile myapi resource list --dry-run
# Verbose mode — request/response headers on stderr
openapi2cli --profile myapi resource list -v
# Skip TLS verification (self-signed certs)
openapi2cli --spec api.json --server https://host -k resource list# Bash
openapi2cli completion bash >> ~/.bashrc
# Zsh
openapi2cli completion zsh >> ~/.zshrc
# Fish
openapi2cli completion fish > ~/.config/fish/completions/openapi2cli.fish| System | Spec Version | Endpoints | Status |
|---|---|---|---|
| MikroTik RouterOS 7.22 | Swagger 2.0 | 6,184 | Working |
| TrueNAS SCALE 24.04 | OpenAPI 3.0 | 643 | Working |
| Proxmox VE | OpenAPI 3.0 | 61+ | Working |
| OPNsense 25.7 | OpenAPI 3.0 | 701 | Working |
| Swagger Petstore v2 | Swagger 2.0 | 20 | Working |
| Swagger Petstore v3 | OpenAPI 3.0 | 19 | Working |
Community spec sources:
- MikroTik: tikoci/restraml
- Proxmox: LUMASERV/proxmox-ve-openapi
- OPNsense: endavis/opnsense-openapi
- TrueNAS: Spec available at
/api/docs/on your TrueNAS instance (REST API deprecated in 25.x)
Relative servers URLs (for example /api/v3) are resolved against the spec's own URL when the spec is loaded over HTTP, so --spec https://host/openapi.json usually needs no --server.
Specs are parsed on every invocation. A spec with a few thousand operations loads in well under a second, so there is no build or cache step to manage. Loading from a URL re-downloads the spec each time; save it locally or in a profile for anything you use often.
spec file/URL → parse (libopenapi) → normalize to unified model → build cobra commands → execute
- Loads the spec from a file, URL, or stdin
- Detects OpenAPI 3.x vs Swagger 2.0 and parses with libopenapi
- Normalizes into a unified internal model (same structure for both versions)
- Generates a Cobra command tree grouped by tags (or path segments when untagged)
- At runtime, builds HTTP requests from flags, applies auth, formats responses
| Flag | Short | Description |
|---|---|---|
--spec |
Path or URL to spec file | |
--server |
API server base URL (overrides spec) | |
--profile |
Use a saved configuration profile | |
--output |
-o |
Output format: json, yaml, table, raw |
--username |
Username for basic auth | |
--password |
Password for basic auth | |
--token |
Bearer token | |
--api-key |
API key value | |
--insecure |
-k |
Skip TLS certificate verification |
--verbose |
-v |
Print request/response headers |
--dry-run |
Show request without executing | |
--timeout |
HTTP request timeout (default: 30s) | |
--version |
Print the version and exit |
go test ./...
golangci-lint run ./...Releases are built by GoReleaser when a v* tag is pushed.
MIT