migration
This commit is contained in:
+62
-207
@@ -6,249 +6,104 @@ icon: lucide/library
|
||||
|
||||
## 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.
|
||||
The application combines a FastMCP server with a pre-built Zensical documentation site. Markdown under `docs/` is the single authored content tree, while native FastMCP providers own skill and prompt discovery.
|
||||
|
||||
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 runtime has four content paths:
|
||||
|
||||
The system is complete in three layers:
|
||||
1. `SkillsDirectoryProvider` publishes native `skill://` resources from packaged skill directories.
|
||||
2. `FileSystemProvider` discovers typed `@prompt` functions from packaged Python modules.
|
||||
3. The general docs registry publishes non-skill Markdown through `resource://docs/{path*}`.
|
||||
4. FastAPI serves the pre-built `site/` directory.
|
||||
|
||||
1. Canonical methodology is maintained in Markdown skill documents.
|
||||
2. Catalog resources provide normalized discovery.
|
||||
3. Zensical builds a static site from those same Markdown sources and the FastAPI app serves it in the FastMCP runtime process.
|
||||
There is no custom skill catalog, prompt catalog, or prompt registry model.
|
||||
|
||||
Prompt documents under `docs/prompts/` are also indexed and exposed as first-class catalog and prompt surfaces.
|
||||
## Source Ownership
|
||||
|
||||
This architecture is anchored by three contracts:
|
||||
### Skills
|
||||
|
||||
1. Docs-first authored content contract under `docs/` with strict per-skill ownership.
|
||||
2. Standard `SKILL.md` frontmatter consumed directly by FastMCP.
|
||||
3. Native `skill://` resource URIs with break-and-replace policy for contract changes.
|
||||
|
||||
Detailed contract pages:
|
||||
|
||||
1. [Content Contract](./contracts/index.md#content-contract)
|
||||
2. [Frontmatter Contract](./contracts/frontmatter.md)
|
||||
3. [URI Contract](./contracts/uris.md)
|
||||
|
||||
This architecture keeps authored content human-friendly while preserving machine-stable contracts.
|
||||
|
||||
## Intent
|
||||
|
||||
The architecture is designed to satisfy three long-term requirements:
|
||||
|
||||
1. Methodology must be editable as markdown by humans.
|
||||
2. Agents must consume stable, discoverable resource contracts, with a minimal read-only catalog tool fallback for constrained clients.
|
||||
3. 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:
|
||||
Each skill owns one directory:
|
||||
|
||||
1. `docs/skills/<skill-id>/SKILL.md`
|
||||
2. `docs/skills/<skill-id>/references/...`
|
||||
2. `docs/skills/<skill-id>/<supporting-path>`
|
||||
|
||||
The skill document and references are the authored source of truth; runtime code indexes and serves these files without becoming a second authored source.
|
||||
`SkillsDirectoryProvider` publishes:
|
||||
|
||||
Each skill publishes three native resource families:
|
||||
1. `skill://<name>/SKILL.md`
|
||||
2. `skill://<name>/_manifest`
|
||||
3. `skill://<name>/{path*}`
|
||||
|
||||
1. `skill://<name>/SKILL.md` for primary instructions
|
||||
2. `skill://<name>/_manifest` for file discovery and integrity metadata
|
||||
3. `skill://<name>/{path*}` for supporting files
|
||||
The provider parses standard skill frontmatter and generates the manifest. The general docs registry excludes `skills/**`, so only the native provider owns this namespace.
|
||||
|
||||
The main resource returns canonical Markdown. The generated manifest lists real relative paths, sizes, and SHA256 hashes so clients can load supporting material selectively.
|
||||
### Prompts
|
||||
|
||||
### Prompt Modules
|
||||
Each prompt has two coordinated sources:
|
||||
|
||||
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.
|
||||
1. `src/personal_mcp/prompts/components/<module>.py` owns the typed signature and runtime metadata.
|
||||
2. `docs/prompts/<prompt-id>/PROMPT.md` owns the canonical prompt prose.
|
||||
|
||||
Prompt modules publish two additive surfaces:
|
||||
The component loads Markdown with `importlib.resources`. The renderer strips documentation frontmatter, requires exact placeholder-to-argument equality, and substitutes typed values. `FileSystemProvider(reload=False)` discovers the components during server construction.
|
||||
|
||||
1. prompt resources for catalog and document retrieval
|
||||
2. MCP prompt objects for prompt-list/get-prompt style client workflows
|
||||
FastMCP exposes prompts through native `prompts/list` and `prompts/get` operations.
|
||||
|
||||
This keeps authored markdown as source-of-truth while allowing clients to discover and invoke prompts directly.
|
||||
### General Docs
|
||||
|
||||
### Catalog Module
|
||||
The docs registry indexes packaged Markdown for `resource://docs/{path*}`. It rejects `skills/**` because skills are provider-owned. Prompt Markdown can remain visible as general documentation, but prompt invocation is owned by the native prompt provider.
|
||||
|
||||
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:
|
||||
|
||||
1. resource://catalog/prompts_index
|
||||
2. resource://catalog/prompts_index{?q,tag,cursor,limit}
|
||||
3. 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:
|
||||
|
||||
1. Parse and validate prompt frontmatter.
|
||||
2. Build the prompt catalog and MCP prompt objects.
|
||||
3. 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`](https://docs.python.org/3/library/importlib.resources.html#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:
|
||||
|
||||
1. Project-authored docs pages
|
||||
2. 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
|
||||
## Runtime Composition
|
||||
|
||||
```mermaid
|
||||
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]
|
||||
A[Packaged Skill Directories] --> B[SkillsDirectoryProvider]
|
||||
C[Typed Prompt Components] --> D[FileSystemProvider]
|
||||
E[Packaged Prompt Markdown] --> C
|
||||
F[General Markdown] --> G[Docs Registry]
|
||||
B --> H[FastMCP Server]
|
||||
D --> H
|
||||
G --> H
|
||||
H --> K[MCP Transport]
|
||||
L[Zensical Site Output] --> M[FastAPI Static Mount]
|
||||
K --> M
|
||||
```
|
||||
|
||||
## Contracts
|
||||
Server construction is lazy with respect to package import. Each application process creates its providers and docs snapshot when the server factory runs. Production providers use `reload=False`; content changes require a process restart.
|
||||
|
||||
### Metadata Contract
|
||||
## Packaging
|
||||
|
||||
Each skill declares standard frontmatter in `docs/skills/<skill-id>/SKILL.md`.
|
||||
The repository root `docs/` directory is the only authored Markdown source. `src/personal_mcp/docs` is a relative symlink used by source checkouts and editable installs. Hatchling follows it and stores regular files beneath `personal_mcp/docs/` in the wheel.
|
||||
|
||||
For the full field-level contract, validation model, and FastMCP metadata mapping, see [Frontmatter Contract](./contracts/frontmatter.md).
|
||||
Runtime reads are package-relative:
|
||||
|
||||
Required fields:
|
||||
1. Prompt content and general docs use `importlib.resources` and `Traversable` APIs.
|
||||
2. `SkillsDirectoryProvider` receives the packaged `personal_mcp/docs/skills` filesystem path.
|
||||
3. No runtime content lookup depends on the current working directory.
|
||||
|
||||
1. name
|
||||
2. description
|
||||
## Public Contracts
|
||||
|
||||
The directory name is the provider identity and must match `name`. There is no skill catalog metadata or sidecar.
|
||||
The machine-facing surfaces are:
|
||||
|
||||
### URI Contract
|
||||
1. Native skill resources under `skill://<name>/...`.
|
||||
2. Native MCP prompt list and get operations.
|
||||
3. `resource://docs/{path*}` for general Markdown.
|
||||
|
||||
Canonical resource URIs are:
|
||||
Canonical contracts are documented in:
|
||||
|
||||
For the full URI semantics, parameter validation rules, and compatibility policy, see [URI Contract](./contracts/uris.md).
|
||||
1. [Prompt Contract](./contracts/prompt.md)
|
||||
2. [Skill Contract](./contracts/skill_contract.md)
|
||||
3. [Frontmatter Contract](./contracts/frontmatter.md)
|
||||
4. [URI Contract](./contracts/uris.md)
|
||||
|
||||
1. skill://<skill_name>/SKILL.md
|
||||
2. skill://<skill_name>/_manifest
|
||||
3. skill://<skill_name>/<supporting_path>
|
||||
4. resource://docs/{path*}
|
||||
5. resource://catalog/prompts_index
|
||||
6. resource://catalog/prompts_index{?q,tag,cursor,limit}
|
||||
7. resource://catalog/prompts/{prompt_id}
|
||||
8. resource://prompts/{prompt_id}/document
|
||||
Only these canonical provider and protocol surfaces are registered.
|
||||
|
||||
Validation rules:
|
||||
## Static Documentation
|
||||
|
||||
1. `skill_name` is the lowercase kebab-case skill directory name.
|
||||
2. `supporting_path` is a provider-validated relative path within that skill.
|
||||
3. Docs `path*` resolves only to normalized Markdown paths under `docs/`.
|
||||
Zensical builds `docs/` into `site/` before deployment. FastAPI mounts that immutable output in the same process that hosts FastMCP. Generated `site/` files are deployment assets and are never an authored source.
|
||||
|
||||
### Resource Registration Contract
|
||||
## Validation
|
||||
|
||||
Skill resources are registered by one `SkillsDirectoryProvider`; prompt and docs resources remain registered from the validated registry.
|
||||
Changes are accepted only after:
|
||||
|
||||
Registration rules:
|
||||
|
||||
1. Use RFC6570 URI templates where appropriate.
|
||||
2. Mark documentation resources as read-only and idempotent.
|
||||
3. Set explicit mime types for resource responses.
|
||||
4. 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.
|
||||
|
||||
1. Breaking URI changes are handled as direct replacement.
|
||||
2. 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:
|
||||
|
||||
1. App starts.
|
||||
2. FastAPI mounts the static docs output directory.
|
||||
3. 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
|
||||
|
||||
1. Update markdown reference content.
|
||||
2. Keep skill `name` and directory identity aligned.
|
||||
3. Build static docs with Zensical and run provider tests.
|
||||
4. Package authored docs into `personal_mcp/docs/`.
|
||||
5. Serve native MCP resources and the static docs mount.
|
||||
|
||||
## Scope and Non-Goals
|
||||
|
||||
In-scope:
|
||||
|
||||
1. Resource-first methodology delivery
|
||||
2. Native FastMCP skill discovery
|
||||
3. Pre-built static docs hosting in app runtime
|
||||
|
||||
Out-of-scope:
|
||||
|
||||
1. Prompt-first orchestration as the primary interface
|
||||
2. Large tool inventories duplicating static guidance across skill modules
|
||||
3. 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:
|
||||
|
||||
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 inputs are treated as content sources, while native skill URIs and generated manifests form the machine-facing skill contract.
|
||||
1. focused provider and protocol tests
|
||||
2. Ruff and ty checks
|
||||
3. a Zensical build
|
||||
4. the full pytest suite
|
||||
5. an installed-wheel smoke test when packaging or provider paths change
|
||||
|
||||
Reference in New Issue
Block a user