Turn an OpenAPI spec into an agent-facing CLI
A spec-driven CLI gives coding agents a discoverable, executable API surface without hand-maintaining one command per endpoint.
| Resource | Link |
|---|---|
| Implementation | vercel-labs/specli |
| Package | specli |
| Contract | OpenAPI Specification |
API documentation is not an execution surface
An OpenAPI document can describe thousands of operations and still be awkward for a coding agent. The agent needs to discover the relevant resource, inspect the accepted inputs, construct a valid request, and receive output it can parse.
Handwritten commands solve that problem only while they stay synchronized with the specification. Every renamed parameter or added operation creates another place for the interface to drift.
specli takes the OpenAPI document as the command registry. It derives resources, actions, arguments, request bodies, and validation from the current schema.
Start with schema discovery
The built-in __schema resource lists the interface before any API operation runs. Human-readable output works for terminal inspection; --json --min produces a compact representation for an agent.
npx specli exec ./openapi.json __schema
npx specli exec ./openapi.json __schema --json --minThis discovery command comes from specli, not from an operation in the supplied API. It gives the caller a bounded way to answer “what can this interface do?” before choosing a resource and action.
Execute resource and action pairs
The public command shape is:
npx specli exec <spec> <resource> <action> [arguments] [options]For a specification that defines a users.list operation with a limit query parameter, the generated command becomes:
npx specli exec ./openapi.json users list --limit 20The resource and action names come from the specification. Flags such as --limit come from path, query, header, or body parameters on that operation; they are not a fixed list baked into the CLI.
Request bodies can use generated field flags, --data for an inline payload, or --file for a payload on disk. Schema validation runs before the HTTP request.
Inspect a request before sending it
Agents need a way to verify a generated request without mutating the target system. --dry-run returns the resolved method, URL, headers, and body without sending the request. --curl renders the same request as a cURL command.
npx specli exec ./openapi.json users list --limit 20 --dry-run
npx specli exec ./openapi.json users list --limit 20 --curlThese modes keep request construction and request execution on the same code path. The preview therefore checks the interface the caller is about to use instead of a separately maintained example.
Keep machine output explicit
Default output is designed for a person at a terminal. --json changes the contract to one JSON value. An HTTP response contains status and body; CLI-level failures use an error field.
{
"status": 200,
"body": {
"items": []
}
}The stable envelope lets an agent branch on HTTP status without scraping colors, tables, or explanatory prose. Non-zero exits distinguish command failures from successful execution.
Put access policy outside generation
Generating commands from a specification does not decide which operations a caller should see. specli exposes the OpenAPI document it receives and executes with the credentials supplied to it.
A company-facing wrapper therefore owns three additional decisions:
- Select or derive the specification available to the caller.
- Resolve credentials without printing secrets into prompts or logs.
- Gate high-impact operations before execution.
This boundary keeps the generated layer mechanical. Policy remains explicit in the platform that chooses the schema, credentials, and execution rules.
Compile a stable executable
Development can run directly through npx. A deployed integration can compile the specification and runtime into a standalone executable with Bun.
npx specli compile ./openapi.json --name company-apiThe compiled binary keeps the same resource-action interface. A programmatic client exposes the same model through list(), help(resource, action), and exec(...), while the AI SDK integration maps list, help, and execution to tools.
The important design choice is not the transport. It is the single source of truth: discovery, validation, previews, CLI execution, and programmatic execution all derive from the same OpenAPI operations.
Takeaways
Discovery belongs in the executable interface
The same OpenAPI document can list resources, explain an action, validate arguments, and execute the request.
Generated flags keep the contract current
Path, query, and body inputs come from the operation schema instead of a parallel command registry.
Machine mode needs a stable envelope
A single JSON value with HTTP status and body is easier for an agent to inspect than decorated terminal output.
Authorization remains a separate boundary
Command generation exposes the supplied specification. A platform wrapper must still decide which specification, credentials, and operations a caller may use.