migration
This commit is contained in:
+53
-158
@@ -2,199 +2,94 @@
|
||||
icon: lucide/server
|
||||
---
|
||||
|
||||
# Static Docs Hosting Pattern
|
||||
# Runtime And Static Docs Layout
|
||||
|
||||
## Purpose
|
||||
|
||||
This document describes the completed layout and runtime pattern used to host a pre-built static documentation site from the same FastAPI app process that runs the FastMCP server.
|
||||
The project serves native MCP content and a pre-built documentation site from one FastAPI process. Markdown is authored once under `docs/`; runtime providers and Zensical consume that same packaged tree for different purposes.
|
||||
|
||||
This design intentionally avoids runtime docs rendering and avoids a separate docs hosting service.
|
||||
|
||||
It also treats Markdown as the single source of truth for both MCP resources and published docs.
|
||||
|
||||
## Completed-State Layout
|
||||
## Repository Layout
|
||||
|
||||
```mermaid
|
||||
---
|
||||
config:
|
||||
treeView:
|
||||
rowIndent: 40
|
||||
rowIndent: 32
|
||||
lineThickness: 2
|
||||
themeVariables:
|
||||
treeView:
|
||||
labelColor: '#FFFFFF'
|
||||
lineColor: '#FFFFFF'
|
||||
---
|
||||
treeView-beta
|
||||
"project-root"
|
||||
"pyproject.toml"
|
||||
"uv.lock"
|
||||
"zensical.toml"
|
||||
"docs"
|
||||
"index.md"
|
||||
"<project-docs>.md"
|
||||
"contracts"
|
||||
"index.md"
|
||||
"<contract-pages>.md"
|
||||
"mcp_layout.md"
|
||||
"prompts"
|
||||
"<prompt-id>"
|
||||
"PROMPT.md"
|
||||
"references"
|
||||
"skills"
|
||||
"<skill-id>"
|
||||
"SKILL.md"
|
||||
"references"
|
||||
"<reference>.md"
|
||||
"prompts/<prompt-id>/PROMPT.md"
|
||||
"skills/<skill-id>/SKILL.md"
|
||||
"skills/<skill-id>/<supporting-files>"
|
||||
"<general-pages>.md"
|
||||
"site"
|
||||
"static build output"
|
||||
"src"
|
||||
"personal_mcp"
|
||||
"__init__.py"
|
||||
"main.py"
|
||||
"mcp.py"
|
||||
"catalog"
|
||||
"<catalog-modules>.py"
|
||||
"registry"
|
||||
"<registry-modules>.py"
|
||||
"web"
|
||||
"<web-modules>.py"
|
||||
"skills"
|
||||
"<skills-modules>.py"
|
||||
"src/personal_mcp"
|
||||
"mcp.py"
|
||||
"prompts/components/*.py"
|
||||
"prompts/content.py"
|
||||
"prompts/provider.py"
|
||||
"registry/"
|
||||
"skills/provider.py"
|
||||
"web/"
|
||||
```
|
||||
|
||||
Notes:
|
||||
Ownership rules:
|
||||
|
||||
1. docs contains both project-authored pages and the canonical skill Markdown tree.
|
||||
2. site contains static build output only.
|
||||
3. docs/skills contains canonical skill Markdown and reference Markdown.
|
||||
4. docs/prompts contains canonical prompt Markdown used for prompt catalog and document surfaces.
|
||||
5. MCP resources and docs site read from the same Markdown sources.
|
||||
1. `docs/skills/` is owned exclusively by `SkillsDirectoryProvider` at runtime.
|
||||
2. `docs/prompts/` owns prompt prose; Python components own prompt metadata and argument schemas.
|
||||
3. The docs registry owns only general Markdown resources and explicitly excludes skills.
|
||||
4. `site/` is generated output.
|
||||
5. The deleted custom `catalog/` package is not part of the runtime.
|
||||
|
||||
## Runtime Composition
|
||||
|
||||
The runtime process serves two surfaces:
|
||||
|
||||
1. MCP protocol surface from FastMCP
|
||||
2. Static docs surface from FastAPI static mount
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Packaged Skill Directory] --> B[SkillsDirectoryProvider]
|
||||
C[Packaged Prompts and Docs] --> D[Validated Registry]
|
||||
B --> E[FastMCP Server]
|
||||
D --> E
|
||||
E --> F[MCP Transport]
|
||||
E --> G[FastAPI Application]
|
||||
G --> H[Static Mount /docs]
|
||||
H --> I[Zensical Site Output]
|
||||
A[Packaged Skills] --> B[SkillsDirectoryProvider]
|
||||
C[Prompt Components] --> D[FileSystemProvider]
|
||||
E[Packaged Markdown] --> F[Docs Registry]
|
||||
B --> G[FastMCP]
|
||||
D --> G
|
||||
F --> G
|
||||
G --> H[MCP Transport]
|
||||
H --> K[FastAPI Application]
|
||||
L[Pre-built site] --> M[Static /docs Mount]
|
||||
K --> M
|
||||
```
|
||||
|
||||
Runtime guarantees:
|
||||
|
||||
1. The skills provider and prompt/docs registry initialize before resource exposure.
|
||||
2. Duplicate resource and template registration fails startup (`on_duplicate="error"`).
|
||||
3. Skill resources come directly from `SkillsDirectoryProvider` directory discovery.
|
||||
4. Legacy per-skill Python servers, custom skill catalogs, and metadata sidecars are not part of the runtime.
|
||||
1. Providers are installed before serving requests.
|
||||
2. Production provider discovery uses `reload=False`.
|
||||
3. Duplicate components fail according to FastMCP's configured duplicate policy.
|
||||
4. Skills and prompts use native FastMCP component surfaces.
|
||||
5. General docs path parsing rejects traversal, backslashes, non-Markdown paths, and the skill namespace.
|
||||
|
||||
## Build and Publish Flow
|
||||
## Build And Publish Flow
|
||||
|
||||
The docs flow is pre-build only.
|
||||
1. Author Markdown under `docs/` and typed prompts under `src/personal_mcp/prompts/components/`.
|
||||
2. Run `uv run zensical build` to produce `site/`.
|
||||
3. Build the wheel, which packages the authored docs under `personal_mcp/docs/`.
|
||||
4. Start the app and serve MCP plus the static site.
|
||||
|
||||
1. Read authored docs pages and skill markdown sources.
|
||||
2. Build static site with Zensical into site.
|
||||
3. Start app and serve site directory as static files.
|
||||
No runtime Markdown-to-HTML conversion occurs.
|
||||
|
||||
No runtime markdown conversion is required.
|
||||
## Machine-Facing Mapping
|
||||
|
||||
## Content Merge Pattern
|
||||
1. `docs/skills/<skill-id>/SKILL.md` maps to `skill://<skill-id>/SKILL.md`.
|
||||
2. Skill supporting files map to `skill://<skill-id>/<path>`.
|
||||
3. Typed prompt components map to native MCP prompt names.
|
||||
4. General `docs/<path>.md` maps to `resource://docs/{path*}`.
|
||||
|
||||
The published docs site always contains both:
|
||||
The server publishes no tool projections of resources or prompts.
|
||||
|
||||
1. Project-authored docs pages
|
||||
2. Skill Markdown content from docs/skills/*/SKILL.md and references
|
||||
## Public Surface Policy
|
||||
|
||||
This ensures the public docs reflect architectural guidance and the exact Markdown served by MCP.
|
||||
Canonical provider and protocol surfaces are the only public interfaces.
|
||||
|
||||
## Markdown-to-Resource Mapping
|
||||
## Static Mount Expectations
|
||||
|
||||
MCP resources map directly to canonical Markdown documents.
|
||||
|
||||
Example mapping model:
|
||||
|
||||
1. docs/skills/<skill-id>/SKILL.md -> skill://<skill-id>/SKILL.md
|
||||
2. docs/skills/<skill-id>/<path> -> skill://<skill-id>/<path>
|
||||
3. docs/<path>.md -> resource://docs/{path*}
|
||||
|
||||
Catalog discovery resources are:
|
||||
|
||||
1. resource://catalog/prompts_index
|
||||
2. resource://catalog/prompts_index{?q,tag,cursor,limit}
|
||||
3. resource://catalog/prompts/{prompt_id}
|
||||
|
||||
Resource registration details:
|
||||
|
||||
1. `skill://<skill-id>/SKILL.md` resolves to each skill's main instructions.
|
||||
2. `skill://<skill-id>/_manifest` lists every skill file with size and SHA256 hash.
|
||||
3. Per-skill wildcard templates resolve validated supporting-file paths.
|
||||
4. `resource://docs/{path*}` resolves normalized Markdown paths under `docs/`.
|
||||
|
||||
When clients cannot attach MCP resources directly, `ResourcesAsTools` exposes generic `list_resources` and `read_resource` tools over the same provider resources.
|
||||
|
||||
## URI Compatibility Policy
|
||||
|
||||
1. Canonical URIs are the only supported URIs in this runtime.
|
||||
2. No backward-compatibility aliases or dual registration paths are maintained.
|
||||
3. Contract changes should update clients to canonical URIs directly.
|
||||
|
||||
## Why This Pattern
|
||||
|
||||
### Operational Simplicity
|
||||
|
||||
One application process serves both protocol and static docs surfaces.
|
||||
|
||||
### Deterministic Docs
|
||||
|
||||
Published docs are immutable static assets for a given build.
|
||||
|
||||
### Documentation Fidelity
|
||||
|
||||
The docs site and MCP resources resolve from the same Markdown sources.
|
||||
|
||||
### Maintainer Experience
|
||||
|
||||
Authors continue to work in markdown while resource contracts remain machine-consumable.
|
||||
|
||||
## FastAPI Static Mount Expectations
|
||||
|
||||
The FastAPI app is expected to:
|
||||
|
||||
1. Mount static directory containing Zensical output.
|
||||
2. Serve index and asset files from that directory.
|
||||
3. Keep docs route stable across releases.
|
||||
|
||||
Recommended route conventions:
|
||||
|
||||
1. /docs for static site root
|
||||
2. /docs/* for static assets and page routes
|
||||
|
||||
## Update Lifecycle
|
||||
|
||||
For each documentation update:
|
||||
|
||||
1. Edit authored docs and skill markdown content.
|
||||
2. Rebuild static site.
|
||||
3. Restart runtime if needed.
|
||||
|
||||
This keeps docs publication explicit and predictable.
|
||||
|
||||
## Example Source Material
|
||||
|
||||
Existing reference docs remain valid content inputs in this pattern:
|
||||
|
||||
1. docs/skills/pytesting/references/pytest-docs.md
|
||||
2. docs/skills/python-logging/references/python-logging-docs.md
|
||||
3. docs/skills/python-logging/references/json-file-logging.md
|
||||
4. docs/skills/fastapi-uv-docker/references/fastapi-best-practices.md
|
||||
|
||||
These are source documents, not deployment artifacts.
|
||||
The FastAPI app mounts the Zensical output, serves index and asset files, and returns a clear unavailable response when the static output is absent. The site directory is immutable for a given build and remains separate from packaged authored Markdown.
|
||||
|
||||
Reference in New Issue
Block a user