Files
prompts/src/personal_mcp/docs/architecture.md
T
2026-08-07 21:07:23 -05:00

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:

  1. SkillsDirectoryProvider publishes native skill:// resources from packaged skill directories.
  2. A custom prompt provider loads declarative prompt definitions from packaged Markdown.
  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 per-prompt Python module.

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 one source: docs/prompts/<prompt-id>/PROMPT.md. Its nested prompt frontmatter owns runtime metadata and argument declarations, while its body owns canonical prose.

The custom provider reads packaged Markdown with importlib.resources, validates metadata and exact placeholder-to-argument equality, and creates native FastMCP prompt objects. It rescans on each list and get request, so an editable deployment observes file additions, edits, and deletions without a restart.

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[Packaged Prompt Markdown] --> D[Markdown Prompt Provider]
    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. Skills use startup discovery, while prompts are reloaded when a client lists or gets prompts.

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
  2. Skill Contract
  3. Frontmatter Contract
  4. URI Contract

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