swagger-cli
A fast, cache-first CLI for exploring OpenAPI specifications. Built for engineering teams and AI agents.
Key properties:
- Query latency: <50ms on cached specs (index-backed, no raw spec parsing)
- First query: <2s including fetch + index build
- Robot mode: 100% structured JSON output with versioned schema contract
- Exit codes: Consistent, actionable, concurrency-safe (14 error types, codes 2-16)
- Offline-capable: all queries work without network after initial fetch
Install
cargo install --path .
Requires Rust 2024 edition.
Quick Start
# Fetch and cache a spec
swagger-cli fetch https://petstore3.swagger.io/api/v3/openapi.json --alias petstore
# List endpoints
swagger-cli list petstore
# Search across the API
swagger-cli search petstore "pet"
# Show endpoint details
swagger-cli show petstore "/pet/{petId}" --method GET
# Browse schemas
swagger-cli schemas petstore
# Machine-readable output (for agents)
swagger-cli list petstore --robot
Commands
fetch
Download and cache an OpenAPI spec.
swagger-cli fetch <URL> --alias <NAME> [OPTIONS]
<URL> accepts HTTP/HTTPS URLs, file:// paths, relative paths, or - for stdin.
| Option | Description |
|---|---|
--alias <NAME> |
Required. Must match ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$ |
-H, --header <HEADER> |
Additional HTTP header (repeatable, format: "Name: Value") |
--bearer <TOKEN> |
Bearer token for Authorization header |
--auth-profile <NAME> |
Auth profile name from config.toml |
--force |
Overwrite existing alias |
--timeout-ms <N> |
HTTP request timeout in milliseconds (default: 10000) |
--max-bytes <N> |
Maximum response size in bytes (default: 26214400 / ~25 MB) |
--retries <N> |
Retries on transient errors (default: 2) |
--allow-private-host <HOST> |
Bypass SSRF protection for this host (repeatable) |
--allow-insecure-http |
Permit plain HTTP |
--resolve-external-refs |
Fetch and inline external $ref entries |
--ref-allow-host <HOST> |
Allowed host for external ref fetching (repeatable, required with --resolve-external-refs) |
--ref-max-depth <N> |
Maximum chain depth for transitive external refs (default: 10) |
--ref-max-bytes <N> |
Maximum total bytes fetched for external refs (default: 10485760 / ~10 MB) |
list
List endpoints from a cached spec.
swagger-cli list [ALIAS] [OPTIONS]
| Option | Description |
|---|---|
--all-aliases |
Query across every cached alias |
-m, --method <METHOD> |
Filter by HTTP method (case-insensitive) |
-t, --tag <TAG> |
Filter by tag |
-p, --path <PATTERN> |
Filter by path pattern (regex) |
--sort <FIELD> |
Sort order: path (default), method, or tag |
-n, --limit <N> |
Maximum results (default: 50) |
-a, --all |
Show all results (no limit) |
show
Display details of a specific endpoint.
swagger-cli show <ALIAS> <PATH> [OPTIONS]
| Option | Description |
|---|---|
-m, --method <METHOD> |
HTTP method to show. Required when path has multiple methods |
--expand-refs |
Expand $ref entries inline |
--max-depth <N> |
Maximum depth for ref expansion (default: 3) |
Output includes the full operation object: summary, description, tags, operationId, security, parameters (path/query/header/cookie), request body, and response schemas with status codes.
Circular references are detected and annotated with {"$circular_ref": "..."}.
search
Full-text search across endpoints and schemas.
swagger-cli search [ALIAS] <QUERY> [OPTIONS]
When using --all-aliases, the first positional argument is treated as the query.
| Option | Description |
|---|---|
--all-aliases |
Search across every cached alias |
--case-sensitive |
Case-sensitive matching |
--exact |
Match query as exact phrase |
--in <FIELDS> |
Fields to search (comma-separated): all (default), paths, descriptions, schemas |
--limit <N> |
Maximum results (default: 20) |
Scoring is tokenized with field weights (path > summary > description) and term coverage boost, quantized to basis points for deterministic output.
schemas
Browse component schemas.
swagger-cli schemas <ALIAS> [OPTIONS]
| Option | Description |
|---|---|
--name <PATTERN> |
Filter schema names by regex |
--list |
List schemas (default mode) |
--show <NAME> |
Show a specific schema by exact name |
--expand-refs |
Expand $ref entries inline (show mode only) |
--max-depth <N> |
Maximum depth for ref expansion (default: 3) |
tags
List tags from a cached spec with endpoint counts.
swagger-cli tags <ALIAS>
aliases
Manage spec aliases.
swagger-cli aliases [OPTIONS]
| Option | Description |
|---|---|
--list |
List all aliases (default) |
--show <ALIAS> |
Full details (URL, version, size, stats) |
--rename <OLD> <NEW> |
Rename an alias |
--delete <ALIAS> |
Delete an alias and cached files |
--set-default <ALIAS> |
Set the default alias (used when ALIAS is omitted in other commands) |
sync
Re-fetch and update cached specs.
swagger-cli sync [ALIAS] [OPTIONS]
| Option | Description |
|---|---|
--all |
Sync all cached specs |
--dry-run |
Check for changes without writing |
--force |
Re-fetch regardless of cache freshness |
--details |
Include per-item change lists in output (capped at 200 items) |
--auth <PROFILE> |
Auth profile name from config |
--jobs <N> |
Maximum concurrent sync jobs, --all only (default: 4) |
--per-host <N> |
Maximum concurrent requests per host, --all only (default: 2) |
--max-failures <N> |
Abort after N alias failures, --all only |
--resume |
Resume a previously interrupted --all sync |
--allow-private-host <HOST> |
Bypass SSRF protection for this host (repeatable) |
Uses ETag + Last-Modified for conditional fetches. Respects Retry-After headers with exponential backoff. Per-alias progress checkpoints enable resumable execution.
diff
Compare two spec versions (structural diff).
swagger-cli diff <LEFT> <RIGHT> [OPTIONS]
| Option | Description |
|---|---|
--fail-on <LEVEL> |
Exit non-zero if changes at this level: breaking |
--details |
Include per-item change descriptions |
Output covers added/removed/modified endpoints and schemas with a summary and breaking-change flag. Useful as a CI gate for API contract changes.
doctor
Check cache health and diagnose issues.
swagger-cli doctor [OPTIONS]
| Option | Description |
|---|---|
--fix |
Attempt auto-repair |
--alias <ALIAS> |
Check a specific alias only |
Checks: directory permissions, meta.json generation + index_hash validation, index pointer validity, stale caches (30+ days), index version compatibility, and torn/partial cache state.
Fix modes: (1) rebuild index from raw, (2) reconstruct meta from raw + index, (3) delete alias only as last resort.
cache
Manage the spec cache.
swagger-cli cache [OPTIONS]
| Option | Description |
|---|---|
--stats |
Show cache statistics (default) |
--path |
Print the cache directory path |
--prune-stale |
Remove aliases older than the stale threshold |
--prune-threshold <DAYS> |
Days before an alias is stale (default: 90) |
--max-total-mb <N> |
LRU eviction until total size is under this limit |
--dry-run |
Preview without deleting |
Global Options
Every command accepts these flags:
| Flag | Description |
|---|---|
--robot |
Structured JSON output (auto-detects non-TTY) |
--pretty |
Pretty-print JSON output |
--network <MODE> |
auto (default), online-only, or offline |
--config <PATH> |
Path to config file (or SWAGGER_CLI_CONFIG env var) |
Robot Mode
All commands support --robot for structured JSON output. Success:
{
"ok": true,
"data": { ... },
"meta": {
"schema_version": 1,
"tool_version": "0.1.0",
"command": "list",
"duration_ms": 12
}
}
Errors emit JSON to stderr:
{
"ok": false,
"error": {
"code": "ALIAS_NOT_FOUND",
"message": "Alias not found: myapi",
"suggestion": "Run 'swagger-cli aliases --list' to see available aliases."
},
"meta": { ... }
}
Exit Codes
| Code | Error | Suggestion |
|---|---|---|
| 0 | Success | |
| 2 | USAGE_ERROR |
Run swagger-cli --help |
| 4 | NETWORK_ERROR |
Check connectivity or use --network offline |
| 5 | INVALID_SPEC |
Verify URL points to valid OpenAPI 3.x JSON/YAML |
| 6 | ALIAS_EXISTS |
Use --force to overwrite |
| 7 | AUTH_ERROR |
Check auth profile in config.toml |
| 8 | ALIAS_NOT_FOUND |
Run aliases --list to see available |
| 9 | CACHE_LOCKED |
Wait or check for stale locks |
| 10 | CACHE_ERROR |
Run doctor --fix |
| 11 | CONFIG_ERROR |
Check config file, run doctor |
| 12 | IO_ERROR |
File system error |
| 13 | JSON_ERROR |
Invalid JSON/YAML parsing |
| 14 | CACHE_INTEGRITY |
Run doctor --fix or re-fetch |
| 15 | OFFLINE_MODE |
Use --network auto or online-only |
| 16 | POLICY_BLOCKED |
Use --allow-private-host or --allow-insecure-http |
Configuration
Config file location: ~/.config/swagger-cli/config.toml (or set SWAGGER_CLI_CONFIG).
[auth_profiles.corp_internal]
credential_source = "env:MY_API_TOKEN"
auth_type = "bearer"
[auth_profiles.api_key]
credential_source = "env:API_KEY"
auth_type = "api_key"
header = "X-API-Key"
credential_source supports env:VAR_NAME and file:/path/to/token.
Cache Layout
Specs are stored per-alias under ~/.cache/swagger-cli/aliases/{alias}/:
| File | Purpose |
|---|---|
raw.source |
Original upstream bytes (YAML or JSON, lossless provenance) |
raw.json |
Canonical normalized JSON (all queries operate on this) |
index.json |
Precomputed query index (endpoints, schemas, tags, search data) |
meta.json |
Fetch metadata, written last as commit marker |
The four-file protocol provides crash consistency: meta.json is written last with a generation counter and content hash, so a torn write is always detectable by doctor.
Security
- SSRF protection: Blocks loopback, private ranges, and multicast addresses by default. Override per-host with
--allow-private-host. - DNS rebinding mitigation: Validates resolved IP after redirects (5 redirect limit).
- Auth redaction: Tokens are never printed in output or logs.
- Streaming byte limit:
--max-bytesprevents OOM on oversized or malicious specs. - Network policy:
--network offlineguarantees zero outbound connections. - External refs are opt-in:
--resolve-external-refsmust be explicitly set with an allowlist of permitted hosts.
License
MIT