ext-skills/docs/archive/skill-uri-scheme.md
Ola Hungerford 5adfff5952
Clean and and re-organize repo docs (#146)
* docs: point README and AGENTS.md at the released spec and official docs

SEP-2640 is Final and the extension ships from specification/stable/skills.mdx,
so the README now leads with a Specification section linking the spec file,
the official docs page (modelcontextprotocol.io/extensions/skills/overview),
the published SEP, and the client matrix. The experimental banner is replaced
with a note that docs/ holds working documents; the charter, pulls, and issues
links move off the redirecting experimental-ext-skills / charter URLs.

AGENTS.md no longer names the SEP PR as the source of truth; it points agents
at the stable spec page and describes the decision-log flow against that file.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: accepted spec changes land in a draft revision, not the stable file

The stable specification is a released snapshot. README and AGENTS.md now say
accepted decision-log proposals go into a draft revision that ships as a new
release, matching the ext-tasks specification layout.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: move pre-release design documents to docs/archive

SEP-2640 is Final, so docs/ now holds only living working documents. Eight
historical documents move to docs/archive with an index explaining what each
was and what superseded it: the SEP baseline copy, why-and-when, use-cases,
approaches, skill-uri-scheme, glossary, client-mcp-support (superseded by the
official client matrix), and agent-plugins-analysis.

Files the published SEP links to by path (decisions, experimental-findings,
open-questions, problem-statement, rationale, related-work, skill-meta-keys)
stay in place so those links keep working. Cross-links are rewritten and
verified; the README contents table is trimmed to match.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: archive open-questions and skill-meta-keys

Both are pre-release documents whose outcomes live in the decision log and
the specification. The published SEP links to them by path; a companion
change in modelcontextprotocol/modelcontextprotocol repoints those links.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: fix sibling links inside archived open-questions and skill-meta-keys

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: keep only the decision log and rationale in docs/

threat-model, experimental-findings, findings-template, problem-statement,
and related-work move to docs/archive with index rows. The candidates
tracker and the archived client-support survey are removed in favor of the
official extension client matrix, and links to them are repointed there.

README drops the Why and Problem Statement sections, which duplicate the
SEP's Motivation and the official overview page. CONTRIBUTING routes new
implementation findings to GitHub issues.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: fix sibling links inside newly archived documents

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: add a concise implementations list

One table each for servers/SDKs and hosts, one line per entry, replacing the
retired candidates tracker and the related-work implementation tables. Seeded
from those plus PR #141 and issue #144.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: put tracking links in the Status column of the implementations list

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: add a vendor/community category to the implementations list

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: replace the interim reference package with the TypeScript SDK row

The @olaservo/ext-skills package is retired in favor of first-class skills
APIs in the TypeScript SDK (typescript-sdk#2798, phase 1 in #2818). The
archived related-work page now points at implementations.md for current
information.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: drop pre-SEP rows from the implementations list

They are already recorded in the archived related-work page; the list now
points there instead. FastMCP stays because its row tracks the migration to v1.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: add official SDK progress, Tachyon, and Inspector 2.6.0 to implementations

From the WG Discord channel and the SDK repos as of 2026-09-15: Go, TypeScript,
Python, and C# SDKs all have open SEP-2640 PRs (Go passes conformance); the
conformance suite merged; Inspector 2.6.0 shipped skills verification; Tachyon
reports a server implementation. Adds an "in progress" status for open PRs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: track Goose host support via the official issue

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: only tag community rows in the implementations list

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: tag MCP-project rows as official in the implementations list

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: split the implementations list into SDKs, servers, and hosts

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs: add MCPJam Inspector to hosts

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Revise implementations table format and content

Updated the implementations table to include language and status columns.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Correct links and clarify documentation references

Updated links to SEP-2640 and clarified document references.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Sambhav Kothari <sambhavs.email@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-16 06:56:20 +02:00

363 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Skill URI Scheme Proposal
> Proposed convention for identifying skill resources over MCP.
**Issue:** [#44](https://github.com/modelcontextprotocol/experimental-ext-skills/issues/44)
**Status:** Incorporated into the draft [Skills Extension SEP](https://github.com/modelcontextprotocol/experimental-ext-skills/pull/69), now submitted to the MCP spec as [SEP-2640](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640). This survey informed the SEP's URI scheme design; see also [PR #70](https://github.com/modelcontextprotocol/experimental-ext-skills/pull/70) for subsequent refinements (multi-segment paths, path-name decoupling).
---
## Summary
This document surveys existing URI patterns for skill resources across implementations, analyzes their trade-offs, and proposes a recommended `skill://` URI scheme for skill resources over MCP.
## Survey of Existing Patterns
### 1. NimbleBrain: `skill://server-name/skill-name`
**Pattern:** `skill://{authority}/{path}`
NimbleBrain uses `skill://` URIs where the authority segment identifies the server or domain, and the path identifies the skill within that server.
```
skill://ipinfo/usage
```
Skills are registered as MCP resources using FastMCP's `@mcp.resource()` decorator. The server instructions direct the agent to read the skill resource before using tools:
```python
mcp = FastMCP("IPInfo", instructions=(
"Before using IPInfo tools, read the skill://ipinfo/usage resource "
"for tool selection guidance and context reuse patterns."
))
@mcp.resource("skill://ipinfo/usage")
def ipinfo_skill() -> str:
return SKILL_CONTENT
```
**Discovery:** Via `resources/list` — skills appear alongside other resources.
**Pros:**
- Clean, human-readable URIs
- Authority segment naturally scopes skills to a server
- Already deployed in production across multiple servers ([mcp-ipinfo](https://github.com/NimbleBrainInc/mcp-ipinfo), [mcp-webfetch](https://github.com/NimbleBrainInc/mcp-webfetch), [mcp-pdfco](https://github.com/NimbleBrainInc/mcp-pdfco), [mcp-folk](https://github.com/NimbleBrainInc/mcp-folk), [mcp-brave-search](https://github.com/NimbleBrainInc/mcp-brave-search))
- Skills colocated with the tools they describe — versioned and shipped atomically
- Ephemeral availability: context present while server is connected, gone when disconnected
**Cons:**
- Authority segment usage varies across implementations (server name vs. skill name)
- No versioning in the URI
- No formal convention for sub-resources (references, scripts)
- Departs from the Agent Skills spec model where a skill is a directory containing at least `SKILL.md` — skills are exposed as flat, opaque resources with no directory structure
### 2. skilljack-mcp: `skill://{skillName}` with directory collections
**Pattern:** `skill://{skillName}` (no authority)
Skilljack uses `skill://` URIs where the skill name is placed directly after the scheme, without an authority segment. It also defines a directory collection pattern using a trailing slash:
```
skill://code-style # SKILL.md content
skill://code-style/ # All files in skill directory (collection)
skill://code-style/reference.md # Individual file (accessed via tool, not listed)
```
**Discovery:** Via `resources/list` with resource templates (`skill://{skillName}`). Includes `_meta` annotations for skill metadata.
**Pros:**
- Simple, minimal URIs for the common case
- Directory collection pattern (`/`) efficiently bundles all files
- Resource templates enable auto-completion via MCP's completion API
- Separates listed resources from tool-accessible files to reduce noise
**Cons:**
- No authority segment means no built-in scoping across multiple servers
- Skill names must be globally unique within a client session
- `SKILL.md` is implicit in the base URI (`skill://code-style`) — diverges from the Agent Skills spec directory model where `SKILL.md` is an explicit file within the skill directory
### 3. skills-over-mcp: `skill://{skillName}` with index and templates
**Pattern:** `skill://{skillName}` plus well-known index URIs
Keith Groves' implementation uses a richer set of `skill://` URIs including an index resource and lookup templates:
```
skill://index # JSON listing all skills
skill://prompt-xml # XML for system prompt injection
skill://code-review # Skill SKILL.md content
skill://code-review/documents # JSON list of supporting documents
skill://code-review/document/SECURITY.md # Individual document
skill://lookup/{name} # Dynamic lookup by name (template)
```
**Discovery:** Via `skill://index` resource (returns JSON array of all skills with URIs) and `resources/list`.
**Pros:**
- Index resource provides structured discovery separate from `resources/list`
- Document sub-paths provide progressive disclosure
- Resource templates with completion support enable dynamic lookup
- XML prompt injection resource for system prompt integration
**Cons:**
- Multiple overlapping discovery mechanisms (index + lookup template + resources/list)
- More complex URI space to learn and implement
- No authority segment
- `SKILL.md` is implicit in the base URI (`skill://code-review`) — diverges from the Agent Skills spec directory model
### 4. FastMCP 3.0: `skill://{skillName}/SKILL.md` with manifest
**Pattern:** `skill://{skillName}/{filePath}`
FastMCP 3.0 uses a file-path-based URI structure where every file within a skill directory gets its own URI, including a synthetic manifest:
```
skill://pdf-processing/SKILL.md # Main instruction file
skill://pdf-processing/_manifest # Synthetic JSON manifest (sizes + SHA-256)
skill://pdf-processing/reference.md # Supporting file
skill://pdf-processing/examples/sample.pdf # Nested supporting file
```
**Discovery:** Via `resources/list` (configurable disclosure level). Client utilities (`list_skills`, `download_skill`, `sync_skills`) provide higher-level access.
**Pros:**
- File-path structure is intuitive and predictable
- Most compatible with the Agent Skills spec model — URIs directly reflect the directory structure (`skill://name/SKILL.md`, `skill://name/references/...`)
- Manifest with SHA-256 hashes enables integrity verification
- Configurable disclosure: `"template"` (minimal listing) vs. `"resources"` (all files listed)
- SDK-level utilities for listing, downloading, and syncing skills
- Built-in providers for multiple skill directory conventions (Claude, Cursor, Codex, VS Code)
**Cons:**
- `SKILL.md` is always explicit in the URI (more verbose for the common case)
- File-path structure couples the URI to the internal directory layout
- No authority segment for multi-server scoping
### 5. Agent Skills Discovery RFC: `/.well-known/skills/{name}/SKILL.md`
**Pattern:** HTTPS URLs under `/.well-known/skills/`
The Cloudflare RFC defines domain-level discovery via HTTP, not a custom URI scheme. Skills are regular HTTPS resources at well-known paths:
```
https://example.com/.well-known/skills/index.json
https://example.com/.well-known/skills/wrangler/SKILL.md
https://example.com/.well-known/skills/wrangler/scripts/deploy.sh
```
**Discovery:** Fetch `/.well-known/skills/index.json` which lists all skills with name, description, and file inventory.
**Pros:**
- No custom URI scheme — uses standard HTTPS
- Domain-level trust model (organizational identity)
- Progressive disclosure built into the spec (3 levels)
- File inventory in index enables prefetching and caching
- Complementary to MCP (discovery and distribution vs. runtime consumption)
**Cons:**
- Not an MCP resource URI scheme — designed for HTTP-level discovery
- Requires organizations to host web endpoints
- Not directly usable as an MCP resource URI
### 6. SEP-2076: `skills/list` and `skills/get`
**Pattern:** New protocol primitive, not URI-based
SEP-2076 proposes skills as a first-class MCP primitive with dedicated methods rather than a URI scheme:
```json
// skills/list response
{
"skills": [{
"name": "git-workflow",
"description": "Follow team Git conventions",
"tags": ["git", "workflow"]
}]
}
// skills/get request
{ "name": "git-workflow" }
```
**Discovery:** Via `skills/list` method (dedicated, not via `resources/list`).
**Pros:**
- Clean separation from other resource types
- Dedicated capability and notification support
- No URI collision concerns
**Cons:**
- Requires protocol-level changes (new methods, capabilities)
- Adds a new primitive when resources may suffice
- Not yet accepted into the MCP spec
- Flattens skills to a name-addressed blob — does not model the Agent Skills spec's directory structure (skill as a directory containing `SKILL.md` plus optional supporting files)
## Comparison Matrix
| Pattern | URI Scheme | Authority | Versioning | Sub-resources | Templates | MCP-native |
|---------|-----------|-----------|------------|---------------|-----------|------------|
| NimbleBrain | `skill://` | Server name | No | No | No | Yes |
| skilljack-mcp | `skill://` | None | No | `/` collection | Yes | Yes |
| skills-over-mcp | `skill://` | None | No | `/document/` path | Yes | Yes |
| FastMCP 3.0 | `skill://` | None | No | File paths | Configurable | Yes |
| Well-Known RFC | `https://` | Domain | No | File paths | N/A | No |
| SEP-2076 | N/A | N/A | N/A | N/A | N/A | New primitive |
## Analysis
### Points of Convergence
All MCP-native implementations have independently converged on `skill://` as the URI scheme. This is a strong signal — four independent implementations chose the same scheme without coordination.
The divergence is in URI structure, specifically:
1. **Authority segment**: NimbleBrain uses it (server name); all others omit it.
2. **Path structure**: Ranges from minimal (`skill://name`) to file-path-based (`skill://name/SKILL.md`).
3. **Sub-resource access**: Different patterns for accessing supporting files.
4. **Discovery**: Some use `resources/list` alone; others add index resources or templates.
### Key Design Decisions
**1. What goes in the authority segment?**
In RFC 3986, the authority component (`scheme://authority/path`) is semantically a host identifier. A skill directory path is not a host. However, all four existing MCP implementations use the double-slash form, placing the first path segment in the authority position. While not semantically precise, this is established practice, produces clean URIs, and works well with MCP-aware parsers that don't need to resolve the authority as a network host.
**Recommendation:** Use the double-slash form (`skill://...`). The first segment of the skill path occupies the authority position by RFC 3986 mechanics but carries no special semantics under this convention — it is just the first path segment. Clients MUST NOT attempt DNS or network resolution of it. This avoids the awkward triple-slash (`skill:///`) form while staying honest about what the segment means.
**2. Should `SKILL.md` be explicit in the URI?**
FastMCP includes `SKILL.md` in every skill content URI. Other implementations treat the skill name itself as the content URI, with `SKILL.md` implicit.
Making `SKILL.md` explicit mirrors the directory structure and aligns with the Agent Skills spec, which defines a skill as a directory containing at least `SKILL.md`. Omitting it creates an abstraction that diverges from the spec and makes the relationship between the URI and the underlying skill format ambiguous.
**Recommendation:** `SKILL.md` MUST be explicit in the URI. The primary skill content is always at `skill://<skill-path>/SKILL.md`. This keeps the URI structure aligned with the Agent Skills spec and makes the directory model visible. Sub-resources are siblings at the same level (e.g., `skill://<skill-path>/references/GUIDE.md`).
**3. How should sub-resources (references, scripts) be addressed?**
Multiple patterns exist: trailing-slash collections (skilljack), `/document/` subpath (skills-over-mcp), direct file paths (FastMCP), and no sub-resource support (NimbleBrain).
**Recommendation:** Use path-based sub-resource addressing for consistency with other URI schemes.
**4. Should the URI path equal the skill name?**
Early drafts coupled the two: one path segment, equal to the frontmatter `name`. That works for a server with a handful of skills but fails when a server needs hierarchy. A large organization serving both `acme/billing/refunds` and `acme/support/refunds` cannot satisfy "single segment" and "segment equals name" simultaneously without renaming one skill to dodge the collision — which defeats the point of having a hierarchy. It also fails for servers with generated skill catalogs where the navigational axes (product, version, API surface) are orthogonal to what the skill is called.
**Recommendation:** Decouple. `<skill-path>` is a locator — one or more `/`-separated segments locating the skill directory within the server's namespace. The skill's identity (its `name`) lives in `SKILL.md` frontmatter and follows the Agent Skills spec naming rules. The URI says where to find it; the frontmatter says what it is.
## Proposed Convention
### URI Scheme: `skill://`
All skill resources MUST use the `skill://` URI scheme.
### URI Structure
```
skill://<skill-path>/SKILL.md
skill://<skill-path>/<file-path>
```
Following [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) structure:
- **Scheme:** `skill`
- **Authority:** The first segment of `<skill-path>`. Carries no special semantics; clients MUST NOT resolve it as a network host.
- **Path:** Remaining `<skill-path>` segments (if any) followed by `<file-path>`.
Where:
- `<skill-path>` is a `/`-separated path of one or more segments locating the skill directory within the server's namespace. MAY be a single segment (`git-workflow`) or nested to arbitrary depth (`acme/billing/refunds`). A `SKILL.md` MUST NOT appear in an ancestor directory of another `SKILL.md` — skills do not nest inside other skills.
- `<file-path>` is the file's path relative to the skill directory root, always `SKILL.md` for the primary content.
### Naming Rules
`<skill-path>` segments SHOULD be valid URI path segments per RFC 3986. No further constraints are imposed on the path — it is the server's organizational choice.
The skill's `name` (in `SKILL.md` frontmatter) is governed by the [Agent Skills specification naming rules](https://agentskills.io/specification#name-field): 1–64 characters, lowercase alphanumeric and hyphens, no leading/trailing or consecutive hyphens. The path is not required to match it.
### URI Patterns
#### Flat skill path
```
skill://git-workflow/SKILL.md
```
Single-segment path. The primary skill content is always at `SKILL.md` within the skill's path, matching the Agent Skills spec directory model.
#### Nested skill path
```
skill://acme/billing/refunds/SKILL.md
```
Multi-segment path. The skill directory is `acme/billing/refunds`; `acme` and `billing` are organizational path segments, not skills. The frontmatter `name` inside this `SKILL.md` might be `refund-handling` — it is independent of the path.
#### Sub-resources
```
skill://pdf-processing/SKILL.md # Primary skill content (required)
skill://pdf-processing/references/FORMS.md # Supporting document
skill://acme/billing/refunds/templates/email.md # Supporting file in nested skill
```
Supporting files are addressed by appending their path relative to the skill directory.
#### Resource templates
```
skill://docs/{product}/SKILL.md # Per-product documentation skills
skill://acme/{domain}/{workflow}/SKILL.md # Nested organizational namespace
skill://{skill_path}/{+file} # Generic: any file in any skill
```
Servers MAY register resource templates with `skill://` URI templates. These are primarily a user-facing discovery mechanism: hosts surface them in the UI with template variables wired to MCP's completion API, letting users interactively browse and select skills.
### Examples
| Use Case | URI | Notes |
|----------|-----|-------|
| Flat path | `skill://git-workflow/SKILL.md` | Single-segment skill path |
| Nested path | `skill://acme/billing/refunds/SKILL.md` | Path is locator; `name` is in frontmatter |
| Supporting document | `skill://code-review/references/SECURITY.md` | Sub-resource within skill directory |
| Supporting file, nested | `skill://acme/billing/refunds/templates/email.md` | Sub-resource in nested skill |
### How Clients Identify Skills
Clients can identify skill resources by:
1. **URI scheme:** Resources with URIs starting with `skill://` are skill resources.
2. **Entry point:** A URI ending in `/SKILL.md` is the skill's entry point; stripping that suffix gives the skill directory.
3. **MIME type:** `SKILL.md` content SHOULD use `text/markdown`.
4. **Annotations:** Servers MAY use the `_meta` field for additional skill metadata.
Enumeration via `resources/list` is optional. A `skill://` URI is directly readable via `resources/read` whether or not it appears in any list; clients MUST NOT treat an empty or absent enumeration as proof that a server has no skills.
### MCP Spec Alignment
The `skill://` scheme is a custom URI scheme as permitted by the MCP specification:
> Custom URI schemes **MUST** be in accordance with [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986).
The proposed scheme follows RFC 3986 structure. It uses existing MCP primitives (`resources/list`, `resources/read`, resource templates, subscriptions) without requiring protocol changes.
### Versioning
Versioning in URIs (e.g., query parameters or path segments) is intentionally deferred. The current convention focuses on establishing the base URI structure. Skill versioning is implicitly tied to the server version — when a server updates, its skill content updates with it.
### Multi-Server URI Collision
Since MCP resources are scoped per-server, identical `skill://` URIs from different servers are distinguishable by their originating server connection. With decoupled paths, the same `<skill-path>` appearing on two servers is less likely than a `name` collision would have been, but still possible.
Clients SHOULD provide a `read_resource` tool that accepts both the server name and the skill resource URI, allowing the model to disambiguate which server's skill to read. Within a skill's `SKILL.md` body, references to sub-resources (e.g., `references/GUIDE.md`) are relative to the skill — similar to how file-based skills use relative paths today. The model can resolve these from context, knowing which server the skill originated from.
Servers MAY include provenance metadata in `_meta` to make origin explicit.
## References
- [MCP Resources specification](https://modelcontextprotocol.io/specification/2025-11-25/server/resources)
- [RFC 3986: URIs](https://datatracker.ietf.org/doc/html/rfc3986)
- [RFC 6570: URI Templates](https://datatracker.ietf.org/doc/html/rfc6570)
- [Agent Skills specification](https://agentskills.io/specification)
- [Agent Skills Discovery RFC](https://github.com/cloudflare/agent-skills-discovery-rfc)
- [NimbleBrain skill:// findings](experimental-findings.md#nimblebrain-skill-resource-consolidation)
- [Approach 6: Official Convention](approaches.md#6-official-convention-as-intermediate-step)