Compare commits
2
Commits
b2ac4102f7
...
9eb4ccbc6e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9eb4ccbc6e | ||
|
|
bbaa84720c |
@@ -4,102 +4,40 @@ icon: lucide/library
|
||||
|
||||
# Architecture
|
||||
|
||||
## Overview
|
||||
Personal MCP is a small publishing service. Markdown is written once and made available in two ways:
|
||||
|
||||
The application combines a FastMCP server with a pre-built Zensical documentation site. Markdown under `src/personal_mcp/docs/` is the single authored content tree, while native FastMCP providers own skill and prompt discovery.
|
||||
1. as an MCP server for AI clients
|
||||
2. as a documentation website for people
|
||||
|
||||
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. `src/personal_mcp/docs/skills/<skill-id>/SKILL.md`
|
||||
2. `src/personal_mcp/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: `src/personal_mcp/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
|
||||
## How It Fits Together
|
||||
|
||||
```mermaid
|
||||
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
|
||||
flowchart LR
|
||||
A[Markdown in src/personal_mcp/docs] --> B[MCP resources and prompts]
|
||||
A --> C[Documentation website]
|
||||
B --> D[AI clients]
|
||||
C --> E[Human readers]
|
||||
```
|
||||
|
||||
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.
|
||||
The running application has two routes:
|
||||
|
||||
## Packaging
|
||||
- `/mcp` is the MCP endpoint.
|
||||
- `/docs/` is the pre-built documentation site.
|
||||
|
||||
The regular directory `src/personal_mcp/docs/` is the only authored Markdown source. The `uv_build` backend includes it as package data beneath `personal_mcp/docs/` in built distributions.
|
||||
The root URL redirects to the website.
|
||||
|
||||
Runtime reads are package-relative:
|
||||
## Content Types
|
||||
|
||||
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.
|
||||
The server publishes three kinds of Markdown content:
|
||||
|
||||
## Public Contracts
|
||||
- **Skills** are reusable guidance that clients read as `skill://` resources.
|
||||
- **Prompts** are parameterized workflows that clients invoke as MCP prompts.
|
||||
- **Documentation** is available to clients through `resource://docs/...` and to people on the website.
|
||||
|
||||
The machine-facing surfaces are:
|
||||
FastMCP provides the MCP behavior. FastAPI hosts that server beside the static site, and Zensical builds the site from the same Markdown files.
|
||||
|
||||
1. Native skill resources under `skill://<name>/...`.
|
||||
2. Native MCP prompt list and get operations.
|
||||
3. `resource://docs/{path*}` for general Markdown.
|
||||
## Source Of Truth
|
||||
|
||||
Canonical contracts are documented in:
|
||||
All authored content lives under `src/personal_mcp/docs/`. The generated `src/personal_mcp/site/` directory is build output and should not be edited by hand.
|
||||
|
||||
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)
|
||||
|
||||
Only these canonical provider and protocol surfaces are registered.
|
||||
|
||||
## Static Documentation
|
||||
|
||||
Zensical builds `src/personal_mcp/docs/` into `src/personal_mcp/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
|
||||
For exact file formats and URI rules, see the [content contracts](./contracts/index.md). For everyday changes, start with the [Authoring Guide](./authoring.md).
|
||||
|
||||
@@ -4,112 +4,48 @@ icon: lucide/pencil
|
||||
|
||||
# Authoring Guide
|
||||
|
||||
This page defines the practical workflow for maintaining skills, prompts, and project documentation in the package-native `src/personal_mcp/docs` source tree.
|
||||
|
||||
Primary references:
|
||||
|
||||
1. [Skill Contract](./contracts/skill_contract.md)
|
||||
2. [Prompt Contract](./contracts/prompt.md)
|
||||
3. [Frontmatter Contract](./contracts/frontmatter.md)
|
||||
4. [URI Contract](./contracts/uris.md)
|
||||
5. [Zensical documentation skill](./skills/zensical-docs/SKILL.md)
|
||||
All authored content lives under `src/personal_mcp/docs/`. The same files feed the MCP server and the documentation website.
|
||||
|
||||
## Source Tree Ownership
|
||||
|
||||
Edit content only under `src/personal_mcp/docs`. This directory is the canonical authored source for both MCP content and the documentation site.
|
||||
|
||||
The `uv_build` backend packages this tree under `personal_mcp/docs/`. The installed package therefore gives runtime providers package-relative content, while Zensical builds the human site directly from `src/personal_mcp/docs` as configured by `docs_dir` in the repository's `zensical.toml`.
|
||||
|
||||
Generated `src/personal_mcp/site/` content is a build artifact and must not be edited by hand.
|
||||
|
||||
## Content Layout
|
||||
|
||||
```text
|
||||
src/personal_mcp/docs/
|
||||
*.md
|
||||
contracts/
|
||||
*.md # General documentation
|
||||
prompts/<prompt-id>/
|
||||
PROMPT.md
|
||||
references/
|
||||
PROMPT.md # One MCP prompt
|
||||
skills/<skill-name>/
|
||||
SKILL.md
|
||||
references/
|
||||
SKILL.md # Main skill guidance
|
||||
references/ # Optional supporting material
|
||||
```
|
||||
|
||||
Keep skill and prompt files inside their owning directories. Relative links may cross sections, but content ownership should remain clear.
|
||||
Do not edit `src/personal_mcp/site/` by hand. It is generated by Zensical.
|
||||
|
||||
## Documentation Pages
|
||||
|
||||
Add general documentation as Markdown under `src/personal_mcp/docs/`. Use relative links between pages. Top-level pages need an `icon` in their frontmatter, and navigation changes belong in `zensical.toml`.
|
||||
|
||||
## Skill Authoring
|
||||
|
||||
A skill is discovered when a direct child of `src/personal_mcp/docs/skills/` contains `SKILL.md`.
|
||||
|
||||
Required frontmatter:
|
||||
A skill is a directory containing `SKILL.md`:
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: <skill-name>
|
||||
description: <what the skill does and when to use it>
|
||||
description: <what this skill covers and when to use it>
|
||||
---
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
1. Use lowercase kebab-case for the directory and `name`.
|
||||
2. Keep `name` exactly equal to the directory name.
|
||||
3. Write a specific description because clients use it for discovery.
|
||||
4. Do not add `x-personal-mcp`, versions, tags, capabilities, or reference mappings.
|
||||
5. Put supporting material anywhere beneath the skill directory, normally under `references/`.
|
||||
6. Link supporting files from `SKILL.md` so humans and agents understand when to load them.
|
||||
|
||||
FastMCP recursively scans every skill file and generates `skill://<name>/_manifest`. Supporting-resource identity is the real relative path, not a synthetic reference id.
|
||||
|
||||
Recommended sequence:
|
||||
|
||||
1. Draft or revise `SKILL.md` routing guidance.
|
||||
2. Add focused supporting files.
|
||||
3. Verify relative links.
|
||||
4. Run the provider tests and docs build.
|
||||
5. Restart running servers because production uses `reload=False`.
|
||||
Use lowercase kebab-case, and keep the directory name and frontmatter `name` identical. Put optional references beneath the same directory and link to them from `SKILL.md` when readers need to know they exist.
|
||||
|
||||
## Prompt Authoring
|
||||
|
||||
A prompt is one self-describing `src/personal_mcp/docs/prompts/<prompt-id>/PROMPT.md` file:
|
||||
A prompt is one `PROMPT.md` file under `src/personal_mcp/docs/prompts/<prompt-id>/`. Its `prompt` frontmatter describes the workflow and arguments; its Markdown body contains the instructions.
|
||||
|
||||
1. Create a lowercase kebab-case directory beneath `src/personal_mcp/docs/prompts/`.
|
||||
2. Add a nested `prompt` frontmatter mapping with version, description, tags, and ordered arguments.
|
||||
3. Give every argument a description and explicit required flag.
|
||||
4. Add `choices` only when a string argument accepts a fixed set of values.
|
||||
5. Use each argument exactly once or more as a `{{argument_name}}` placeholder in the body.
|
||||
6. Do not add a Python component, name field, metadata sidecar, or central catalog entry.
|
||||
Use each declared argument as a `{{placeholder}}` in the body. The server validates prompt metadata and placeholders when the prompt is discovered.
|
||||
|
||||
The custom provider rescans prompt documents during every native list and get request. Changes in an editable checkout are therefore visible on the next request without a process restart. Invalid metadata or placeholder drift fails that request with a configuration error.
|
||||
The [Prompt Contract](./contracts/prompt.md) and [Frontmatter Contract](./contracts/frontmatter.md) contain the exact schema.
|
||||
|
||||
## 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 documentation contract.
|
||||
|
||||
## Writing Quality
|
||||
|
||||
1. Prefer focused sections and descriptive headings.
|
||||
2. Link feature-level claims to authoritative sources.
|
||||
3. Use relative links for internal pages.
|
||||
4. Keep code examples minimal and actionable.
|
||||
5. Avoid bare URLs in prose.
|
||||
6. Load only supporting material relevant to the immediate task.
|
||||
|
||||
## Copilot Routing
|
||||
|
||||
Active instructions should point directly to native main resources:
|
||||
|
||||
1. `skill://zensical-docs/SKILL.md`
|
||||
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.
|
||||
|
||||
## Validation Checklist
|
||||
## Validate Changes
|
||||
|
||||
```bash
|
||||
uv run zensical build
|
||||
@@ -118,13 +54,6 @@ uv run ty check
|
||||
uv run pytest
|
||||
```
|
||||
|
||||
For packaging changes, also build and inspect an installed wheel so provider path resolution is verified outside the editable checkout.
|
||||
Restart a running server after changing content so every surface reads the latest package data.
|
||||
|
||||
## Navigation
|
||||
|
||||
When adding or moving pages:
|
||||
|
||||
1. update `zensical.toml`
|
||||
2. keep top-level page icons in frontmatter
|
||||
3. rebuild the site
|
||||
4. verify internal links and navigation labels
|
||||
For detailed rules, see the [content contracts](./contracts/index.md). For writing and site features, use the [Zensical documentation skill](./skills/zensical-docs/SKILL.md).
|
||||
|
||||
@@ -2,129 +2,56 @@
|
||||
icon: lucide/bot
|
||||
---
|
||||
|
||||
# Copilot MCP Mechanics
|
||||
# Using With GitHub Copilot
|
||||
|
||||
## Purpose
|
||||
Once Personal MCP is configured as a VS Code MCP server, Copilot can use its resources, prompts, and read-only tools.
|
||||
|
||||
This page explains how GitHub Copilot in VS Code consumes native skill resources and prompts from `personal-mcp`.
|
||||
For general connection details, see [Using Personal MCP](./usage.md). For VS Code setup options, see [Add and manage MCP servers](https://code.visualstudio.com/docs/agent-customization/mcp-servers).
|
||||
|
||||
## Capability Lanes
|
||||
## Skills And Documentation
|
||||
|
||||
Copilot interacts with MCP servers through independently exposed lanes:
|
||||
Use **MCP: Browse Resources** to inspect the server's resources. Skills appear as `skill://<name>/SKILL.md`; general pages appear under `resource://docs/...`.
|
||||
|
||||
1. tools invoked during execution
|
||||
2. resources attached as read-only context
|
||||
3. server-provided prompts
|
||||
For a task that needs guidance:
|
||||
|
||||
This server publishes skills as native `skill://` resources, general docs as `resource://docs/{path*}` resources, and workflows as native MCP prompt objects. It intentionally publishes no compatibility tools that mirror resources or prompts.
|
||||
1. choose the skill whose description best matches the task
|
||||
2. read its main `SKILL.md`
|
||||
3. read `_manifest` only when supporting material is needed
|
||||
4. attach or read only the relevant supporting files
|
||||
|
||||
## VS Code Feature Coverage
|
||||
When the current chat surface supports MCP resource attachments, the same resources are available from **Add Context**.
|
||||
|
||||
The server uses every FastMCP feature that applies to its read-only guidance workload:
|
||||
## Prompts
|
||||
|
||||
| Feature | Usage |
|
||||
| --- | --- |
|
||||
| Server identity | The initialize response includes a stable name, usage instructions, and a self-contained icon for VS Code's MCP server UI. |
|
||||
| Tools | No tools are published for this documentation-only server surface. Resource and prompt operations stay on native MCP capabilities. |
|
||||
| Resources | Documentation and skills use native resources and wildcard resource templates with explicit Markdown MIME types. |
|
||||
| Prompts | Declarative workflows use native prompt objects with descriptions, display titles, typed arguments, and slash-command access. |
|
||||
| Argument completion | Prompt arguments with authored `choices` are returned through `completion/complete` as the user types. |
|
||||
Personal MCP prompts appear as `/<server>.<prompt>` chat commands. Select a command and fill in its arguments to start the workflow. Arguments with a fixed list of choices offer completion as you type.
|
||||
|
||||
[FastMCP server identity](https://gofastmcp.com/servers/server), [component icons](https://gofastmcp.com/servers/icons), [tool metadata](https://gofastmcp.com/servers/tools), and [argument completion](https://gofastmcp.com/servers/completions) define the implementation details. [VS Code's MCP documentation](https://code.visualstudio.com/docs/agent-customization/mcp-servers) describes how tools, resources, prompts, and MCP Apps appear in the client.
|
||||
## Automatic Use
|
||||
|
||||
The following capabilities are conditional rather than useful by default:
|
||||
Copilot can use four fallback tools when the chat surface does not expose resources or prompts directly:
|
||||
|
||||
1. MCP Apps require an interactive tool result such as a form or visualization; this server returns guidance and structured resource data only.
|
||||
2. Sampling is appropriate only when server-side work must ask VS Code to run an LLM. The current server retrieves authored content and does not generate it.
|
||||
3. Elicitation is appropriate only when a running operation needs additional user input. Prompt arguments already collect all required input before execution.
|
||||
4. Progress, client logging, and background tasks require long-running operations. Current reads and prompt rendering are bounded local operations.
|
||||
5. Client roots matter only when server behavior depends on client filesystem roots. This server reads packaged content and never traverses a client workspace.
|
||||
6. `website_url` requires a canonical public deployment URL. None is configured, so the server does not advertise a guessed address.
|
||||
- `list_resources` and `read_resource`
|
||||
- `list_prompts` and `get_prompt`
|
||||
|
||||
Add one of these capabilities when a concrete workflow needs it, then cover its negotiated capability and protocol response in the HTTP MCP smoke tests. See the [FastMCP Apps overview](https://gofastmcp.com/apps/overview), [sampling](https://gofastmcp.com/servers/sampling), [elicitation](https://gofastmcp.com/servers/elicitation), [progress reporting](https://gofastmcp.com/servers/progress), and [MCP context](https://gofastmcp.com/servers/context) for the activation criteria.
|
||||
|
||||
## Native Skill Resources
|
||||
|
||||
For every skill, Copilot can discover:
|
||||
|
||||
1. `skill://<name>/SKILL.md`
|
||||
2. `skill://<name>/_manifest`
|
||||
3. `skill://<name>/{path*}` supporting-file template
|
||||
|
||||
The main resource description comes from `SKILL.md`. The manifest discloses supporting paths, sizes, and SHA256 hashes. Native resources remain the only skill content and discovery contract; the tools search or delegate to that same resource surface rather than maintaining a parallel catalog.
|
||||
|
||||
## Resource Picker Availability
|
||||
|
||||
`MCP Resources...` in Add Context requires both:
|
||||
|
||||
1. a connected server advertising resource capability
|
||||
2. a chat surface that exposes MCP resource attachment
|
||||
|
||||
A successful `resources/list` response does not guarantee the picker appears in every session type. Use `MCP: Browse Resources` to distinguish server availability from chat UI availability.
|
||||
|
||||
## Recommended Workflow
|
||||
|
||||
For autonomous agents:
|
||||
|
||||
1. browse native resources and compare skill descriptions
|
||||
2. read one relevant `skill://<name>/SKILL.md`
|
||||
3. read `_manifest` only if supporting detail may be needed
|
||||
4. read only selected supporting files
|
||||
|
||||
For manual context attachment, browse the server's resources and attach the same bounded set of files.
|
||||
|
||||
## Prompt Examples
|
||||
|
||||
Resource attachment:
|
||||
These tools access the same content as the native features. A repository instruction can guide Copilot toward the intended order:
|
||||
|
||||
```text
|
||||
Use the attached personal-mcp skill as guidance, then reconcile it with the repository before proposing changes.
|
||||
```
|
||||
|
||||
Direct loading:
|
||||
|
||||
```text
|
||||
Read skill://async-fastapi-sqlmodel/SKILL.md and apply only the sections relevant to this repository.
|
||||
```
|
||||
|
||||
Supporting material:
|
||||
|
||||
```text
|
||||
Read skill://pytesting/_manifest, select the one reference relevant to async test lifecycle, and use that file with the main skill instructions.
|
||||
```
|
||||
|
||||
## Repository Instruction Pattern
|
||||
|
||||
A repo-level instruction should name the native retrieval order and context budget:
|
||||
|
||||
```md
|
||||
When a task matches a personal-mcp skill:
|
||||
|
||||
1. Prefer an already attached native skill resource.
|
||||
2. Otherwise browse MCP resources and select one `skill://<name>/SKILL.md` by description.
|
||||
3. Read the selected skill and 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.
|
||||
1. Prefer an attached skill resource, or browse resources and choose one by description.
|
||||
2. Read its main file and load supporting material only when needed.
|
||||
3. Reconcile the guidance with the current repository before editing.
|
||||
```
|
||||
|
||||
Instructions steer behavior but do not force VS Code to attach resources automatically.
|
||||
|
||||
## Prompt Objects
|
||||
|
||||
Prompts remain separate from skills. When the client supports MCP prompt APIs, use prompt listing and `get_prompt` for parameterized workflows. Each authored `PROMPT.md` is the complete source of truth for its metadata, arguments, and prose; changes are loaded on the next prompt request.
|
||||
Instructions guide resource use but do not force VS Code to attach resources automatically.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
1. Use `MCP: List Servers` to confirm the server is enabled.
|
||||
2. Use `MCP: Browse Resources` to confirm native skill resources exist.
|
||||
3. Confirm `Add Context > MCP Resources` lists server resources in the active chat surface.
|
||||
4. Restart the MCP server after changing skill files because production uses `reload=False`.
|
||||
5. Reload the VS Code window if the server is healthy but the resource or tool picker remains stale.
|
||||
2. Use `MCP: Browse Resources` to confirm resources are available.
|
||||
3. Restart the MCP server after changing its content.
|
||||
4. Reload the VS Code window if the server is healthy but the resource or tool list remains stale.
|
||||
|
||||
## Further Reading
|
||||
|
||||
1. [FastMCP Skills Provider](https://gofastmcp.com/servers/providers/skills)
|
||||
2. [Add and manage MCP servers](https://code.visualstudio.com/docs/agent-customization/mcp-servers)
|
||||
3. [MCP configuration reference](https://code.visualstudio.com/docs/agents/reference/mcp-configuration)
|
||||
4. [Manage context for AI](https://code.visualstudio.com/docs/chat/copilot-chat-context)
|
||||
5. [Skill Usage Mechanics](./usage.md)
|
||||
1. [VS Code MCP configuration](https://code.visualstudio.com/docs/agents/reference/mcp-configuration)
|
||||
2. [Managing context in VS Code](https://code.visualstudio.com/docs/chat/copilot-chat-context)
|
||||
3. [Using Personal MCP](./usage.md)
|
||||
|
||||
@@ -4,45 +4,46 @@ icon: lucide/rocket
|
||||
|
||||
# Personal MCP
|
||||
|
||||
This project is a document library of software patterns, best practices, and structured references to external documentation. The same markdown files are published through two equivalent surfaces, so human-readable docs and MCP resources stay aligned.
|
||||
Personal MCP is a library of software development guidance for people and AI assistants. Content is written once in Markdown and published as both a documentation website and an MCP server.
|
||||
|
||||
## MCP Server
|
||||
## What It Provides
|
||||
|
||||
An [MCP server](https://modelcontextprotocol.io/docs/getting-started/intro) at `/mcp` provides context for AI systems. The markdown files are exposed as [resources](https://modelcontextprotocol.io/docs/learn/server-concepts#resources) and are structured to be easily consumed by [MCP clients](https://modelcontextprotocol.io/docs/learn/client-concepts), such as VS Code.
|
||||
- **Skills** provide focused guidance for development tasks.
|
||||
- **Prompts** provide reusable workflows with named inputs.
|
||||
- **Documentation** makes the same material easy to browse and maintain.
|
||||
|
||||
## Docs
|
||||
The HTTP service exposes the [MCP](https://modelcontextprotocol.io/docs/getting-started/intro) endpoint at `/mcp` and the website at `/docs/`.
|
||||
|
||||
A website at `/docs` for humans to read and review.
|
||||
## Quick Start
|
||||
|
||||
## Quick start
|
||||
|
||||
Install dependencies first:
|
||||
Install dependencies, build the website, and start the server:
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
uv run zensical build
|
||||
uv run personal-mcp --host 127.0.0.1 --port 8765
|
||||
```
|
||||
|
||||
Run the app locally with the static docs rebuilt first, using [Uvicorn factory mode](https://www.uvicorn.org/settings/#application):
|
||||
Then open `http://127.0.0.1:8765/docs/` or connect an MCP client to `http://127.0.0.1:8765/mcp`.
|
||||
|
||||
The MCP server can also run over standard input and output:
|
||||
|
||||
```bash
|
||||
uv run zensical build && uv run uvicorn personal_mcp.web.app:create_app --factory --host 127.0.0.1 --port 8765
|
||||
uv run mcp-stdio
|
||||
```
|
||||
|
||||
Build and run the Docker image with the same exposed port:
|
||||
For Docker:
|
||||
|
||||
```bash
|
||||
docker build -t personal-mcp . && docker run --rm -p 8765:8765 personal-mcp
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
When the server is running, the health check is available at `/healthz` and the generated docs are available at `/docs/`.
|
||||
## Read Next
|
||||
|
||||
## Architecture
|
||||
|
||||
- [Resource-First Pattern Module Architecture](./architecture.md)
|
||||
- [Contracts](./contracts/index.md)
|
||||
- [Content Contract](./contracts/index.md#content-contract)
|
||||
- [Frontmatter Contract](./contracts/frontmatter.md)
|
||||
- [URI Contract](./contracts/uris.md)
|
||||
- [Static Docs Hosting Pattern](./mcp_layout.md)
|
||||
- [Skill Usage Mechanics](./usage.md)
|
||||
- [Copilot MCP Mechanics](./copilot.md)
|
||||
- [Using Personal MCP](./usage.md)
|
||||
- [Authoring Guide](./authoring.md)
|
||||
- [Architecture](./architecture.md)
|
||||
- [Running the Server](./mcp_layout.md)
|
||||
- [Testing](./testing.md)
|
||||
- [Security](./securing.md)
|
||||
- [Content Contracts](./contracts/index.md)
|
||||
|
||||
@@ -2,92 +2,43 @@
|
||||
icon: lucide/server
|
||||
---
|
||||
|
||||
# Runtime And Static Docs Layout
|
||||
# Running The Server
|
||||
|
||||
## Purpose
|
||||
Personal MCP can run as an HTTP service or as a local stdio process.
|
||||
|
||||
The project serves native MCP content and a pre-built documentation site from one FastAPI process. Markdown is authored once under `src/personal_mcp/docs/`; runtime providers and Zensical consume that same package-owned tree for different purposes.
|
||||
## Local HTTP Server
|
||||
|
||||
## Repository Layout
|
||||
Build the website before starting the application:
|
||||
|
||||
```mermaid
|
||||
---
|
||||
config:
|
||||
treeView:
|
||||
rowIndent: 32
|
||||
lineThickness: 2
|
||||
---
|
||||
treeView-beta
|
||||
"project-root"
|
||||
"src/personal_mcp"
|
||||
"docs"
|
||||
"prompts/<prompt-id>/PROMPT.md"
|
||||
"skills/<skill-id>/SKILL.md"
|
||||
"skills/<skill-id>/<supporting-files>"
|
||||
"<general-pages>.md"
|
||||
"site"
|
||||
"static build output"
|
||||
"app.py"
|
||||
"mcp.py"
|
||||
"skills.py"
|
||||
"prompts/"
|
||||
"registry/"
|
||||
```bash
|
||||
uv sync
|
||||
uv run zensical build
|
||||
uv run personal-mcp --host 127.0.0.1 --port 8765
|
||||
```
|
||||
|
||||
Ownership rules:
|
||||
The server then provides:
|
||||
|
||||
1. `src/personal_mcp/docs/skills/` is owned exclusively by `SkillsDirectoryProvider` at runtime.
|
||||
2. Each file under `src/personal_mcp/docs/prompts/` owns its prompt metadata, argument schema, and prose.
|
||||
3. The docs registry owns only general Markdown resources and explicitly excludes skills.
|
||||
4. `src/personal_mcp/site/` is generated output.
|
||||
5. The deleted custom `catalog/` package is not part of the runtime.
|
||||
- `http://127.0.0.1:8765/docs/` for the website
|
||||
- `http://127.0.0.1:8765/mcp` for MCP clients
|
||||
|
||||
## Runtime Composition
|
||||
The host, port, log level, debug mode, and reload behavior can be set with command-line options or `PERSONAL_MCP_` environment variables.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Packaged Skills] --> B[SkillsDirectoryProvider]
|
||||
C[Packaged Prompt Markdown] --> D[Markdown Prompt Provider]
|
||||
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
|
||||
## Local Stdio Server
|
||||
|
||||
For clients that manage the server process themselves:
|
||||
|
||||
```bash
|
||||
uv run mcp-stdio
|
||||
```
|
||||
|
||||
Runtime guarantees:
|
||||
This mode provides MCP only; it does not host the website.
|
||||
|
||||
1. Providers are installed before serving requests.
|
||||
2. Prompt discovery rescans authored files on each list and get request.
|
||||
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.
|
||||
## Docker
|
||||
|
||||
## Build And Publish Flow
|
||||
The included Compose configuration builds the website into the image and publishes the service on port `8765`:
|
||||
|
||||
1. Author prompt definitions and prose under `src/personal_mcp/docs/prompts/`.
|
||||
2. Run `uv run zensical build` to produce `src/personal_mcp/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.
|
||||
```bash
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
No runtime Markdown-to-HTML conversion occurs.
|
||||
|
||||
## Machine-Facing Mapping
|
||||
|
||||
1. `src/personal_mcp/docs/skills/<skill-id>/SKILL.md` maps to `skill://<skill-id>/SKILL.md`.
|
||||
2. Skill supporting files map to `skill://<skill-id>/<path>`.
|
||||
3. Declarative prompt documents map to native MCP prompt names.
|
||||
4. General `src/personal_mcp/docs/<path>.md` maps to `resource://docs/{path*}`.
|
||||
|
||||
The server publishes no tool projections of resources or prompts.
|
||||
|
||||
## Public Surface Policy
|
||||
|
||||
Canonical provider and protocol surfaces are the only public interfaces.
|
||||
|
||||
## Static Mount Expectations
|
||||
|
||||
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.
|
||||
For a remote deployment, place the service behind a reverse proxy and review the [security guidance](./securing.md).
|
||||
|
||||
@@ -2,138 +2,41 @@
|
||||
icon: lucide/shield-check
|
||||
---
|
||||
|
||||
# Securing Remote Access
|
||||
# Security
|
||||
|
||||
## Context
|
||||
## Public By Design
|
||||
|
||||
This project exposes two related surfaces from the same runtime:
|
||||
The application does not implement authentication. Its current purpose is to publish read-only guidance, so everything exposed through the server must be safe to make public.
|
||||
|
||||
1. a static documentation site under `/docs`
|
||||
2. a Streamable HTTP MCP endpoint under `/mcp`
|
||||
This includes:
|
||||
|
||||
The same Markdown content backs both surfaces. For the current project shape, the MCP server is resource-first and primarily exposes public skill and documentation text. It is not intended to expose secrets, private data, shell access, filesystem access, or tools with side effects.
|
||||
- the website under `/docs/`
|
||||
- resources and prompts under `/mcp`
|
||||
- the four read-only fallback tools
|
||||
|
||||
The expected deployment path is:
|
||||
Do not add secrets, private notes, credentials, or sensitive environment details to the authored content.
|
||||
|
||||
## Remote Deployment
|
||||
|
||||
Place the service behind a reverse proxy or tunnel rather than exposing the container directly. The edge can provide TLS, rate limiting, access logs, and optional authentication without adding those concerns to this small application.
|
||||
|
||||
A simple deployment is:
|
||||
|
||||
```text
|
||||
Public internet
|
||||
-> Cloudflare Tunnel
|
||||
-> Caddy
|
||||
-> personal-mcp container
|
||||
Internet -> reverse proxy or tunnel -> personal-mcp
|
||||
```
|
||||
|
||||
## Decision
|
||||
The website and MCP endpoint can remain public while they contain only public, read-only content. Use edge authentication if access should be limited.
|
||||
|
||||
For the current use case, heavy application-level authentication is not required.
|
||||
## When Authentication Becomes Required
|
||||
|
||||
The recommended posture is:
|
||||
|
||||
1. Keep the service behind Cloudflare Tunnel and Caddy.
|
||||
2. Do not expose the container port directly to the public internet.
|
||||
3. Treat everything exposed through MCP as publishable public documentation.
|
||||
4. Add stronger authentication only if the MCP surface later includes sensitive content or tools with meaningful side effects.
|
||||
|
||||
This keeps the deployment simple while preserving a clear upgrade path.
|
||||
|
||||
## Tradeoffs
|
||||
|
||||
### Leaving `/mcp` Public
|
||||
|
||||
This is acceptable if `/mcp` exposes only the same public Markdown already available through `/docs`.
|
||||
|
||||
Benefits:
|
||||
|
||||
1. lowest operational friction
|
||||
2. fewer compatibility issues with MCP clients
|
||||
3. no need to implement OAuth, mTLS, JWT validation, or custom auth middleware
|
||||
4. consistent with the project assumption that documentation content is public
|
||||
|
||||
Risks:
|
||||
|
||||
1. random scraping, probing, or fuzzing of a machine endpoint
|
||||
2. possible bandwidth or CPU nuisance traffic
|
||||
3. accidental future exposure if new tools or private resources are added
|
||||
4. less control over who can use the MCP endpoint
|
||||
|
||||
### Protecting `/mcp` With Cloudflare Access
|
||||
|
||||
Cloudflare Access can add a lightweight gate using GitHub, Google, one-time PIN, or service tokens.
|
||||
|
||||
Benefits:
|
||||
|
||||
1. reduces random internet traffic
|
||||
2. requires little app code
|
||||
3. works well for a small trusted team
|
||||
4. provides logs and centralized access control
|
||||
|
||||
Costs:
|
||||
|
||||
1. browser-based login may not work with all MCP clients
|
||||
2. non-browser MCP clients may need Cloudflare Access service tokens
|
||||
3. adds operational configuration for a low-sensitivity endpoint
|
||||
|
||||
### Using mTLS
|
||||
|
||||
mTLS is useful when both client and server environments are tightly controlled.
|
||||
|
||||
Benefits:
|
||||
|
||||
1. strong client identity
|
||||
2. good fit for service-to-service or private infrastructure
|
||||
3. can be used between Cloudflare, Caddy, and the backend if desired
|
||||
|
||||
Costs:
|
||||
|
||||
1. harder certificate provisioning and rotation
|
||||
2. weaker compatibility with normal MCP clients
|
||||
3. unnecessary for public documentation-only content
|
||||
|
||||
For this project, mTLS is not the primary recommendation.
|
||||
|
||||
## Practical Recommendation
|
||||
|
||||
Use a simple public-docs posture unless the endpoint changes.
|
||||
|
||||
Recommended current setup:
|
||||
|
||||
```text
|
||||
/docs public
|
||||
/mcp public or lightly protected
|
||||
```
|
||||
|
||||
If `/mcp` remains public, add only basic operational safeguards:
|
||||
|
||||
1. keep Cloudflare Tunnel and Caddy in front
|
||||
2. avoid publishing `8765` directly
|
||||
3. enable Cloudflare or Caddy rate limiting if traffic becomes noisy
|
||||
4. monitor logs for unusual request volume
|
||||
5. document that MCP resources must remain safe to publish
|
||||
|
||||
A slightly stricter setup is also reasonable:
|
||||
|
||||
```text
|
||||
/docs public
|
||||
/mcp Cloudflare Access or service token
|
||||
```
|
||||
|
||||
This is the best option if the team wants to reduce drive-by MCP traffic without adding auth code to the application.
|
||||
|
||||
## Upgrade Trigger
|
||||
|
||||
Add real authentication before introducing any MCP capability that can:
|
||||
Protect `/mcp` before adding any capability that can:
|
||||
|
||||
1. read non-public files
|
||||
2. access private notes or credentials
|
||||
3. call upstream APIs
|
||||
2. access private data or credentials
|
||||
3. call authenticated services
|
||||
4. mutate data
|
||||
5. run commands
|
||||
6. expose environment details
|
||||
7. perform expensive computation
|
||||
6. perform expensive work
|
||||
|
||||
At that point, prefer edge-level authentication first, such as Cloudflare Access, and consider proper OAuth 2.1 resource-server behavior only if broad public MCP client interoperability becomes a goal.
|
||||
|
||||
## Security Invariant
|
||||
|
||||
Everything exposed by the MCP server must be safe to publish publicly.
|
||||
|
||||
If that invariant stops being true, `/mcp` should be protected before the new capability is deployed.
|
||||
At that point, choose authentication based on the clients that need to connect. Edge authentication is the simplest option for a small trusted audience; standards-based MCP authorization is more appropriate when broad client interoperability is required.
|
||||
|
||||
@@ -4,96 +4,44 @@ icon: lucide/flask-conical
|
||||
|
||||
# Testing
|
||||
|
||||
This page describes the current test layout and execution model for this repository.
|
||||
|
||||
Primary guidance sources:
|
||||
- [Pytest scaffolding skill](./skills/pytesting/SKILL.md)
|
||||
- [Pytest docs reference](./skills/pytesting/references/pytest-docs.md)
|
||||
- [FastAPI + uv + Docker skill](./skills/fastapi-uv-docker/SKILL.md)
|
||||
|
||||
## Goals
|
||||
|
||||
1. Keep local feedback fast with deterministic tests.
|
||||
2. Mirror source modules with focused test groups.
|
||||
3. Keep endpoint and MCP surface checks explicit.
|
||||
4. Make marker usage strict and intentional.
|
||||
The test suite checks that the same public MCP behavior works over HTTP and stdio.
|
||||
|
||||
## Current Test Layout
|
||||
|
||||
Current tree:
|
||||
|
||||
```text
|
||||
tests/
|
||||
__init__.py
|
||||
conftest.py
|
||||
registry/
|
||||
test_read.py
|
||||
ingest/
|
||||
test_current_docs.py
|
||||
test_document.py
|
||||
models/
|
||||
test_document_validation.py
|
||||
prompts/
|
||||
test_content_renderer.py
|
||||
test_filesystem_provider.py
|
||||
skills/
|
||||
test_provider.py
|
||||
web/
|
||||
conftest.py
|
||||
test_endpoint_connections.py
|
||||
test_mcp_prompts.py
|
||||
test_mcp_skills.py
|
||||
server_contract.py
|
||||
test_http.py
|
||||
test_stdio.py
|
||||
```
|
||||
|
||||
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/`
|
||||
`server_contract.py` contains the shared expectations. Both transport tests verify the resources, prompts, fallback tools, and representative reads against that contract.
|
||||
|
||||
## Markers And Strictness
|
||||
## Run Tests
|
||||
|
||||
Configured markers in `pyproject.toml`:
|
||||
- `unit`: fast deterministic tests with no external dependencies
|
||||
- `integration`: framework or component integration tests
|
||||
- `smoke`: thin critical-path checks
|
||||
|
||||
Pytest runs with `--strict-markers`, so any unregistered marker fails the test run.
|
||||
|
||||
## Fixture Layering
|
||||
|
||||
Fixture placement follows test scope:
|
||||
1. `tests/conftest.py` for cross-suite defaults.
|
||||
2. `tests/web/conftest.py` for web and endpoint client setup.
|
||||
|
||||
Prefer adding fixtures at the narrowest scope that serves more than one test.
|
||||
|
||||
## Command Baseline
|
||||
|
||||
Canonical invocation:
|
||||
Run the full suite with:
|
||||
|
||||
```bash
|
||||
uv run pytest
|
||||
```
|
||||
|
||||
Useful filtered runs:
|
||||
Run one transport while working on a focused change:
|
||||
|
||||
```bash
|
||||
uv run pytest --collect-only -q
|
||||
uv run pytest -m unit -q
|
||||
uv run pytest -m integration -q
|
||||
uv run pytest -m smoke -q
|
||||
uv run pytest tests/test_http.py -q
|
||||
uv run pytest tests/test_stdio.py -q
|
||||
```
|
||||
|
||||
## Adding New Tests
|
||||
The repository uses strict pytest markers. Register any new marker in `pyproject.toml` before using it.
|
||||
|
||||
When adding coverage:
|
||||
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.
|
||||
## Full Validation
|
||||
|
||||
This keeps the suite aligned with the current architecture while preserving a fast local test loop.
|
||||
```bash
|
||||
uv run zensical build
|
||||
uv run ruff check .
|
||||
uv run ty check
|
||||
uv run pytest
|
||||
```
|
||||
|
||||
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.
|
||||
See the [Pytesting skill](./skills/pytesting/SKILL.md) when adding or restructuring tests.
|
||||
@@ -2,105 +2,59 @@
|
||||
icon: lucide/workflow
|
||||
---
|
||||
|
||||
# Skill Usage Mechanics
|
||||
# Using Personal MCP
|
||||
|
||||
## Purpose
|
||||
Personal MCP gives clients access to skills, prompts, and general documentation. Use the smallest piece of content that matches the task instead of loading the whole library.
|
||||
|
||||
This page describes how clients discover and load `personal-mcp` skills published by the [FastMCP Skills Provider](https://gofastmcp.com/servers/providers/skills).
|
||||
## Connect
|
||||
|
||||
Skills are MCP resources. The client remains responsible for selecting guidance, loading only useful supporting material, and applying it to the current workspace.
|
||||
|
||||
## Published Skill Surface
|
||||
|
||||
Each directory beneath `src/personal_mcp/docs/skills/` publishes:
|
||||
|
||||
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 server uses `supporting_files="template"`. Main files and manifests appear in `resources/list`; supporting files stay behind per-skill wildcard templates so the resource list remains compact.
|
||||
|
||||
The manifest contains every skill-relative path, byte size, and SHA256 hash. References do not have synthetic ids or a separate catalog record.
|
||||
|
||||
Prompts are available through native MCP prompt discovery and rendering.
|
||||
|
||||
## Discovery Workflow
|
||||
|
||||
Use this bounded sequence:
|
||||
|
||||
1. List resources or call FastMCP `list_skills()`.
|
||||
2. Compare skill names and descriptions.
|
||||
3. Read one selected `skill://<name>/SKILL.md`.
|
||||
4. Read `skill://<name>/_manifest` only when supporting material may be useful.
|
||||
5. Fetch the minimum supporting paths needed for the task.
|
||||
6. Reconcile the guidance with the actual repository code before making changes.
|
||||
|
||||
Do not load every skill or every supporting file up front.
|
||||
|
||||
## FastMCP Client Utilities
|
||||
|
||||
FastMCP provides native utilities in `fastmcp.utilities.skills`:
|
||||
|
||||
1. `list_skills(client)` discovers main skill resources.
|
||||
2. `get_skill_manifest(client, name)` parses a generated manifest.
|
||||
3. `download_skill(client, name, target_dir)` downloads one skill.
|
||||
4. `sync_skills(client, target_dir)` downloads all advertised skills.
|
||||
|
||||
These utilities operate directly on the native `skill://` contract and require no repository-specific adapter.
|
||||
|
||||
## Copilot Invocation
|
||||
|
||||
In VS Code, skills can arrive through:
|
||||
|
||||
1. explicit attachment from `Add Context > MCP Resources` or `MCP: Browse Resources`
|
||||
2. direct resource reads on selected `skill://<name>/SKILL.md` entries
|
||||
3. 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. Use `MCP: Browse Resources` to confirm server-side availability, then attach only the minimum skill resources needed for the current task.
|
||||
|
||||
A reliable prompt is:
|
||||
The HTTP endpoint is `/mcp`. For a local server on port `8765`, connect to:
|
||||
|
||||
```text
|
||||
Browse MCP resources, select the best matching skill://.../SKILL.md entry by description, inspect its _manifest only if supporting detail is needed, and reconcile the guidance with this workspace.
|
||||
http://127.0.0.1:8765/mcp
|
||||
```
|
||||
|
||||
## Thin Shim Pattern
|
||||
Clients that launch servers as subprocesses can use:
|
||||
|
||||
Consumer repositories can bind file scopes to native skill resources with short `.github/instructions/*.instructions.md` files.
|
||||
|
||||
| `applyTo` scope | Companion docs | Primary skill resource |
|
||||
| --- | --- | --- |
|
||||
| `**/*.md` | [Authoring Guide](./authoring.md) | `skill://zensical-docs/SKILL.md` |
|
||||
| `tests/**` | [Testing](./testing.md) | `skill://pytesting/SKILL.md` |
|
||||
| `.vscode/**` | [VS Code Configuration](./skills/vscode-configuration/SKILL.md) | `skill://vscode-configuration/SKILL.md` |
|
||||
|
||||
Minimal shape:
|
||||
|
||||
```md
|
||||
---
|
||||
name: <scope name>
|
||||
description: Route <path scope> edits to a personal-mcp skill.
|
||||
applyTo: '<glob>'
|
||||
---
|
||||
|
||||
Load `skill://<skill-name>/SKILL.md` first. Read `_manifest` and supporting files only when the task needs deeper detail. Apply the guidance to the current repository rather than treating it as generated output.
|
||||
```bash
|
||||
uv run mcp-stdio
|
||||
```
|
||||
|
||||
## Failure Recovery
|
||||
## Use A Skill
|
||||
|
||||
When no skill is an obvious match:
|
||||
Skills are MCP resources. A client should:
|
||||
|
||||
1. compare the available main-resource descriptions again
|
||||
2. select at most two candidates
|
||||
3. read their main files, not all supporting files
|
||||
4. ask one clarifying question if the choice remains ambiguous
|
||||
1. browse the available `skill://<name>/SKILL.md` resources
|
||||
2. choose one by its name and description
|
||||
3. read the main `SKILL.md`
|
||||
4. read its `_manifest` only when extra reference material is needed
|
||||
5. load only the relevant supporting files
|
||||
|
||||
When a supporting path fails, refresh `_manifest`; file paths are the public supporting-resource identifiers.
|
||||
The guidance should then be checked against the code and conventions in the current workspace.
|
||||
|
||||
## Runtime Checklist
|
||||
## Use A Prompt
|
||||
|
||||
1. Confirm MCP connectivity.
|
||||
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. Keep loaded context bounded to the selected skill and relevant files.
|
||||
Prompts are reusable workflows with named arguments. Browse the server's prompts, select one by its description, and supply the requested values when invoking it.
|
||||
|
||||
In VS Code, MCP prompts appear as chat slash commands. Resources can be opened from **MCP: Browse Resources** and attached as context when the active chat surface supports it.
|
||||
|
||||
## Tool Fallbacks
|
||||
|
||||
Some clients can call tools but cannot browse MCP resources or prompts directly. For those clients, the server exposes four read-only tools:
|
||||
|
||||
- `list_resources`
|
||||
- `read_resource`
|
||||
- `list_prompts`
|
||||
- `get_prompt`
|
||||
|
||||
They provide access to the same underlying content. Clients with native resource and prompt support should use those native features.
|
||||
|
||||
## Example Request
|
||||
|
||||
```text
|
||||
Browse the available Personal MCP skills, choose the best match for this task,
|
||||
read its main SKILL.md, and load supporting files only if they are needed.
|
||||
Apply the guidance to this repository rather than treating it as generated output.
|
||||
```
|
||||
|
||||
For the exact resource and prompt formats, see the [content contracts](./contracts/index.md).
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastmcp import FastMCP
|
||||
from fastmcp.server.transforms import PromptsAsTools
|
||||
from fastmcp.server.transforms import ResourcesAsTools
|
||||
from mcp_types import Icon
|
||||
|
||||
from .prompts.provider import prompt_lifespan
|
||||
@@ -10,8 +12,9 @@ from .skills import skill_lifespan
|
||||
|
||||
_SERVER_INSTRUCTIONS = """Personal development guidance exposed as native MCP resources and prompts.
|
||||
|
||||
Use prompts for parameterized workflows. For task-specific guidance, browse native skill resources,
|
||||
select one skill://<name>/SKILL.md resource, and read its manifest only when supporting detail is needed.
|
||||
Use prompts for parameterized workflows; tool-only agents can discover and render them with
|
||||
list_prompts and get_prompt. For task-specific guidance, browse native skill resources, select one
|
||||
skill://<name>/SKILL.md resource, and read its manifest only when supporting detail is needed.
|
||||
"""
|
||||
_SERVER_ICON = Icon(
|
||||
src=(
|
||||
@@ -59,6 +62,10 @@ def create_mcp() -> FastMCP:
|
||||
def docs_markdown(path: str) -> dict[str, str]:
|
||||
return read_docs_markdown_path(registry, path)
|
||||
|
||||
# Bridges tool-only clients that cannot browse native resources or prompts directly.
|
||||
mcp.add_transform(ResourcesAsTools(mcp))
|
||||
mcp.add_transform(PromptsAsTools(mcp))
|
||||
|
||||
return mcp
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from fastmcp import Client
|
||||
from mcp_types import TextContent
|
||||
from mcp_types import TextResourceContents
|
||||
|
||||
|
||||
@@ -6,8 +7,9 @@ async def assert_server_contract(client: Client) -> None:
|
||||
resources = {str(resource.uri) for resource in await client.list_resources()}
|
||||
templates = {str(template.uri_template) for template in await client.list_resource_templates()}
|
||||
prompts = {prompt.name for prompt in await client.list_prompts()}
|
||||
tools = {tool.name for tool in await client.list_tools()}
|
||||
|
||||
assert await client.list_tools() == []
|
||||
assert tools == {"get_prompt", "list_prompts", "list_resources", "read_resource"}
|
||||
assert "skill://pytesting/SKILL.md" in resources
|
||||
assert "resource://docs/{path*}" in templates
|
||||
assert "skill://pytesting/{path*}" in templates
|
||||
@@ -20,3 +22,13 @@ async def assert_server_contract(client: Client) -> None:
|
||||
assert "# Pytesting" in skill_content[0].text
|
||||
assert isinstance(docs_content[0], TextResourceContents)
|
||||
assert '"format": "markdown"' in docs_content[0].text
|
||||
|
||||
listed = await client.call_tool("list_resources")
|
||||
listed_content = listed.content[0]
|
||||
assert isinstance(listed_content, TextContent)
|
||||
assert "skill://pytesting/SKILL.md" in listed_content.text
|
||||
|
||||
read = await client.call_tool("read_resource", {"uri": "skill://pytesting/SKILL.md"})
|
||||
read_content = read.content[0]
|
||||
assert isinstance(read_content, TextContent)
|
||||
assert "# Pytesting" in read_content.text
|
||||
|
||||
+3
-3
@@ -11,7 +11,7 @@
|
||||
# The site_name is shown in the page header and the browser window title
|
||||
#
|
||||
# Read more: https://zensical.org/docs/setup/basics/#site_name
|
||||
site_name = "Documentation"
|
||||
site_name = "Personal MCP"
|
||||
|
||||
site_dir = "src/personal_mcp/site"
|
||||
docs_dir = "src/personal_mcp/docs"
|
||||
@@ -20,12 +20,12 @@ docs_dir = "src/personal_mcp/docs"
|
||||
# meaningful description of the site content for use by search engines.
|
||||
#
|
||||
# Read more: https://zensical.org/docs/setup/basics/#site_description
|
||||
site_description = "A new project generated from the default template project."
|
||||
site_description = "Software development guidance published as MCP resources, prompts, and human-readable documentation."
|
||||
|
||||
# The site_author attribute. This is used in the HTML head element.
|
||||
#
|
||||
# Read more: https://zensical.org/docs/setup/basics/#site_author
|
||||
site_author = "<your name here>"
|
||||
site_author = "Personal MCP"
|
||||
|
||||
# The site_url is the canonical URL for your site. When building online
|
||||
# documentation you should set this.
|
||||
|
||||
Reference in New Issue
Block a user