Writing docs for AI agents
This documentation is written agentic-first: the primary consumer of any given page is as likely to be an AI coding agent (Claude Code, or another MCP client) retrieving it mid-task as it is a person reading it top to bottom. That changes how pages should be written, not just what they contain.
How agents reach these docs
This site runs docusaurus-plugin-mcp-server,
which exposes two MCP tools over the built docs:
docs_search- full-text search across every page, returning URL, snippet, and relevance scoredocs_fetch- fetches one page's full content as markdown, given a URL fromdocs_search
An agent working in this repo calls docs_search instead of grepping source comments or relying
on stale training data, then docs_fetchs the specific page it needs. That only produces good
results if pages are written to be retrieved and read in isolation.
Running the docs site locally
cd docusaurus
npm install
npm run build # generates build/mcp/docs.json and build/mcp/search-index.json
npm run dev:mcp # builds, then serves the MCP endpoint at http://localhost:8011/mcp
Re-run npm run build after editing docs content so the MCP index picks up the changes, then
restart dev:mcp (or re-run both together - the dev:mcp script in docusaurus/package.json
chains npm run build and node mcp-server.mjs). The devcontainer's docusaurus service does
this automatically and serves the site on port 8010.
This repo registers the local server with Claude Code at the project level (.mcp.json), so
anyone opening core-api in Claude Code gets docs_search / docs_fetch automatically once the
server above is running. To wire it up again by hand:
claude mcp add --transport http core-api-docs http://localhost:8011/mcp -s project
Conventions for every page
- Frontmatter is required:
id,title,description,sidebar_position. Thedescriptionbecomes the snippet shown indocs_searchresults and page metadata - write it as a one-sentence summary of the page, not a generic tagline. - Open with a summary paragraph. The first paragraph should state what the page covers and
who it's for, in full, without assuming the reader already has context from a page they
arrived from.
docs_fetchreturns the whole page - there is no guarantee the agent read anything before it. - No dangling references. Don't write "as mentioned above," "see below," or "the following
diagram" - link explicitly (
[Getting started](/intro/getting-started)) or restate the point. Pages are retrieved individually; "above" and "below" have no meaning out of context. - Name things, don't pronoun them. Prefer "the billing engine" or "
core-api" over "it" when referring to a system component, especially at the start of a section - agents (and skimming humans) resolve antecedents worse than a full read does. - One topic per page. Split rather than growing a single page to cover multiple concerns.
Smaller, focused pages mean a
docs_searchhit pulls in less irrelevant content. - State versions and assumptions explicitly. Write "Python 3.13+" and "PostgreSQL 16," not "the latest version" - a training cutoff or a stale cache shouldn't be able to make a vague claim wrong.
- Cross-reference by path, e.g.
/architecture/api-conventions, so links resolve the same way for a human clicking through the site and fordocs_fetchresolving a URL from search results. - Code samples are ground truth. Keep them copy-pasteable, and update them in the same change that alters the behavior they demonstrate - stale examples are worse than none, since an agent will trust and run them.