migration

This commit is contained in:
John Lancaster
2026-08-07 20:07:21 -05:00
parent 2a2700b78c
commit 5b6d5aaec4
70 changed files with 1182 additions and 3633 deletions
+62 -207
View File
@@ -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
+10 -9
View File
@@ -72,22 +72,23 @@ Recommended sequence:
## Prompt Authoring
Prompts remain registry-backed:
Prompts pair typed Python metadata with canonical Markdown prose:
1. Keep one canonical `PROMPT.md`.
2. Align directory name, `name`, and `x-personal-mcp.id`.
3. Include `resource://prompts/<prompt-id>/document` in capabilities.
4. Define arguments beneath `x-personal-mcp.arguments`.
5. Keep long rationale and sources in `references/`.
1. Add one `@prompt` function under `src/personal_mcp/prompts/components/`.
2. Use the function signature for arguments, requiredness, and literal constraints.
3. Set name, description, tags, and version on the decorator.
4. Keep the canonical body in `docs/prompts/<prompt-id>/PROMPT.md`.
5. Keep Markdown placeholders exactly equal to the Python argument names.
6. Use only documentation-site fields in Markdown frontmatter.
Prompt argument names must be valid Python identifiers. Each argument accepts optional `title`, `description`, and `required`; unknown fields fail strict validation.
The production `FileSystemProvider` discovers component modules. Do not add prompt registry models, catalog resources, or dynamic signature generation.
## Frontmatter Safety
1. Quote scalar values containing `:`.
2. Quote values with reserved YAML characters such as `#`, `{}`, `[]`, or leading `*`.
3. Use block scalars for punctuation-heavy multiline text.
4. Keep fields within the applicable skill or prompt contract.
4. Keep fields within the applicable skill or documentation contract.
## Writing Quality
@@ -106,7 +107,7 @@ Active instructions should point directly to native main resources:
2. `skill://pytesting/SKILL.md`
3. `skill://vscode-configuration/SKILL.md`
When deeper guidance is needed, read the selected skill's `_manifest` and fetch supporting files by their listed path. Tool-only clients use `list_resources` and `read_resource` over the same URIs.
When deeper guidance is needed, read the selected skill's `_manifest` and fetch supporting files by their listed path.
## Validation Checklist
+10 -26
View File
@@ -4,7 +4,7 @@ icon: lucide/braces
# Frontmatter Contract
This page defines the authored frontmatter contracts for native FastMCP skills and registry-backed prompts.
This page defines frontmatter ownership for native skills and prompt documentation.
## Skill Frontmatter
@@ -27,38 +27,22 @@ Rules:
The provider uses the directory name as the URI identity and the frontmatter `description` as the main resource description. Repository tests enforce directory/name parity and reject extra skill frontmatter fields.
## Prompt Frontmatter
## Prompt Documentation Frontmatter
Prompts remain registry-backed and retain repository metadata:
Prompt runtime metadata is defined by typed Python components, not Markdown frontmatter. A prompt document may retain only fields consumed by the static documentation site:
```yaml
---
name: <prompt-id>
description: <what the prompt does and when to use it>
x-personal-mcp:
id: <prompt-id>
version: <semver>
tags:
- <tag>
capabilities:
- resource://prompts/<prompt-id>/document
arguments:
<argument-name>:
title: <display title>
description: <input guidance>
required: true
icon: lucide/messages-square
---
```
Prompt rules:
1. `name`, `description`, and `x-personal-mcp` are required.
2. `x-personal-mcp.id`, `name`, and the prompt directory name must match.
3. `version` must be semantic version text.
4. `capabilities` must include `resource://prompts/<prompt-id>/document`.
5. Argument names must be valid Python identifiers.
6. Argument entries accept optional `title`, `description`, and `required` fields.
7. Unknown prompt fields are rejected by the strict Pydantic registry models.
1. Do not duplicate prompt names, descriptions, versions, tags, or arguments in Markdown YAML.
2. Argument names must be valid Python identifiers in the component signature.
3. Literal value constraints belong in Python type annotations.
4. Markdown placeholders must exactly match the component argument names.
See the MCP [prompts concept documentation](https://modelcontextprotocol.io/docs/learn/server-concepts#prompts) and [schema reference](https://modelcontextprotocol.io/specification/latest/schema) for the protocol-level prompt shape.
@@ -70,11 +54,11 @@ Skill validation is file- and provider-oriented:
2. FastMCP parses the description and scans all files when the provider is created.
3. Repository tests enforce the stricter standard-only frontmatter and directory/name rules.
Prompt validation remains registry-oriented and fails server startup for invalid metadata, duplicate prompt ids, or malformed arguments.
Prompt validation is provider- and renderer-oriented. Provider discovery validates decorated functions, while focused tests render every prompt and reject placeholder drift.
## Invariants
1. Skills remain directly portable to tools that understand standard Agent Skills directories.
2. Native skill discovery has no parallel catalog metadata source.
3. Prompts retain the richer metadata required by their catalog and MCP prompt-object surfaces.
3. Prompts use FastMCP's native component metadata and protocol surface without a parallel catalog.
4. All authored content remains under `docs/`.
+29 -22
View File
@@ -4,11 +4,11 @@ icon: lucide/messages-square
# Prompt Contract
This page defines the canonical contract for prompts in the docs-first MCP architecture.
This page defines the canonical contract for typed prompts discovered by FastMCP's `FileSystemProvider`.
## Canonical Prompt Shape
Each prompt is one directory under `docs/prompts/`:
Each prompt has a Python component and one canonical Markdown document:
```mermaid
---
@@ -22,27 +22,31 @@ config:
lineColor: '#FFFFFF'
---
treeView-beta
"docs/"
"... (other docs)"
"prompts/"
"<prompt-id>/"
"PROMPT.md"
"references/"
"... (one or more markdown files, optional nested folders)"
"src/personal_mcp/prompts/"
"components/"
"<prompt_module>.py"
"content.py"
"provider.py"
"docs/prompts/"
"<prompt-id>/"
"PROMPT.md"
```
Rules:
1. `PROMPT.md` is required for every prompt.
2. `references/` is the only place for prompt-specific supporting docs.
3. Nested folders inside `references/` are allowed so a prompt can reorganize internals without changing global architecture.
4. Prompt directories are independent ownership boundaries; no cross-prompt file writes.
1. Each component exports one typed function decorated with `@prompt`.
2. Function parameters define the MCP argument names, requiredness, and accepted values.
3. Decorator fields define runtime name, description, tags, and version.
4. The function loads its matching `docs/prompts/<prompt-id>/PROMPT.md` through `importlib.resources`.
5. `PROMPT.md` owns the rendered prompt prose and uses `{argument_name}` placeholders.
6. The renderer requires exact equality between the function's arguments and the Markdown placeholders.
## Metadata Location Constraint
## Ownership Boundary
1. Prompt metadata is embedded in YAML frontmatter in `PROMPT.md`.
2. No `metadata.yaml` sidecar exists in the end state.
3. Reference lookup metadata is documented and explicit: top-level `references/*.md` are auto-discovered from filenames, while `PROMPT.md` frontmatter declares overrides and nested mappings when needed.
1. Python owns runtime metadata and the callable schema.
2. Markdown owns prompt prose and may contain only documentation-site frontmatter.
3. There is no custom prompt catalog, prompt registry model, or metadata sidecar.
4. `FileSystemProvider(reload=False)` discovers components when the server is created.
## Prompt Id Contract
@@ -53,8 +57,8 @@ Rules:
3. Must start with a letter.
4. No underscores, spaces, dots, or uppercase characters.
5. Directory name should equal `prompt-id` in each committed revision.
6. Frontmatter `id` should equal directory name in each committed revision.
7. Treat `prompt-id` as immutable after release; any rename is a breaking replacement and clients must move to the new id.
6. The `@prompt` name and Markdown directory name must equal `prompt-id`.
7. Treat `prompt-id` as immutable after release; a rename is a breaking replacement.
Valid examples:
@@ -68,8 +72,11 @@ Invalid examples:
2. `Prompt-Template`
3. `docs.prompt`
## Direct Documentation Inclusion
## Rendering Contract
1. For direct API documentation, use mkdocstrings directives rather than pasting large code blocks.
2. Keep manually-authored code examples short and task-focused; large implementation excerpts are out of scope for this contract.
1. The renderer strips one leading YAML frontmatter block before returning prompt content.
2. Required values are supplied by the typed function signature.
3. An omitted optional value renders as `Not provided`.
4. Unknown prompt ids and mismatched placeholders fail immediately.
5. Prompt content is read from packaged resources and does not depend on the working directory.
+8 -13
View File
@@ -4,7 +4,7 @@ icon: lucide/link
# URI Contract
This page defines the public resource URI contract for native skills, registry-backed prompts, and general authored documentation.
This page defines the public resource URI contract for native skills and general authored documentation.
## Native Skill URIs
@@ -44,17 +44,11 @@ skill://pytesting/references/pytest-docs.md
FastMCP confines reads to the selected skill directory. Absolute paths, traversal outside the directory, missing files, directories, and symlinks that resolve outside the skill root are rejected.
## Prompt And Docs URIs
## General Docs URI
Prompts and general documentation retain the existing registry-backed resource surface:
General authored documentation is exposed through `resource://docs/{path*}`. The wildcard accepts normalized relative POSIX Markdown paths beneath `docs/`, excludes the provider-owned `skills/` subtree, and rejects absolute paths, traversal segments, backslashes, and non-Markdown targets.
1. `resource://catalog/prompts_index`
2. `resource://catalog/prompts_index{?q,tag,cursor,limit}`
3. `resource://catalog/prompts/{prompt_id}`
4. `resource://prompts/{prompt_id}/document`
5. `resource://docs/{path*}`
Prompt ids remain lowercase kebab-case. The docs wildcard accepts normalized relative POSIX Markdown paths beneath `docs/` and rejects absolute paths, traversal segments, backslashes, and non-Markdown targets.
Prompts are MCP prompt components rather than resources. Clients discover them with the protocol `prompts/list` operation and render them with `prompts/get`.
## Discovery Order
@@ -66,11 +60,11 @@ For skills:
4. read `_manifest` when supporting material may be needed
5. fetch only the supporting paths relevant to the task
For prompts, use the prompt catalog or MCP prompt-object APIs.
For prompts, use the native MCP prompt APIs or their generic tool projection.
## Compatibility Policy
## Stability Policy
The native `skill://` family directly replaces the repository's former custom skill URI and catalog surfaces. No compatibility aliases or dual registrations are maintained. Prompt and general-doc URIs are unaffected.
The provider and protocol surfaces documented here are the complete public contract. Contract changes replace the affected surface directly.
Skill renames are breaking because the directory name is part of every native skill URI. Supporting-file renames change the corresponding manifest path and URI.
@@ -80,3 +74,4 @@ Skill renames are breaking because the directory name is part of every native sk
2. [MCP resources](https://modelcontextprotocol.io/specification/latest/server/resources)
3. [RFC 3986 URI syntax](https://www.rfc-editor.org/rfc/rfc3986)
4. [RFC 6570 URI templates](https://www.rfc-editor.org/rfc/rfc6570)
5. [FastMCP prompts](https://gofastmcp.com/servers/prompts)
+3 -21
View File
@@ -6,7 +6,7 @@ icon: lucide/bot
## Purpose
This page explains how GitHub Copilot in VS Code consumes native skill resources from `personal-mcp`, including sessions where tools are visible but resource attachment is not.
This page explains how GitHub Copilot in VS Code consumes native skill resources and prompts from `personal-mcp`.
## Capability Lanes
@@ -16,7 +16,7 @@ Copilot interacts with MCP servers through independently exposed lanes:
2. resources attached as read-only context
3. server-provided prompts
This server publishes skills as native `skill://` resources, prompts through registry-backed resources and MCP prompt objects, and generic resource fallback tools through FastMCP.
This server publishes skills as native `skill://` resources and prompts as native MCP prompt objects.
## Native Skill Resources
@@ -39,22 +39,11 @@ A successful `resources/list` response does not guarantee the picker appears in
## Recommended Workflow
When resource attachment is available:
1. browse the server's resources
2. attach one relevant `skill://<name>/SKILL.md`
3. attach `_manifest` only if supporting detail may be needed
4. attach only selected supporting files
When only tools are available:
1. call `list_resources`
2. select a native main skill URI by name and description
3. call `read_resource` for that URI
4. read `_manifest` and supporting files only as needed
Both paths resolve through the same FastMCP provider.
## Prompt Examples
Resource attachment:
@@ -63,12 +52,6 @@ Resource attachment:
Use the attached personal-mcp skill as guidance, then reconcile it with the repository before proposing changes.
```
Tool-only discovery:
```text
Call list_resources, choose the best matching skill://.../SKILL.md resource, and read it. Inspect its _manifest only if a supporting file is needed. Load at most two candidate skills.
```
Direct loading:
```text
@@ -89,7 +72,7 @@ A repo-level instruction should name the native retrieval order and context budg
When a task matches a personal-mcp skill:
1. Prefer an already attached native skill resource.
2. Otherwise use `list_resources` and select one `skill://<name>/SKILL.md` resource by description.
2. Otherwise browse MCP resources and select one `skill://<name>/SKILL.md` resource by description.
3. Read `_manifest` only when supporting material is needed.
4. Load at most two candidate main files and only the relevant supporting paths.
5. Reconcile guidance with the current repository before editing.
@@ -107,7 +90,6 @@ Prompt modules remain separate from skills. When the client supports MCP prompt
2. Use `MCP: Browse Resources` to confirm native skill resources exist.
3. Restart the MCP server after changing skill files because production uses `reload=False`.
4. Reload the VS Code window if the server is healthy but the resource picker remains stale.
5. In tool-only sessions, verify `list_resources` and `read_resource` are visible.
## Further Reading
+53 -158
View File
@@ -2,199 +2,94 @@
icon: lucide/server
---
# Static Docs Hosting Pattern
# Runtime And Static Docs Layout
## Purpose
This document describes the completed layout and runtime pattern used to host a pre-built static documentation site from the same FastAPI app process that runs the FastMCP server.
The project serves native MCP content and a pre-built documentation site from one FastAPI process. Markdown is authored once under `docs/`; runtime providers and Zensical consume that same packaged tree for different purposes.
This design intentionally avoids runtime docs rendering and avoids a separate docs hosting service.
It also treats Markdown as the single source of truth for both MCP resources and published docs.
## Completed-State Layout
## Repository Layout
```mermaid
---
config:
treeView:
rowIndent: 40
rowIndent: 32
lineThickness: 2
themeVariables:
treeView:
labelColor: '#FFFFFF'
lineColor: '#FFFFFF'
---
treeView-beta
"project-root"
"pyproject.toml"
"uv.lock"
"zensical.toml"
"docs"
"index.md"
"<project-docs>.md"
"contracts"
"index.md"
"<contract-pages>.md"
"mcp_layout.md"
"prompts"
"<prompt-id>"
"PROMPT.md"
"references"
"skills"
"<skill-id>"
"SKILL.md"
"references"
"<reference>.md"
"prompts/<prompt-id>/PROMPT.md"
"skills/<skill-id>/SKILL.md"
"skills/<skill-id>/<supporting-files>"
"<general-pages>.md"
"site"
"static build output"
"src"
"personal_mcp"
"__init__.py"
"main.py"
"mcp.py"
"catalog"
"<catalog-modules>.py"
"registry"
"<registry-modules>.py"
"web"
"<web-modules>.py"
"skills"
"<skills-modules>.py"
"src/personal_mcp"
"mcp.py"
"prompts/components/*.py"
"prompts/content.py"
"prompts/provider.py"
"registry/"
"skills/provider.py"
"web/"
```
Notes:
Ownership rules:
1. docs contains both project-authored pages and the canonical skill Markdown tree.
2. site contains static build output only.
3. docs/skills contains canonical skill Markdown and reference Markdown.
4. docs/prompts contains canonical prompt Markdown used for prompt catalog and document surfaces.
5. MCP resources and docs site read from the same Markdown sources.
1. `docs/skills/` is owned exclusively by `SkillsDirectoryProvider` at runtime.
2. `docs/prompts/` owns prompt prose; Python components own prompt metadata and argument schemas.
3. The docs registry owns only general Markdown resources and explicitly excludes skills.
4. `site/` is generated output.
5. The deleted custom `catalog/` package is not part of the runtime.
## Runtime Composition
The runtime process serves two surfaces:
1. MCP protocol surface from FastMCP
2. Static docs surface from FastAPI static mount
```mermaid
flowchart TD
A[Packaged Skill Directory] --> B[SkillsDirectoryProvider]
C[Packaged Prompts and Docs] --> D[Validated Registry]
B --> E[FastMCP Server]
D --> E
E --> F[MCP Transport]
E --> G[FastAPI Application]
G --> H[Static Mount /docs]
H --> I[Zensical Site Output]
A[Packaged Skills] --> B[SkillsDirectoryProvider]
C[Prompt Components] --> D[FileSystemProvider]
E[Packaged Markdown] --> F[Docs Registry]
B --> G[FastMCP]
D --> G
F --> G
G --> H[MCP Transport]
H --> K[FastAPI Application]
L[Pre-built site] --> M[Static /docs Mount]
K --> M
```
Runtime guarantees:
1. The skills provider and prompt/docs registry initialize before resource exposure.
2. Duplicate resource and template registration fails startup (`on_duplicate="error"`).
3. Skill resources come directly from `SkillsDirectoryProvider` directory discovery.
4. Legacy per-skill Python servers, custom skill catalogs, and metadata sidecars are not part of the runtime.
1. Providers are installed before serving requests.
2. Production provider discovery uses `reload=False`.
3. Duplicate components fail according to FastMCP's configured duplicate policy.
4. Skills and prompts use native FastMCP component surfaces.
5. General docs path parsing rejects traversal, backslashes, non-Markdown paths, and the skill namespace.
## Build and Publish Flow
## Build And Publish Flow
The docs flow is pre-build only.
1. Author Markdown under `docs/` and typed prompts under `src/personal_mcp/prompts/components/`.
2. Run `uv run zensical build` to produce `site/`.
3. Build the wheel, which packages the authored docs under `personal_mcp/docs/`.
4. Start the app and serve MCP plus the static site.
1. Read authored docs pages and skill markdown sources.
2. Build static site with Zensical into site.
3. Start app and serve site directory as static files.
No runtime Markdown-to-HTML conversion occurs.
No runtime markdown conversion is required.
## Machine-Facing Mapping
## Content Merge Pattern
1. `docs/skills/<skill-id>/SKILL.md` maps to `skill://<skill-id>/SKILL.md`.
2. Skill supporting files map to `skill://<skill-id>/<path>`.
3. Typed prompt components map to native MCP prompt names.
4. General `docs/<path>.md` maps to `resource://docs/{path*}`.
The published docs site always contains both:
The server publishes no tool projections of resources or prompts.
1. Project-authored docs pages
2. Skill Markdown content from docs/skills/*/SKILL.md and references
## Public Surface Policy
This ensures the public docs reflect architectural guidance and the exact Markdown served by MCP.
Canonical provider and protocol surfaces are the only public interfaces.
## Markdown-to-Resource Mapping
## Static Mount Expectations
MCP resources map directly to canonical Markdown documents.
Example mapping model:
1. docs/skills/<skill-id>/SKILL.md -> skill://<skill-id>/SKILL.md
2. docs/skills/<skill-id>/<path> -> skill://<skill-id>/<path>
3. docs/<path>.md -> resource://docs/{path*}
Catalog discovery resources are:
1. resource://catalog/prompts_index
2. resource://catalog/prompts_index{?q,tag,cursor,limit}
3. resource://catalog/prompts/{prompt_id}
Resource registration details:
1. `skill://<skill-id>/SKILL.md` resolves to each skill's main instructions.
2. `skill://<skill-id>/_manifest` lists every skill file with size and SHA256 hash.
3. Per-skill wildcard templates resolve validated supporting-file paths.
4. `resource://docs/{path*}` resolves normalized Markdown paths under `docs/`.
When clients cannot attach MCP resources directly, `ResourcesAsTools` exposes generic `list_resources` and `read_resource` tools over the same provider resources.
## URI Compatibility Policy
1. Canonical URIs are the only supported URIs in this runtime.
2. No backward-compatibility aliases or dual registration paths are maintained.
3. Contract changes should update clients to canonical URIs directly.
## Why This Pattern
### Operational Simplicity
One application process serves both protocol and static docs surfaces.
### Deterministic Docs
Published docs are immutable static assets for a given build.
### Documentation Fidelity
The docs site and MCP resources resolve from the same Markdown sources.
### Maintainer Experience
Authors continue to work in markdown while resource contracts remain machine-consumable.
## FastAPI Static Mount Expectations
The FastAPI app is expected to:
1. Mount static directory containing Zensical output.
2. Serve index and asset files from that directory.
3. Keep docs route stable across releases.
Recommended route conventions:
1. /docs for static site root
2. /docs/* for static assets and page routes
## Update Lifecycle
For each documentation update:
1. Edit authored docs and skill markdown content.
2. Rebuild static site.
3. Restart runtime if needed.
This keeps docs publication explicit and predictable.
## Example Source Material
Existing reference docs remain valid content inputs in this pattern:
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 are source documents, not deployment artifacts.
The FastAPI app mounts the Zensical output, serves index and asset files, and returns a clear unavailable response when the static output is absent. The site directory is immutable for a given build and remains separate from packaged authored Markdown.
+10 -36
View File
@@ -1,41 +1,18 @@
---
name: authoring
description: Provide a practical checklist and baseline template for authoring docs-first MCP modules and repository-specific Copilot instruction shims.
x-personal-mcp:
id: authoring
version: 1.0.0
tags:
- authoring
- mcp
- fastmcp
- copilot
- prompts
- scaffolding
capabilities:
- resource://prompts/authoring/document
arguments:
artifact_type:
title: Artifact type
description: "Enum (case-sensitive): skill | prompt | shim."
required: true
artifact_id:
title: Artifact id
description: Lowercase kebab-case id for the module or shim.
required: true
goal:
title: Goal
description: One-sentence capability statement describing what to create and when to use it.
required: true
scope_glob:
title: Scope glob
description: Optional applyTo glob for shim outputs.
required: false
icon: lucide/messages-square
---
# Authoring Bootstrap
Use this prompt to author or update docs-first MCP modules in this repository, including repository-specific Copilot thin shims.
## Supplied Inputs
- `artifact_type`: {{artifact_type}}
- `artifact_id`: {{artifact_id}}
- `goal`: {{goal}}
- `scope_glob`: {{scope_glob}}
## Inputs
1. artifact_type: one of skill, prompt, shim
@@ -51,7 +28,7 @@ Load only what matches the requested artifact:
2. Prompt metadata and structure: [Prompt Contract](../../contracts/prompt.md)
3. Skill metadata and structure (only for skill outputs): [Skill Contract](../../contracts/skill_contract.md)
4. Thin shim mechanics and path binding: [Skill Usage Mechanics](../../usage.md)
5. Copilot resource attachment and fallback behavior: [Copilot MCP Mechanics](../../copilot.md)
5. Copilot resource attachment behavior: [Copilot MCP Mechanics](../../copilot.md)
## Workflow
@@ -70,11 +47,8 @@ Load only what matches the requested artifact:
8. Keep guidance deterministic and minimal, with explicit references to source docs.
9. If artifact_type is shim:
- bind one applyTo scope to one `skill://<name>/SKILL.md` resource URI
- prefer MCP resource attachment first
- use MCP resource attachment
- inspect the selected skill's `_manifest` only when supporting material is needed
- if resource attachment is unavailable, use the generic fallback tools:
1. list_resources
2. read_resource
10. Return created or updated file paths and any validation commands that should be run.
## Output Contract
+8 -31
View File
@@ -1,41 +1,18 @@
---
name: greenfield-architecture
description: Research established patterns and design a high-level architecture for a new app or library with explicit tradeoffs and test strategy.
x-personal-mcp:
id: greenfield-architecture
version: 1.0.0
tags:
- architecture
- planning
- greenfield
- design
- testing
- prompts
capabilities:
- resource://prompts/greenfield-architecture/document
arguments:
scope_type:
title: Scope type
description: "Scope type: app or library."
required: true
intent_document:
title: Intent document
description: Optional full document describing goals, context, and desired outcomes.
required: false
problem_domain:
title: Problem domain
description: Domain and business goal for the new app or library when no full intent document is provided.
required: false
constraints:
title: Constraints
description: Runtime, deployment, and non-functional constraints.
required: false
icon: lucide/messages-square
---
# Greenfield Architecture Planner
Use this prompt to design a new software app or library architecture in generic terms.
## Supplied Inputs
- `scope_type`: {{scope_type}}
- `intent_document`: {{intent_document}}
- `problem_domain`: {{problem_domain}}
- `constraints`: {{constraints}}
## Inputs
1. intent_document: optional full document that explains goals, context, constraints, and desired outcomes
+6 -15
View File
@@ -1,25 +1,16 @@
---
name: jsfiddle-page-layout
description: Create a responsive sample page layout for a user-supplied domain and return paste-ready HTML and CSS for JSFiddle.
x-personal-mcp:
id: jsfiddle-page-layout
version: 1.1.0
tags:
- frontend
- html
- css
- jsfiddle
- layout
- prototyping
- prompts
capabilities:
- resource://prompts/jsfiddle-page-layout/document
icon: lucide/messages-square
---
# JSFiddle Page Layout
Create a polished sample page layout for the supplied domain. The result must run by pasting the markup and styles into the [JSFiddle](https://jsfiddle.net/) HTML and CSS panes.
## Supplied Inputs
- `domain`: {{domain}}
- `layout_brief`: {{layout_brief}}
## Inputs
1. `domain`: the product, service, organization, or subject represented by the page, including its intended audience when known
+11 -33
View File
@@ -1,36 +1,18 @@
---
name: mcp-consumer-repo-shim
description: Create one repository-specific thin shim instruction file that binds a file scope to a user-selected Personal MCP skill resource and enforces resource-first Copilot retrieval behavior.
x-personal-mcp:
id: mcp-consumer-repo-shim
version: 1.0.0
tags:
- copilot
- mcp
- instructions
- shims
- prompts
capabilities:
- resource://prompts/mcp-consumer-repo-shim/document
arguments:
apply_to_glob:
description: File glob scope for the shim applyTo field, such as tests/** or **/*.md.
required: true
primary_skill_resource:
description: Primary native skill resource URI in the form skill://<skill-name>/SKILL.md.
required: true
shim_title:
description: Human-readable name for the instruction shim frontmatter.
required: false
companion_docs_page:
description: Optional relative docs link for human-facing companion guidance.
required: false
icon: lucide/messages-square
---
# MCP Consumer Repository Shim
Use this prompt to generate exactly one repository-scoped Copilot instruction shim for an MCP consumer repository.
## Supplied Inputs
- `apply_to_glob`: {{apply_to_glob}}
- `primary_skill_resource`: {{primary_skill_resource}}
- `shim_title`: {{shim_title}}
- `companion_docs_page`: {{companion_docs_page}}
## Inputs
- Required:
@@ -45,7 +27,7 @@ Use this prompt to generate exactly one repository-scoped Copilot instruction sh
Load only sections relevant to the requested shim:
1. Thin shim pattern and scope guidance: [Skill Usage Mechanics](../../usage.md)
2. VS Code Copilot MCP behavior and fallback mechanics: [Copilot MCP Mechanics](../../copilot.md)
2. VS Code Copilot MCP resource behavior: [Copilot MCP Mechanics](../../copilot.md)
3. Authoring workflow and validation checklist: [Authoring Guide](../../authoring.md)
4. Instruction metadata expectations and examples: [Copilot customization skill](../../skills/copilot-customization/SKILL.md)
@@ -60,11 +42,8 @@ Load only sections relevant to the requested shim:
- include a primary rule that uses the selected primary_skill_resource first
- include a bounded execution pattern (load primary doc, apply only relevant sections, keep edits minimal)
6. Include VS Code/Copilot integration mechanics in the shim body:
- prefer MCP resource attachment when available
- use MCP resource attachment
- inspect `_manifest` only when the task needs supporting material
- if attachment is unavailable, use the generic fallback tools:
1. list_resources
2. read_resource
- ask one clarifying question when confidence is low
7. If companion_docs_page is provided, include it as a companion docs link line.
8. Do not generate additional files, code changes, or batch shim packs.
@@ -98,8 +77,7 @@ Execution pattern:
3. Keep edits minimal and aligned with repository conventions.
4. Prefer MCP resource attachment when available in the current chat surface.
5. Read the selected skill's `_manifest` only when supporting material is needed.
6. If MCP resource attachment is unavailable, use `list_resources` and `read_resource`.
7. If confidence is low, ask one clarifying question before editing.
6. If confidence is low, ask one clarifying question before editing.
Companion docs page: <optional-relative-doc-link>
```
@@ -1,41 +1,18 @@
---
name: nicegui-component-extraction
description: Extract a user-selected component from a JSFiddle page layout and implement it as a reusable NiceGUI render function with responsive styling and typed bindable state where needed.
x-personal-mcp:
id: nicegui-component-extraction
version: 1.0.0
tags:
- nicegui
- components
- frontend
- refactoring
- jsfiddle
- prompts
capabilities:
- resource://prompts/nicegui-component-extraction/document
arguments:
component:
title: Component
description: Component or page region to extract, identified by its visible label, semantic role, or selector.
required: true
source_layout:
title: Source layout
description: Optional HTML and CSS from the JSFiddle page layout prompt; when omitted, use the latest applicable output in the conversation.
required: false
target_location:
title: Target location
description: Optional target NiceGUI page, module, or package in which to create and integrate the component.
required: false
behavior_requirements:
title: Behavior requirements
description: Optional interactions, state, callbacks, or content variations the extracted component must support.
required: false
icon: lucide/messages-square
---
# NiceGUI Component Extraction
Extract one user-selected component from the output of the [JSFiddle Page Layout](../jsfiddle-page-layout/PROMPT.md) prompt and implement it as a reusable NiceGUI component in the target repository.
## Supplied Inputs
- `component`: {{component}}
- `source_layout`: {{source_layout}}
- `target_location`: {{target_location}}
- `behavior_requirements`: {{behavior_requirements}}
## Inputs
1. `component`: required visible label, semantic role, or selector identifying the component to extract
+8 -25
View File
@@ -1,35 +1,18 @@
---
name: pytest-fill-scaffold
description: Fill scaffolded pytest test methods with assertions, fixtures, and minimal test data while preserving concise test names and one-line intent docstrings.
x-personal-mcp:
id: pytest-fill-scaffold
version: 1.0.0
tags:
- pytest
- testing
- scaffolding
- prompts
capabilities:
- resource://prompts/pytest-fill-scaffold/document
arguments:
target_files:
description: Target test file paths under tests/.
required: true
stack:
description: Runtime stack type for fixture and marker choices.
required: true
strategy:
description: Balance between minimal and comprehensive implementation.
required: false
marker_lane:
description: Preferred marker lane when applicable.
required: false
icon: lucide/messages-square
---
# Pytest Fill Scaffold
Use this prompt after test scaffolding exists and method names/docstrings are already in place.
## Supplied Inputs
- `target_files`: {{target_files}}
- `stack`: {{stack}}
- `strategy`: {{strategy}}
- `marker_lane`: {{marker_lane}}
## Inputs
- Target test file(s) under tests/.
+8 -25
View File
@@ -1,35 +1,18 @@
---
name: pytest-scaffold
description: Plan and optionally scaffold pytest file and class structure for selected Python modules while preserving concise behavior-focused test names and one-line intent docstrings.
x-personal-mcp:
id: pytest-scaffold
version: 1.0.0
tags:
- pytest
- testing
- scaffolding
- prompts
capabilities:
- resource://prompts/pytest-scaffold/document
arguments:
target_modules:
description: Target module path(s) under src/.
required: true
mode:
description: Execution mode, either plan-only or scaffold.
required: true
path_strategy:
description: Optional mapping preference for src to tests paths.
required: false
naming_style:
description: Optional preference for concise method naming style.
required: false
icon: lucide/messages-square
---
# Pytest Scaffold
Use this prompt to consistently plan and scaffold pytest test modules for selected Python source modules.
## Supplied Inputs
- `target_modules`: {{target_modules}}
- `mode`: {{mode}}
- `path_strategy`: {{path_strategy}}
- `naming_style`: {{naming_style}}
## Inputs
- Required:
@@ -66,7 +66,6 @@ Choose one of these patterns:
- Read selected supporting files at `skill://<skill-name>/<supporting-path>`.
2. Discovery-first strategy:
- List resources, compare native main-resource names and descriptions, then load the best matching `SKILL.md`.
- In tool-only clients, use only `list_resources` and `read_resource` for the same sequence.
### Authoring guidance for shims
+9 -8
View File
@@ -29,14 +29,13 @@ tests/
registry/
test_read.py
ingest/
conftest.py
test_current_docs.py
test_document.py
test_prompt.py
models/
test_document_validation.py
test_prompt_validation.py
test_registry_payload_models.py
prompts/
test_content_renderer.py
test_filesystem_provider.py
skills/
test_provider.py
web/
@@ -49,6 +48,7 @@ tests/
Source-to-test alignment today:
- `src/personal_mcp/registry/ingest/` -> `tests/registry/ingest/`
- `src/personal_mcp/registry/models/` -> `tests/registry/models/`
- `src/personal_mcp/prompts/` -> `tests/prompts/`
- `src/personal_mcp/skills/provider.py` -> `tests/skills/test_provider.py`
- `src/personal_mcp/web/` and MCP HTTP surface -> `tests/web/`
@@ -65,8 +65,7 @@ Pytest runs with `--strict-markers`, so any unregistered marker fails the test r
Fixture placement follows test scope:
1. `tests/conftest.py` for cross-suite defaults.
2. `tests/registry/ingest/conftest.py` for ingest-specific setup.
3. `tests/web/conftest.py` for web and endpoint client setup.
2. `tests/web/conftest.py` for web and endpoint client setup.
Prefer adding fixtures at the narrowest scope that serves more than one test.
@@ -90,9 +89,11 @@ uv run pytest -m smoke -q
## Adding New Tests
When adding coverage:
1. Place tests under the nearest existing module subtree (`registry/`, `skills/`, or `web/`).
1. Place tests under the nearest existing module subtree (`prompts/`, `registry/`, `skills/`, or `web/`).
2. Mirror the source path where practical.
3. Reuse existing `conftest.py` files before adding new fixture layers.
4. Add markers only when they convey execution intent, and register new markers in `pyproject.toml` first.
This keeps the suite aligned with the current architecture while preserving a fast local test loop.
This keeps the suite aligned with the current architecture while preserving a fast local test loop.
Prefer durable boundaries over implementation details: provider discovery, prompt rendering, traversal rejection, protocol behavior, and installed-package path resolution. Do not test deleted catalog projections, Pydantic immutability internals, or helper delegation.
+5 -28
View File
@@ -22,7 +22,7 @@ The server uses `supporting_files="template"`. Main files and manifests appear i
The manifest contains every skill-relative path, byte size, and SHA256 hash. References do not have synthetic ids or a separate catalog record.
Prompts remain available through prompt catalog resources, prompt document resources, and MCP prompt objects.
Prompts are available through native MCP prompt discovery and rendering.
## Discovery Workflow
@@ -48,41 +48,19 @@ FastMCP provides native utilities in `fastmcp.utilities.skills`:
These utilities operate directly on the native `skill://` contract and require no repository-specific adapter.
## Tool-Only Clients
The server installs [`ResourcesAsTools`](https://gofastmcp.com/servers/transforms/resources-as-tools), which exposes generic tools:
1. `list_resources`
2. `read_resource`
A tool-only client should list resources, select a `skill://<name>/SKILL.md` URI, and read it. It can then read `_manifest` and selected supporting paths through the same tool.
There are no skill-specific search, detail, or document tools. This avoids maintaining a second discovery implementation.
## Optional Tool Search
For large tool inventories, FastMCP search transforms can reduce tool-list noise:
1. `PERSONAL_MCP_TOOL_SEARCH=none|regex|bm25` defaults to `none`.
2. `PERSONAL_MCP_TOOL_SEARCH_MAX_RESULTS=<positive int>` defaults to `5`.
3. `list_resources` and `read_resource` remain visible in search modes.
These settings filter tools, not native skill resources.
## Copilot Invocation
In VS Code, skills can arrive through:
1. explicit attachment from `Add Context > MCP Resources` or `MCP: Browse Resources`
2. generic `list_resources` and `read_resource` tool calls
3. a slash-command prompt that names a specific native skill URI
2. a slash-command prompt that names a specific native skill URI
Instructions can steer retrieval, but they do not guarantee automatic resource attachment in every chat surface.
A reliable prompt for a tool-only session is:
A reliable prompt is:
```text
Use personal-mcp list_resources to find the best matching skill://.../SKILL.md resource. Read one selected skill, inspect its _manifest only if supporting detail is needed, and reconcile the guidance with this workspace.
Browse personal-mcp resources and select the best matching skill://.../SKILL.md resource. Read one selected skill, inspect its _manifest only if supporting detail is needed, and reconcile the guidance with this workspace.
```
## Thin Shim Pattern
@@ -124,5 +102,4 @@ When a supporting path fails, refresh `_manifest`; file paths are the public sup
2. Confirm at least one `skill://<name>/SKILL.md` resource is listed.
3. Read its `_manifest` and verify `SKILL.md` appears with a SHA256 hash.
4. Read one supporting file through its manifest path.
5. Confirm `list_resources` and `read_resource` are available for tool-only clients.
6. Keep loaded context bounded to the selected skill and relevant files.
5. Keep loaded context bounded to the selected skill and relevant files.