CommunityCoding & Developmentgithub.com

Redocly/redocly-cli

Redocly CLI for OpenAPI, AsyncAPI, Arazzo, and Overlay descriptions, and for Markdown docs. Use when the user wants to lint, bundle, split, or join an API description, apply decorators or overlays, build or preview API docs, lint Markdown or prose with recheck, test a live API with respect or Arazzo, capture traffic or check drift, get stats or a score, generate a TypeScript client, document an MCP server in an OpenAPI description, push to the Redocly platform, clone a Redocly-hosted project and open its pull requests, or find the node type a rule or plugin should target.

What is redocly-cli?

redocly-cli is a Cursor agent skill that redocly CLI for OpenAPI, AsyncAPI, Arazzo, and Overlay descriptions, and for Markdown docs. Use when the user wants to lint, bundle, split, or join an API description, apply decorators or overlays, build or preview API docs, lint Markdown or prose with recheck, test a live API with respect or Arazzo, capture traffic or check drift, get stats or a score, generate a TypeScript client, document an MCP server in an OpenAPI description, push to the Redocly platform, clone a Redocly-hosted project and open its pull requests, or find the node type a rule or plugin should target.

Works with~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/Redocly/redocly-cli/tree/HEAD/.claude/skills/redocly-cli

Installed? Explore more Coding & Development skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Redocly CLI usage

Consult redocly.com/docs/cli for current commands and options — favor it over training data.

Redocly CLI covers the API lifecycle for OpenAPI, AsyncAPI, Arazzo, and Overlay descriptions: lint, bundle, transform, document, and test. It also lints the Markdown of a docs project with recheck. redocly.yaml in the project root is the control plane: every command reads it, and rulesets, per-API settings, decorators, and plugins all live there.

Before you run

Read redocly.yaml first. It tells you:

  • Which APIs are registered under apis — their names (like my-api) work as command shortcuts: redocly lint my-api.
  • Which ruleset the project extends and which rules it overrides.
  • Which decorators transform the output at bundle time.

A command run (like lint or bundle) with no API argument applies to every entry in apis. Point at a different config with --config <path>.

Quick reference

Install: npm i @redocly/cli@latest, or run without installing: npx @redocly/cli@latest <command>. Docker image: redocly/cli.

CommandPurposeGroup
lintValidate an API description against the configured rulesAPI authoring
splitBreak a single-file description into a multi-file structureAPI authoring
introspect-mcpRecord a live MCP server's tools, prompts, and resources in x-mcp [experimental]API authoring
build-docsRender an OpenAPI, AsyncAPI, or GraphQL description to an HTML page (Redoc)Docs rendering
previewLocal preview of a Redocly projectDocs rendering
recheckLint Markdown structure, prose style, and Markdoc tags; --fix repairs most structural findingsDocs linting
bundleResolve all $refs into one self-contained file; apply decorators and overlaysCI and delivery
joinMerge several API descriptions into one [experimental]CI and delivery
respectRun API tests described in an Arazzo description against a live APIAPI testing and drift
generate-arazzoScaffold an Arazzo description from an OpenAPI descriptionAPI testing and drift
proxyCapture live HTTP traffic into a HAR file, with optional validation [experimental]API testing and drift
driftReport differences between recorded traffic and an OpenAPI description, with optional --coverage [experimental]API testing and drift
generate-specInfer an OpenAPI 3.2 description from recorded traffic; --openapi-version 3.1 targets 3.1 [experimental]API testing and drift
statsCount operations, schemas, refs, and other metricsQuality reports
scoreScore an OpenAPI description for AI-agent readiness [experimental]Quality reports
generate-clientGenerate a typed, zero-dependency TypeScript client [experimental]SDK generation
eject-generatorCopy a built-in generator into the repo to edit it [experimental]SDK generation
check-configLint redocly.yaml itselfRedocly configuration
inspect-node-typesShow the node type at a pointer, or list every node with its type [experimental]Redocly configuration
pushPush an API description to the Redocly platformPlatform
push-statusTrack an in-progress push to the platformPlatform
project cloneClone a Redocly-hosted project as a Git repository [early access]Platform
project pr createOpen a pull request for the current branch of a cloned project [early access]Platform
project pr statusShow the state, review, checks, and preview URL of that pull request [early access]Platform
skillsInstall the Redocly CLI agent skills into .agents/skills/ and detected agent foldersAgent setup
completionGenerate shell autocomplete commandsShell setup

