CLI

Run the right docs command with the right flags: init, preview, check, and agent setup.

Global options

These options apply before any subcommand.

bash
docs [global options] <command> [command options]
--api-urlurl

Base docs.page API URL for agent commands. When unset, the CLI uses the production API.

Environment variable: DOCS_PAGE_API_BASE

--help, -hflagoptional

Show help for the command.

--version, -vflagoptional

Print the CLI version.

init, preview, and check do not call the docs.page API.


docs init

Initialize docs.page files in a project directory.

bash
docs init [path] [flags]
pathstringoptional

Project directory to initialize. Defaults to ..

--namestringoptional

Project name written into docs.json. Inferred from package.json, pubspec.yaml, or the folder name when omitted in interactive mode.

--docsflagoptional

Create starter docs/**/*.mdx files. Default in non-interactive mode when neither --docs nor --no-docs is passed.

--no-docsflagoptional

Write docs.json only; skip starter page files.

--overwriteflagoptional

Replace existing files created by docs.page init.

In an interactive terminal, the CLI prompts for missing values. In non-interactive mode (CI or piped stdin), pass --name, --docs or --no-docs, and --overwrite when replacing existing files; otherwise the command exits with a Missing --<flag> error.

Errors

ConditionMessage
docs.json exists in non-interactive mode without --overwritedocs.json already exists. Re-run with --overwrite to replace it.
docs/ conflicts in non-interactive modedocs/ already exists. … Re-run with --overwrite … or --no-docs …
Init templates missing from the packageUnable to find docs.page init templates.
Required flag missing in non-interactive modeMissing --<flag>. Pass it as an option when running non-interactively.

Output

On success, the CLI prints created file paths or No docs.page files were changed. when all targets already exist.


docs preview

Start a local preview server and open the docs.page preview UI.

bash
docs preview [flags]
--portnumberoptional

TCP port for the local WebSocket server. When omitted, the CLI binds an ephemeral port on localhost (OS-assigned).

--no-browserflagoptional

Do not open the preview URL automatically.

Requires docs.json or docs.yaml and at least one .mdx file under docs/.

Errors

ConditionMessage
Missing config fileNo docs.json or docs.yaml file was found in the current directory.
Missing docs/ directoryNo docs/ directory was found in the current directory.
No page filesNo .mdx files were found in the docs/ directory.
Invalid --port value`--port` must be a valid TCP port.
Port bind failureNode.js EADDRINUSE or related bind error

Output

