9.5 KiB
Step 5 Results: Registry-Driven FastMCP Resource Registration (RFC6570 + Startup Safety)
This section finalizes Step 5 by defining how FastMCP resources are registered from the Step 4 docs registry using RFC6570 URI templates, explicit metadata, and strict duplicate-registration safety.
Greenfield Framing (Normative)
This Step 5 design is for the greenfield target state:
- Registry-driven resources are the primary and authoritative discovery/read surface.
- No legacy per-skill hardcoded resource registration is retained.
- Resource contracts are defined for net-new clients and replace prior contracts without transition shims.
- Step 6 tool fallback layers on top of this resource contract, not as a competing source of truth.
- Breaking changes are intentional in this full-refactor phase.
Research Baseline (FastMCP + URI Templates)
Authoritative references used for this step:
- FastMCP Resources and Templates docs (resource decorator, template behavior)
- FastMCP RFC6570 support docs (simple params, wildcard params, query params)
- FastMCP duplicate handling docs (
on_duplicate_resources) - FastMCP annotations guidance (
readOnlyHint,idempotentHint)
Best-practice conclusions applied to this design:
- Use URI templates for parameterized resources instead of generating N static resource handlers.
- Use wildcard template parameters (
{path*}) for hierarchical docs paths. - Set startup duplicate policy to
on_duplicate_resources="error"to fail fast on contract collisions. - Set explicit
mime_typeand resource annotations for all docs resources. - Keep registration deterministic and sourced only from the validated Step 4 registry.
Registration Responsibilities (Normative)
The Step 5 registration layer MUST:
- Consume only the validated in-memory registry produced by Step 4.
- Register canonical resource discovery surfaces and skill document/reference surfaces.
- Use RFC6570 templates where URI patterns are parameterized.
- Use wildcard templates where path depth is variable.
- Attach read-only/idempotent annotations to documentation resources.
- Set explicit MIME types for all registered resources.
- Fail startup if duplicate URI/template keys are encountered.
Canonical Resource Surface (from Registry)
The preferred resources registered in this phase are:
resource://catalog/skills_indexresource://catalog/skills_index{?q,tag,capability,cursor,limit}(optional filtered/paginated discovery template)resource://catalog/skills/{skill_id}resource://skills/{skill_id}/documentresource://skills/{skill_id}/references/{ref_id}resource://docs/{path*}
Registration decision rules:
- Use static resource registration for fixed singleton endpoints (for example
skills_index). - Use template registration for parameterized endpoints (
{skill_id},{ref_id}) and optional discovery query templates. - Use wildcard template registration for hierarchical docs routing (
{path*}). - Keep the singleton and query-template discovery surfaces semantically equivalent (same schema, query template adds filtering/pagination only).
Progressive Discovery Contract
Discovery-first behavior for Step 5 resources:
skills_indexreturns summaries only (no embedded full SKILL.md bodies).- Each summary includes canonical follow-up URIs so clients can progressively fetch detail (
catalog/skills/{skill_id}thenskills/{skill_id}/document). - Filtered/paginated discovery uses RFC6570 query params (
q,tag,capability,cursor,limit) with deterministic ordering. - Handlers should enforce bounded page size and return explicit continuation metadata when pagination is active.
- Errors for unsupported filter params or invalid cursor/limit are explicit and actionable.
RFC6570 Template Contract
Path parameters:
{skill_id}and{ref_id}are single-segment template params.{path*}is a wildcard param and may capture multi-segment paths separated by/.
Validation contract at resource-read time:
skill_idmust exist in registry.ref_idmust exist in that skill’s reference manifest.- wildcard
path*must normalize to an allowed docs-relative markdown path. - invalid params return explicit not-found or validation errors (no silent fallback).
Template function signature contract:
- Required URI params must exist as function parameters.
- Avoid hidden implicit params not represented in template.
- Keep template handlers side-effect free.
Metadata and Annotation Contract
Each docs/resource registration should specify explicit metadata:
mime_type- skill docs and references:
text/markdown - catalog payloads:
application/json
- skill docs and references:
annotationsreadOnlyHint: trueidempotentHint: true
tags- include stable categories such as
catalog,skill-doc,reference,docs
- include stable categories such as
version- project-defined version from registry metadata where applicable
meta- include normalized identifiers (for example
skill_id,ref_id,source_relpath) when useful
- include normalized identifiers (for example
Startup Safety and Duplicate Policy
FastMCP initialization contract for this phase:
- Construct the root server with
on_duplicate_resources="error". - Register all Step 5 resources during startup composition before serving traffic.
- Treat duplicate registration as a hard startup failure.
Duplicate conflict classes covered:
- static URI vs static URI collision
- static URI vs template key collision
- template URI vs template URI collision
- conflicting registrations introduced by future aliases without explicit migration handling
Registration Architecture
Use one dedicated registration module that converts registry records into FastMCP resources.
Recommended API:
register_docs_resources(mcp: FastMCP, registry: DocsRegistry) -> None
Responsibilities of register_docs_resources:
- register singleton catalog resources
- register parameterized catalog/detail templates
- register skill document and reference templates
- register docs wildcard template
- apply shared annotations and MIME defaults consistently
Separation of concerns:
- Step 4 validates and normalizes docs state.
- Step 5 only registers handlers and reads from validated registry state.
- Request handlers do not re-discover filesystem/package structure.
Handler Behavior Contract
Catalog handlers:
skills_indexreturns compact deterministic discovery payload (summary records only) and supports progressive follow-up links.skills/{skill_id}returns one normalized detail record or not-found.
Skill document handlers:
skills/{skill_id}/documentreturns canonical SKILL markdown content.- MIME type is always
text/markdown.
Reference handlers:
skills/{skill_id}/references/{ref_id}resolves via frontmatter manifest mapping.- MIME type is explicit from manifest or defaults to
text/markdown.
Wildcard docs handler:
docs/{path*}serves markdown docs under canonical packaged docs tree.- traversal outside docs root is blocked.
Integration Plan for Existing Modules
Primary composition updates:
- Implement registry-driven registration in src/personal_mcp/mcp.py as the canonical resource composition path.
- Keep src/personal_mcp/main.py responsible for startup wiring order (load registry first, then register resources).
- Use src/personal_mcp/catalog/server.py as registry-backed handlers only.
Lifecycle order (required):
- load and validate registry (Step 4)
- initialize FastMCP with duplicate error policy
- register all Step 5 resources/templates
- start server
Testing Plan (Step 5 Scope)
Unit/integration tests:
- resource registration succeeds with valid registry
- duplicate resource registration fails at startup
skills/{skill_id}template resolves expected recordskills/{skill_id}/documentreturns markdown with correct MIMEskills/{skill_id}/references/{ref_id}resolves manifest-mapped filedocs/{path*}resolves nested docs paths and blocks traversal attempts- all registered docs resources include
readOnlyHintandidempotentHint - catalog payload order is deterministic
- filtered/paginated
skills_index{?q,tag,capability,cursor,limit}responses are deterministic and schema-compatible with the singleton index response - catalog index payload excludes full markdown bodies and includes follow-up URIs for progressive reads
Smoke tests:
- list resources includes singleton and template entries
- read representative skill doc URI and reference URI successfully
- read representative wildcard docs URI successfully
Acceptance Criteria for Step 5 Completion
Step 5 is complete when all are true:
- Resource registration is fully registry-driven (no per-skill hardcoded decorators required for core docs surfaces).
- RFC6570 templates are used for parameterized URI families, including wildcard where needed.
- All docs resources declare explicit MIME types and read-only/idempotent annotations.
on_duplicate_resources="error"is enabled and verified by tests.- Startup fails safely on registration conflicts.
Non-goals for Step 5
- No tool fallback discovery behavior implementation (Step 6).
- No packaging build inclusion mechanics (Step 7).
- No CI gate expansion details (Step 9).
- No migration shims for legacy URI aliases in the greenfield baseline.
- No ranking-strategy implementation for discovery tools beyond what is needed to preserve deterministic resource-first discovery contracts.
- No backward-compat resource aliases, adapter handlers, or dual registration paths.