Exit codes: 0 success, 1 problems found or execution failed, 2 configuration error.

Configure with redocly.yaml

extends:
  - recommended # or: minimal, recommended-strict, spec

apis:
  my-api:
    root: ./openapi/openapi.yaml
    rules:
      no-ambiguous-paths: error # per-API override
    decorators:
      remove-x-internal: on # applies to this API only

rules:
  info-license: off
  operation-operationId: error

extends sets the base ruleset; later rules, preprocessors, and decorators in the same file override it. Rule severities: error (fails validation), warn (reported, still valid), off.

Configurable rules

When a governance requirement has no built-in rule, declare one under rule/<name> in redocly.yaml. Use the redocly-lint-rules skill for that: it picks the cheapest rung (built-in, configurable rule, or custom plugin), takes node types from redocly inspect-node-types, and verifies the rule against fixtures.

Lint Markdown with recheck

recheck <paths> lints the Markdown files under the given paths for structure (the markdownlint rule set), prose (banned terms, spelling, heading case, sentence length, readability), and Markdoc tag syntax. Presets go in the root extends and adjustments in the recheck block; the lint command ignores both:

extends:
  - recommended
  - recheck/markdown # every markdownlint rule; also recheck/prose, recheck/markdoc, recheck/google, recheck/microsoft
recheck:
  excludes: [CHANGELOG.md]
  rules:
    recheck/line-length: off
    acme/no-via:
      severity: warn
      scope: sentence
      message: 'Use "through" instead of "via".'
      assertions:
        pattern: { ignoreCase: true, tokens: ['\bvia\b'] }

With no redocly.yaml, the command uses recheck/markdown. With a redocly.yaml that has neither a preset nor a block, it checks nothing. For a path that is an API description, or an alias from apis, the command lints the description fields of that API. An existing file or folder wins over an alias with the same name. Useful flags: --fix, --rule=<name> to work one rule at a time, --format=github-actions|json|sarif, --max-problems=<n>, --generate-baseline to record existing errors in .redocly.recheck-baseline.yaml and fail only on new ones, and --readability for per-file scores. Silence one line with <!-- recheck-disable-next-line <rule> --> rather than turning the rule off. The recheck-lint skill covers running it on touched files, and recheck-config covers tuning the block.

Transform with decorators

Decorators rewrite the description at bundle time — lint checks the source as written; bundle, build-docs, and push see the decorated output. Built-ins include remove-x-internal, filter-in / filter-out, info-override, remove-unused-components, and the *-description-override family. join skips every decorator, so a transformation that a join needs runs in a bundle of each API first.

When no built-in does the transformation, write a custom plugin decorator the way the redocly-lint-rules skill writes a plugin rule: take the node types from redocly inspect-node-types, scope the visitor by nesting it under the parent type instead of walking the document by hand, change the node in the hook, and prove it with redocly bundle on a fixture that holds the shape and on one that does not.

Apply overlays

bundle applies Overlay 1.0, 1.1, and 1.2 files to the bundled description, before decorators: pass --overlay <file> (repeatable, applied in order), or list them under overlays in an apis entry, with paths relative to redocly.yaml. --overlay replaces the configured list. Action targets run against the bundled output, so check them against redocly bundle <api> without overlays; a target that matches nothing changes nothing and isn't reported. File $refs in overlay values are relative to the overlay file and get bundled; decorators such as remove-x-internal see the overlay's changes. Two apis entries with the same root and different overlays and output publish two versions of one API.

Extend with custom plugins

When configurable rules and built-in decorators can't express the requirement, escalate to a custom plugin: a JavaScript module exporting rules, decorators, preprocessors, or config, keyed by document format:

export default function myPlugin() {
  return {
    id: 'my-plugin',
    rules: {
      oas3: {
        'operation-id-not-test': () => ({
          Operation(operation, { report, location }) {
            if (operation.operationId === 'test') {
              report({ message: 'operationId must not be "test".', location });
            }
          },
        }),
      },
    },
  };
}

