Skip to content
npx rapidoc lint # every API in rapidoc.config.*
npx rapidoc lint ./specs/orders.yaml # one file (or a URL)
npx rapidoc lint --strict --format sarif > rapidoc.sarif

A valid spec can still make a poor portal: operations without an operationId get page URLs that change when their summary is edited, bodies without examples leave Try and the mock server with nothing to show, tags that aren’t declared have no description for their sidebar group. rapidoc lint finds those. It runs validate’s check first, so one CI step covers both; an invalid spec is not linted further.

Each finding names the file, line and column, and the rule:

🔍 orders: specs/orders.yaml
❌ 1 error(s):
specs/orders.yaml:37:7 operationId "createOrder" is also used by POST /orders [operation-operationId-unique] (#/paths/~1orders~1{id}/delete/operationId)
⚠️ specs/orders.yaml:11:5 GET /orders has no summary [operation-summary] (#/paths/~1orders/get)
⚠️ specs/orders.yaml:22:11 application/json request body has no example [media-example] (#/paths/~1orders/post/requestBody/content/application~1json)

Each rule has a severity: error fails the run, warn is reported (and fails with --strict), off is skipped. The defaults lean on warn, so the first run on an existing spec doesn’t fail CI. rapidoc lint --rules prints this list.

Rule Checks Why it matters Default
operation-operationId Every operation has an operationId. Page URLs are built from it (otherwise from the summary, which changes); so are MCP tool names. warn
operation-operationId-unique No two operations share one. They would share a page URL and a tool name. error
operation-operationId-url-safe Letters, digits, _, - and . only. It appears in URLs. warn
operation-summary Every operation has a summary. The sidebar label and the MCP tool’s title. warn
operation-description Every operation has a description. Readers, and the MCP tool’s description. off
operation-tag-defined Tags used are in the top-level tags list. The sidebar group’s description and order come from there. warn
tag-description Every top-level tag has a description. It introduces the group on the API page. off
operation-2xx-response A 2xx or 3xx response is documented. Try has nothing to show as the expected result. warn
operation-4xx-response A 4xx response is documented. Readers see the error shapes. off
security-defined POST, PUT, PATCH and DELETE have a security requirement, their own or the document’s. security: [] opts out. Try and the mock server need it; MCP marks them as consequential. warn
security-scheme-defined Every scheme a requirement names is declared. Try’s authentication panel is built from the declarations. error
no-unused-components Every component is referenced. Documentation of nothing. warn
media-example Request and response bodies have an example, on the media type or its schema (or on every property). Try fills the request with it; the mock server answers with it. warn
path-kebab-case Path segments other than parameters are kebab-case. Naming. off
no-server-example-com Servers aren’t example.com or localhost. Try would call nowhere. warn
info-contact info.contact is set. Shown in the API page header. off
info-license info.license is set. Shown in the API page header. off

Most specific wins: --rule on the command line, then the API’s entry under lint.apis, then lint.rules, then the defaults above.

rapidoc.config.yaml
lint:
rules:
operation-description: warn
no-unused-components: off
apis:
legacy: # an API that can't meet a rule yet
operation-operationId: off
npx rapidoc lint --rule operation-description=warn --rule path-kebab-case=error

The lint key is read straight from the file, so linting one spec needs no other package. A misspelled rule name is an error with a suggestion.

Option Meaning
--rule <name>=<error | warn | off> Set a rule’s severity; repeat for more.
--rules List the rules, their defaults and what they check.
--format pretty | json | sarif pretty (default) for the terminal; json for scripts; sarif for GitHub code scanning, with every rule described.
--strict Fail on warnings too.
--remote Also fetch remote specs in apis: and remote $refs.

Exit code 1 on errors (or warnings with --strict), 2 for a wrong rule name or severity:

.github/workflows/docs.yml
# in a job's steps:
- run: npx rapidoc lint --strict

Upload a SARIF report to see the findings on the pull request, as the Validate page shows.

One spec, a URL, or a folder of OpenAPI files: @rapidoc/cli alone. A portal folder (with rapidoc.config.*): @rapidoc/portal, to read the apis: list.