Reference
CLI and config file
Every flag of ondocs index, init, dev and eval, and the config module.
The ondocs command has four subcommands: index builds or checks the index, init writes the endpoint for your host, dev serves the endpoint on your machine, and eval scores retrieval against questions whose answers you know. Run them with npx ondocs, or from a package.json script.
ondocs index
ondocs index [dir] [options] builds ask-index.json from the Markdown, MDX and HTML files in dir.
| Flag | Default | What it does |
|---|---|---|
-o, --out <file> | ask-index.json | Where to write the index. |
--check | off | Exit 1 if the index is stale. Never calls a model. |
--base-url <url> | / | URL prefix for pages, such as /docs or a full origin. |
-e, --embedding <spec> | OpenAI when a key is set | openai:<model>, workers-ai:@cf/<model>, <provider>/<model>, mock[:<dims>] or none. |
--dimensions <n> | the model's | Vector size, for models that support it. With --check, the size the index must have. |
--chunk-size <chars> | 1200 | Maximum characters per chunk. |
--chunk-overlap <chars> | 150 | Characters shared by consecutive chunks of a section. |
--ignore <glob> | none | Skip matching files. Repeatable. |
--framework <name> | detected | docusaurus, starlight, next or none: how file paths become URLs. |
--clean-urls | off | Drop .html from HTML files' URLs. |
--llms-txt <dir> | off | Also write llms.txt, llms-full.txt and a .md per page into dir. |
--no-llms-index, --no-llms-full, --no-llms-markdown | Leave out one of those. | |
--llms-title, --llms-description | package.json name | The site's name and summary, at the top of llms.txt. |
--site-url, --mcp-url | none | The site's origin, for absolute links, and its MCP endpoint, for llms.txt. |
-c, --config <file> | none | A module whose default export is an AskConfig. |
-q, --quiet | off | Only print errors. |
-h, --help, -v, --version | Print the help, or the version. |
Choosing the embedding model
Without --embedding, the CLI uses openai:text-embedding-3-small when OPENAI_API_KEY is set, or openai/text-embedding-3-small through AI Gateway when only AI_GATEWAY_API_KEY is. With neither, it fails rather than quietly building a keyword-only index, and suggests -e mock to try it without a key. -e none builds a keyword-only index on purpose. -e workers-ai:@cf/baai/bge-small-en-v1.5 embeds with Workers AI over Cloudflare's REST API, with CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN, for the Workers AI Worker; its vector size is fixed, so --dimensions does not apply.
Environment and exit codes
The CLI reads .env and .env.local from the working directory, without overriding variables that are already set. It exits with 0 on success, 1 when the build fails or --check finds the index stale, and 2 on a usage error.
ondocs init
ondocs init [options] writes the ask endpoint and the MCP endpoint for the site in the working directory and the host it deploys to: Vercel, Netlify, Cloudflare (Pages, or a Worker with static assets) or GitHub Pages, whose endpoint is a Cloudflare Worker of its own. It detects the site from its config (Docusaurus, Starlight, Astro, Next.js, VitePress, Hugo, MkDocs, Jekyll or Eleventy) and the host from vercel.json, netlify.toml, a wrangler config or a GitHub Pages workflow, and asks for the host when it cannot tell. Deploying shows what it writes for each.
| Flag | Default | What it does |
|---|---|---|
--host <name> | detected, else asked | vercel, netlify, cloudflare or github-pages. |
--provider <name> | workers-ai | For github-pages: workers-ai, with no API key, or openai. |
--site-url <url> | from the site's config | The site's public URL with its base path, which the GitHub Pages Worker reads. |
--name <text> | the site's title | The site's name, in the model's instructions. |
--out <dir> | detected | A static site's build folder, where the index goes. |
--no-mcp | the MCP endpoint is on | Write the ask endpoint only. |
--dry-run | off | Print every file it would write, and write nothing. |
-y, --yes | asks | Overwrite files that differ without asking. |
-h, --help | Print the help. |
It prints each file it created, updated or left unchanged, the environment variables to set and where, and the steps left: the packages to install, the dialog to add and the deploy. It exits with 0 when everything is written, 1 when it left a file as it was or an edit for you to make by hand, and 2 on a usage error. It reads no .env file and no credential, and it deploys nothing. An Astro site with an SSR adapter gets no file: its integration serves the endpoints.
ondocs dev
ondocs dev [options] serves POST /api/ask on 127.0.0.1, answering from a built index, for the dialog on your site's dev server. It serves the same index as an MCP server at /api/mcp, keyword-only, for your editor's agent.
| Flag | Default | What it does |
|---|---|---|
--index <file> | ask-index.json, then the build output of Docusaurus, Astro or VitePress | The index to serve. |
--port <n> | 8787 | Port to listen on. |
--allow-origin <origin> | localhost | Another origin allowed to call it, or *. Repeatable. |
--model <id> | gpt-5.4-mini | OpenAI model for answers, when OPENAI_API_KEY is set. |
-h, --help | Print the help. |
It embeds questions with the model the index records, answers with OpenAI when OPENAI_API_KEY is set and with the mock model otherwise, and reloads the index when the file changes. It only answers pages on this machine (localhost, 127.0.0.1 and [::1] origins, on any port) and requests addressed to localhost, so a site you visit cannot spend your key through it, and it caps request bodies at 64 KiB. Try it locally shows it with each integration.
ondocs eval
ondocs eval <questions.yaml> [options] scores retrieval against a file of questions with the pages that answer them, and questions marked unanswerable: hit@1, hit@3, refusal precision and refusal recall, question by question. It exits 1 when a score is under its threshold. Measure and improve answers has the file's format.
| Flag | Default | What it does |
|---|---|---|
--index <file> | the file's index, then ask-index.json, build/, dist/, dist/client/, .vitepress/dist/ | The index to score. |
--min-hit-at-1, --min-hit-at-3, --min-refusal-precision, --min-refusal-recall | the file's thresholds | Thresholds from 0 to 1. |
--keyword-only | off | Search by keywords only, embedding nothing. |
--json | off | Print the report as JSON. |
-h, --help | Print the help. |
It embeds each question with the model the index records, as ondocs dev does, and calls no language model. It loads .env and .env.local like index, and exits 2 on a usage error or a file it cannot read.
The config file
For an embedding provider the specs don't cover, or content that is not on disk, pass a config module with --config. Every field is optional:
// ondocs.config.mjs
import { cohere } from '@ai-sdk/cohere';
import { getPosts } from './lib/cms.mjs';
/** @type {import('ondocs/node').AskConfig} */
export default {
embeddingModel: cohere.embedding('embed-multilingual-v3.0'),
baseUrl: '/docs',
documents: async () =>
(await getPosts()).map((post) => ({
id: post.slug,
url: `/blog/${post.slug}`,
title: post.title,
content: post.markdown,
})),
};| Field | What it does |
|---|---|
embeddingModel | An AI SDK embedding model, or null for keyword-only. |
embeddingProviderOptions | Passed to the embedding model, such as { openai: { dimensions: 512 } }. |
chunking | { maxChars, overlap }. |
baseUrl | URL prefix for pages loaded from the folder. |
ignore | Glob patterns of files to skip. |
framework | 'auto' (the CLI's default), 'docusaurus', 'starlight', 'next' or 'none'. |
cleanUrls | Drop .html from HTML files' URLs. |
documents | { id, url, title, content } records from elsewhere, or a function returning them. |
defineConfig from ondocs/node types the object without a JSDoc comment. Share the config with your route handler, as the ondocs website does, so the index and the queries always use the same embedding model.