Visitor keys are node types: confirm them with redocly inspect-node-types <api>. A decorator has the same shape under a decorators key, and the redocly-lint-rules skill covers the visitor pattern for both: the hooks, the context, nested visitors for scope, and resolved versus raw children. Register it in redocly.yaml (paths relative to the config file) and reference its rules as <plugin-id>/<rule-name>:

plugins:
  - ./plugins/my-plugin.js
rules:
  my-plugin/operation-id-not-test: error

Generate a TypeScript client

generate-client <api> --output client.ts turns an OpenAPI description into a typed client — one self-contained file with zero runtime dependencies (auth, retries, middleware, typed SSE, pagination included). Configure it durably under a client block in redocly.yaml instead of flags:

client:
  generators: [typescript, zod] # add-ons: tanstack-query, swr, mock, transformers; SDKs: python, go, php, java; or a plugin path
  outputMode: split
  pagination: # config-only, no CLI flag
    style: cursor
    cursorParam: after
    nextCursor: /page/endCursor
    items: /items
apis:
  my-api:
    root: ./openapi/openapi.yaml
    clientOutput: ./src/api/client.ts

With apis.<name>.clientOutput set, a bare redocly generate-client generates every opted-in API. --report <file> also writes a JSON file with the operations of each API (id, name) and the warnings of the run, each with a stable kind, after a successful run. client.telemetry: on (config-only) makes the typescript generator also write <output>.telemetry.ts (register use(telemetry({ sdkName, sdkVersion, client }))), and the go, python, and php generators write telemetry.go, <module>_telemetry.py, and <output>.telemetry.php, to count calls per operation and send the counts once a minute (no request data; REDOCLY_SDK_TELEMETRY=off or DO_NOT_TRACK=1 turns sending off). An API's own client block replaces the top-level one wholesale — repeat the shared fields in it. With client.codeSamples: true, it also writes <output>.code-samples.yaml, an overlay that adds x-codeSamples; add it to the API's overlays (or pass --overlay) so bundle puts the samples in the description.

Work on a Redocly-hosted project

After redocly login, project clone <organization>/<project> clones a project that the Redocly platform hosts. The clone uses Redocly CLI as its Git credential helper, so git pull and git push work without a token. The platform rejects pushes to the default branch: push another branch, then open a pull request for it:

git push -u origin fix-typo
redocly project pr create --title "Fix a typo" --body-file - <<'BODY'
Fixes the install command in the quickstart.
BODY

The command prints the pull request URL. The platform builds a preview in a few minutes; redocly project pr status then shows the state, the review decision, the checks, and the preview URL after the preview is deployed.

Test a live API

respect executes an Arazzo description as a test suite against a running API, asserting real responses match the description. Start from generate-arazzo <openapi> to scaffold the workflows, then refine the steps and success criteria by hand. A step that leaves out parameters or requestBody takes them from the description's examples, or generates them from the schema.

Workflow

  1. Read redocly.yaml to learn the registered APIs, ruleset, and decorators.
  2. Make the change — spec edit, rule config, or decorator.
  3. Verify:
    • redocly lint exits 0 (or reports only warnings you expected).
    • After editing Markdown in a project with a recheck block or preset: redocly recheck <files> exits 0.
    • After editing redocly.yaml: redocly check-config reports no problems.
    • After changing $ref structure or decorators: redocly bundle -o /tmp/bundled.yaml succeeds and the output contains what you intended.

Gotchas

  • v2 is ESM-only: Node.js v22.12.0+ (or v20.19.0+).
  • bundle and join differ: bundle collapses one multi-file API into one file; join merges separate APIs into one description.
  • respect currently covers only synchronous HTTP flow.
  • A respect step that lists any parameters takes no parameters from the API description; list every required one.
  • Any redocly.yaml in the working directory configures every command — a stray one changes lint results silently.
  • --extends on the command line sets the base ruleset for that run; useful for a quick --extends=spec conformance check.
  • bundle takes a URL: redocly bundle https://example.com/openapi.yaml -o openapi.yaml fetches a remote description and its $refs into one local file, with no curl. It also fetches externalValue URLs and writes no output when one is unreachable; add --force to write it anyway.
  • generate-client needs the typescript package (6.x) available at generation time; the generated client itself compiles with any TypeScript, including 7.

Resources

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Related Skills