Bundle and products.json formats#
Two JSON files connect product sites to the hub and to the MCP server. docs-kit build writes docs-bundle.json next to each product site. The hub repository maintains products.json.
docs-bundle.json#
{
"schemaVersion": 1,
"product": "flow",
"title": "Flow",
"tagline": "Process transparency for agentic work",
"repo": "kontourai/flow",
"sha": "<git rev-parse HEAD at build time>",
"builtAt": "2026-10-10T12:00:00.000Z",
"siteUrl": "https://kontourai.github.io/flow/",
"digest": "<sha256 hex>",
"documents": [
{ "source": "README.md", "section": null, "title": "Flow", "landing": true, "url": "https://kontourai.github.io/flow/index.html", "repoPath": "README.md", "lineOffset": 0, "markdown": "# Flow\n..." },
{ "source": "docs/getting-started.md", "section": "Start Here", "title": "Getting started", "landing": false, "url": "https://kontourai.github.io/flow/docs/getting-started.html", "repoPath": "docs/getting-started.md", "lineOffset": 4, "markdown": "# Getting started\n..." }
],
"topics": [
{ "id": "workflows", "title": "Workflows", "source": "docs/concepts.md#workflows", "url": "https://kontourai.github.io/flow/docs/concepts.html#workflows", "markdown": "## Workflows\n..." }
]
}
documents[0]is the landing page, withlanding: trueandsection: null. The listed documents follow in manifest order, withlanding: false. A document'stitleis thetitleset on itsdocumentsentry indocs-kit.json, if any. Otherwise it is its first Markdown H1 outside blockquotes and lists, then the text of the first raw-HTML<h1>that has text, then a simple front-mattertitle:, then the file name without.md.markdownis the source file as written, minus a leading YAML front-matter block.- Each document's
urlis the pagebuildgenerates:index.htmlfor the landing page, otherwise the source path with.mdreplaced by.html, undersiteUrl. A bundle-only document ("publish": false) has no page, so itsurlishttps://github.com/<repo>/blob/<sha>/<path>(HEADin place of<sha>whenmcpserves a directory outside git), and itsmarkdownhas relative links made absolute (images and other embedded files tohttps://raw.githubusercontent.com/<repo>/<sha>/<path>), as are topics taken from it. Published documents keep their Markdown as written. Redirect stubs from the manifest'sredirectsare not listed; the bundle has no field for them. repoPathandlineOffset(since 0.6.0) say wheremarkdownsits in the repository:repoPathis the source path from the git top level (it differs fromsourceonly when--rootis a subdirectory), andlineOffsetis the number of front-matter lines stripped beforemarkdown's first line, so line N ofmarkdownis line N +lineOffsetof the file. The MCPlocatetool uses them for file line numbers and GitHub links. Both are optional for readers: a bundle built before 0.6.0 has neither, andlocatethen assumes no front matter and says so. Neither is part ofdigest.- A topic's
markdownis a heading section: it runs from the anchor heading up to the next top-level heading of the same or a higher level. Deeper headings stay in the section. A topic without an anchor gets the whole document. taglineis""when the manifest omits it.digestis the SHA-256 (hex) ofJSON.stringify({documents, topics}). Documents are reduced to{source, section, title, landing, markdown}and topics to{id, title, source, markdown}, in manifest order, withmarkdownas written (before bundle-only link rewriting, which embeds the sha and site URL). URLs,sha, andbuiltAtare left out, so the digest identifies the content alone.- The hub's
thinstate and the MCPdocCountcount only documents withlanding: false.
mcp --repo and mcp --workspace build the same object in memory on every tool call. Outside a git checkout, their sha is null. They add dirty: true when the working tree has uncommitted changes. The MCP server validates every bundle down to each document and topic; a malformed one is reported as unavailable.
products.json#
The hub's product list, validated strictly. An unknown key is refused, and each product must equal the repository name in its repo:
{
"schemaVersion": 1,
"products": [
{ "product": "flow", "repo": "kontourai/flow" }
]
}
docs-kit hub copies it next to index.html. docs-kit mcp --hub <url> reads <url>/products.json and then <url>/<product>/docs-bundle.json for each product.