Commands
agent-commerce import openapi
Convert a local OpenAPI 3.x document into reviewable resource drafts.
agent-commerce import openapi <source> [options]Arguments
<source>pathrequired.yaml, .yml or .json OpenAPI 3.0, 3.1 or 3.2 document. Remote URLs are not supported.Options
--output <path>default: <source-stem>.agent-commerce.yaml--force--base-url <url>servers entry. Absolute http(s), no query or fragment.--operation <operationId>operationId or the generated id. One that matches nothing fails the run.--tag <tag>--freepricing: { type: free }.--expose <protocols>expose:, comma-separated from http,mcp,a2a,acp.--strict--jsonExamples
agent-commerce import openapi ./openapi.yaml$ agent-commerce import openapi ./openapi.yaml
OpenAPI 3.1: ./openapi.yaml
Imported: 12
Skipped: 1
Warnings: 3
Skipped operations:
…
Warnings:
…
Generated:
openapi.agent-commerce.yaml
Pricing/exposure were not inferred.
Review the generated resources before merging them into config.yaml.What a draft looks like
POST /users/{userId}/orders?notify=true with a JSON body becomes:
# Generated by agent-commerce import openapi. Review before use.
# Source: openapi.yaml (OpenAPI 3.1)
# Merge the resources below into config.yaml once pricing, exposure and
# any backend authentication have been decided.
resources:
# REVIEW: pricing and exposure are not inferred from OpenAPI. Add e.g.
# pricing: { type: free } # or { type: fixed, amount: "0.01", currency: USDC } with payments: [x402]
# expose: [http] # http | mcp | a2a | acp
createOrder:
name: Create an order
description: Create an order
input:
type: object
properties:
path:
type: object
properties:
userId:
type: string
required:
- userId
additionalProperties: false
query:
type: object
properties:
notify:
type: boolean
required:
- notify
additionalProperties: false
body:
type: object
properties:
productId:
type: string
quantity:
type: integer
required:
- productId
additionalProperties: false
required:
- path
- query
- body
additionalProperties: false
backend:
type: http
method: POST
url: https://api.example.com/users/{userId}/orders
inputBindings:
path: path
query: query
body: bodyIds come from operationId, normalized, or from <method>_<path>. They are stable across runs; two operations that resolve to the same id fail the import instead of being renamed.
Support matrix
| Feature | Status |
|---|---|
| OpenAPI 3.0, 3.1, 3.2 — YAML or JSON | supported |
| Swagger 2.0 | convert first |
| internal $ref | supported |
| external $ref, remote URL source | refused |
| GET, POST, PUT, PATCH, DELETE | supported |
| HEAD, OPTIONS, TRACE, QUERY, other | skipped, warned |
| primitive path (simple) and query (form) parameters | supported |
| deepObject, object/array parameters, cookies, dynamic headers | unsupported |
| application/json and application/*+json bodies | supported |
| multipart, form-urlencoded, binary, streaming | unsupported |
| security credentials | never imported |
A required unsupported feature skips the whole operation; an optional one is left out with a warning. A body on GET or DELETE is always left out with a warning. Schemas keep type, properties, required, additionalProperties, enum and items; validation keywords the gateway would not enforce are dropped and listed.
The draft also gets an output schema from one explicit 2xx JSON response: 200, then 201, 202, then the lowest other status. If that response has no schema, or one that cannot be converted, the output is left out with a warning; no other response is tried.
Security properties
- Local files only, at most 10 MiB. Nothing in the document is executed, and the importer makes no network requests.
- Every external
$refis refused before validation; internal references get cycle and depth checks, and__proto__is refused as a reference segment, parameter name or property name. - Backend hosts come only from
serversor--base-url. A relative or non-HTTP(S) server URL, or one with a query or fragment, skips that operation. - Security declarations become a warning and a review comment, never credentials or agent input.
Accept,Content-TypeandAuthorizationheader parameters are ignored. - Vendor extensions are ignored and cannot set pricing, payments, backend URLs or exposure.
- Output is written to a temporary sibling and renamed; replacing an existing file needs
--force.
Exit codes
0 on success, warnings included. 1 on a load, import or write error, an --operation that matched nothing, an --expose value that is not a supported protocol, an existing output file without --force, no supported operation imported, or any warning under --strict. A failed run writes no file.
redocly bundle or swagger-cli bundle. Re-importing overwrites and never merges, so import into a new path and diff. The CLI writes only free pricing; a fixed price is a manual edit.