Generate CLI tools from OpenAPI 3.0 specifications.
opencligen takes an OpenAPI spec and generates a complete Go CLI application with:
- One command per endpoint
- Commands grouped by tags
- Support for
x-clioverrides for customizing names, flags, and configuration - JSON and SSE (Server-Sent Events) response handling
go install github.com/crunchloop/opencligen/cmd/opencligen@latestOr build from source:
git clone https://github.com/crunchloop/opencligen
cd opencligen
go build -o opencligen ./cmd/opencligenGenerate a CLI from your OpenAPI spec:
opencligen gen --spec api.json --out ./mycli --name mycli --buildThis will:
- Parse your OpenAPI spec
- Generate a Go CLI application in
./mycli - Build the binary at
./mycli/mycli
opencligen gen [flags]
Flags:
--spec string Path to OpenAPI spec file (required)
--out string Output directory (required)
--name string Application name (required)
--module string Go module name (optional, defaults to app name)
--build Build the generated CLI after generation
--dry-run Print plan without generating files# Generate and preview the plan
opencligen gen --spec api.json --out /tmp/mycli --name mycli --dry-run
# Generate and build
opencligen gen --spec api.json --out ./mycli --name mycli --buildThe generated CLI follows these conventions:
Commands are organized by OpenAPI tags:
mycli
├── tasks # From tag: "tasks"
│ ├── list # GET /v1/tasks
│ ├── create # POST /v1/tasks
│ ├── get <id> # GET /v1/tasks/{id}
│ └── cancel <id> # POST /v1/tasks/{id}/cancel
├── workspaces # From tag: "workspaces"
│ ├── list
│ └── get <id>
└── stream # From tag: "stream"
└── subscribe # SSE endpoint
The generated CLI requires a base URL. Configure it via:
- Command-line flag:
--base-url https://api.example.com - Environment variable:
MYAPP_BASE_URL=https://api.example.com - Config file:
~/.config/myapp/config.yaml
# ~/.config/myapp/config.yaml
base_url: https://api.example.com
headers:
Authorization: Bearer token123For endpoints with request bodies, use the --data flag:
# Inline JSON
mycli tasks create --data '{"name": "Task 1"}'
# From file
mycli tasks create --data @task.json
# From stdin
echo '{"name": "Task 1"}' | mycli tasks create --data @-All generated CLIs include these global flags:
--base-url: API base URL--timeout: Request timeout (default: 30s)--header: Extra headers (repeatable)
Customize the generated CLI using x-cli vendor extensions in your OpenAPI spec.
paths:
/tasks/{taskId}/activities:
get:
operationId: listTaskActivities
x-cli:
name: "tasks activities" # Custom command path
aliases: ["act", "a"] # Command aliases
hidden: true # Hide from help
group: "admin" # Override tag groupingparameters:
- name: X-Org-Id
in: header
x-cli:
flag: "org" # Custom flag name
shorthand: "o" # Single-letter shorthand
env: "ORG_ID" # Environment variable
config: "org_id" # Config file key
positional: false # Force as flag (for path params)Operation level:
| Option | Type | Description |
|---|---|---|
name |
string | Space-delimited command path (e.g., "tasks activities") |
aliases |
[]string | Command aliases |
hidden |
bool | Hide command from help output |
group |
string | Override tag grouping |
Parameter level:
| Option | Type | Description |
|---|---|---|
flag |
string | Override flag name |
shorthand |
string | Single-letter shorthand |
env |
string | Environment variable to read from |
config |
string | Config file key to read from |
positional |
bool | Whether path param is positional (default: true) |
By default, command names are derived from operationId:
| operationId | Command |
|---|---|
listTasks |
list |
getTask |
get |
createTask |
create |
updateTask |
update |
deleteTask |
delete |
startProcess |
start |
cancelTask |
cancel |
subscribeStream |
subscribe |
customOperation |
custom-operation |
Use x-cli.name to override this behavior.
Flags are derived from parameter names:
- Query/path params: converted to kebab-case
- Header params:
X-prefix stripped, converted to kebab-caseX-User-Id→--user-idX-Request-ID→--request-id
Use x-cli.flag to override.
Endpoints returning text/event-stream are automatically handled:
mycli stream subscribe
# Outputs each SSE data chunk as pretty-printed JSONmake test
# or
go test ./...make lintmake buildSee CONTRIBUTING.md for details.
opencligen/
├── cmd/opencligen/ # Generator CLI
├── internal/
│ ├── spec/ # OpenAPI spec loading
│ ├── plan/ # Command plan builder
│ ├── gen/ # Code generation
│ │ ├── templates/ # Go templates
│ │ └── runtime/ # Embedded runtime
│ ├── runtime_skel/ # Runtime implementation
│ └── testdata/ # Test fixtures
└── README.md
MIT