Claude CodeでMkDocs Materialの文書を書く — build --strictで検証
Claude CodeにMkDocs Materialの文書を書かせ、mkdocs build --strictでnav漏れとリンク切れを自己修正させる手順です。validation、permissions、Stop hookの例付きです。
Claude CodeにMkDocs Materialのドキュメントを書かせるなら、mkdocs build --strict を完了条件にするのが手堅いです。strictモードは、警告が1件でも出るとビルドを中断します。nav(ナビゲーション)への登録漏れも、存在しないファイルへのリンクも、Claude Codeが自分で読んで直せる失敗に変わります。
文書は、文法が正しくても壊れます。ページを足したのにnavに入れ忘れる。見出しを変えたせいで、別ページからのアンカーリンクが切れる。目で読み返しても気づきにくいこの種の欠陥を、コマンド1本の終了コードで拾う構成を、設定ファイルごとに示します。
--strict はどの警告を落とすのか
mkdocs build --strict(短縮形は -s)は、警告が出た時点でビルドを中断するフラグです。CLIリファレンスの説明は「警告があればビルドを中断する」で、mkdocs.yml の strict: true でも同じ動作にできます(既定は false)。
肝心なのは、何が「警告」になるかです。リンクとnavの検査は、validation という設定で重大度を選びます。値は warn / info / ignore の3つです。warn にした項目が、strictのときにエラーへ変わります。
| 項目 | 検出する内容 | MkDocs 1.6の既定 |
|---|---|---|
nav.omitted_files | 検出する内容docsにあるのにnavへ載っていないページ | MkDocs 1.6の既定info |
nav.not_found | 検出する内容navが指すファイルが存在しない | MkDocs 1.6の既定warn |
links.not_found | 検出する内容本文のリンク先ファイルが存在しない | MkDocs 1.6の既定warn |
links.anchors | 検出する内容リンク先ページに該当アンカーがない | MkDocs 1.6の既定info |
links.absolute_links | 検出する内容/foo/bar.html のような絶対リンク | MkDocs 1.6の既定info |
links.unrecognized_links | 検出する内容認識できない相対リンク | MkDocs 1.6の既定info |
既定のままだと、--strict を付けても落ちるのは「navのファイルが無い」と「リンク先ファイルが無い」の2種類だけです。ページの登録漏れとアンカー切れは info なので、素通りします。Claude Codeに検証を任せる前に、ここを締める必要があります。
mkdocs.yml を最大限に厳しくする
公式の設定リファレンスは、ほとんどのサイトに向く「最大の厳しさ」の設定を載せています。次の形が、それに沿った例です。
site_name: Example Docs
theme:
name: material
validation:
omitted_files: warn
absolute_links: warn
unrecognized_links: warn
anchors: warnomitted_files のように nav や links を省いたキーは、両方に効きます。たとえば absolute_links: warn は nav.absolute_links と links.absolute_links を同時に warn にします。アンカーの検査は1.6で入ったものなので、手元のMkDocsが古いと効きません。
意図して載せないページもあるでしょう。その場合は not_in_nav にパターンを書くと、omitted_files の警告が出なくなります。exclude_docs に入れたファイルは、not_in_nav を含意します。Claude Codeにはこの2つを使い分けさせ、警告を消すためだけにnavへ無理に追加させないことが大切です。
strict: true を mkdocs.yml に書く方法もありますが、コマンドラインに --strict を付ける運用のほうが、作業中だけ緩めたいときに融通が利きます。CIと手元で同じコマンドを使えば、「手元では通ったのにCIで落ちた」という差も出にくくなります。設定ファイルを切り替えたいときは -f で別のファイルを指定できます。
Claude Codeへ検証を渡す2つの場所
設定が締まったら、次は「いつ検証するか」を決めます。Claude Codeには、指示として渡す場所と、強制として渡す場所があります。
CLAUDE.mdに完了条件を書く
CLAUDE.md はセッションの開始時に読まれる指示です。文書プロジェクトでは、書き方の規約よりも「何をもって完了とするか」を先に置きます。
# ドキュメント作業のルール
- ページを追加・移動・改名したら、`mkdocs.yml` の nav を同時に更新する
- 作業の終わりに `mkdocs build --strict` を実行し、終了コード 0 を確認する
- 警告が出たら、警告を消すために `validation` の値を下げない。原因のファイルを直す
- `not_in_nav` と `exclude_docs` は、読者に見せないページにだけ使う3つ目の規則が要です。厳しい設定の下で行き詰まったモデルは、設定側を緩めるほうが早いと判断しがちです。禁止を明文化しておけば、その近道を塞げます。
permissionsで再実行を確認なしにする
検証コマンドは何度も回します。そのたびに承認を求められると、自己修正のループが人の手待ちで止まります。許可ルールは Bash(<コマンド>) の形で書き、* で可変部分を表せます。
{
"permissions": {
"allow": [
"Bash(mkdocs build --strict)",
"Bash(mkdocs build --strict *)"
]
}
}この内容は .claude/settings.json に置きます。コマンド全体が一致する場合だけ許可されるので、mkdocs gh-deploy のような公開系は引き続き確認が入ります。gh-deploy はGitHub Pagesへ公開するサブコマンドです。許可に混ぜないでください。
警告をClaude Codeが直せる形で読む
--strict が失敗すると、MkDocsは警告文を出します。その文面は、公式リファレンスに例が載っています。Claude Codeに読ませると、何を直すかが文面から特定できます。
strict が失敗したときの切り分け
- Q警告文は「not included in the nav configuration」か?答えが次へ答えがはい
docsにあるのにnavへ載っていないページです。
mkdocs.ymlのnavに追記します。読者に見せないページならnot_in_navに入れます。 - Q警告文は「contains a link ... but the target is not found」か?答えが次へ答えがはい
リンク先のファイルが存在しません。パスの打ち間違いか、改名・移動の追従漏れです。リンク元の
.md側を直します。 - Q警告文は「does not contain an anchor」か?答えが次へ答えがはい
ページはあるものの、
#見出しに対応する見出しがありません。見出しを変えたなら、リンク側のアンカーも合わせます。
それ以外は文面を読んで原因を特定
「unrecognized relative link」は、../foo/bar/ のようにMarkdownファイルを指していない相対リンクです。文面に「Did you mean ...」と候補が出るので、それに従います。
対応を表にすると次のとおりです。警告文はMkDocs公式の例からの引用で、実際の出力は対象ファイル名に置き換わります。
| 警告 | 直す場所 | Claude Codeへの指示の例 |
|---|---|---|
| navに載っていないページ | 直す場所mkdocs.yml | Claude Codeへの指示の例「docs/guide/setup.md をnavの「ガイド」配下に追加して」 |
| リンク先が見つからない | 直す場所リンク元の .md | Claude Codeへの指示の例「警告に出たリンクのパスを実在するファイルに直して」 |
| アンカーが存在しない | 直す場所リンク元または見出し | Claude Codeへの指示の例「リンクを現在の見出しに合わせて。見出しを戻さないで」 |
| 絶対リンク | 直す場所リンク元の .md | Claude Codeへの指示の例「相対パスに書き換えて。または relative_to_docs を使う」 |
絶対リンクについては、validation.links.absolute_links に relative_to_docs を指定する方法があります(1.6の新機能)。/dir2/bar.md のようにdocsのルートからの絶対パスで書けるようになり、検証も相対リンクと同じ規則で走ります。リンクを書き換えるより、方針ごと決めたいときに選ぶ手です。
編集のたびに強制する — Stop hookでビルドを走らせる
CLAUDE.mdの指示は、守られないことがあります。確実に走らせたいなら、hookを使います。Stop はClaude Codeが応答を終えようとする時点で発火し、ここでブロックすると、会話が続きます。
次のスクリプトは、strictビルドが失敗したら終了コード2で終わり、標準エラーに警告を流します。
#!/bin/sh
# .claude/hooks/mkdocs-strict.sh
out=$(mkdocs build --strict 2>&1) || {
echo "$out" >&2
exit 2
}{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "sh .claude/hooks/mkdocs-strict.sh",
"timeout": 120
}
]
}
]
}
}hookの終了コードが2だと、Claude Codeはその動作をブロックします。Stop ではClaudeの停止が防がれ、標準エラーの内容が次の指示として渡されます。つまり、警告文がそのまま修正依頼になります。
無限ループを心配する必要はあまりありません。Stop hookが連続で8回続行させると、Claude Codeは次のブロックを無効にしてターンを終えます。それでも、直せない警告(外部の変更が必要など)で8回消費するのは無駄です。そのときは、残った警告を人間に報告させる一文をCLAUDE.mdに足すのが効きます。
timeout は秒単位で、commandタイプの既定は600秒です。ページ数の多いサイトでは、ビルド時間に合わせて見直してください。
hookの組み立て方そのものは、hooksの設定を一から試す入門で扱っています。編集直後に検査する PostToolUse 型の設計は、actionlintでworkflowを検証する手順と同じ考え方です。
つまずきやすい点
MkDocsとMaterialの版がずれる。Material for MkDocsはpipでインストールします。公式は、次のメジャー版へ意図せず上がらないよう pip install mkdocs-material=="9.*" のように固定し、pip freeze > requirements.txt でロックファイルを作ることを勧めています。検証結果が環境で変わると、自己修正のループが成り立ちません。依存はMkDocs、Markdown、Pygments、Python Markdown Extensionsまでまとめて入ります。
Dockerイメージはプレビュー専用。公式イメージ squidfunk/mkdocs-material では mkdocs が入口で、既定のコマンドは serve です。ビルドの検証にも使えますが、公式は、コンテナは本番デプロイには向かない(開発用サーバーは本番想定でない)としています。プラグインを足したいときは、FROM squidfunk/mkdocs-material を元にしたDockerfileを作ります。
strictに通っても、読めるとは限らない。検査の対象は、リンクとnavの整合、それにプラグインや拡張が出す警告です。文章の正確さ、手順の抜け、スクリーンショットの古さは見ません。ここは人間のレビューか、別の検査(textlintなど)の領分です。
独自の検査も警告として足せる。 hooks(1.4以降)にPythonスクリプトを登録すると、独自の検査を警告として足せます。公式の例では、http:// で始まるリンクを検出して警告を出しています。strictモードでは、その警告も致命的になります。
prebuild_index のような任意機能の失敗。公式の説明では、node が見つからないなどの失敗は通常「警告を出して続行」ですが、--strict を付けるとエラーになります。ローカルでは通るのにCIで落ちる、という差の一因になりえます。
検証コマンドの使い分け
| 目的 | コマンド | 向く場面 |
|---|---|---|
| 書きながら見た目を確認 | コマンドmkdocs serve | 向く場面人が画面で確認するとき |
| リンク・navの整合を検証 | コマンドmkdocs build --strict | 向く場面Claude Codeの完了条件、CI |
| 公開 | コマンドmkdocs gh-deploy | 向く場面検証が通ったあと、人が実行 |
serve は警告を出しても動き続けるため、Claude Codeの検証には向きません。終了コードで成否が返る build --strict が、自己修正のループには合います。公開は検証と切り離して、許可リストに入れないのが安全です。
同じ「出力を差分や終了コードで確かめる」発想は、kustomizeのoverlayを組む手順やhreflangの相互参照を洗う検証にも通じます。対象が設定ファイルでも文書でも、完了条件を機械が判定できる形にすることが、Claude Codeを使いこなす近道です。
まとめ
MkDocs Materialの文書づくりでは、validation を warn に締めたうえで mkdocs build --strict を完了条件にすると、nav漏れ・リンク切れ・アンカー切れがビルド失敗として表に出ます。CLAUDE.mdには「設定を緩めて警告を消さない」を明記し、permissionsで再実行を許可し、Stop hookで強制する。この三段で、Claude Codeは警告文を読んで自分で直す流れになります。
既定のまま --strict だけを付けても、ページの登録漏れとアンカー切れは通ります。検証コマンドより先に見直す対象は、validation の値です。