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.

FlagDefaultWhat it does
-o, --out <file>ask-index.jsonWhere to write the index.
--checkoffExit 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 setopenai:<model>, workers-ai:@cf/<model>, <provider>/<model>, mock[:<dims>] or none.
--dimensions <n>the model'sVector size, for models that support it. With --check, the size the index must have.
--chunk-size <chars>1200Maximum characters per chunk.
--chunk-overlap <chars>150Characters shared by consecutive chunks of a section.
--ignore <glob>noneSkip matching files. Repeatable.
--framework <name>detecteddocusaurus, starlight, next or none: how file paths become URLs.
--clean-urlsoffDrop .html from HTML files' URLs.
--llms-txt <dir>offAlso write llms.txt, llms-full.txt and a .md per page into dir.
--no-llms-index, --no-llms-full, --no-llms-markdownLeave out one of those.
--llms-title, --llms-descriptionpackage.json nameThe site's name and summary, at the top of llms.txt.
--site-url, --mcp-urlnoneThe site's origin, for absolute links, and its MCP endpoint, for llms.txt.
-c, --config <file>noneA module whose default export is an AskConfig.
-q, --quietoffOnly print errors.
-h, --help, -v, --versionPrint 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.

FlagDefaultWhat it does
--host <name>detected, else askedvercel, netlify, cloudflare or github-pages.
--provider <name>workers-aiFor github-pages: workers-ai, with no API key, or openai.
--site-url <url>from the site's configThe site's public URL with its base path, which the GitHub Pages Worker reads.
--name <text>the site's titleThe site's name, in the model's instructions.
--out <dir>detectedA static site's build folder, where the index goes.
--no-mcpthe MCP endpoint is onWrite the ask endpoint only.
--dry-runoffPrint every file it would write, and write nothing.
-y, --yesasksOverwrite files that differ without asking.
-h, --helpPrint 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.

FlagDefaultWhat it does
--index <file>ask-index.json, then the build output of Docusaurus, Astro or VitePressThe index to serve.
--port <n>8787Port to listen on.
--allow-origin <origin>localhostAnother origin allowed to call it, or *. Repeatable.
--model <id>gpt-5.4-miniOpenAI model for answers, when OPENAI_API_KEY is set.
-h, --helpPrint 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.

FlagDefaultWhat 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-recallthe file's thresholdsThresholds from 0 to 1.
--keyword-onlyoffSearch by keywords only, embedding nothing.
--jsonoffPrint the report as JSON.
-h, --helpPrint 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:

JavaScript
// 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,
    })),
};
FieldWhat it does
embeddingModelAn AI SDK embedding model, or null for keyword-only.
embeddingProviderOptionsPassed to the embedding model, such as { openai: { dimensions: 512 } }.
chunking{ maxChars, overlap }.
baseUrlURL prefix for pages loaded from the folder.
ignoreGlob patterns of files to skip.
framework'auto' (the CLI's default), 'docusaurus', 'starlight', 'next' or 'none'.
cleanUrlsDrop .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.