11 KiB
icon
| icon |
|---|
| lucide/library |
Architecture
Overview
The platform is implemented as a resource-first MCP system with an integrated static documentation surface. The same methodology content powers both MCP resources and the published docs site.
An MCP server is a runtime that exposes machine-readable resources and tools through stable interfaces so AI clients can discover and consume context consistently. Here, the server's role is intentionally narrow: publish canonical methodology documents as resources, keep discovery predictable through a catalog layer, and serve the same source material as pre-built static documentation.
The system is complete in three layers:
- Canonical methodology is maintained in Markdown skill documents.
- Catalog resources provide normalized discovery.
- Zensical builds a static site from those same Markdown sources and the FastAPI app serves it in the FastMCP runtime process.
Prompt documents under docs/prompts/ are also indexed and exposed as first-class catalog and prompt surfaces.
This architecture is anchored by three contracts:
- Docs-first authored content contract under
docs/with strict per-skill ownership. - Standard
SKILL.mdfrontmatter consumed directly by FastMCP. - Native
skill://resource URIs with break-and-replace policy for contract changes.
Detailed contract pages:
This architecture keeps authored content human-friendly while preserving machine-stable contracts.
Intent
The architecture is designed to satisfy three long-term requirements:
- Methodology must be editable as markdown by humans.
- Agents must consume stable, discoverable resource contracts, with a minimal read-only catalog tool fallback for constrained clients.
- Public documentation must be pre-built static output served from the application runtime without a separate docs service.
System Model
Pattern Modules
Each skill encapsulates one methodology domain in a docs-owned directory:
docs/skills/<skill-id>/SKILL.mddocs/skills/<skill-id>/references/...
The skill document and references are the authored source of truth; runtime code indexes and serves these files without becoming a second authored source.
Each skill publishes three native resource families:
skill://<name>/SKILL.mdfor primary instructionsskill://<name>/_manifestfor file discovery and integrity metadataskill://<name>/{path*}for supporting files
The main resource returns canonical Markdown. The generated manifest lists real relative paths, sizes, and SHA256 hashes so clients can load supporting material selectively.
Prompt Modules
Prompt guidance can be authored in docs/prompts/ using either canonical prompt directories (docs/prompts/<prompt-id>/PROMPT.md) or legacy markdown files during migration.
Prompt modules publish two additive surfaces:
- prompt resources for catalog and document retrieval
- MCP prompt objects for prompt-list/get-prompt style client workflows
This keeps authored markdown as source-of-truth while allowing clients to discover and invoke prompts directly.
Catalog Module
The catalog publishes normalized records for prompts. Skills use FastMCP's native resource discovery and client utilities instead of a parallel catalog.
Typical catalog resources:
- resource://catalog/prompts_index
- resource://catalog/prompts_index{?q,tag,cursor,limit}
- resource://catalog/prompts/{prompt_id}
Only canonical catalog resources are part of the runtime contract in this phase.
Registry Loader
Importing the package does not read or parse documentation. The MCP server and FastAPI application factories initialize content when constructing a runnable server. The prompt/docs registry reads packaged resources through importlib.resources.files(...) and Traversable APIs; the native skills provider receives the packaged personal_mcp/docs/skills filesystem path.
Loader responsibilities:
- Parse and validate prompt frontmatter.
- Build the prompt catalog and MCP prompt objects.
- Index authored Markdown for
resource://docs/{path*}.
Skill loading is owned by SkillsDirectoryProvider, which scans the packaged skills directory and constructs native resources before the server starts serving requests.
The immutable registry is cached for the process lifetime. Each Uvicorn worker constructs and retains its own registry because worker processes do not share Python objects. Registry load failure is a server-factory startup error, not a package-import error or partial runtime warning.
Content Sources
Content is authored in markdown under docs/ and managed as long-form reference material. Skill documents and companion references now live under docs/skills/, while project-authored pages remain alongside them in the docs tree. Resource handlers expose the same authored documents through stable resource URIs.
The repository root docs/ directory is the only authored source. The src/personal_mcp/docs path is a relative symlink to that directory for source-checkout and editable-install workflows; it is not a second content tree and packaging does not depend on traversing it.
For wheel builds, Hatchling's normal src/personal_mcp package traversal follows the relative docs symlink and archives its targets as regular files under personal_mcp/docs/. No force-include mapping is used because that would add the same archive paths twice. The prompt/docs registry uses importlib.resources.files, while SkillsDirectoryProvider scans the package-relative filesystem path. Neither path depends on the current working directory.
Static Docs Surface
Static docs are built directly from two markdown source streams:
- Project-authored docs pages
- Skill and reference markdown pages
The merged docs tree is built by Zensical into static files and served by the FastAPI app.
Generated site/ files are deployment assets for the human-facing static site. They are separate from the authored Markdown resources packaged under personal_mcp/docs/.
Data Flow
flowchart TD
A[Authored Skill Directories] --> B[SkillsDirectoryProvider]
B --> C[Native Skill Resources]
D[Authored Prompts and Docs] --> E[Prompt and Docs Registry]
E --> F[Prompt Catalog and Docs Resources]
A --> G[Zensical Static Build]
D --> G
G --> H[FastAPI Static Mount]
Contracts
Metadata Contract
Each skill declares standard frontmatter in docs/skills/<skill-id>/SKILL.md.
For the full field-level contract, validation model, and FastMCP metadata mapping, see Frontmatter Contract.
Required fields:
- name
- description
The directory name is the provider identity and must match name. There is no skill catalog metadata or sidecar.
URI Contract
Canonical resource URIs are:
For the full URI semantics, parameter validation rules, and compatibility policy, see URI Contract.
- skill://<skill_name>/SKILL.md
- skill://<skill_name>/_manifest
- skill://<skill_name>/<supporting_path>
- resource://docs/{path*}
- resource://catalog/prompts_index
- resource://catalog/prompts_index{?q,tag,cursor,limit}
- resource://catalog/prompts/{prompt_id}
- resource://prompts/{prompt_id}/document
Validation rules:
skill_nameis the lowercase kebab-case skill directory name.supporting_pathis a provider-validated relative path within that skill.- Docs
path*resolves only to normalized Markdown paths underdocs/.
Resource Registration Contract
Skill resources are registered by one SkillsDirectoryProvider; prompt and docs resources remain registered from the validated registry.
Registration rules:
- Use RFC6570 URI templates where appropriate.
- Mark documentation resources as read-only and idempotent.
- Set explicit mime types for resource responses.
- Configure duplicate URI handling with
on_duplicate="error"for startup safety.
This keeps runtime behavior deterministic and prevents accidental URI collisions.
Versioning Rule
URIs are unversioned and canonical in this phase.
- Breaking URI changes are handled as direct replacement.
- No compatibility aliases or dual URI families are maintained.
Static Hosting Pattern
The docs site is pre-built and served by the same FastAPI runtime process used by the MCP app.
Runtime behavior:
- App starts.
- FastAPI mounts the static docs output directory.
- Requests to docs paths are served as static assets.
This provides a single deployment artifact with no runtime markdown rendering dependency.
Advantages
Single Source of Truth
Methodology is authored once and reused in both MCP resources and docs pages.
High-Fidelity Agent Context
Resources expose the same canonical Markdown that humans author and review.
Operational Simplicity
A single app process serves MCP and docs surfaces.
Long-Term Maintainability
Markdown remains easy to review, while contracts remain stable for clients.
Client Independence
Clients can use Ask, Edit, or Agent modes without requiring prompt-first orchestration. Prompt objects are available as an additive MCP surface, while resource retrieval remains the canonical source path. MCP affordances are still chat-surface-dependent: some clients or sessions expose resource attachment directly, while others make tool invocation the more reliable retrieval path.
Authoring and Publishing Lifecycle
- Update markdown reference content.
- Keep skill
nameand directory identity aligned. - Build static docs with Zensical and run provider tests.
- Package authored docs into
personal_mcp/docs/. - Serve native MCP resources and the static docs mount.
Scope and Non-Goals
In-scope:
- Resource-first methodology delivery
- Native FastMCP skill discovery
- Pre-built static docs hosting in app runtime
Out-of-scope:
- Prompt-first orchestration as the primary interface
- Large tool inventories duplicating static guidance across skill modules
- Separate dynamic docs service at runtime
The prompt catalog remains an independent surface. Tool-only skill clients use generic resource tools rather than a skill-specific compatibility layer.
Example Content Inputs
Existing markdown reference sets are valid examples of authored source material for this architecture:
- docs/skills/pytesting/references/pytest-docs.md
- docs/skills/python-logging/references/python-logging-docs.md
- docs/skills/python-logging/references/json-file-logging.md
- docs/skills/fastapi-uv-docker/references/fastapi-best-practices.md
These inputs are treated as content sources, while native skill URIs and generated manifests form the machine-facing skill contract.