changed to skill provider

This commit is contained in:
John Lancaster
2026-08-07 19:09:54 -05:00
parent c6817a074e
commit 44edffb8b7
48 changed files with 552 additions and 2946 deletions
+47 -59
View File
@@ -21,8 +21,8 @@ Prompt documents under `docs/prompts/` are also indexed and exposed as first-cla
This architecture is anchored by three contracts:
1. Docs-first authored content contract under `docs/` with strict per-skill ownership.
2. `SKILL.md` frontmatter contract with Anthropic fields plus `x-personal-mcp` metadata.
3. Canonical resource URI contract with break-and-replace policy for contract changes.
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:
@@ -51,11 +51,13 @@ Each skill encapsulates one methodology domain in a docs-owned directory:
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 resource families:
Each skill publishes three native resource families:
1. document
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 document resource returns canonical Markdown, while clients can perform any downstream section extraction they need.
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
@@ -70,29 +72,27 @@ This keeps authored markdown as source-of-truth while allowing clients to discov
### Catalog Module
The catalog is the canonical discovery layer and publishes normalized records for all modules. It may also expose a minimal set of read-only discovery tools that resolve back to the same canonical markdown content when a client chat surface does not expose MCP resource attachment.
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/skills_index
2. resource://catalog/skills_index{?q,tag,capability,cursor,limit}
3. resource://catalog/skills/{skill_id}
4. resource://catalog/prompts_index
5. resource://catalog/prompts_index{?q,tag,cursor,limit}
6. resource://catalog/prompts/{prompt_id}
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 request the registry when constructing a runnable server, using packaged resources through `importlib.resources.files(...)` and `Traversable` APIs.
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 SKILL.md frontmatter for each skill.
2. Validate schema and cross-field constraints before any resource registration.
3. Build an in-memory registry keyed by `skill_id`.
4. Fail fast for duplicate ids, missing markdown files, and broken reference mappings.
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.
@@ -102,7 +102,7 @@ Content is authored in markdown under `docs/` and managed as long-form reference
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 forced inclusion](https://hatch.pypa.io/latest/config/build/#forced-inclusion) maps the root `docs/` tree to `personal_mcp/docs/`. The wheel therefore contains regular resource files at that destination rather than a symlink. Runtime registry loading uses [`importlib.resources.files`](https://docs.python.org/3/library/importlib.resources.html#importlib.resources.files) and `Traversable` operations from the `personal_mcp` package anchor, so it does not depend on the repository layout or current working directory.
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
@@ -119,36 +119,29 @@ Generated `site/` files are deployment assets for the human-facing static site.
```mermaid
flowchart TD
A[Authored Markdown] --> C[Resource Handlers]
B[Pattern Metadata] --> D[Catalog Resources]
A --> E[Zensical Static Build]
E --> H[FastAPI Static Mount]
H --> I[Served Docs Site]
D --> I
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 frontmatter in `docs/skills/<skill-id>/SKILL.md`.
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](./contracts/frontmatter.md).
Anthropic-facing required fields:
Required fields:
1. name
2. description
Repository indexing metadata is declared in `x-personal-mcp`:
1. id
2. version
3. tags
4. capabilities
5. optional references map (for nested entries, overrides, and aliases)
No `metadata.yaml` sidecar is part of the end-state contract.
The directory name is the provider identity and must match `name`. There is no skill catalog metadata or sidecar.
### URI Contract
@@ -156,28 +149,24 @@ Canonical resource URIs are:
For the full URI semantics, parameter validation rules, and compatibility policy, see [URI Contract](./contracts/uris.md).
1. resource://skills/<skill_id>/document
2. resource://skills/<skill_id>/references/<ref_id>
3. resource://catalog/skills_index
4. resource://catalog/skills_index{?q,tag,capability,cursor,limit}
5. resource://catalog/skills/{skill_id}
6. resource://docs/{path*}
7. resource://catalog/prompts_index
8. resource://catalog/prompts_index{?q,tag,cursor,limit}
9. resource://catalog/prompts/{prompt_id}
10. resource://prompts/{prompt_id}/document
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
Validation rules:
1. `skill_id` is lowercase kebab-case and must satisfy the stable skill id contract.
2. `ref_id` is lowercase kebab-case and must resolve from either:
- top-level auto-discovery of `references/*.md` filename stems, or
- an explicit `x-personal-mcp.references` entry.
3. `path*` resolves only to normalized markdown paths under `docs/`.
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/`.
### Resource Registration Contract
Resources are registered from the validated registry, not by ad hoc per-skill hardcoding.
Skill resources are registered by one `SkillsDirectoryProvider`; prompt and docs resources remain registered from the validated registry.
Registration rules:
@@ -232,16 +221,17 @@ Clients can use Ask, Edit, or Agent modes without requiring prompt-first orchest
## Authoring and Publishing Lifecycle
1. Update markdown reference content.
2. Update metadata if capability surface changes.
3. Build static docs with Zensical.
4. Serve built output through FastAPI static mount.
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. Catalog-based discovery
2. Native FastMCP skill discovery
3. Pre-built static docs hosting in app runtime
Out-of-scope:
@@ -250,9 +240,7 @@ Out-of-scope:
2. Large tool inventories duplicating static guidance across skill modules
3. Separate dynamic docs service at runtime
Allowed exception:
1. A small catalog-level tool layer is acceptable when it improves client interoperability without creating a second source of truth for skill content.
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
@@ -263,4 +251,4 @@ Existing markdown reference sets are valid examples of authored source material
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 resource URIs and catalog payloads remain the machine-facing contracts.
These inputs are treated as content sources, while native skill URIs and generated manifests form the machine-facing skill contract.