Docs assistants

The two ways to ask these docs a question: the docs MCP server for Claude, and the docs chat for people running the site locally.

2026-11-07Status: Live

Two ways to ask the house docs

The documentation you are reading is also a queryable corpus. There are two front ends onto it, for two audiences, both retrieving over committed files rather than an external index:

  • the docs-MCP server — for Claude and other agents (Claude Code, the IDE extensions), over stdio;
  • the docs chat — for a person in the browser, behind the 💬 button in the bottom-right corner of every docs page.

The chat answers wherever the docs run as a server — on Flightcontrol's docs web service with its ANTHROPIC_API_KEY, or locally; see "Where the chat works" below.

The corpus

Both front ends search committed documentation, read at request time:

  • the docs-MCP corpus is apps/docs/content + .claude/rules + CLAUDE.md (see docs-MCP) — not .claude/skills, .claude/reference or .claude/plans;
  • the chat corpus is every .md and .html file under the docs app's content/ — the same pages the site renders.

The header search box is a third, narrower index: the static /api/search-index, built from the rendered categories.

An answer can only ever be as current as the committed docs. The CI docs-drift step that would hold them to the code needs ANTHROPIC_API_KEY, which is not provisioned in this repo, so it always skips; the only drift check that runs is the advisory pre-commit hook, on machines with the claude CLI. Treat a stale doc as a bug and fix it in the same change as the code.

The docs-MCP server — for agents

packages/docs-mcp is a stdio Model Context Protocol server registered in the root .mcp.json as v4-docs, so any MCP-aware assistant working in the repo can call it. It exposes three tools:

Tool Does
search_docs ranked corpus paths with snippets
list_docs every file in the corpus
read_doc a guarded read of one file, inside the corpus roots

Full detail: docs-MCP.

Use it when Claude is already in the repo and needs to ground an answer or a change in the house conventions.

The docs chat — for people

The chat is an agentic assistant. Rather than a single retrieval-then-answer pass, Claude (claude-sonnet-5) is given a search_docs tool (BM25 over the section text, with a heavy boost for terms in the path and headings) and the conversation, and it searches — possibly several times — before it answers. The route (src/app/api/chat/route.ts) streams an NDJSON body so the UI can show the work as it happens:

Event Meaning
searching a search_docs call is running (the query is shown)
delta answer tokens, as they arrive
sources the sections it drew on, deduped, at the end
error a graceful, user-facing message
done the turn is complete

Answers cite their sources — the doc sections the assistant actually read — so a reader can jump to the page and verify. The chat sends prior turns back as history, so follow-ups keep context. /chat is only a pointer page to the widget.

The API key

The chat calls Claude, so it needs an Anthropic API key. It resolves one server-side (ANTHROPIC_API_KEY), and the widget also accepts an optional bring-your-own key (the ⚙ button) that is used for that request only — never logged, never stored. With no key available it says so, pointing at SECRETS.md, rather than failing opaquely.

Where the chat works

The chat needs a server for its POST /api/chat handler, and the docs are deployed both ways (apps/docs/next.config.ts):

  • The Flightcontrol web service (euro-league-docs-web-development) runs the docs as a Next.js server. Set ANTHROPIC_API_KEY on that service in the Flightcontrol dashboard and the chat answers for everyone, billed to that key. A reader who enters their own key through ⚙ uses theirs instead.
  • The static service (euro-league-docs-development) and Vercel serve exported files (DOCS_STATIC_EXPORT=1). There the 💬 widget appears but cannot answer; the header search still works, because /api/search-index is generated at build time.

Locally, pnpm --filter @v4/docs dev (http://localhost:4400) runs the chat with ANTHROPIC_API_KEY from your environment or a key entered through ⚙.

Which to use

You are… Use
Claude / an agent working in the repo the docs-MCP server (v4-docs)
a person reading the docs the header search; the 💬 chat (on the docs web service, or locally)
writing a doc and want it findable by both write it in content/ — both index it automatically