Repository navigation
Description
Relocated from dezren39/darwin-nix#117 on 2026-10-28 (placement audit): mcpx's single source lives in developing-today/code (pkgs/mcpx); re-home tracked at #309. Original body below; issue references inside it are historical (dezren39/nix numbering).
Parent: #90
Summary
Pick the static site generator for the mcpx docs. The notes ask for "the most common and simple modern choice" and point at "that thing all the rust/k8s people use". That hint is ambiguous: the Rust book and most Rust project docs are mdBook, while kubernetes.io is Hugo + Docsy. This issue compares five candidates against the requirements the other docs issues place on the generator, and recommends one. The decision is small but everything else in the docs theme builds on it, so it goes first.
Original notes
- documentation
- make a book using whatever is the most common and simple modern choice
- that thing all the rust/k8s people use is fine
Current state
- No site, no generator config, no docs build. The docs are plain markdown under
pkgs/mcpx/docs/(story.md, configuration.md, protocol.md, ...) plusAGENTS.mdandplugin/opencode/README.md. They render on GitHub and nowhere else. - Some reference output is already generated from single sources:
mcpx man(roff, written bypackage.nixpostInstall),mcpx config --schema,mcpx schema --format ...,GET /v1/openapi.json. The settings table indocs/configuration.mdis hand-regenerated and guarded byinternal/settings/docs_test.go. See 🎨 Palette: Improve accessibility of editor search panel #144. - CI:
.github/workflows/mcpx.ymlinstalls Nix and builds.#packages.x86_64-linux.mcpx; build(deps): bump build/buck/preludes/buck2-prelude fromd956689to3cfc766#49 generalises builds to every flake output. A docs site should be a flake output too (nix build .#mcpx-docs), so it is checked the same way.
Requirements the generator must serve
These come from sibling issues. Everything here is also possible by hand; the question is how much custom code each generator needs.
- (a) Hierarchical, collapsible version history (🎨 Palette: Add ARIA labels and live regions to search panel #150). Raw
<details>/<summary>passes through all five generators. The part that needs code is the "bubbling": computing a parent entry's latest release from its nested children and rendering it collapsed. That needs a preprocessor, hook or component. - (b) Generated reference pages (🎨 Palette: Improve accessibility of editor search panel #144): settings table, CLI help and man page, OpenAPI, tool types. They are produced by the
mcpxbinary at build time and dropped in as markdown files, or included into pages. - (c) An agent-markdown twin of every page (Update module github.com/jackc/pgx/v5 to v5.9.2 [SECURITY] #120):
llms.txt,llms-full.txt, a raw.mdnext to every.html. - (d) A marketing-style home page (🎨 Palette: Add aria-labels to buttons and inputs #155): video, copy buttons, a random rotating prompt.
- (e) The basics: search, dark mode, mermaid/diagrams, link checking. Versioned doc sets (v1/, v2/ copies of the whole site) are probably not needed, because 🎨 Palette: Add ARIA labels and live regions to search panel #150 puts version history inside the pages. Open question below.
Comparison
Versions were checked on 2026-09-30 against the nixpkgs pinned by this flake (nix eval --inputs-from . nixpkgs#<pkg>.version) and npm/PyPI.
| mdBook | Hugo + Hextra (or Docsy) | MkDocs Material | Docusaurus | Starlight (Astro) | |
|---|---|---|---|---|---|
| Who uses it | Rust book, most Rust projects | kubernetes.io (Docsy), many Go projects | many CNCF / Python projects | Meta and many JS projects | Astro, a growing number of JS/TS projects |
| Runtime | one Rust binary | one Go binary (Hugo extended). Hextra needs no Node. Docsy needs Node (PostCSS) | Python + plugins | Node + React, large node_modules |
Node + Astro |
| Latest / in nixpkgs | 0.5.4 / mdbook 0.5.4 |
Hugo 0.166.0 / hugo 0.166.0. The theme comes in as a Hugo module or a flake input |
mkdocs 1.6.1, unreleased since 2024-08-30; material 9.7.7 in nixpkgs | 3.10.2 / not packaged | starlight 0.42.4 on astro 7.3.5 / not packaged |
| Maintenance | active. 0.5.0 was a breaking release for preprocessors and renderers (release notes). nixpkgs dropped mdbook-linkcheck for incompatibility with 0.5 (replaced by mdbook-linkcheck2) |
active, frequent releases | Maintenance mode since Nov 2025: critical fixes only, EOL extended to 2027-05-05 (announcement, #8523). Its successor Zensical is at 0.0.66, pre-1.0, and does not yet support the MkDocs plugin ecosystem | active | active, but pre-1.0: the 0.x minors break things |
Nix build (.#mcpx-docs, #49) |
trivial: runCommand with mdbook build |
trivial if the theme is vendored (flake input or hugo mod vendor). Hugo modules fetch over the network, which a sandboxed build cannot do |
python3.withPackages, fine for packaged plugins. Unpackaged ones (e.g. mkdocs-llmstxt, not in nixpkgs) need packaging |
buildNpmPackage + npmDepsHash. Every dependency bump needs a hash repair (the #49 generalisation) |
same as Docusaurus |
| (a) history bubbling | preprocessor: any executable that reads [context, book] JSON on stdin and writes the book to stdout (docs). It can be written in Go, in this repo |
render hooks / shortcodes in Go templates. Tree logic in templates is awkward, so a pre-build step is likely anyway | hooks (Python) or mkdocs-macros |
MDX + React component, or a remark plugin | remark/rehype plugin or an Astro component |
| (b) generated reference | {{#include file.md:anchor}} of files written before the build |
files in content/, or data files + templates |
include-markdown / snippets | MDX imports, or files dropped in | files dropped in, or content collections |
| (c) agent twin | none built in. Options: third-party renderers (mdbook-llms-txt-tools, not in nixpkgs), or a preprocessor that writes .md + llms.txt, as Fluree did (fluree/db#1340) |
native: Hugo has a built-in markdown output format (text/markdown, docs). .md per page and llms.txt via one template each |
mkdocs-llmstxt 0.5.0 (not under Zensical) |
docusaurus-plugin-llms 0.6.0 (community) |
starlight-llms-txt 0.12.0 (llms.txt, -full, -small) |
| (d) marketing home | weakest: needs a custom theme or a hand-written index.html outside the book |
good: Hextra ships a landing layout (hero, feature grid). Any custom layout is possible | custom home.html override |
best: arbitrary React pages | good: template: splash + hero, and custom Astro components |
| (e) search | built in (client-side) | Hextra: FlexSearch built in | built in | Algolia, or local plugins | Pagefind built in |
| (e) dark mode | built-in themes | yes | yes | yes | yes |
| (e) mermaid | mdbook-mermaid (nixpkgs 0.17.1) |
Hextra: built in | built in | @docusaurus/theme-mermaid |
plugin |
| (e) versioned doc sets | no | manual | mike |
native, best in class | plugin (starlight-versions) |
| (e) link check | mdbook-linkcheck2 (nixpkgs 0.13.0), or lychee (nixpkgs 0.24.2) on the output |
lychee on the output |
built-in warnings plus lychee |
built-in broken-link check at build time | starlight-links-validator |
| Authoring complexity | lowest: book.toml + SUMMARY.md |
highest: Go templates, lookup order, modules | low | medium: React/MDX | medium: Astro/MDX |
lychee works on the built HTML of any generator, so link checking does not decide anything. Docs checks run in CI; see the testing trackers under #91 (CI pipeline #95, integration/environments #97).
Approaches
Approach A (least recommended): a Node generator, Starlight or Docusaurus
This covers the most requirements out of the box: a splash home page, llms.txt plugins, Pagefind or Algolia search, and native versioning in Docusaurus.
Why not:
- It adds a Node toolchain and a lockfile to a repository whose product is a Go binary.
- Every npm bump changes
npmDepsHash. build(deps): bump build/buck/preludes/buck2-prelude fromd956689to3cfc766#49 already has to automate that for the packages that need it, and this would add one more. - Starlight is pre-1.0 and follows Astro majors:
starlight-llms-txtdropped Astro 6 to support Astro 7 (PR #127). Expect that churn to repeat. - None of this is "simple" in the sense the notes ask for.
MkDocs Material is excluded outright rather than listed as an approach. It is in maintenance mode with an announced end of life, MkDocs 1.x itself has had no release since August 2024, and the successor is pre-1.0 without plugin support. Starting a new site on it in 2026 would mean migrating it within a year.
Approach B (middle): Hugo + Hextra
One Go binary in nixpkgs that covers all five requirements natively. It has a built-in markdown output format for the agent twin, templates for llms.txt, a landing-page layout for the home page, built-in search and mermaid, and render hooks and shortcodes for the history.
This is the "k8s" reading of the hint, though kubernetes.io uses Docsy, not Hextra. Docsy pulls in Node for PostCSS, so it loses the single-binary advantage. Pick Hextra or another Node-free theme.
Costs:
- Go templates are the hardest authoring model of the five. The tree logic in 🎨 Palette: Add ARIA labels and live regions to search panel #150 fits a template badly, so it would probably become a pre-build step anyway.
- The theme has to be vendored for a sandboxed Nix build.
- "Book" is not Hugo's native shape: navigation comes from the section structure and weights, not from one
SUMMARY.md.
Choose B over C if the home page and site chrome become a larger share of the work than the book itself.
Approach C (recommended): mdBook for the book, a hand-built static home page, and generator-independent build steps
-
mdBook renders the book: the level-1 and level-2 pages, the reference and the compendium. It is literally "a book", it is the "rust" reading of the hint, it is the simplest configuration of the five, and it is a single binary already in nixpkgs.
-
The home page is one hand-written
index.htmlplus a little JS: the video, copy buttons and a random rotating prompt (🎨 Palette: Add aria-labels to buttons and inputs #155). mdBook is weakest here, and a hybrid avoids fighting its theme. One static page is fully under our control, and its bot twin is a plainindex.md(Update module github.com/jackc/pgx/v5 to v5.9.2 [SECURITY] #120). -
Everything clever is a Go program in this repo, run as an mdBook preprocessor over stdin/stdout or as a step before or after the build:
- the history bubbling (⚡ Bolt: Optimize ProseMirror decoration widget rendering #151);
- the
.mdtwin andllms.txt/llms-full.txt(Update module github.com/jackc/pgx/v5 to v5.9.2 [SECURITY] #120); - the reference emitters, which are
mcpxitself (⚡ Bolt: Optimize cursor color generation and position grouping #145).
None of that code depends on mdBook's internals beyond the JSON book format, so switching to Hugo later means rewriting only the glue.
-
The whole site is one flake output,
nix build .#mcpx-docs, depending on.#mcpxfor the generated pages (fix(deps): update github.com/charmbracelet/ssh digest to ebfa259 - autoclosed #118, build(deps): bump build/buck/preludes/buck2-prelude fromd956689to3cfc766#49).
Risks:
- mdBook 0.5 already broke third-party preprocessors once. We depend only on the JSON protocol, and the flake lock pins the version, so an upgrade is a deliberate bump that CI checks.
- There are no versioned doc sets. 🎨 Palette: Add ARIA labels and live regions to search panel #150 makes that unnecessary, but see the open questions.
- Search covers the book, not the home page. That is acceptable for a one-page home.
Why C over B: the notes ask for simple, and a book. mdBook gives both, and the requirements it lacks natively (the twin, the home page, the history) need custom code in every generator, B included. Keeping that code in Go, next to the binary it documents, is the smaller long-term cost.
Decision to make now: C. Of the open questions below, only a "yes" to 3 (whole-site versioned doc sets) would reopen it, in favour of Docusaurus. Questions 1, 2 and 4 are answered after the pick and do not change it (1 and 2 follow #158's repository decision). #118's flake output and deploy, #120's twin emitter, #151's preprocessor hook and #155's home page all assume the answer, so this goes first. If there is doubt, the spike in the footer settles it in hours.
Open questions
- Does the site live in this monorepo (
pkgs/mcpx/docs-site/or similar) or move with mcpx if it ever gets its own repo (github.com/dezren39/mcpxis already the Go module path)? See fix(deps): update github.com/charmbracelet/ssh digest to ebfa259 - autoclosed #118. - One generator and one site for every flake package's docs, or mcpx only? One Pages site per repo (fix(deps): update github.com/charmbracelet/ssh digest to ebfa259 - autoclosed #118) pushes towards "one site, mcpx first".
- Are versioned doc sets (a whole site per release) ever wanted, or does in-page history (🎨 Palette: Add ARIA labels and live regions to search panel #150) replace them? If they are wanted, Docusaurus's advantage matters and C would need a
v<version>/directory scheme. - Does the home page need to share the book's CSS and theme, or can it look deliberately different?
Ease · Impact · Related
Ease S (decision; a spike building three existing pages in mdBook and Hugo would take hours) · Impact high (every docs issue builds on it) · Depends on / related: #49, #118, #120, #155, #144, #145, #150, #151
Security/auth deferred; see tracker.
Activity
developing-today commentedon Oct 28, 2026
CODE-864
dezren39 commentedon Oct 28, 2026
History carried over from dezren39/darwin-nix#117 (verbatim, oldest first):
@dezren39 · 2026-09-30T07:20:14Z
Integration pass. Placed in the DAG rooted at #181.
d956689to222dd7f#90 (site platform)@dezren39 · 2026-09-30T11:49:11Z
Issues pass (2026-09-30, at 05c78b2).
dezren39 commentedon Oct 29, 2026
🤖 Agent note · picked up
dezren39 commentedon Oct 29, 2026
Triage verdict — task 2834 (2026-10-29)
Decision confirmed: Approach C — mdBook. The issue itself records the decision ("Decision to make now: C"), with the full five-way comparison and reasons on the issue; the only condition that would reopen it (whole-site versioned doc sets, open question 3) has not been filed by anyone. This triage adopts C as settled and routes the build — it does not re-open the comparison.
Dedupe — no competing decision, nothing built. Searched code issues for a docs site generator / mdBook choice for mcpx: no other issue covers it. Scope confirmed against current main (code search, 2026-10-29): zero hits for
book.tomland zero formcpx-docs— no generator config, no docs flake output, no site exists yet; the docs are still plain markdown underpkgs/mcpx/docs/rendering only on GitHub, exactly as the issue describes.Implementation follow-up enqueued as queue task 3236, scoped to the book skeleton only:
SUMMARY.mdcovering the existingpkgs/mcpx/docs/pages without rewriting their content;.#mcpx-docsflake output building the book with the flake-pinnedmdbookfrom nixpkgs, sandboxed, checked in CI like other flake outputs;internal/settings/docs_test.go.Explicitly out of that packet (sibling docs issues that assume this decision and build on the skeleton): the hand-written home page, the
llms.txt/.mdtwin emitter, the version-history preprocessor, and site deployment. Open questions 1, 2 and 4 stay with their owning issues as the issue directs; none of them changes the generator pick.dezren39 commentedon Oct 29, 2026
🤖 Agent note · done
56 remaining items
dezren39 commentedon Oct 30, 2026
🤖 Agent note · picked up
ci: retrigger workflows on current head (#1939)
docs(mcpx): register docs/testing/feature-inventory.md in the compend…
Merge pull request #2629 from developing-today/queue/3236-1939-mcpx-m…
dezren39 commentedon Oct 30, 2026
🤖 Agent note · done
.#mcpx-docsflake output are live on main; this issue auto-closed on merge.nix build .#mcpx-docspasses; settings docs tests pass (TestTheDocumentationListsEverySetting,TestTheDocumentationDescribesTheScopes,TestEveryDocumentHasAChapter— the last after registeringdocs/testing/feature-inventory.md, which main had merged without a manifest entry). Codex: clean at head; its one P2 was fixed in 684a133 with a thread reply. Along the way: merged current main into the branch (manifest union conflict resolved) — the branch had gone dirty as main moved.internal/settingsguard tests fail identically on clean main — tracked in mcpx: three internal/settings guard tests fail on main (compendium chapter + undeclared adapter env) #2697. CI also never created workflow runs for this PR's post-opening pushes (only CodeRabbit ran on later heads) — filed as CI: pushes to PR #2629 after opening created no workflow runs (synchronize events dropped) #2713; verification above was done on the laptop per the worker runbook for exactly this case.dezren39 commentedon Oct 30, 2026
🤖 Agent note · base-URL plumbing follow-up (from #1941 / queue task 3242)
.#mcpx-docsoutput landed by PR docs(mcpx): stand up the mdBook book and .#mcpx-docs flake output (#1939) #2629 does not accept a base-URL / site-url argument:pkgs/mcpx/docs.nixtakes only{ lib, runCommand, mdbook }andpkgs/mcpx/book.tomlsets no[output.html] site-url. Per the mcpx docs: build the site in CI and deploy to GitHub Pages #1941 packet's fallback (plumb only if trivial, otherwise file back here): the Pages deploy workflow (PR for mcpx docs: build the site in CI and deploy to GitHub Pages #1941) builds.#mcpx-docsexactly as a local build does, so local and CI outputs are identical rather than differing only in the base URL./code/base baked in, the plumbing is: add asiteUrlargument todocs.nix(writing[output.html] site-urlinto the copied book.toml beforemdbook build), thread it throughlib/default.nix:581(mcpxDocs), and expose a CI variant output. mdBook's relative links work under/code/without it today.dezren39 commentedon Oct 30, 2026
🤖 Agent note · done
Outcome: PR #2629 merged at 2026-10-30T11:33:09Z (merge commit
c8ee2a6), and the merge is an ancestor of currentmain. Verified fresh this run:nix build .#mcpx-docs→/nix/store/32inal5g…-mcpx-docs, 106 rendered HTML pages;book.toml,pkgs/mcpx/docs/SUMMARY.md,pkgs/mcpx/docs.nix, and themcpx-docsflake output inlib/default.nixare all present onmain. The build is a sandboxedrunCommandusing the flake-pinnedmdbook, no network.internal/settingsdocs_test.gotests —TestTheDocumentationListsEverySetting,TestTheDocumentationDescribesTheScopes, plusTestEveryDocumentHasAChapterandTestTheEnvironmentDocIsCurrent— PASS.Pre-existing failures (not from this work): two unrelated
internal/settingstests fail identically on a cleanorigin/mainworktree —TestEverySettingHasAnEffectProbeOrAnExemption(missing effect probes formodel.budget/default/provider/timeout,script.imports,script.importsOnDynamic) andTestTheScriptEnvironmentIsWhatTheCodeSets(MCPX_ADAPTER_DECLARATION_SHA256,MCPX_EPHEMERALundeclared). Proven pre-existing by running them in a detached worktree oforigin/main. They belong to the settings/effect-probe line, not the docs skeleton; worth their own backlog issue.Notes / risks: issue #1939's generator decision is now implemented, not just recorded, so the sibling docs issues (home page, llms.txt twin emitter, version-history preprocessor, deployment) are unblocked.