On success, the CLI prints Local preview server started., the WebSocket URL (ws://localhost:<port>), and a Preview URL shaped like https://docs.page/preview?url=ws://localhost:<port>. The server runs until you stop it with Ctrl+C (exit code 0).


docs check

Check documentation for broken links and missing assets.

bash
docs check [path] [flags]
pathstringoptional

Project directory to check. Defaults to ..

--internal-linksoff | warn | erroroptional

Check internal links and frontmatter redirect, next, and previous paths. Default: error.

--assetsoff | warn | erroroptional

Check that referenced local image and asset files exist. Default: error.

--external-linksoff | warn | erroroptional

Fetch external URLs and report failures. Default: error.

--ignore-external-hostsstringoptional

Comma-separated hosts to skip when checking external links. Skipped links are listed as skip and counted in the summary; no request is made for them.

Entries match on hostname only and cover subdomains, so npmjs.org also covers www.npmjs.org but never evil-npmjs.org.attacker.net. A pasted URL, a host:port, a *. or . prefix, and a trailing dot are all accepted; empty entries are dropped.

Unioned with check.ignoreExternalHosts in docs.json. Neither replaces the other.

--severity-override-hostsstringoptional

Comma-separated host=severity pairs that set the severity for every external-link failure on a matching host. Values are warn or error only.

Host spelling matches --ignore-external-hosts: a pasted URL, a host:port, a *. or . prefix, and a trailing dot are all accepted. Entries match on hostname and cover subdomains; a lookalike host does not match. When both a parent and a child hostname match, the longer hostname wins.

Unioned with check.severityOverrideHosts in docs.json. When the same host appears in both, the flag wins.

--debugflagoptional

After external-link checks and before the normal summary, print plain-text debug lines for each HTTP attempt and a per-host totals line. No docs.json key.

Per-attempt lines look like debug <hostname> <METHOD> <outcome> <duration>ms, where <outcome> is the HTTP status, timeout, or unreachable.

Then one line per host, sorted by hostname: debug host <hostname> requests=<n> ok=<n> unverified=<n> broken=<n> timeouts=<n> 429s=<n>. Counts are per HTTP attempt (HEAD and GET are separate). ok is status 100–299. unverified is 401, 403, 405, or 429. 429s counts status 429 and is also included in unverified. timeouts are AbortError from this check's own timer. broken is every other failure.

Ignored hosts and --external-links off make no requests and print no debug lines. Without --debug, nothing extra is printed.

--renderoff | warn | erroroptional

Validate that each page's MDX renders without errors. Default: error.

--metadataoff | warn | erroroptional

Warn when title or description is missing on pages that use auto-generated social preview images. Also checks site name and description in docs.json. Default: error.

All five severity flags accept off, warn, or error. Default for each: error.

Ignore external hosts from docs.json

Declare hosts once in docs.json so CI does not repeat the flag:

json
{
  "check": {
    "ignoreExternalHosts": ["npmjs.org", "stackoverflow.com"]
  }
}

Values from docs.json and --ignore-external-hosts are unioned. --external-links off still skips external checking entirely.

Override external-link severity per host from docs.json

Declare per-host severity once in docs.json so CI does not repeat the flag:

json
{
  "check": {
    "severityOverrideHosts": {
      "rnfirebase.io": "error",
      "stackoverflow.com": "warn"
    }
  }
}

The flag and the map are unioned; the flag wins when the same host is in both.

Severity for an external-link failure is resolved in this order:

  1. --external-links off skips the request. The map does not turn the check back on.
  2. If the host matches severityOverrideHosts, that severity is used for every failure: bot-gate (401, 403, 405, 429), 404, 5xx, DNS, and timeout.
  3. Otherwise an unverified bot-gate stays a warning.
  4. Otherwise the failure uses --external-links.

Bot gates

Hosts that answer 401, 403, 405, or 429 are refusing an automated request rather than reporting a missing page. For hosts not listed in severityOverrideHosts, those responses are reported as warnings so they never fail CI, and the message says the link was not verified. A host override of error makes the same responses fail CI. Missing pages (404), server errors, DNS failures, and timeouts use the override when the host matches, and otherwise remain at the configured --external-links severity.

External link retries

Each external request is tried at most three times (the first attempt plus two retries) when the response is HTTP 429 or the connection drops (ECONNRESET, ECONNREFUSED, EPIPE, ETIMEDOUT, UND_ERR_SOCKET, UND_ERR_CONNECT_TIMEOUT). Responses such as 401, 403, 404, 405, and 5xx, DNS failures like ENOTFOUND, and this check's own 10s timeout (External link timed out after 10000ms.) are not retried.

On 429, the wait follows Retry-After when it is a delta-seconds value or an HTTP-date. If that header is missing or unparseable, the waits are 200ms then 400ms. Dropped-connection retries use the same 200ms then 400ms backoff (there is no Retry-After for those). Every wait is capped at 2 seconds. There is no flag or docs.json key for this behavior.

If HEAD returns 429 and retries are exhausted, the link is classified as unverified and no GET is sent. A dropped HEAD that still fails after retries falls through to GET, as does a 405 HEAD. That follow-up GET is only retried when the GET itself is a 429 or a dropped connection.

With --debug, each try (including failed ones) produces one debug line.

External link concurrency

External link checks run at most 8 at once, and at most 2 against the same hostname. The cap is the hostname only (www.example.com and example.com are different hosts). A slot is held for the whole check of one URL, including retry waits; checking the same URL twice does not take a second slot. There is no flag or docs.json key for this behavior.

Exit codes

CodeMeaning
0No error-level issues found.
1One or more error-level issues found.

Errors

ConditionMessage
Missing configNo docs.json or docs.yaml file was found.
Invalid docs.jsondocs.json is not valid JSON: …
Invalid docs.yamldocs.yaml is not valid YAML: …
No page filesNo docs/**/*.mdx files were found.
Broken internal linkInternal link points to a missing docs page. (or frontmatter variant)
Missing assetReferenced asset does not exist.
Unreachable external URLUnable to reach external link: … or External link returned &lt;status&gt; …
Timed out external URLExternal link timed out after 10000ms.
Host refused an automated request (warning)External link host rejected an automated request (&lt;status&gt;); the link was not verified.
Host in the ignore list (skipped)External link host is in the ignore list.

docs agent create

Create an in-docs chat agent for a GitHub repository.

bash
docs agent create [flags]
--repoorg/nameoptional

Target GitHub repository. Prompted when omitted in an interactive terminal.

--providerstringoptional

LLM provider: openai, anthropic, google, or xai.

--apikeystringoptional

Provider API key. Encrypted locally before upload. Prompted as a password when omitted in an interactive terminal.

--gh-authstringoptional

GitHub token instead of gh auth token.

--forceflagoptional

Overwrite an existing agent configuration.

Success

The CLI prints Your documentation agent is ready to use. and a JSON snippet with agent.key to add to docs.json.

Errors

ConditionMessage
Missing --repo in non-interactive modeMissing --repo.
Invalid repository format`--repo` must be in the form `org/name`.
Invalid provider`--provider` must be one of: xai, openai, anthropic, google.
API key too short`--apikey` must be longer than 1 character.
gh not installedGitHub CLI (\gh`) is required when `--gh-auth` is not provided.`
gh not authenticatedUnable to read a GitHub auth token from \gh`. Run `gh auth login`, or pass `--gh-auth`.`
API error responseServer \error` string or Agent creation failed (<status> …).`
Missing token in responseAgent creation failed: response did not include a token.

docs agent delete

Delete the agent configuration for a repository.

bash
docs agent delete [flags]
--repoorg/nameoptional

Target GitHub repository. Prompted when omitted in an interactive terminal.

--gh-authstringoptional

GitHub token instead of gh auth token.

Success

The CLI prints Deleted agent for org/name.

Errors

ConditionMessage
Missing --repo in non-interactive modeMissing --repo.
Invalid repository format`--repo` must be in the form `org/name`.
GitHub auth failureSame messages as agent create
API error responseServer \error` string or Agent deletion failed (<status> …).`

See also