Skip to content

Commit f585594

Browse files
committed
docs: replace MkDocs with Zensical
Migrate the v2 docs build from MkDocs Material to Zensical, the Material team's successor (as Starlette and uvicorn have done). Zensical natively re-implements search, glightbox and mkdocstrings, but — unlike MkDocs — runs no arbitrary plugins or hooks. This SDK's docs relied on three of those, so they are reimplemented as standalone build steps around `zensical build`: - API reference: `mkdocs-gen-files` + `mkdocs-literate-nav` become `scripts/docs/gen_ref_pages.py` (writes the `docs/api/` mkdocstrings stubs) and `scripts/docs/build_config.py` (splices the nested API nav into a generated `mkdocs.gen.yml`, since Zensical has no literate-nav). - llms.txt: the former MkDocs hook becomes `scripts/docs/llms_txt.py`, a post-build step over the source tree, with no dependency on build internals. `mkdocs.yml` stays the source config, with the MkDocs-only YAML tags (`!relative`, `!ENV`, `!!python/name:`) translated to the string forms Zensical understands and the emoji functions pointed at `zensical.extensions.emoji`. The generators moved out of `docs/` (Zensical publishes everything under docs_dir) into `scripts/docs/`, and `scripts/build-docs.sh` now picks the toolchain per worktree so the combined v1 (MkDocs) + v2 (Zensical) build stays correct. Adds `scripts/serve-docs.sh` for local preview. The docs dependency group drops mkdocs, mkdocs-material[imaging] and the gen-files/glightbox/literate-nav plugins for `zensical`. mkdocstrings is floored at 1.0.4 / mkdocstrings-python 2.0.5: Zensical's compatibility layer targets that API, and the older line renders API pages with an unregistered-autorefs error. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CTkPwxyKkLTnqZdeiCMCzK
1 parent d287c98 commit f585594

15 files changed

Lines changed: 568 additions & 575 deletions

File tree

.github/workflows/deploy-docs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ on:
1414
- src/mcp/**
1515
- src/mcp-types/**
1616
- scripts/build-docs.sh
17+
- scripts/docs/**
1718
- pyproject.toml
1819
- uv.lock
1920
- .github/workflows/deploy-docs.yml

.github/workflows/docs-preview.yml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
name: Docs Preview
22

3-
# Builds the mkdocs site for a PR and deploys it to Cloudflare Pages.
3+
# Builds the Zensical site for a PR and deploys it to Cloudflare Pages.
44
#
5-
# Security: mkdocs executes Python from the PR (mkdocstrings imports src/mcp,
6-
# `!!python/name:` directives). The build is gated by `authorize` (admin sender
7-
# for auto-preview, admin/maintainer commenter for /preview-docs) and isolated
8-
# from Cloudflare secrets — `build` runs PR code with no secrets and hands the
9-
# static site to `deploy` via an artifact, so PR code never shares a runner
10-
# with the Cloudflare token.
5+
# Security: the build executes Python from the PR (mkdocstrings imports src/mcp,
6+
# the scripts/docs/ generators run). The build is gated by `authorize` (admin
7+
# sender for auto-preview, admin/maintainer commenter for /preview-docs) and
8+
# isolated from Cloudflare secrets — `build` runs PR code with no secrets and
9+
# hands the static site to `deploy` via an artifact, so PR code never shares a
10+
# runner with the Cloudflare token.
1111
#
1212
# Required configuration:
1313
# - secrets.CLOUDFLARE_API_TOKEN (scope: Account → Cloudflare Pages → Edit)
@@ -21,6 +21,7 @@ on:
2121
- docs/**
2222
- docs_src/**
2323
- mkdocs.yml
24+
- scripts/docs/**
2425
- pyproject.toml
2526
issue_comment:
2627
types: [created]
@@ -129,7 +130,11 @@ jobs:
129130
version: 0.9.5
130131

131132
- run: uv sync --frozen --group docs
132-
- run: uv run --frozen --no-sync mkdocs build
133+
# Zensical runs no MkDocs plugins/hooks: generate the API reference and the
134+
# concrete config, build, then generate llms.txt (see scripts/docs/).
135+
- run: uv run --frozen --no-sync python scripts/docs/build_config.py
136+
- run: uv run --frozen --no-sync zensical build -f mkdocs.gen.yml --strict
137+
- run: uv run --frozen --no-sync python scripts/docs/llms_txt.py --site-dir site
133138

134139
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
135140
with:

.github/workflows/shared.yml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,13 @@ jobs:
103103
- name: Check README snippets are up to date
104104
run: uv run --frozen scripts/update_readme_snippets.py --check
105105

106-
# `mkdocs.yml` sets `strict: true` and `pymdownx.snippets: check_paths: true`,
107-
# but until this job existed the docs were only ever built post-merge by
108-
# `deploy-docs.yml`, so a broken link, a missing nav target, or a deleted
109-
# `docs_src/` include went green on the PR and broke the next deploy of main.
110-
# This is the check path; `deploy-docs.yml` stays the deploy path.
106+
# `zensical build --strict` fails on broken links / missing nav targets and
107+
# `pymdownx.snippets: check_paths: true` fails on a deleted `docs_src/`
108+
# include; the llms_txt step additionally re-resolves every snippet and link.
109+
# Until this job existed the docs were only ever built post-merge by
110+
# `deploy-docs.yml`, so those failures went green on the PR and broke the next
111+
# deploy of main. This is the check path; `deploy-docs.yml` stays the deploy
112+
# path.
111113
docs:
112114
runs-on: ubuntu-latest
113115
steps:
@@ -123,5 +125,10 @@ jobs:
123125
- name: Install dependencies
124126
run: uv sync --frozen --all-extras --python 3.10
125127

128+
# Zensical runs no MkDocs plugins/hooks: generate the API reference and
129+
# the concrete config, build strictly, then generate llms.txt.
126130
- name: Build the docs in strict mode
127-
run: uv run --frozen --no-sync mkdocs build --strict
131+
run: |
132+
uv run --frozen --no-sync python scripts/docs/build_config.py
133+
uv run --frozen --no-sync zensical build -f mkdocs.gen.yml --strict
134+
uv run --frozen --no-sync python scripts/docs/llms_txt.py --site-dir site

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,13 @@ venv.bak/
141141
# Rope project settings
142142
.ropeproject
143143

144-
# mkdocs documentation
144+
# documentation
145145
/site
146146
/.worktrees/
147+
# Generated at build time by docs/hooks/ (the API reference tree and the
148+
# concrete Zensical config spliced from mkdocs.yml).
149+
/docs/api/
150+
/mkdocs.gen.yml
147151

148152
# mypy
149153
.mypy_cache/

docs/hooks/gen_ref_pages.py

Lines changed: 0 additions & 40 deletions
This file was deleted.

docs/hooks/llms_txt.py

Lines changed: 0 additions & 184 deletions
This file was deleted.

0 commit comments

Comments
 (0)