110 lines
4.1 KiB
Markdown
110 lines
4.1 KiB
Markdown
---
|
|
icon: lucide/library
|
|
---
|
|
|
|
# Architecture
|
|
|
|
## Overview
|
|
|
|
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.
|
|
|
|
The runtime has four content paths:
|
|
|
|
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.
|
|
|
|
There is no custom skill catalog, prompt catalog, or prompt registry model.
|
|
|
|
## Source Ownership
|
|
|
|
### Skills
|
|
|
|
Each skill owns one directory:
|
|
|
|
1. `docs/skills/<skill-id>/SKILL.md`
|
|
2. `docs/skills/<skill-id>/<supporting-path>`
|
|
|
|
`SkillsDirectoryProvider` publishes:
|
|
|
|
1. `skill://<name>/SKILL.md`
|
|
2. `skill://<name>/_manifest`
|
|
3. `skill://<name>/{path*}`
|
|
|
|
The provider parses standard skill frontmatter and generates the manifest. The general docs registry excludes `skills/**`, so only the native provider owns this namespace.
|
|
|
|
### Prompts
|
|
|
|
Each prompt has two coordinated sources:
|
|
|
|
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.
|
|
|
|
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.
|
|
|
|
FastMCP exposes prompts through native `prompts/list` and `prompts/get` operations.
|
|
|
|
### General Docs
|
|
|
|
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.
|
|
|
|
## Runtime Composition
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
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
|
|
```
|
|
|
|
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.
|
|
|
|
## Packaging
|
|
|
|
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.
|
|
|
|
Runtime reads are package-relative:
|
|
|
|
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.
|
|
|
|
## Public Contracts
|
|
|
|
The machine-facing surfaces are:
|
|
|
|
1. Native skill resources under `skill://<name>/...`.
|
|
2. Native MCP prompt list and get operations.
|
|
3. `resource://docs/{path*}` for general Markdown.
|
|
|
|
Canonical contracts are documented in:
|
|
|
|
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)
|
|
|
|
Only these canonical provider and protocol surfaces are registered.
|
|
|
|
## Static Documentation
|
|
|
|
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.
|
|
|
|
## Validation
|
|
|
|
Changes are accepted only after:
|
|
|
|
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
|