Serve Markdown by MkDocs (DocView)
Use this skill when you want a quick, web-based viewer for Markdown scattered across a repo (not necessarily docs/), while preserving the original directory structure.
Typical user phrasing that should trigger this skill:
- •“serve markdowns/docs/md/textfiles/etc with mkdocs, using
<work_dir>as the work dir”
Interpretation:
- •
<work_dir>is the work directory (create it if missing; reuse it if it exists). This folder holds the refresh script, a scanner script, a YAML manifest, the MkDocs config (if needed), a staged symlink tree, andsite/build output. - •By default, staged symlinks are placed under a subdirectory (default:
<work_dir>/_staged/) so you can ignore them with a local<work_dir>/.gitignorewhile keeping scripts/config tracked if you want.
This skill’s default approach is:
- •generate a staged tree under
<work_dir>/_staged/(typically symlinks; can be adapted to copying) - •generate
<work_dir>/mkdocs.ymlonly if missing (existing config is preserved) - •enable Mermaid + KaTeX by default (via
pymdown-extensions+ KaTeX/Mermaid JS/CSS includes) - •run
<mkdocs_cmd> serve(use MkDocs defaults unless you specify otherwise)
Dependency Resolution (MkDocs)
This skill must locate an existing mkdocs first. Do not auto-install it.
Resolution order (stop at the first one that works):
- •Project Pixi environment (preferred when available):
pixi run mkdocs --version
If that works, use <mkdocs_cmd> = pixi run mkdocs.
- •Active virtualenv / venv (if the user is already in one):
mkdocs --version python -m mkdocs --version
If either works, use <mkdocs_cmd> = mkdocs (or python -m mkdocs if the console script is not available).
- •Global Pixi tools (if the user installed tools via
pixi globaland exposed them onPATH):
pixi global list mkdocs --version
If that works, use <mkdocs_cmd> = mkdocs.
- •uv tools (only if
mkdocsis already installed as a tool; do not trigger installs):
uv tool list uv tool dir mkdocs --version
If uv tool list shows mkdocs but mkdocs is not on PATH, run it via the uv tools directory:
tool_dir="$(uv tool dir)"
"${tool_dir}/mkdocs/bin/mkdocs" --version
If that works, use <mkdocs_cmd> = mkdocs (or use the explicit path from above).
- •System Python (last resort):
python3 -m mkdocs --version python -m mkdocs --version
If either works, use <mkdocs_cmd> = python3 -m mkdocs (or python -m mkdocs).
If none of the above finds a working mkdocs, fail fast and report “missing dependency: mkdocs”. Never attempt to install mkdocs automatically; let the user install it in their preferred environment manager.
Plugin Installation (after MkDocs is found)
Once mkdocs is found, the agent may auto-install any MkDocs plugins/themes/markdown extensions needed by <work_dir>/mkdocs.yml, but must install them into the same environment that provides <mkdocs_cmd>.
Guidance:
- •Preferred verification step: run
<mkdocs_cmd> build -f <work_dir>/mkdocs.yml(or<mkdocs_cmd> serve -f <work_dir>/mkdocs.yml) and look for missing-module errors (for example:No module named ..., missingmkdocs-material, missingpymdown-extensions, missingmkdocs-extrafiles, etc). - •Install only what’s needed to satisfy the config (theme/plugins/markdown_extensions). Do not install
mkdocsitself automatically.
Notes:
- •Mermaid and KaTeX support in this skill’s scaffolded config does not require an MkDocs plugin; it uses built-in
extra_javascript/extra_csspluspymdown-extensions(pymdownx.superfencesandpymdownx.arithmatex).
Environment-specific install strategy:
- •If
<mkdocs_cmd>ispixi run mkdocs(project Pixi):
- •Prefer updating the project manifest (do not
pip installdirectly):
pixi add --pypi mkdocs-material pymdown-extensions
Add other required plugins similarly (example):
pixi add --pypi mkdocs-extrafiles mkdocs-include-markdown-plugin
Then re-run <mkdocs_cmd> build -f <work_dir>/mkdocs.yml to verify.
- •If
<mkdocs_cmd>comes from a venv / system Python:
- •Install into that Python (use the same interpreter that runs MkDocs):
python -m pip install mkdocs-material pymdown-extensions
Then re-run <mkdocs_cmd> build -f <work_dir>/mkdocs.yml to verify.
- •If
<mkdocs_cmd>comes from a uv tool install:
- •Install into the uv tool environment (only after confirming it exists; do not trigger installs of MkDocs itself):
tool_dir="$(uv tool dir)"
ls -la "${tool_dir}/mkdocs/bin" # inspect this directory to find the tool's python
"${tool_dir}/mkdocs/bin/python" -m pip install mkdocs-material pymdown-extensions
Then re-run the uv-provided MkDocs command to verify.
When to Use
- •You have Markdown scattered across multiple folders (notes, design docs, runbooks, PRDs, etc).
- •You want “browse everything” without curating
nav:in the mainmkdocs.yml. - •You want a dedicated service name/port separate from the main docs site.
Parameters to Collect
- •Work directory: e.g.
docview-prd,docview-reports,tmp/docview-issues - •Site title: e.g.
PRD View - •Serve address/port:
- •Default: keep it local (MkDocs default is typically
127.0.0.1:8000) - •If the user asks to “make it public”: bind
0.0.0.0(for example0.0.0.0:8000or0.0.0.0:<port>)
- •Default: keep it local (MkDocs default is typically
- •Scan inputs (repo-relative paths or glob patterns): e.g.
<docs_dir> <notes_dir>or<docs_dir>/**or**/*.md - •Optional: include/exclude rules (hidden dirs, externals, and whether to respect gitignore when discovering files)
Workflow
0) If <work_dir> already exists, look for “refresh” cues first
If the user points to an existing <work_dir>, they may mean “refresh/rebuild” rather than “re-scaffold”.
Before generating anything, check for these files inside <work_dir>:
- •
refresh-docs-tree.sh: if present, prefer running it to recreate the staged tree (typically under_staged/, or your chosen--staging-dir), while preserving existing rules and defaults. - •
mkdocs.yml: if present, prefer reusing it (preservesdev_addr/ ports, theme/plugins, etc). - •
docview.yml: if present, prefer reusing it (preserves the default scan patterns, exclusions, and gitignore policy). - •
README.md: often documents the env var names (like*_DIRS/*_REPO_ROOT) and default scan patterns.
Typical “refresh intent” actions:
bash <work_dir>/refresh-docs-tree.sh <mkdocs_cmd> serve -f <work_dir>/mkdocs.yml
Only re-scaffold (and overwrite) if the user explicitly asks to “regenerate config/script” (use --force).
1) Create (or reuse) a dedicated work dir
Run the scaffolder (writes a new service folder with a refresh-docs-tree.sh, .gitignore, and README):
pixi run python magic-context/skills/devel/serve-md-by-mkdocs/scripts/scaffold_docview_service.py \ --work-dir <work_dir> \ --site-name "Reports View" \ --staging-dir _staged \ --default-target .
Then run:
bash <work_dir>/refresh-docs-tree.sh <mkdocs_cmd> serve -f <work_dir>/mkdocs.yml
If you want a non-default bind address/port, either:
- •scaffold with
--dev-addr <addr:port>(bakes it into<work_dir>/mkdocs.yml), or - •scaffold with
--public(bakes0.0.0.0:8000into<work_dir>/mkdocs.yml), or - •override at runtime:
<mkdocs_cmd> serve -f <work_dir>/mkdocs.yml -a 0.0.0.0:<port>
2) Re-index specific paths/patterns (without re-scaffolding)
Once <work_dir>/refresh-docs-tree.sh exists, you can point it at specific paths:
- •
bash <work_dir>/refresh-docs-tree.sh <docs_dir> <notes_dir> - •or set the generated
*_DIRSenv var shown in<work_dir>/README.md - •or edit
<work_dir>/docview.ymlto change the default patterns used when you runbash <work_dir>/refresh-docs-tree.shwith no args/env override
Manifest (<work_dir>/docview.yml)
<work_dir>/docview.yml captures your “what should be staged” intent for symlink creation.
Schema:
- •
magic-context/skills/devel/serve-md-by-mkdocs/schemas/docview.schema.json
Key fields:
- •
mkdocs.dev_addr: records the intended bind address/port (and is used to generate<work_dir>/mkdocs.ymlonly when that file is missing) - •
scan.include_globs: glob patterns used to discover Markdown (repo-relative) - •
scan.exclude_globs: glob patterns excluded from Markdown discovery - •
scan.force_globs: glob patterns to scan even if gitignored (explicit user intent) - •
scan.auto_exclude_generated: if true (default), avoid scanning DocView/MDView workdirs and their generated trees - •
scan.respect_gitignore: defaulttrue(do not scan gitignored dirs/files for Markdown discovery) - •
assets.include_images: defaulttrue(stage local images referenced by selected Markdown)
Example (abridged):
version: 1 scan: auto_exclude_generated: true respect_gitignore: true include_globs: ["**/*.md"] exclude_globs: ["<big_dir>/**"] force_globs: ["<gitignored_dir>/**"] assets: include_images: true
Rules:
- •By default, Markdown discovery respects
.gitignoreand usesscan.include_globsfrom the manifest. - •By default, discovery excludes any directories that start with
.(controlled byscan.include_hidden: false). - •By default, discovery also auto-excludes DocView/MDView workdirs (including their staged trees like
_staged/ordocs/, andsite/) using file/dir-structure heuristics, to avoid self-indexing loops and duplicate pages. - •If you explicitly want to scan a gitignored location, add it under
scan.force_globs(or pass it as an explicit arg torefresh-docs-tree.sh, which is treated as strong intent). - •Referenced image assets are still staged even if gitignored, as long as the file exists.
Default scan behavior (when you don’t specify scan locations): the scaffolder writes scan.include_globs so the refresh script scans the whole workspace for Markdown (for example **/*.md) while respecting .gitignore.
3) Add Pixi tasks (optional but recommended)
Add three tasks under [tool.pixi.tasks]:
- •
<task_prefix>-refresh:bash <work_dir>/refresh-docs-tree.sh - •
<task_prefix>-serve:bash <work_dir>/refresh-docs-tree.sh && mkdocs serve -f <work_dir>/mkdocs.yml - •
<task_prefix>-build:bash <work_dir>/refresh-docs-tree.sh && mkdocs build -f <work_dir>/mkdocs.yml
Pick a port based on your local context (or rely on MkDocs defaults).
Note: Pixi tasks run inside the project Pixi environment. Only add these tasks if mkdocs (and any referenced theme/plugins/extensions from <work_dir>/mkdocs.yml) are available in that environment.
Verification (required)
After running bash <work_dir>/refresh-docs-tree.sh, verify that all symlinks under the staging directory are valid (no broken links):
find <work_dir>/<staging_dir> -xtype l -print
Expected: no output.
<staging_dir> is usually _staged (or whatever you set via --staging-dir; it should match docs_dir in <work_dir>/mkdocs.yml).
If there is output, rerun the refresh and/or check whether the target source files were moved/deleted, or whether your selected paths/patterns (*_DIRS or CLI args) include paths that no longer exist.
Note: refresh may emit warnings like “missing asset referenced by …” when Markdown references images that don’t exist on disk; those files won’t be staged.
Also verify that the work dir contains the scanner script which decides what gets staged (Markdown + referenced image assets):
- •
<work_dir>/scan-files-to-stage.py
Notes / Gotchas
- •Git hygiene: by default,
<work_dir>/.gitignoreignores the staging subdir (like_staged/),site/,mkdocs.yml, andrepo-root.txt. Keep or change this based on whether you want staged symlinks tracked. - •Gitignore-aware scanning: by default, file discovery respects
.gitignore(gitignored files/dirs won’t be scanned). However, if a selected Markdown page references a gitignored image file, it will still be staged (symlinked) as long as the file exists. - •Auto-excluding generated workdirs: by default, the scanner avoids scanning DocView/MDView workdirs (including this one) to prevent recursion/duplication. Set
scan.auto_exclude_generated: falsein<work_dir>/docview.ymlif you intentionally want to index those directories. - •Manifest is required:
<work_dir>/docview.ymlis always created by this skill, and<work_dir>/scan-files-to-stage.pytreats a missing manifest as an error. - •No-symlink alternative: if you prefer not to stage via symlinks/copies, consider using the
mkdocs-extrafilesplugin to map externalsrcpaths into virtualdestpaths underdocs_dir. - •Symlinks: the default implementation uses symlinks. On Windows, symlink creation may require elevated permissions or Developer Mode; if this is a blocker, reimplement the refresh step by copying files instead of linking.
- •Mermaid: enable
pymdownx.superfenceswith amermaidfence + Material integration (the scaffolder emits this). - •KaTeX (math): the scaffolder also emits
pymdownx.arithmatex+ KaTeX auto-render viaextra_javascript/extra_css(you can swap to MathJax if preferred). - •Mermaid/KaTeX init scripts: the scaffolder writes
<work_dir>/javascripts/mermaid-init.jsand<work_dir>/javascripts/katex-init.js, andrefresh-docs-tree.shstages them intodocs_dirso MkDocs can serve them.