4.1 KiB
icon
| 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:
SkillsDirectoryProviderpublishes nativeskill://resources from packaged skill directories.FileSystemProviderdiscovers typed@promptfunctions from packaged Python modules.- The general docs registry publishes non-skill Markdown through
resource://docs/{path*}. - 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:
docs/skills/<skill-id>/SKILL.mddocs/skills/<skill-id>/<supporting-path>
SkillsDirectoryProvider publishes:
skill://<name>/SKILL.mdskill://<name>/_manifestskill://<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:
src/personal_mcp/prompts/components/<module>.pyowns the typed signature and runtime metadata.docs/prompts/<prompt-id>/PROMPT.mdowns 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
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:
- Prompt content and general docs use
importlib.resourcesandTraversableAPIs. SkillsDirectoryProviderreceives the packagedpersonal_mcp/docs/skillsfilesystem path.- No runtime content lookup depends on the current working directory.
Public Contracts
The machine-facing surfaces are:
- Native skill resources under
skill://<name>/.... - Native MCP prompt list and get operations.
resource://docs/{path*}for general Markdown.
Canonical contracts are documented in:
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:
- focused provider and protocol tests
- Ruff and ty checks
- a Zensical build
- the full pytest suite
- an installed-wheel smoke test when packaging or provider paths change