Lint
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.sarifA 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 |
Settings
Section titled “Settings”Most specific wins: --rule on the command line, then the API’s entry under lint.apis, then lint.rules, then the defaults above.
lint: rules: operation-description: warn no-unused-components: off apis: legacy: # an API that can't meet a rule yet operation-operationId: offnpx rapidoc lint --rule operation-description=warn --rule path-kebab-case=errorThe 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.
Options
Section titled “Options”| 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:
# in a job's steps:- run: npx rapidoc lint --strictUpload a SARIF report to see the findings on the pull request, as the Validate page shows.
Which packages it needs
Section titled “Which packages it needs”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.