diff --git a/AGENTS.md b/AGENTS.md index 54eed1a..d12ea71 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,16 +1,17 @@ ## What to reference as a source -**IMPORTANT**: The v1 SEP source of truth is the PR, not this repository. The specification text for the Skills Extension lives on **[SEP-2640](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640)** (`modelcontextprotocol/modelcontextprotocol`, branch [`sep/skills-extension`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/sep/skills-extension/seps/2640-skills-extension.md)). That PR is authoritative. +**IMPORTANT**: The source of truth for the Skills extension (`io.modelcontextprotocol/skills`) is [`specification/stable/skills.mdx`](specification/stable/skills.mdx) in this repository. It is the normative text of the extension, written against base protocol revision `2026-07-28`, and is what the official documentation at [modelcontextprotocol.io/extensions/skills/overview](https://modelcontextprotocol.io/extensions/skills/overview) summarizes. -[`docs/sep-draft-skills-extension.md`](docs/sep-draft-skills-extension.md) is a verbatim copy of the v1 baseline, synced from that branch at a commit pinned in the file's header. It exists so Working Group discussion, meeting notes, and decision records can quote and link stable text. +[SEP-2640](https://modelcontextprotocol.org/seps/2640-skills-extension) is the accepted proposal behind the extension (Status: Final; [PR #2640](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640) merged 2026-09-13). [`docs/archive/sep-draft-skills-extension.md`](docs/archive/sep-draft-skills-extension.md) is a copy of that SEP text pinned at the commit named in its header, kept so Working Group discussion, meeting notes, and decision records can quote and link stable text. It is a historical baseline, not the current spec. -- **Do not answer questions about what the spec says from this repository alone.** The copy is only as current as its last sync — check the pinned commit in the file header against the canonical branch before relying on it. +- **Answer questions about what the extension requires from `specification/stable/skills.mdx`**, not from the SEP copy or the `docs/` folder. Where the spec page and the SEP differ, the [decision log](docs/decisions.md) records why (see the 2026-09-08 entry). +- The `docs/` folder holds design history, rationale, experimental findings, and trackers. Treat it as context, not as normative text. -## Proposing changes beyond v1 +## Proposing changes to the specification -Changes beyond v1 are proposed here rather than added to the upstream SEP. The vehicle is a dated entry in [`docs/decisions.md`](docs/decisions.md) with `**Status:** Proposed`, in the ADR-lite format used throughout that file (Status / Context / Decision / Rationale / References) — the PR carrying that entry is the proposal. +Changes are proposed here. The vehicle is a dated entry in [`docs/decisions.md`](docs/decisions.md) with `**Status:** Proposed`, in the ADR-lite format used throughout that file (Status / Context / Decision / Rationale / References) — the PR carrying that entry is the proposal. -Once a proposal is accepted, the resulting spec text is applied to the baseline copy and that section is marked with a pointer back to its record. A section without such a marker is v1 as it stands upstream. +`specification/stable/skills.mdx` is a released snapshot and is not edited in place. Once a proposal is accepted, the resulting text lands in a draft revision of the specification (a `draft/` directory alongside the released text, following the layout used by [ext-tasks](https://github.com/modelcontextprotocol/ext-tasks/tree/main/specification)), the entry's status is updated to Accepted, and the draft ships as a new stable revision when released. When a decision supersedes or amends an earlier one, add a forward pointer to the earlier entry's `**Status:**` line rather than rewriting the entry. The log is an auditable trace of the group's reasoning over time, not a snapshot of current state. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d6801bd..b266fe6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ This Working Group welcomes contributions from anyone interested in skills distr - Joining discussions in the [#skills-over-mcp-wg Discord channel](https://discord.com/channels/1358869848138059966/1464745826629976084) (info on joining the Discord server [here](https://modelcontextprotocol.io/community/communication#discord)) - Opening or commenting on [GitHub Discussions](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/categories/meeting-notes-skills-over-mcp-wg) in the main MCP repo -- Sharing experimental findings from your own implementations +- Sharing findings from your own implementations as GitHub issues - Contributing to documentation and pattern evaluation ## Communication Channels @@ -15,7 +15,7 @@ This Working Group welcomes contributions from anyone interested in skills distr | :--- | :--- | :--- | | [Discord #skills-over-mcp-wg](https://discord.com/channels/1358869848138059966/1464745826629976084) | Quick questions, coordination, async discussion | Best effort | | [GitHub Discussions](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/categories/meeting-notes-skills-over-mcp-wg) | Meeting notes, long-form technical proposals, experimental findings | Weekly triage | -| This repository | Living reference for approaches, findings, and decisions | Updated after meetings | +| This repository | The specification, decision log, and design rationale | Updated after meetings | ## Coordination with the Agent Skills Spec @@ -41,15 +41,14 @@ Outputs include: ## Contribution Guidelines -### Documenting Approaches and Findings +### Sharing Implementation Findings -When adding experimental findings or new approaches: +Findings from implementations are shared as [GitHub issues](https://github.com/modelcontextprotocol/ext-skills/issues) rather than as documents in this repository. The pre-v1 findings and their template are frozen in [`docs/archive/`](docs/archive/). When reporting a finding: -- Start from the [experimental findings template](docs/findings-template.md) when adding a finding - Include enough detail for others to reproduce or evaluate -- Note which clients and servers were tested +- Note which clients and servers were tested, and the specification revision - Be explicit about what worked, what didn't, and what remains untested -- Write "Not documented" for missing historical details instead of inferring them +- Write "Not documented" for missing details instead of inferring them - Attribute community input with GitHub handles and link to the source where possible ### Community Input diff --git a/README.md b/README.md index efabb47..3f14688 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,37 @@ # Skills Over MCP Working Group -> ⚠️ **Experimental** — This repository is an incubation space for the Skills Over MCP Working Group. Contents are exploratory and do not represent official MCP specifications or recommendations. +This repository is the home of the official [Model Context Protocol](https://modelcontextprotocol.io) **Skills extension** (`io.modelcontextprotocol/skills`), based on [SEP-2640](https://modelcontextprotocol.io/seps/2640-skills-extension), and of the Skills Over MCP Working Group's working documents. -**📄 SEP-2640 (Skills Extension):** [modelcontextprotocol#2640](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640) — **the source of truth for the v1 spec text.** Review and comments belong on the PR. The copy in this repo is a synced baseline for discussion; see [`docs/sep-draft-skills-extension.md`](docs/sep-draft-skills-extension.md). -**Charter:** [modelcontextprotocol.io/community/skills-over-mcp/charter](https://modelcontextprotocol.io/community/skills-over-mcp/charter) — mission, scope, membership, active work items, and success criteria. +## Specification + +| Resource | Where | +| :--- | :--- | +| **Specification (source of truth)** | [`specification/stable/skills.mdx`](specification/stable/skills.mdx) — the extension spec, written against base protocol revision `2026-07-28` | +| **Official documentation** | [modelcontextprotocol.io/extensions/skills/overview](https://modelcontextprotocol.io/extensions/skills/overview) — condensed overview with examples and message flow | +| **SEP-2640: Skills Extension** | [modelcontextprotocol.io/seps/2640-skills-extension](https://modelcontextprotocol.io/seps/2640-skills-extension) — the accepted SEP (Status: Final; [PR #2640](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640) merged 2026-09-13) | +| **Client support** | [Extension client matrix](https://modelcontextprotocol.io/extensions/client-matrix) — which clients implement the extension | + +The stable specification is a released snapshot and is not edited in place. Changes are proposed as dated entries in the [decision log](docs/decisions.md) (see [AGENTS.md](AGENTS.md) for the process) and, once accepted, land in a draft revision of the specification that ships as a new release. + +> ℹ️ The [`docs/`](docs/) folder holds the [decision log](docs/decisions.md), the [design rationale](docs/rationale.md), and the [implementations list](docs/implementations.md). Earlier design documents, findings, and trackers are frozen in [`docs/archive/`](docs/archive/). None of it is part of the specification. + +**Charter:** [modelcontextprotocol.io/community/working-groups/skills-over-mcp](https://modelcontextprotocol.io/community/working-groups/skills-over-mcp) — mission, scope, membership, active work items, and success criteria. **Project board:** [Skills Over MCP WG](https://github.com/orgs/modelcontextprotocol/projects/38/views/1) **Meeting notes:** [Skills Over MCP WG discussions](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/categories/meeting-notes-skills-over-mcp-wg) **Discord:** [#skills-over-mcp-wg](https://discord.com/channels/1358869848138059966/1464745826629976084) -**Open work:** [Pull requests](https://github.com/modelcontextprotocol/experimental-ext-skills/pulls) — proposals, decisions, implementations, and other in-flight contributions welcome. - -## Why Skills Over MCP? - -MCP servers give agents tools, but tools alone are insufficient for complex workflows — tool descriptions tell an agent *what* a tool does, not *how to orchestrate* multiple tools to achieve a goal. Skills bridge this gap. They are structured "how-to" knowledge: multi-step workflows, conditional logic, and orchestration instructions that can run to hundreds of lines. - -Skills are *context*, and MCP is a *context protocol*. Agents already connect to remote services over MCP to get tools — they can get the know-how to use those tools through the same channel. A remote MCP server can serve both its tools and the instructions for using them together, as a single atomic unit. This also enables automatic discovery (connect to a server, find its skills), dynamic updates (server-side changes flow without reinstall), multi-server composition (skills orchestrating tools across servers), and enterprise distribution (RBAC, multi-tenant, version-adaptive content) — all through infrastructure MCP servers already provide. - -See [why-and-when.md](docs/why-and-when.md) for the full value proposition and a guide for when MCP distribution applies vs. simpler alternatives. For an accessible external framing of the premise, see Angie Jones's ["Skills Over MCP"](https://aaif.io/blog/skills-over-mcp/) (Agentic AI Foundation) — "ship the manual with the product." - -## Problem Statement - -Native "skills" support in host applications demonstrates demand for rich workflow instructions, but there's no convention for exposing equivalent functionality through MCP primitives. Current limitations include: - -- **Server instructions load only at initialization** — new or updated skills require re-initializing the server -- **Complex workflows exceed practical instruction size** — some skills require hundreds of lines of markdown with references to bundled files -- **No discovery mechanism** — users installing MCP servers don't know if there's a corresponding skill they should also install -- **Multi-server orchestration** — skills may need to coordinate tools from multiple servers - -See [problem-statement.md](docs/problem-statement.md) for full details. +**Open work:** [Pull requests](https://github.com/modelcontextprotocol/ext-skills/pulls) and [issues](https://github.com/modelcontextprotocol/ext-skills/issues) — proposals, decisions, implementations, and other in-flight contributions welcome. ## Repository Contents | Document | Description | | :--- | :--- | -| [Problem Statement](docs/problem-statement.md) | Current limitations and gaps | -| [Why Skills Over MCP?](docs/why-and-when.md) | Value proposition and decision guide | -| [Use Cases](docs/use-cases.md) | Key use cases driving this work | -| [Approaches](docs/approaches.md) | Approaches being explored (not mutually exclusive) | -| [SEP-2640: Skills Extension](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640) | Proposal to serve skills over MCP via the Resources primitive. The v1 baseline text is kept at [`docs/sep-draft-skills-extension.md`](docs/sep-draft-skills-extension.md), synced from the canonical SEP. Comments and review of v1 happen on the PR; changes beyond v1 are proposed as entries in the [decision log](docs/decisions.md). | -| [Open Questions](docs/open-questions.md) | Unresolved questions with community input (see also [issues](https://github.com/modelcontextprotocol/experimental-ext-skills/issues) and [meeting notes](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/categories/meeting-notes-skills-over-mcp-wg)) | -| [Experimental Findings](docs/experimental-findings.md) | Results from implementations and testing | -| [Related Work](docs/related-work.md) | SEPs, implementations, and external resources | -| [Threat Model](docs/threat-model.md) | Threat model for skills served over MCP (SEP-2640), with delivery-model recommendations and an archive appendix | -| [Skills Extension Candidates](docs/skills-extension-candidates.md) | MCP servers, dev tools, SDKs, and skills repositories that are candidates for adopting the skills extension | -| [Client MCP Support](docs/client-mcp-support.md) | Survey of model-facing MCP resource loading and SEP-2640 support across open-source clients | -| [Decision Log](docs/decisions.md) | Record of key decisions with context and rationale | -| [Rationale](docs/rationale.md) | Design rationale for SEP-2640's Resources-based skills extension | -| [Glossary](docs/glossary.md) | Working definitions for key Skills Over MCP terms | +| [Specification](specification/stable/skills.mdx) | The Skills extension specification (`io.modelcontextprotocol/skills`) — source of truth | +| [Decision Log](docs/decisions.md) | ADR-lite record of the group's decisions, and the vehicle for proposing changes to the specification | +| [Rationale](docs/rationale.md) | Design rationale for the Resources-based extension | +| [Implementations](docs/implementations.md) | Servers, SDKs, and hosts that serve or consume skills over MCP | +| [Archive](docs/archive/) | Pre-release design documents, findings, and trackers, frozen when SEP-2640 was marked Final | + +For the case for serving skills over MCP, see the [official overview](https://modelcontextprotocol.io/extensions/skills/overview) and the Motivation section of [SEP-2640](https://modelcontextprotocol.io/seps/2640-skills-extension). ## Contributing diff --git a/docs/archive/README.md b/docs/archive/README.md new file mode 100644 index 0000000..bdb97a7 --- /dev/null +++ b/docs/archive/README.md @@ -0,0 +1,19 @@ +# Archive + +Documents the Working Group produced while designing the Skills extension, frozen once [SEP-2640](https://modelcontextprotocol.io/seps/2640-skills-extension) was marked Final (2026-09-13). They are kept for history and so the [decision log](../decisions.md) can link to the material it cites. Nothing here is normative; the specification is [`specification/stable/skills.mdx`](../../specification/stable/skills.mdx). + +| Document | What it was | Superseded by | +| :--- | :--- | :--- | +| [SEP-2640 baseline copy](sep-draft-skills-extension.md) | Verbatim copy of the SEP text pinned at an August 2026 draft commit, kept so discussion could quote stable text | The published [SEP-2640](https://modelcontextprotocol.io/seps/2640-skills-extension) and the [stable specification](../../specification/stable/skills.mdx) | +| [Why Skills Over MCP?](why-and-when.md) | Value proposition and decision guide written while the approach was being argued for | SEP-2640 Motivation; the README | +| [Use Cases](use-cases.md) | Use cases that drove the design | SEP-2640 Motivation | +| [Approaches](approaches.md) | Map of the six approaches considered before converging on the convention approach | Decision log entries 2026-02-21 and 2026-02-26; SEP-2640 | +| [Skill URI Scheme Proposal](skill-uri-scheme.md) | Survey of `skill://` URI patterns across early implementations and the proposed convention | Decision log 2026-04-16 (superseded in part by the 2026-07-16 v1 scope entry); the specification's URI rules | +| [Open Questions](open-questions.md) | Early open questions with community input, gathered before the SEP existed | Decision log entries and the specification; remaining post-v1 items are tracked in issues ([#131](https://github.com/modelcontextprotocol/ext-skills/issues/131), [#126](https://github.com/modelcontextprotocol/ext-skills/issues/126)) | +| [Using `_meta` for Skill Resources](skill-meta-keys.md) | Draft guidelines for `_meta` keys on skill resources | Decision log 2026-03-16; the specification reserves the `io.modelcontextprotocol.skills/` prefix and defines no keys | +| [Glossary](glossary.md) | Working definitions used across the design documents | The terms as defined in the specification and the [Agent Skills specification](https://agentskills.io/specification) | +| [Agent Plugins x Skills Over MCP](agent-plugins-analysis.md) | Analysis of how the Agent Plugins packaging format relates to the extension | Point-in-time analysis; no successor document | +| [Problem Statement](problem-statement.md) | The gaps the extension set out to address | SEP-2640 Motivation | +| [Related Work](related-work.md) | SEPs, implementations, and external resources gathered during design | The [extension client matrix](https://modelcontextprotocol.io/extensions/client-matrix) for client support; implementation links otherwise unmaintained | +| [Experimental Findings](experimental-findings.md) | Results from prototype implementations, mostly against pre-v1 drafts ([template](findings-template.md)) | The conformance suite; new findings are shared as GitHub issues | +| [Threat Model](threat-model.md) | Threat model for skills served over MCP, written against the draft SEP, with the archive-delivery appendix | The specification's Security Considerations, which made the host obligations normative | diff --git a/docs/agent-plugins-analysis.md b/docs/archive/agent-plugins-analysis.md similarity index 100% rename from docs/agent-plugins-analysis.md rename to docs/archive/agent-plugins-analysis.md diff --git a/docs/approaches.md b/docs/archive/approaches.md similarity index 100% rename from docs/approaches.md rename to docs/archive/approaches.md diff --git a/docs/experimental-findings.md b/docs/archive/experimental-findings.md similarity index 100% rename from docs/experimental-findings.md rename to docs/archive/experimental-findings.md diff --git a/docs/findings-template.md b/docs/archive/findings-template.md similarity index 100% rename from docs/findings-template.md rename to docs/archive/findings-template.md diff --git a/docs/glossary.md b/docs/archive/glossary.md similarity index 99% rename from docs/glossary.md rename to docs/archive/glossary.md index 260832b..4d8c123 100644 --- a/docs/glossary.md +++ b/docs/archive/glossary.md @@ -41,7 +41,7 @@ This glossary defines working terminology for the Skills Over MCP documents. It ## References - [SEP-2640: Skills Extension](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640) — the extension these terms describe (v1 copy at [sep-draft-skills-extension.md](sep-draft-skills-extension.md)) -- [Decision Log](decisions.md) — Working Group decisions that ground several definitions +- [Decision Log](../decisions.md) — Working Group decisions that ground several definitions - [Agent Skills specification](https://agentskills.io/specification) - [MCP Resources specification](https://modelcontextprotocol.io/specification/2025-11-25/server/resources) - [MCP Tools specification](https://modelcontextprotocol.io/specification/2025-11-25/server/tools) diff --git a/docs/open-questions.md b/docs/archive/open-questions.md similarity index 100% rename from docs/open-questions.md rename to docs/archive/open-questions.md diff --git a/docs/problem-statement.md b/docs/archive/problem-statement.md similarity index 100% rename from docs/problem-statement.md rename to docs/archive/problem-statement.md diff --git a/docs/related-work.md b/docs/archive/related-work.md similarity index 97% rename from docs/related-work.md rename to docs/archive/related-work.md index e6b3f8a..2564d9c 100644 --- a/docs/related-work.md +++ b/docs/archive/related-work.md @@ -10,7 +10,7 @@ | ~~[SEP-2093](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2093)~~ | MCP Spec | ~~Resource Contents Metadata and Capabilities: scoped `resources/list`, per-resource capabilities, `resources/metadata` endpoint~~ — **rejected** ([labeled upstream](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2093)) | | ~~[SEP-2076](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2076)~~ | MCP Spec | ~~Agent Skills as a first-class MCP primitive~~ — **closed** (2026-02-24, without merge) | -> See also [**skills-extension-candidates.md**](skills-extension-candidates.md) for a tracker of MCP servers, dev tools, SDKs, and skills repositories that are candidates for adopting the skills extension. +> Client support for the extension is tracked on the official [extension client matrix](https://modelcontextprotocol.io/extensions/client-matrix). The implementation tables below are frozen; [implementations.md](../implementations.md) has more recent information. ## Working Group Member Implementations diff --git a/docs/sep-draft-skills-extension.md b/docs/archive/sep-draft-skills-extension.md similarity index 99% rename from docs/sep-draft-skills-extension.md rename to docs/archive/sep-draft-skills-extension.md index d2df6cb..a996ee6 100644 --- a/docs/sep-draft-skills-extension.md +++ b/docs/archive/sep-draft-skills-extension.md @@ -12,12 +12,12 @@ > > **The v1 spec text lives on that PR. Review and comments belong there, not on this copy.** > -> This file is the v1 baseline: a verbatim copy of the canonical SEP at commit [`753b9f2`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/753b9f2be43e07fdd070e535d75f190cff14beea/seps/2640-skills-extension.md) (2026-08-22) on the [`sep/skills-extension`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/sep/skills-extension/seps/2640-skills-extension.md) branch, kept here so Working Group discussion and decision records can quote and link stable text. It is only as current as that pinned commit. For what v1 comprises and why, see the 2026-07-16 v1 scope entry in the [decision log](decisions.md). +> This file is the v1 baseline: a verbatim copy of the canonical SEP at commit [`753b9f2`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/753b9f2be43e07fdd070e535d75f190cff14beea/seps/2640-skills-extension.md) (2026-08-22) on the [`sep/skills-extension`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/sep/skills-extension/seps/2640-skills-extension.md) branch, kept here so Working Group discussion and decision records can quote and link stable text. It is only as current as that pinned commit. For what v1 comprises and why, see the 2026-07-16 v1 scope entry in the [decision log](../decisions.md). > -> **To propose a change beyond v1**, add a dated entry to [`decisions.md`](decisions.md) with **Status: Proposed**, in the ADR-lite format used throughout that file — the PR carrying that entry is the proposal. Once a proposal is accepted, the resulting spec text is applied to this document and its section marked with a pointer to the record: +> **To propose a change beyond v1**, add a dated entry to [`decisions.md`](../decisions.md) with **Status: Proposed**, in the ADR-lite format used throughout that file — the PR carrying that entry is the proposal. Once a proposal is accepted, the resulting spec text is applied to this document and its section marked with a pointer to the record: > > ```markdown -> > **Beyond v1** — [2026-08-04: Batch resource read](decisions.md) · Proposed +> > **Beyond v1** — [2026-08-04: Batch resource read](../decisions.md) · Proposed > ``` > > A section without such a marker is v1 as it stands upstream. Re-sync by overwriting the unmarked text from the canonical file and updating the commit reference above. diff --git a/docs/skill-meta-keys.md b/docs/archive/skill-meta-keys.md similarity index 100% rename from docs/skill-meta-keys.md rename to docs/archive/skill-meta-keys.md diff --git a/docs/skill-uri-scheme.md b/docs/archive/skill-uri-scheme.md similarity index 100% rename from docs/skill-uri-scheme.md rename to docs/archive/skill-uri-scheme.md diff --git a/docs/threat-model.md b/docs/archive/threat-model.md similarity index 99% rename from docs/threat-model.md rename to docs/archive/threat-model.md index c128803..a4a0df8 100644 --- a/docs/threat-model.md +++ b/docs/archive/threat-model.md @@ -278,6 +278,6 @@ Threats the current SEP revision does **not** fully close, and directions raised - [`dangerous-skills-mcp`](https://github.com/olaservo/dangerous-skills-mcp) — the executable adversarial corpus (fixtures, oracles, smoke client). Live: `https://olaservo-dangerous-skills-mcp.hf.space/mcp`. Forked from [`gricha/dangerous-skills`](https://github.com/gricha/dangerous-skills). - [Agent Skills Discovery RFC](https://github.com/cloudflare/agent-skills-discovery-rfc) (Cloudflare) — SHA-256 content integrity and per-file digests; the closest external analog for the integrity model. - [Open Questions §10](open-questions.md#10-how-should-skills-handle-security-and-trust-boundaries) — the WG's trust-boundary discussion and community input. -- [Decision Log](decisions.md) — instructor-format scoping, filesystem-as-host-detail, the `resources/directory/read` method, and the digest/archive decisions. +- [Decision Log](../decisions.md) — instructor-format scoping, filesystem-as-host-detail, the `resources/directory/read` method, and the digest/archive decisions. - [Skill `_meta` Keys](skill-meta-keys.md) — `_meta` key conventions for skill resources, including the reserved `io.modelcontextprotocol.skills/` prefix. - [RFC 8089: The "file" URI Scheme](https://datatracker.ietf.org/doc/html/rfc8089) — the no-authority `file:` forms behind `adv-file-url`. diff --git a/docs/use-cases.md b/docs/archive/use-cases.md similarity index 100% rename from docs/use-cases.md rename to docs/archive/use-cases.md diff --git a/docs/why-and-when.md b/docs/archive/why-and-when.md similarity index 100% rename from docs/why-and-when.md rename to docs/archive/why-and-when.md diff --git a/docs/client-mcp-support.md b/docs/client-mcp-support.md deleted file mode 100644 index 683cf0c..0000000 --- a/docs/client-mcp-support.md +++ /dev/null @@ -1,215 +0,0 @@ -# Client Research: Model-facing MCP Resource & SEP-2640 Support - -> **Scope.** This page tracks two related areas of client support: -> -> 1. **Model-facing MCP resource loading** — does the client expose a tool that lets the model trigger an MCP `resources/read`? This is the SHOULD proposed in [modelcontextprotocol/modelcontextprotocol#2527](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2527) (which phrases it as "by URI"); for survey purposes we also count by-name variants where the framework resolves a model-supplied name to a URI before calling `resources/read` (adk-python is the one such case found). The bulk of this page is this survey. -> 2. **SEP-2640 skills extension support** — as clients ship [SEP-2640](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640) implementations, this page tracks them. **fast-agent is the first surveyed client to ship one** (registry/install scope — see its deep dive), verified live against the Hugging Face MCP server, which is the first server-side implementation we've interoperated with. SEP-2640-related issues, PRs, and shipped implementations are tracked per-client in the "Open issues/PRs to watch" column rather than via a separate status field. -> -> ℹ️ **SEP-2640 claims here are pinned to a draft revision.** The July 8–15, 2026 v1 rework ([2026-07-16 decision record](decisions.md)) removed archives, replaced `skill://index.json` with a `skills/list` method, replaced the single per-entry digest with a per-file `resources` manifest, added `skills/get`, and gated `resources/directory/read` behind a `directoryRead` capability. **fast-agent has since realigned to that shape** — its docs pin draft revision [`d7490ec`](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640/commits/d7490ecd1a250f7bc8c3ebb0d65450dfec274bad) and explicitly drop the older index/archive path — as has its server counterpart, both confirmed by [@evalstate](https://github.com/evalstate) in Discord (2026-08-04). Note the client side ships behind a prerelease install (`--prerelease=allow`; see its deep dive). This is the second realignment (the first was 2026-06-19); since the SEP is still a draft under review, expect further churn and re-verify against the SEP's current revision. The SEP is now at [`0eb05fe`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/0eb05fe9fbd6b4c5e3fbe7e097028dd0b68a10cf/seps/2640-skills-extension.md) (2026-08-05), but that delta leaves the wire contract intact, so `d7490ec` pins remain compatible — see [skills-extension-candidates.md](skills-extension-candidates.md) for what it does change. -> -> **Why these are tracked together.** SEP-2640 layers skills on top of MCP resources. If a host's progressive-disclosure flow involves the model itself loading L2/L3 skill content from `skill://…` or related resource URIs, then the resource-read affordance for the model becomes critical for skills. A client's resource-loading shape today is a strong predictor of how it'll fit SEP-2640 tomorrow. -> -> See also [**skills-extension-candidates.md**](skills-extension-candidates.md) for the matching server-side tracker: MCP servers, dev tools, SDKs, and skills repositories that are candidates for adopting SEP-2640. -> - -## At-a-glance comparison - -Category values: **Framework** = SDK/library you build agents on top of · **CLI** = end-user coding agent or CLI · **IDE** = editor-embedded chat surface. - -| Client | Category | Tool exposed to model? | Tool name(s) | Tool signature | Calls `resources/read` on connected server? | Enablement gate | End-user docs? | Open issues/PRs to watch | -| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | -| **codex** (OpenAI) | CLI | Yes | `read_mcp_resource`, `list_mcp_resources`, `list_mcp_resource_templates` | `(server, uri)` — server explicitly named | Yes — handler calls `session.read_resource()` | Any MCP server is configured (`params.mcp_tools.is_some()`) | No — only the LLM-visible tool description; an internal steer tells the model to prefer `tool_search` | _none yet — add as found_ | -| **goose** (Block) | CLI | Yes | `read_resource`, `list_resources` | `(extension_name, uri)` on `read_resource` — `extension_name` required; `list_resources` takes an optional `extension_name` filter | Yes — `ExtensionManager::read_resource` → `client.read_resource(...)` | ≥1 enabled extension reports `ServerCapabilities::resources` | Yes — [`extension-manager-mcp.md`](https://github.com/block/goose/blob/main/documentation/docs/mcp/extension-manager-mcp.md) | _none yet — add as found_ | -| **fast-agent** | Framework | Yes (multiplexed) | `get_resource` (no model-facing `list_resources`) | `(uri, server_name=None)` — `server_name` optional; also handles bundled `internal://` URIs through the same tool | Yes for MCP URIs — `_read_resource()` → `agent.get_resource(resource_uri=uri, namespace=server_name)`; `internal://` URIs short-circuit to bundled resources | Opt-in — `config.harness_tools`, default `False` (also stripped when `tool_only`) | Partial — `skills-over-mcp.md` covers the SEP-2640 install flow; the `get_resource` tool itself has no dedicated docs section | **SEP-2640 v1 shipped** (registry/install scope) — consumes the `io.modelcontextprotocol/skills` extension to install skills via `skills/list` / `skills/get` + per-file digest-verified `resources/read` ([`skills_extension.py`](https://github.com/evalstate/fast-agent/blob/main/src/fast_agent/mcp/skills_extension.py), [`mcp_registry.py`](https://github.com/evalstate/fast-agent/blob/main/src/fast_agent/skills/mcp_registry.py), [`skills-over-mcp.md`](https://github.com/evalstate/fast-agent/blob/main/docs/docs/mcp/skills-over-mcp.md)); pins draft `d7490ec` and treats legacy `skill://index.json` `skill-md`/archive entries as unsupported; still does not read skill resources at model runtime. Verified live against [hf-mcp-server](https://github.com/huggingface/hf-mcp-server). **Watch:** [#816](https://github.com/evalstate/fast-agent/pull/816) (still open) adds MCP-served skill *runtime* loading (URI-backed manifests, `SkillReader` resource reads, untrusted-content wrapping) | -| **vscode** (GitHub Copilot) | IDE | Yes (FS-provider indirection) | `copilot_readFile`, `copilot_listDirectory` (general-purpose, not MCP-specific) | `(path)` — accepts `mcp-resource://…` URIs as paths; the FS provider routes to MCP RPC | Yes — `mcp-resource://` URIs route via `IFileService` → `McpResourceFilesystem` provider → `r.readResource(...)` MCP RPC ([`mcpResourceFilesystem.ts`](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.ts)) | Server must advertise `McpCapability.Resources`; model needs a URI to pass (typically obtained from a user attachment — the earlier Copilot Chat `resource_link`→`mcp-resource://` pre-wrap has since been removed; see deep dive) | No explicit doc, but mechanism is operational. [Connor Peet's comment on #2527](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2527#issuecomment-4282395437) is the clearest write-up | _none yet — add as found_ | -| **opencode** | CLI | No | — (internal `readResource` only) | — | Internal only — `readResource()` exists in [`packages/opencode/src/mcp/index.ts`](https://github.com/anomalyco/opencode/blob/main/packages/opencode/src/mcp/index.ts) but is invoked only when the user attaches a resource via file picker; `mcp.tools()` in `prompt.ts` forwards MCP *tools* but never a resource-read tool | n/a | Docs (`mcp-servers.mdx`) advertise tool forwarding only | _none yet — add as found_ | -| **deepagents** (LangChain) | Framework | No | — | — | n/a — delegates MCP wiring to [`langchain-mcp-adapters`](https://github.com/langchain-ai/langchain-mcp-adapters) (via `convert_mcp_tool_to_langchain_tool()` / `_build_cached_mcp_tool()` in [`mcp_tools.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/code/deepagents_code/mcp_tools.py)); that adapter only converts MCP tools, not resources | n/a | No mention in README | **Upstream-blocked**: needs a change in `langchain-mcp-adapters` (or a deepagents wrapper around `client.read_resource()`) | -| **strands-agents** (AWS) | Framework | No (internal SDK only) | — | — | Internal only — `MCPClient.read_resource_sync()` and `list_resources_sync()` in [`mcp_client.py`](https://github.com/strands-agents/harness-sdk/blob/main/strands-py/src/strands/tools/mcp/mcp_client.py) call MCP `resources/read` / `resources/list`, but `MCPAgentTool` (the only adapter) wraps `mcp.types.Tool` only and `MCPClient.load_tools()` (the `ToolProvider` interface) returns tools only | n/a | No — `docs/MCP_CLIENT_ARCHITECTURE.md` and `AGENTS.md` do not mention MCP resources | _none yet — add as found_ | -| **Claude Code** (closed source, reference) | CLI | Yes | `ReadMcpResourceTool` | `(server, uri)` per [public docs](https://code.claude.com/docs/en/tools-reference) | Documented; source not verifiable | n/a | Yes — public tools reference page | n/a | -| **adk-python** (Google ADK) | Framework | Yes (by name, not URI) | `load_mcp_resource` | `(resource_names: array[string])` — model passes catalog names; framework resolves each to a URI and calls `session.read_resource(uri=…)`. The catalog is injected into the model's context by `_append_resources_to_llm_request()` rather than via a separate list call | Yes — `McpToolset.read_resource()` calls `session.read_resource(uri=…)` ([`mcp_toolset.py`](https://github.com/google/adk-python/blob/main/src/google/adk/tools/mcp_tool/mcp_toolset.py)) | Opt-in via `use_mcp_resources=True` on `McpToolset` (default `False`) | No — no user-facing docs found | _none yet — add as found_ | -| **agent-framework** (Microsoft) | Framework | No (tools-only client bridge) | — | — | n/a — `MCPTool` / `MCPStdioTool` / `MCPStreamableHTTPTool` / `MCPWebsocketTool` in [`_mcp.py`](https://github.com/microsoft/agent-framework/blob/main/python/packages/core/agent_framework/_mcp.py) materialize MCP *tools* into the agent's tool registry; no `read_resource` callsite found in client code (only in a test) | n/a | Samples cover MCP tool integration only | _none yet — add as found_ | -| **cline** | IDE | Yes | `access_mcp_resource` | `(server_name, uri)` | Yes — [`McpHub.readResource(serverName, uri)`](https://github.com/cline/cline/blob/main/apps/vscode/src/services/mcp/McpHub.ts) calls `resources/read`; invoked from [`AccessMcpResourceHandler`](https://github.com/cline/cline/blob/main/apps/vscode/src/core/task/tools/handlers/AccessMcpResourceHandler.ts) | Server's `resources` capability surfaces in system prompt context via the [`mcp.ts` formatter](https://github.com/cline/cline/blob/main/apps/vscode/src/core/prompts/system-prompt/components/mcp.ts) | No dedicated user-facing docs found | _none yet — add as found_ | -| **crewAI** | Framework | No | — | — | n/a — `crewai-tools` MCP adapter ([`mcp_adapter.py`](https://github.com/crewAIInc/crewAI-tools/blob/main/crewai_tools/adapters/mcp_adapter.py)) is built on `mcpadapt` and converts MCP tools only — same upstream-blocked pattern as smolagents | n/a | MCP adapter docs cover tools only | **Upstream-blocked** by `mcpadapt` (shared with smolagents) | -| **hermes-agent** (Nous Research) | CLI | Yes | `mcp_{server}_read_resource`, `mcp_{server}_list_resources` (one pair per connected server) | `(uri)` — server is encoded in the tool name | Yes — `_make_read_resource_handler()` in [`tools/mcp_tool.py`](https://github.com/NousResearch/hermes-agent/blob/main/tools/mcp_tool.py) calls `session.read_resource(uri)` and registers the tool per server | Two gates: `tools.resources` config flag (default on) AND server's advertised `capabilities.resources` | Yes — [`features/mcp.md`](https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/features/mcp.md) and [`guides/use-mcp-with-hermes.md`](https://github.com/NousResearch/hermes-agent/blob/main/website/docs/guides/use-mcp-with-hermes.md) | _none yet — add as found_ | -| **mastra** | Framework | No (internal SDK only) | — | — | Internal only — [`resource.ts`](https://github.com/mastra-ai/mastra/blob/main/packages/mcp/src/client/actions/resource.ts) exposes a `read(uri)` SDK method that calls `client.readResource(uri)`, but it is **not** registered as an LLM-facing tool; the model-facing tool bridge converts MCP tools only | n/a | SDK docs cover the action; no LLM-tool exposure | _none yet — add as found_ | - -## Cross-cutting observations - -1. **Three implementation patterns for model-facing MCP resource access.** - 1. **Dedicated MCP resource tools** — Codex, Goose, Claude Code, Cline: explicit `read_mcp_resource` / `read_resource` / `access_mcp_resource` (+ optional `list_*`) registered alongside other MCP tools. Most discoverable by the model; closest literal reading of #2527. adk-python is a near-relative — its `load_mcp_resource` takes a batch of `resource_names` in one call rather than a single URI, but the affordance shape is the same. - 2. **Multiplexed resource tool** — fast-agent: one `get_resource` tool handles both bundled (`internal://`) and MCP URIs behind a single name. Simpler surface for the model; relies on URI scheme to disambiguate. - 3. **FS-provider indirection via namespaced URIs** — VS Code: no MCP-specific tool. A dedicated URI scheme (`mcp-resource://`) is registered with the filesystem service so the generic `readFile` / `listDirectory` tools transparently reach MCP `resources/read`. Reuses the agent's existing file-reading affordance; costs nothing in tool-count budget. Downside: no `list` equivalent — the model can only read URIs it's been handed. - -2. **Dedicated-tool implementers converge on `(server, uri)`.** Codex, Goose, Claude Code, and Cline all take an explicit *required* server identifier alongside the URI. fast-agent takes the same pair but with `server_name` **optional** — the one surveyed implementation where the model may omit server identity entirely, which is the failure mode the takeaways flag below. hermes-agent is the remaining variant in pattern (1)'s family: it encodes server-in-tool-name (one tool per server) and takes only `(uri)`. adk-python is the outlier — it takes `(resource_names: array[string])` and resolves URIs via a model-visible catalog injected into context. - -3. **Trust models diverge.** Per-server enablement (Goose), unconditional-when-MCP-configured (Codex), capability-gated FS provider (VS Code), capability-gated dedicated tool (Cline), or framework opt-in flag (adk-python, `use_mcp_resources=True`, default off). For skills-over-MCP this matters because the "who can read what" boundary is currently set by each host individually — a portable skill that depends on `resources/read` will work or not based on whether the host considers MCP resource access a model-grade affordance. - -4. **Discoverability differs sharply between patterns — and within them.** Within pattern (1), discovery shapes diverge: Codex, Goose, hermes-agent (per server), and Claude Code pair `read_*` with a `list_*` tool so the model can enumerate resources on its own; Cline instead injects each server's `resources` and `resourceTemplates` into the system prompt via its `mcp.ts` formatter; adk-python injects an in-context catalog of resource names via `_append_resources_to_llm_request()`. Pattern (2) (fast-agent) has *no* model-facing `list_resources` on current main — of its two harness tools only `get_resource` reads resources; `list_resources` exists on the agent/aggregator but is never registered as a tool. Pattern (3) (VS Code) has *no list equivalent* — the model can only read a URI it's been handed (user attachment → chat context, or an MCP tool returning a `resource_link`). For skills this matters less than it once did: v1 moved enumeration to a `skills/list` *method*, which the host calls directly rather than routing through the model's resource-read tool — so a client's missing `list_resources` no longer blocks skill discovery. It still matters for the L2/L3 step, where the model reads specific skill files by URI. - -5. **VS Code's FS-provider pattern is worth its own consideration for skills.** Because `mcp-resource://` URIs are first-class in the file service, *any* tool that takes a path argument in VS Code can transparently read MCP resources — including, in principle, a skill loader. The skills-over-MCP design could lean on this by treating `skill://server/name/SKILL.md` as just another URI scheme registered with the host's file abstraction. This is closer to a registry-style integration (cf. how VS Code surfaces skills via `ChatSessionCustomizationProvider` rather than as system-prompt content). - -## Per-client deep dives - -### Agent SDKs / frameworks - -#### fast-agent -Verified at commit [`79b903c`](https://github.com/evalstate/fast-agent/commit/79b903c) (0.10.1, 2026-08-04). **Restructured since the prior `10a996b` (2026-06-02) check:** `smart_agent.py` is gone and the `smart` tool with it; the model-facing harness tools now live in [`core/harness_tools.py`](https://github.com/evalstate/fast-agent/blob/main/src/fast_agent/core/harness_tools.py). - -- **Model-facing tool:** `get_resource`, registered via `agent.add_tool(...)` in `set_harness_tools()` alongside `slash_command` (the two members of `HARNESS_TOOL_NAMES`). `_read_resource()` routes `internal://` to bundled resources; everything else hits the connected MCP server via `agent.get_resource(resource_uri=uri, namespace=server_name)` → MCP `resources/read`. -- **Signature:** `(uri, server_name=None)` — multiplexed across bundled and MCP URIs by scheme, and `server_name` is now **optional**, so the model can omit the server identifier (see the server-identity point in the takeaways). -- **Enablement changed — now opt-in, default off.** Gated on `agent.config.harness_tools`, which defaults to `False` ([`agent_types.py:115`](https://github.com/evalstate/fast-agent/blob/main/src/fast_agent/agents/agent_types.py)); harness tools are also stripped when `tool_only` is set. This page previously recorded fast-agent as unconditional for every `SmartAgent` — that is no longer accurate, and it moves fast-agent into the same opt-in category as adk-python's `use_mcp_resources=True`. -- **No model-facing `list_resources`:** unchanged — `list_resources` exists on the agent/aggregator but is not registered as a tool, so the model can only read a URI it's been handed. - -**SEP-2640 v1 skills extension (shipped — registry/install scope).** Verified at commit [`79b903c`](https://github.com/evalstate/fast-agent/commit/79b903c). fast-agent is the first surveyed client to ship a SEP-2640 implementation, and has now realigned to the v1 shape. - -- **Pinned draft revision.** [`skills-over-mcp.md`](https://github.com/evalstate/fast-agent/blob/main/docs/docs/mcp/skills-over-mcp.md) pins compatibility to SEP-2640 revision [`d7490ec`](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640/commits/d7490ecd1a250f7bc8c3ebb0d65450dfec274bad) and states plainly that this is "draft compatibility, not support for a ratified MCP standard." Legacy servers publishing `skill://index.json` with `skill-md` or archive artifacts are **explicitly unsupported** — the older path was removed, not kept alongside. Pinning the SEP revision in user-facing docs is a practice worth noting for other implementers. -- **What it implements:** the *registry and installation* portion of the SEP, not model-facing resource loading. When a connected server advertises the `io.modelcontextprotocol/skills` extension capability (`server_supports_mcp_skills()` checks `capabilities.extensions` in [`mcp_registry.py`](https://github.com/evalstate/fast-agent/blob/main/src/fast_agent/skills/mcp_registry.py)), fast-agent treats it as an MCP-backed skills registry. -- **Flow (v1):** `/skills registry` calls paginated `skills/list`; installing an entry refreshes it via `skills/get`, then fetches every file named in its `resources` manifest through `resources/read` and requires each to match its declared SHA-256 before writing the local copy. Sidecar metadata records host-assigned server identity, skill URI, and the manifest. Entries omitting `resources` (dynamically generated skills) are listed but **not installable** — no complete digest manifest means no integrity check and no update revision. -- **Exercises v1's unlisted-skill path.** `/skills add skill://acme/example/SKILL.md` installs a skill absent from the listing, with the server confirming the URI via `skills/get` — the exact gap the [2026-07-15 `skills/get` decision](decisions.md) was written to close, now with a working implementation behind it. Name-collision handling is implemented per v1 too: same-named listing entries are preserved and disambiguated by URI, though the local managed directory still admits only one skill per name. -- **Integrity ≠ trust.** The docs carry an explicit warning that a passing SHA-256 check only means the bytes match the manifest *that server supplied* — it does not authenticate server or publisher, nor vouch for the skill's instructions. Useful framing for the [threat model](threat-model.md). -- **Provisional wire models.** The pinned MCP Python SDK ships no typed SEP-2640 models, so fast-agent carries its own for `skills/list`, `skills/get`, and `resources/directory/read` ([`skills_extension.py`](https://github.com/evalstate/fast-agent/blob/main/src/fast_agent/mcp/skills_extension.py)). A concrete data point on what adopting the extension costs while SDK support lags. -- **Install requires opting into prereleases.** Per [@evalstate](https://github.com/evalstate) (fast-agent's author) in Discord, v1 support must be installed as `uv tool install -U --prerelease=allow fast-agent-mcp` — `fast-agent-mcp` 0.10.1 is published on PyPI, but it pins `fastmcp-slim[server]==4.0.0b1` (plus `mcp==2.0.0` / `mcp-types==2.0.0`), and uv refuses prerelease dependencies unless told otherwise. So the first end-to-end SEP-2640 v1 client stack is reachable only through a prerelease install path — worth knowing before treating "shipped" as "generally available." -- **Still not model-facing at runtime.** Active skills do **not** read supporting files from the MCP server during a session; [PR #816](https://github.com/evalstate/fast-agent/pull/816) ("Add MCP-served skill runtime support") remains **open**. The SEP-2640 path is still host-driven install, distinct from the model-facing `get_resource` tool above. (The `SkillReader` in main serves local skill files in non-ACP contexts, not MCP-served ones.) -- **Realignment history:** two rounds. [#825](https://github.com/evalstate/fast-agent/pull/825) (merged 2026-06-19, with [#831](https://github.com/evalstate/fast-agent/pull/831) hardening) moved it to the 2026-06-05 contract; the v1 migration landed later inside the 0.10 release series ([#892](https://github.com/evalstate/fast-agent/pull/892)/[#905](https://github.com/evalstate/fast-agent/pull/905)) rather than as a standalone skills PR. -- **Verified against a live server:** the [Hugging Face MCP server](https://github.com/huggingface/hf-mcp-server) is the server-side counterpart, which migrated to v1 in [#219](https://github.com/huggingface/hf-mcp-server/pull/219) (merged 2026-08-03); see its row in [skills-extension-candidates.md](skills-extension-candidates.md). fast-agent's docs walk through `/mcp connect --name hf https://huggingface.co/mcp` → `/skills registry hf` → `/skills add`. - ---- - -#### adk-python (Google ADK) -Verified at commit [`61a3933`](https://github.com/google/adk-python/commit/61a39330d) (2026-06-03). - -- **MCP integration:** [`src/google/adk/tools/mcp_tool/`](https://github.com/google/adk-python/tree/main/src/google/adk/tools/mcp_tool) package — `McpToolset` (lowercase c; `MCPToolset` is a deprecated alias) is the entry point used by callers to connect an ADK agent to an MCP server. -- **Resource RPC wired:** [`mcp_toolset.py`](https://github.com/google/adk-python/blob/main/src/google/adk/tools/mcp_tool/mcp_toolset.py) exposes `async def read_resource(self, name, readonly_context=None)` which calls `session.read_resource(uri=resource_info["uri"])`. -- **Model-facing tool:** [`load_mcp_resource_tool.py`](https://github.com/google/adk-python/blob/main/src/google/adk/tools/load_mcp_resource_tool.py) defines `load_mcp_resource`. **Not two-shot** — the tool's input schema is `resource_names: array[string]` (one call returns the contents of N resources). The catalog of available resources is exposed to the model via `_append_resources_to_llm_request()` injecting it into the LLM context, rather than via a separate `list` tool. -- **Enablement:** opt-in via the `use_mcp_resources=True` constructor flag on `McpToolset` (default `False`). When set, `get_tools()` appends `LoadMcpResourceTool` to the toolset alongside the dynamically discovered MCP tools. -- **End-user docs:** none found in `README.md` or the docs folder — the affordance is undocumented for end users despite being implemented. -- **Why interesting:** ADK is the client with the most rigorous skill validation in the parallel skills survey, so this is where the spec extension and the resource-tool extension converge. The batch `resource_names` shape is a distinct fourth signature among dedicated-tool implementers. - ---- - -#### agent-framework (Microsoft) -Verified at commit [`c3901a4`](https://github.com/microsoft/agent-framework/commit/c3901a4dd) (2026-06-03). - -- **MCP integration:** Multi-transport client tools — `MCPTool` plus `MCPStdioTool`, `MCPStreamableHTTPTool`, `MCPWebsocketTool` in [`_mcp.py`](https://github.com/microsoft/agent-framework/blob/main/python/packages/core/agent_framework/_mcp.py). The client-facing methods are `load_tools()`, `call_tool()`, `load_prompts()`, `get_prompt()` — no resource methods. .NET equivalents (e.g. `DefaultMcpToolHandler`) under [`dotnet/src/`](https://github.com/microsoft/agent-framework/tree/main/dotnet/src) expose `InvokeToolAsync()` only. -- **Resource RPC wired:** No MCP resource RPC at the model boundary. The only production `read_resource` callsites are in [`_skills.py`](https://github.com/microsoft/agent-framework/blob/main/python/packages/core/agent_framework/_skills.py) and refer to **skill** resources, not the model-facing MCP `resources/read`. All MCP `resources/read` references are confined to tests. -- **Update:** upstream has since added **MCP-based skills *discovery*** (recent commits use MCP resources internally for skill metadata / `skill://index.json` lookups via `_skills.py`) — but this is still not exposed to the model as a resource-read tool. -- **Why on the list:** dual-stack Python/.NET framework with rich skills metadata in the parallel skills survey. The asymmetry — skills support without a model-facing MCP resource tool — is the kind of gap a #2527-aligned PR would close. - ---- - -#### crewAI -Verified at commit [`051fa0c`](https://github.com/crewAIInc/crewAI/commit/051fa0c1c) (2026-06) of the main `crewAI` repo, which vendors `crewai-tools` under `lib/crewai-tools/` (the adapter is now under `lib/crewai-tools/src/crewai_tools/`). - -- **MCP integration:** [`mcp_adapter.py`](https://github.com/crewAIInc/crewAI/blob/main/lib/crewai-tools/src/crewai_tools/adapters/mcp_adapter.py) imports `mcp` (`StdioServerParameters`, `CallToolResult`, `TextContent`, `Tool`) and `mcpadapt.core` (`MCPAdapt`, `ToolAdapter`); `CrewAIToolAdapter.adapt(func, mcp_tool: Tool)` converts MCP tools to CrewAI `BaseTool` objects. -- **Resource RPC wired:** No — `adapt()` is typed to accept only `mcp_tool: Tool`; zero matches for `resource`/`Resource` anywhere in the adapter file or directory. `_run()` extracts `CallToolResult` content only. -- **Model-facing tool:** None. -- **Why on the list:** Same upstream block as **smolagents** — both depend on [`mcpadapt`](https://github.com/grll/mcpadapt) (`mcpadapt>=0.1.9` declared as optional dep in `lib/crewai-tools/pyproject.toml`), which is tools-only. A single upstream change in `mcpadapt` flips both clients. This is the highest-leverage adapter-library target identified so far. - ---- - -#### deepagents (LangChain) -Verified at commit [`436409f`](https://github.com/langchain-ai/deepagents/commit/436409fc) (2026-06-03). Note the repo has since been restructured into a monorepo — the MCP code now lives under `libs/code/deepagents_code/`. - -- **MCP wiring is outsourced** to `langchain-mcp-adapters` — [`mcp_tools.py`](https://github.com/langchain-ai/deepagents/blob/main/libs/code/deepagents_code/mcp_tools.py) calls `convert_mcp_tool_to_langchain_tool()` / `_build_cached_mcp_tool()` (the older `load_mcp_tools()` entry point is no longer used). The adapter does not expose `resources/read` as a tool — zero hits for resource-read in deepagents source; sessions only call `list_tools()` / `call_tool()`. -- **What it would take:** either upstream adds a resource-read tool, or deepagents wraps `client.read_resource()` outside the adapter. - ---- - -#### mastra -Verified at commit [`f82cc72`](https://github.com/mastra-ai/mastra/commit/f82cc72edc) (2026-06). - -- **MCP integration:** [`packages/mcp/src/client/client.ts`](https://github.com/mastra-ai/mastra/blob/main/packages/mcp/src/client/client.ts) imports `Client` from `@modelcontextprotocol/sdk/client/index.js`. [`actions/resource.ts`](https://github.com/mastra-ai/mastra/blob/main/packages/mcp/src/client/actions/resource.ts) exposes `public async read(uri: string)` which directly returns `this.client.readResource(uri)`. -- **Resource RPC wired:** Yes, but **internal SDK only**. `ResourceClientActions` is mounted as `this.resources` on the client — an SDK surface for callers, not registered as an LLM-facing tool. -- **Model-facing tool:** No. The model-facing bridge is `tools()` at [`client.ts`](https://github.com/mastra-ai/mastra/blob/main/packages/mcp/src/client/client.ts) which calls `this.client.listTools()` and iterates only the returned tools array — resources are never traversed. -- **Why on the list:** Mastra's skill versioning architecture (content-addressable BlobStore, draft→publish lifecycle) is the most sophisticated. Unlocking resource-read at the model boundary would be a small change relative to the rest of the framework — the SDK plumbing already exists. - ---- - -#### strands-agents -Verified at commit [`0e0035f`](https://github.com/strands-agents/harness-sdk/commit/0e0035fb) (2026-06). Strands matches the **mastra pattern**: resource RPC wired in the SDK, but no model-facing tool. The Python SDK lives in the `strands-py/` package of the `strands-agents/harness-sdk` monorepo. - -- **Resource RPC wired but unbridged:** `MCPClient.read_resource_sync()`, `list_resources_sync()`, and `list_resource_templates_sync()` in [`mcp_client.py`](https://github.com/strands-agents/harness-sdk/blob/main/strands-py/src/strands/tools/mcp/mcp_client.py) are SDK-public methods, but [`MCPAgentTool`](https://github.com/strands-agents/harness-sdk/blob/main/strands-py/src/strands/tools/mcp/mcp_agent_tool.py) only wraps `mcp.types.Tool` and delegates to `call_tool_async(...)`. Outside tests, nothing in the repo invokes the resource methods. -- **Why on the list:** Strands has its own local-filesystem skills implementation at [`agent_skills.py`](https://github.com/strands-agents/harness-sdk/blob/main/strands-py/src/strands/vended_plugins/skills/agent_skills.py), so the framework already does progressive disclosure. Wiring resource-read to the model is the obvious next step for an MCP-backed skill story. - ---- - -### Coding agents / CLIs - -#### codex (OpenAI) -Verified at commit [`ad2012d`](https://github.com/openai/codex/commit/ad2012d645b7146d31bb03f98e2bd9371635d11a). (The handlers were reorganized from the single `codex-rs/tools/src/mcp_resource_tool.rs` file into a per-tool module directory since the prior `67849d9` check.) - -- **Model-facing tools:** `read_mcp_resource`, `list_mcp_resources`, `list_mcp_resource_templates`, each a handler module under [`codex-rs/core/src/tools/handlers/mcp_resource/`](https://github.com/openai/codex/tree/main/codex-rs/core/src/tools/handlers/mcp_resource); registered unconditionally via `add_mcp_resource_tools` in [`spec_plan.rs`](https://github.com/openai/codex/blob/main/codex-rs/core/src/tools/spec_plan.rs), gated on `context.mcp_tools.is_some()`. The read handler [`read_mcp_resource.rs`](https://github.com/openai/codex/blob/main/codex-rs/core/src/tools/handlers/mcp_resource/read_mcp_resource.rs) calls `session.read_resource(&server, …)`. -- **Signature:** `(server, uri)` — model names the server explicitly. No user-facing doc; an internal steer (in `apps_instructions.rs`) tells the model to prefer `tool_search`. - ---- - -#### goose (AAIF) -Verified at commit [`45d8bf8`](https://github.com/aaif-goose/goose/commit/45d8bf81d09d478ceedba8f6d1f0ad906123a981). - -- **Model-facing tools:** `read_resource`, `list_resources` registered in [`ext_manager.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/agents/platform_extensions/ext_manager.rs) when at least one extension reports `ServerCapabilities::resources`. Dispatch flows through [`extension_manager.rs`](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/agents/extension_manager.rs) → `client.read_resource(...)` → MCP `resources/read`. Documented at [`extension-manager-mcp.md`](https://github.com/block/goose/blob/main/documentation/docs/mcp/extension-manager-mcp.md). -- **Signature:** `(extension_name, uri)` on `read_resource` — `extension_name` is required. `list_resources` takes an optional `extension_name` filter; the tool description directs the model to call `list_resources` first when ownership is unknown. - ---- - -#### hermes-agent (Nous Research) -Verified at commit [`03ba06e`](https://github.com/NousResearch/hermes-agent/commit/03ba06ebf) (2026-06). No drift across the 376 commits since the prior `72ff3e9` check. - -- **MCP integration:** Full integration in [`tools/mcp_tool.py`](https://github.com/NousResearch/hermes-agent/blob/main/tools/mcp_tool.py). -- **Resource RPC wired:** Yes — `_make_read_resource_handler()` calls `await server.session.read_resource(uri)`; the per-server schemas are built in `_build_utility_schemas()`. -- **Model-facing tools:** Yes — both `mcp_{safe_name}_read_resource` (taking `uri`) and `mcp_{safe_name}_list_resources` (no parameters) registered per connected server via `_build_utility_schemas()`. Conditionally registered when the server advertises `capabilities.resources` AND the per-server `tools.resources` config flag is on (default). -- **Signature:** `(uri)` — server is encoded in the tool name (one tool per server), so the model implicitly selects the server by selecting the tool. **Distinct from every other pattern surveyed**: not `(server, uri)`, not `(resource_names: array[string])` batch, not `(uri)`-with-probing, not URI-virtualized — it's *one tool per server*. The matching `list_resources` per server gives the model a discovery affordance without cross-server probing. -- **End-user docs:** [`features/mcp.md`](https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/features/mcp.md) and [`guides/use-mcp-with-hermes.md`](https://github.com/NousResearch/hermes-agent/blob/main/website/docs/guides/use-mcp-with-hermes.md) both document the utility wrappers. (Minor doc/code mismatch: the user-facing docs name the tools as bare `read_resource` / `list_resources`, but the actual model-facing names include the `mcp_{server}_` prefix.) -- **Why interesting:** The per-server-tool naming is a candidate disambiguation pattern for skills-over-MCP — the model can't pick the wrong server because each tool only binds to one. - ---- - -#### Claude Code (closed source — reference only) - -Claude Code is closed source so we cannot verify the loader, but the [public tools reference](https://code.claude.com/docs/en/tools-reference) documents `ReadMcpResourceTool` accepting `server` and `uri` parameters. Listed here as a reference data point for the `(server, uri)` signature shape also adopted by Codex, Goose, fast-agent, and Cline. - ---- - -#### opencode -Verified at commit [`2a33add`](https://github.com/anomalyco/opencode/commit/2a33addd2) on the canonical `dev` default branch. - -- **Tools forwarded to the model** in [`packages/opencode/src/mcp/index.ts`](https://github.com/anomalyco/opencode/blob/main/packages/opencode/src/mcp/index.ts) via `client.callTool()`; tool naming convention `{server_name}_{tool_name}` (sanitized, underscore-separated — `sanitize(clientName) + "_" + sanitize(mcpTool.name)`). The model-tool bridge in [`packages/opencode/src/session/tools.ts`](https://github.com/anomalyco/opencode/blob/main/packages/opencode/src/session/tools.ts) forwards only `mcp.tools()`. -- **Resource-read is UI-only:** `readResource()` in the same file is invoked only from the file picker (`session/prompt.ts` attachment path), never registered as an LLM tool. Docs ([`mcp-servers.mdx`](https://github.com/anomalyco/opencode/blob/main/packages/web/src/content/docs/mcp-servers.mdx)) advertise tool forwarding only. - ---- - -### IDE extensions - -#### vscode (GitHub Copilot) -Verified at commit [`ebb335f`](https://github.com/microsoft/vscode/commit/ebb335fad02) (vscode core, 2026-06-03); the Copilot Chat extension was re-checked against current `microsoft/vscode-copilot-chat` main. VS Code is the unique pattern here: no MCP-specific tool — generic `copilot_readFile` / `copilot_listDirectory` tools transparently reach MCP servers via filesystem-provider indirection on a custom URI scheme. - -- **URI scheme + FS provider:** [`McpResourceURI`](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/mcp/common/mcpTypes.ts) defines `mcp-resource://` URIs that encode the MCP server's definition ID in the authority — self-routing. [`McpResourceFilesystem`](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.ts) is registered for that scheme; `_readURIInner` decodes the URI, looks up the `McpServer`, and calls `r.readResource(...)` — the MCP `resources/read` RPC. Capability-gated on `McpCapability.Resources`. -- **`resource_link` pre-wrap — removed:** the doc previously described `mcpLanguageModelToolContribution.ts` converting an MCP tool's `resource_link` into an `mcp-resource://` URI for later re-reading via `copilot_readFile`. As of current main that file is gone and `microsoft/vscode-copilot-chat` no longer references the `mcp-resource://` scheme at all. The core scheme + FS provider in vscode itself remain intact, but the extension no longer auto-wraps `resource_link`s — so the model now has fewer built-in ways to obtain such a URI (the live forwarding path observed in the local clone renders `resource_link`s as plain text). *Worth re-confirming the current intended mechanism upstream.* -- **Caveat — discoverability:** the model can only read a URI it has been handed (e.g. a user attachment). No `list_mcp_resources`-equivalent **for the model**. Note vscode core *does* now expose `IMcpServer.resources()` / `resourceTemplates()` ([`mcpTypes.ts`](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/mcp/common/mcpTypes.ts)), but these feed a *user-facing* resource quick-pick (`mcpResourceQuickAccess.ts`), not a model tool. [Connor Peet on PR #2527](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2527#issuecomment-4282395437) is the clearest write-up of this pattern. - ---- - -#### cline - -Verified at commit [`81792d2`](https://github.com/cline/cline/commit/81792d20c) (2026-06-04). Note the repo restructured into a monorepo — the VS Code extension source now lives under `apps/vscode/src/` (was `src/`). - -- **MCP integration:** Depends on `@modelcontextprotocol/sdk` `^1.25.1` per `apps/vscode/package.json`. -- **Resource RPC wired:** Yes. [`McpHub.readResource(serverName, uri)`](https://github.com/cline/cline/blob/main/apps/vscode/src/services/mcp/McpHub.ts) issues a raw `resources/read` request against the named connection's client and decodes with `ReadResourceResultSchema`. -- **Model-facing tool:** Yes. [`AccessMcpResourceHandler`](https://github.com/cline/cline/blob/main/apps/vscode/src/core/task/tools/handlers/AccessMcpResourceHandler.ts) calls `mcpHub.readResource(...)` from the model-tool execution pipeline. The model sees `access_mcp_resource` as a registered tool taking `(server_name, uri)`. -- **Discoverability:** The [system-prompt formatter](https://github.com/cline/cline/blob/main/apps/vscode/src/core/prompts/system-prompt/components/mcp.ts) enumerates each connected server's `resources` and `resourceTemplates` in `formatMcpServersList()`. Populated by `fetchResourcesList()` and `fetchResourceTemplatesList()` in `McpHub.ts`. -- **End-user docs:** none found in `README.md`; no `docs/` directory in the repo root. -- **Why interesting:** Cline has the most extensive skills implementation in the parallel survey (incl. the admin-locked enterprise `globalSkills` primitive), so the *presence* of full resource-read support, in-prompt enumeration, and dedicated handler is the natural complement. - -## Takeaways for SEP-2640 (skills extension) - -- **v1's protocol surface has a working client/server pair, and realignment is fast but not free.** fast-agent and hf-mcp-server have both migrated to the July v1 shape (fast-agent pinning revision `d7490ec`; hf-mcp-server via [#219](https://github.com/huggingface/hf-mcp-server/pull/219), 2026-08-03), so `skills/list`, `skills/get`, per-file digest verification, and `directoryRead` gating are all exercised end-to-end — including v1-specific paths like installing an unlisted skill by URI through `skills/get`. Two observations for the WG: (a) this pair has now realigned **twice in seven weeks** (2026-06-19, then early August), and each round was a breaking change — both implementations dropped the old shape rather than supporting both, and fast-agent's archive download/extract hardening was discarded outright when archives became a deferred feature; (b) neither can lean on the SDK — fast-agent carries provisional local wire models because the pinned MCP Python SDK has no typed SEP-2640 models, which is a standing cost for every adopter until the SDKs catch up. Implementation experience is real evidence for the SEP's readiness here, but it is evidence about a pinned revision, so it should be re-dated whenever the draft moves — and about a prerelease install path on the client side, not a generally-available one. -- **First shipped client + server pair.** **fast-agent** is the first surveyed client to ship a SEP-2640 implementation — but scoped to *registry/install*: it consumes the `io.modelcontextprotocol/skills` extension to install digest-verified skills into its managed skills directory, and does not (yet) read skill resources at model runtime ([#816](https://github.com/evalstate/fast-agent/pull/816) still open). It was verified live against the **Hugging Face MCP server**, the first server-side implementation we've interoperated with (advertises the extension with `directoryRead: true` plus `resources: { subscribe: false, listChanged: false }`; tracked in [skills-extension-candidates.md](skills-extension-candidates.md)). One deployment detail worth carrying into the SEP discussion: HF serves skills **over HTTP transports only**, not over long-lived STDIO. Notably, the first real-world wrinkle was operational, not protocol-level: a client that retry-loops `resources/subscribe` (cursor-vscode) flooded the HF server, prompting a client-denylist mitigation ([hf-mcp-server#164](https://github.com/huggingface/hf-mcp-server/pull/164)) — a reminder that serving skills as resources inherits the resource subsystem's failure modes. -- **Seven of thirteen open-source clients surveyed** (Codex, Goose, fast-agent, VS Code, hermes-agent, adk-python, Cline) satisfy #2527's SHOULD; closed-source Claude Code's public docs confirm it does too. Goose and hermes-agent also satisfy the implicit expectation that this be documented for end users; the other implementers ship the affordance with no user-facing documentation. -- **Four implementation patterns** for model-facing MCP resource access — all support the layering Peter sketches in his #2640 comment, but with different costs: - - **Dedicated tools, `(server, uri)`** (Codex, Goose, Claude Code, fast-agent, Cline — fast-agent is also multiplexed across `internal://`): explicit `read_resource` / `access_mcp_resource` registered alongside other MCP tools. Most discoverable; closest literal reading of #2527. By volume, this is the dominant pattern. - - **Dedicated tool, `(resource_names: array[string])`** (adk-python): batch read; the available resources are surfaced to the model via context injection rather than a separate list tool. Same affordance shape as the `(server, uri)` family but with the server identifier embedded in the catalogued resource name rather than passed as a parameter. - - **One tool per server, `(uri)`** (hermes-agent): server is encoded in the tool name (`mcp_{server}_read_resource`), so the model selects the server by selecting the tool. Trades catalog tokens for unambiguity. Pairs with `mcp_{server}_list_resources` so the model has a per-server discovery affordance. - - **FS-provider indirection via namespaced URIs** (VS Code): no MCP-specific tool. `mcp-resource://` URIs are registered with the file service; generic `readFile` / `listDirectory` tools transparently reach `resources/read`. Costs nothing in tool-count budget; loses `list` affordance. - - Reliability implication: each pattern enforces server identity differently — explicit parameter (`(server, uri)`), tool choice (per-server tool), catalog-name lookup (adk-python), or URI authority (`mcp-resource:///...`). **The spec should nudge implementations to keep server identity mandatory** so a skill always resolves to its owning server. Otherwise the host has to probe every connected server when the model omits it — either silently picking the wrong one, or iterating through all of them at the cost of latency and tokens. fast-agent's optional `server_name` is the live instance of this: notably, its SEP-2640 install path does *not* inherit the ambiguity, since `/skills registry ` binds a specific server and skill provenance is recorded per install — a useful signal that skill-scoped operations want stronger server binding than a general resource-read tool. -- **Adapter libraries block two "no" rows.** **crewAI** depends on [`mcpadapt`](https://github.com/grll/mcpadapt); **deepagents** depends on [`langchain-mcp-adapters`](https://github.com/langchain-ai/langchain-mcp-adapters). Both adapters are tools-only — the unlock for either client lives in the adapter, not the client repo. -- **Internal SDK without LLM-tool exposure** (mastra, strands-agents) is its own pattern: the resource RPC is wired in the SDK but not bridged to the model. Closing this gap is typically smaller-scope than wiring the RPC from scratch. diff --git a/docs/decisions.md b/docs/decisions.md index 831c4aa..1211f0a 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -18,7 +18,7 @@ For background on the ADR format, see [adr.github.io](https://adr.github.io/). **References:** - [Feb 13 meeting notes](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/2248) (Key Decisions & Agreements) -- [Problem Statement](problem-statement.md) +- [Problem Statement](archive/problem-statement.md) --- @@ -82,7 +82,7 @@ For background on the ADR format, see [adr.github.io](https://adr.github.io/). **References:** - [Issue #14](https://github.com/modelcontextprotocol/experimental-ext-skills/issues/14) - [PR #17](https://github.com/modelcontextprotocol/experimental-ext-skills/pull/17) -- [Approaches doc](approaches.md) +- [Approaches doc](archive/approaches.md) --- @@ -116,7 +116,7 @@ For background on the ADR format, see [adr.github.io](https://adr.github.io/). - [PR #60](https://github.com/modelcontextprotocol/experimental-ext-skills/pull/60) - [Issue #55](https://github.com/modelcontextprotocol/experimental-ext-skills/issues/55) - [Discord discussion](https://discord.com/channels/1358869848138059966/1482008994062274610) -- [Using `_meta` for Skill Resources](skill-meta-keys.md) +- [Using `_meta` for Skill Resources](archive/skill-meta-keys.md) --- @@ -124,7 +124,7 @@ For background on the ADR format, see [adr.github.io](https://adr.github.io/). **Status:** Superseded in part — three of the bullets below were changed in SEP-2640 v1: enumeration moved from a `skill://index.json` resource to a `skills/list` method, the no-nesting constraint was reversed (nested skills are permitted, gated on fresh activation consent), and `skill://` was made non-privileged rather than the marker of what counts as a skill. See the 2026-07-16 v1 scope entry below, items 2, 6, and 8. The URI structure itself carries forward unchanged: explicit `SKILL.md`, final path segment equal to the skill `name`, optional organizational prefix, authority segment without special semantics. -**Context:** Several independent MCP implementations (FastMCP 3.0, NimbleBrain, skilljack-mcp, skills-over-mcp, etc.) had converged on using Resources to represent skills using either `skill://` or domain-specific URI schemes, but diverged on the rest of the URI structure. This included variations around whether to use an authority segment, whether `SKILL.md` is explicit in the URI, how to address sub-resources, and how the URI path relates to the skill's frontmatter `name`. A survey of these patterns was published in [`skill-uri-scheme.md`](skill-uri-scheme.md) and informed the draft [Skills Extension SEP (#69)](https://github.com/modelcontextprotocol/experimental-ext-skills/pull/69). The path↔name relationship went through two drafts before settling: the first required a single path segment equal to the `name`, which broke for servers needing hierarchy (e.g., `acme/billing/refunds` vs. `acme/support/refunds`); a second draft fully decoupled path from `name`, which was too loose — a URI like `skill://a/b/c/SKILL.md` revealed nothing about what the skill was called without a frontmatter round trip. +**Context:** Several independent MCP implementations (FastMCP 3.0, NimbleBrain, skilljack-mcp, skills-over-mcp, etc.) had converged on using Resources to represent skills using either `skill://` or domain-specific URI schemes, but diverged on the rest of the URI structure. This included variations around whether to use an authority segment, whether `SKILL.md` is explicit in the URI, how to address sub-resources, and how the URI path relates to the skill's frontmatter `name`. A survey of these patterns was published in [`skill-uri-scheme.md`](archive/skill-uri-scheme.md) and informed the draft [Skills Extension SEP (#69)](https://github.com/modelcontextprotocol/experimental-ext-skills/pull/69). The path↔name relationship went through two drafts before settling: the first required a single path segment equal to the `name`, which broke for servers needing hierarchy (e.g., `acme/billing/refunds` vs. `acme/support/refunds`); a second draft fully decoupled path from `name`, which was too loose — a URI like `skill://a/b/c/SKILL.md` revealed nothing about what the skill was called without a frontmatter round trip. **Decision:** Adopt `skill:///SKILL.md` as the recommended URI convention for skill resources over MCP, with: @@ -143,7 +143,7 @@ For background on the ADR format, see [adr.github.io](https://adr.github.io/). - [PR #70](https://github.com/modelcontextprotocol/experimental-ext-skills/pull/70) — URI scheme refinements (merged 2026-04-16) - [Issue #44](https://github.com/modelcontextprotocol/experimental-ext-skills/issues/44) — URI scheme discussion - [Draft Skills Extension SEP (#69)](https://github.com/modelcontextprotocol/experimental-ext-skills/pull/69) -- [Skill URI Scheme Proposal](skill-uri-scheme.md) +- [Skill URI Scheme Proposal](archive/skill-uri-scheme.md) --- diff --git a/docs/implementations.md b/docs/implementations.md new file mode 100644 index 0000000..b4d8ed6 --- /dev/null +++ b/docs/implementations.md @@ -0,0 +1,44 @@ +# Example Implementations + +Example servers, SDKs, and hosts that serve or consume skills over MCP. Official client support is tracked on the [extension client matrix](https://modelcontextprotocol.io/extensions/client-matrix); this list is broader and community-maintained. + +**Status:** `v1` implements the released extension · `partial` implements some of it · `pre-v1` targets an earlier draft · `prototype` fork or demo · `in progress` open PR · `planned` issue only. A link after the status points to the issue or PR tracking the work. + +**Category:** `official` maintained by the MCP project · `community` individual or community project · unmarked rows are maintained by the organization behind the product + +Implementations that predate the SEP are recorded in the archived [related work](archive/related-work.md) and are not repeated here. + +To add or update a row, open a PR. Keep notes to one line. + +## SDKs and frameworks + +| Implementation | Category | Language | Status | Notes | +| :--- | :--- | :--- | :--- | :--- | +| [Go SDK](https://github.com/modelcontextprotocol/go-sdk) | `official` | Go | `in progress` ([#1238](https://github.com/modelcontextprotocol/go-sdk/pull/1238)) | Passes the conformance suite; filesystem provider in [#1240](https://github.com/modelcontextprotocol/go-sdk/pull/1240) | +| [TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) | `official` | TypeScript | `in progress` ([#2818](https://github.com/modelcontextprotocol/typescript-sdk/pull/2818)) | Phase 1: schemas, client ops, server handlers. Tracking issue [#2798](https://github.com/modelcontextprotocol/typescript-sdk/issues/2798) | +| [Python SDK](https://github.com/modelcontextprotocol/python-sdk) | `official` | Python | `in progress` ([#3485](https://github.com/modelcontextprotocol/python-sdk/pull/3485)) | Tracking issue [#3486](https://github.com/modelcontextprotocol/python-sdk/issues/3486) | +| [C# SDK](https://github.com/modelcontextprotocol/csharp-sdk) | `official` | C# | `in progress` ([#1864](https://github.com/modelcontextprotocol/csharp-sdk/pull/1864)) | Alternative PR [#1856](https://github.com/modelcontextprotocol/csharp-sdk/pull/1856); maintainers to pick | +| [FastMCP SkillsProvider](https://gofastmcp.com/servers/providers/skills) | | Python | `pre-v1` ([#129](https://github.com/modelcontextprotocol/ext-skills/issues/129)) | Own `skill://` shape | +| [mcpkit](https://github.com/panyam/mcpkit) | `community` | Go | `partial` ([#780](https://github.com/panyam/mcpkit/issues/780)) | Server and host. v1 security rules; catalog still on the index-resource shape | +| [Tachyon](https://github.com/tachyonmcp/tachyon/tree/main/examples/mcp-skills) | | Java | `v1` | Self-reported 2026-09-14; requires clients to advertise the extension capability | + +## Servers + +| Implementation | Category | Language | Status | Notes | +| :--- | :--- | :--- | :--- | :--- | +| [hf-mcp-server](https://github.com/huggingface/hf-mcp-server) | | TypeScript | `v1` | Hugging Face. `skills/list`, `skills/get`, `directoryRead`. HTTP transports only | +| [github-stars-contrib-mcp-server](https://github.com/svg153/github-stars-contrib-mcp-server) | `community` | Python | `v1` ([#144](https://github.com/modelcontextprotocol/ext-skills/issues/144)) | Passes the [conformance suite](https://github.com/modelcontextprotocol/conformance) server scenarios | +| [github-mcp-server](https://github.com/github/github-mcp-server/pull/2428) | | Go | `prototype` | Demo branch, not for merge | + +## Hosts (including agent harnesses, IDEs, and web applications) + +| Implementation | Category | Status | Notes | +| :--- | :--- | :--- | :--- | +| [fast-agent](https://github.com/evalstate/fast-agent/blob/main/docs/docs/mcp/skills-over-mcp.md) | `community` | `partial` | First client interoperated end-to-end with hf-mcp-server | +| [MCP Inspector](https://github.com/modelcontextprotocol/inspector/blob/main/clients/cli/README.md#skill-verification---verify) | `official` | `partial` | SEP-2640 support since 2.6.0 (2026-09-09), including CLI skill verification | +| [MCPJam Inspector](https://github.com/MCPJam/inspector) | | `partial` | Skills surface in the app and CLI; declares the extension capability | +| [ChatGPT plugins](https://developers.openai.com/plugins/build/mcp-server#import-skills-from-the-mcp-server) | | `partial` | Imports skills at plugin submission, static snapshot | +| [VS Code fork](https://github.com/tobi-oye/vscode/pull/1) | `community` | `prototype` | `skills/list` discovery and loading ([findings](archive/experimental-findings.md)) | +| [Goose](https://github.com/aaif-goose/goose) | | `planned` ([#12068](https://github.com/aaif-goose/goose/issues/12068)) | Prototype fork in [ext-skills#125](https://github.com/modelcontextprotocol/ext-skills/pull/125) | +| [mcpkit host](https://github.com/panyam/mcpkit) | `community` | `partial` | `load_skill` tool, verified reads, per-origin resolution | +| [agent-harness](https://github.com/ar27111994/agent-harness) | `community` | `planned` ([#492](https://github.com/ar27111994/agent-harness/issues/492)) | Digest-pinned skill store | diff --git a/docs/rationale.md b/docs/rationale.md index 3959d70..d5decd7 100644 --- a/docs/rationale.md +++ b/docs/rationale.md @@ -56,7 +56,7 @@ The virtual-filesystem model this SEP builds on had a read operation (`resources `resources/directory/read` is the readdir analog: scoped, paginated, and composable — listings mark subdirectories with `inode/directory`, so an agent descends a skill's tree exactly as it would walk a directory locally. -Two alternatives were considered. Extending `resources/list` with a scope parameter would change a core method's semantics from inside an extension, and a URI-prefix filter misstates the model anyway — prefixes are string matching, not structure. Embedding a file manifest in `SKILL.md` or the listing was rejected as the navigation mechanism: it would freeze the listing at authoring or publication time and bloat context for skills with many files, while a method keeps listings live and on demand. The `resources` enumeration ([Resources](sep-draft-skills-extension.md#resources)) is not that manifest — it is an integrity commitment consumed by the host at verification and approval time, with no need to occupy model context, and the dynamically generated skills that need live listings most are exactly the ones that carry `"dynamic"` in its place. +Two alternatives were considered. Extending `resources/list` with a scope parameter would change a core method's semantics from inside an extension, and a URI-prefix filter misstates the model anyway — prefixes are string matching, not structure. Embedding a file manifest in `SKILL.md` or the listing was rejected as the navigation mechanism: it would freeze the listing at authoring or publication time and bloat context for skills with many files, while a method keeps listings live and on demand. The `resources` enumeration ([Resources](archive/sep-draft-skills-extension.md#resources)) is not that manifest — it is an integrity commitment consumed by the host at verification and approval time, with no need to occupy model context, and the dynamically generated skills that need live listings most are exactly the ones that carry `"dynamic"` in its place. Although introduced by this extension, the method is deliberately general — any directory resource qualifies, under any scheme — making it a candidate for promotion into the core Resources primitive if usage warrants. @@ -68,18 +68,18 @@ The listing could instead carry a curated subset of skill metadata — `name` an An earlier revision carried one digest per entry, covering only `SKILL.md`. That left every supporting file unbound: a server could obtain approval for a benign skill, then rotate `references/GUIDE.md` — instructional content the model follows as readily as the skill body — while the approved digest stayed valid. Persisted approval covered the one file a user is least likely to be attacked through. -Enumerating every file covers both rotation and addition: the set is complete, so a new file is as detectable as a changed one. It also supports pinning — approval binds to the whole set, and each file is verified against it when read. That gives the consistency half of the atomic-snapshot property archive distribution ([Appendix: Deferred Features](sep-draft-skills-extension.md#appendix-deferred-features)) offered: a host can never unknowingly mix files from two versions. Unlike an archive it requires no unpacking surface, and no file is retrieved ahead of need ([Integrity and verification](sep-draft-skills-extension.md#integrity-and-verification)). The cost falls on dynamically generated skills, which cannot publish stable digests; they carry `"resources": "dynamic"` instead, and accept that hosts may decline them. +Enumerating every file covers both rotation and addition: the set is complete, so a new file is as detectable as a changed one. It also supports pinning — approval binds to the whole set, and each file is verified against it when read. That gives the consistency half of the atomic-snapshot property archive distribution ([Appendix: Deferred Features](archive/sep-draft-skills-extension.md#appendix-deferred-features)) offered: a host can never unknowingly mix files from two versions. Unlike an archive it requires no unpacking surface, and no file is retrieved ahead of need ([Integrity and verification](archive/sep-draft-skills-extension.md#integrity-and-verification)). The cost falls on dynamically generated skills, which cannot publish stable digests; they carry `"resources": "dynamic"` instead, and accept that hosts may decline them. ## Why Does an Enclosing Skill's Manifest Include Its Nested Skills? -An earlier revision treated a nested `SKILL.md` as a boundary: a host walking an enclosing skill stopped there rather than taking in the subtree. The shipped model treats a nested skill's files as ordinary supporting files of the enclosing skill, so they appear in both manifests ([Resources](sep-draft-skills-extension.md#resources)). +An earlier revision treated a nested `SKILL.md` as a boundary: a host walking an enclosing skill stopped there rather than taking in the subtree. The shipped model treats a nested skill's files as ordinary supporting files of the enclosing skill, so they appear in both manifests ([Resources](archive/sep-draft-skills-extension.md#resources)). Content-bound approval binds to the `resources` set, so the set has to cover every file the skill can introduce into model context. A boundary would leave gaps in it at paths the server controls, and content in a gap could change without changing the approved set. The cost is that changing one nested skill revokes the persisted approval of every skill whose manifest encloses it. -Approval remains per skill. An enclosing skill's approval covers reading a nested `SKILL.md` as ordinary content, never activating it ([Nested skills](sep-draft-skills-extension.md#nested-skills)) — so a host does not need to detect nesting to apply the consent rule, and nothing in a listing marks the relationship. +Approval remains per skill. An enclosing skill's approval covers reading a nested `SKILL.md` as ordinary content, never activating it ([Nested skills](archive/sep-draft-skills-extension.md#nested-skills)) — so a host does not need to detect nesting to apply the consent rule, and nothing in a listing marks the relationship. ## Why Retrieve Files Only When They Are Needed? -An earlier revision let a host fetch, verify, and cache a skill's entire `resources` set at approval time and serve every later read from that copy. That is now prohibited: no file is retrieved on connection, on listing, or at approval. `SKILL.md` is fetched when the skill is loaded and a supporting file when it is read ([Integrity and verification](sep-draft-skills-extension.md#integrity-and-verification)). +An earlier revision let a host fetch, verify, and cache a skill's entire `resources` set at approval time and serve every later read from that copy. That is now prohibited: no file is retrieved on connection, on listing, or at approval. `SKILL.md` is fetched when the skill is loaded and a supporting file when it is read ([Integrity and verification](archive/sep-draft-skills-extension.md#integrity-and-verification)). -One reason for this is server load. A listing may be arbitrarily large — these are the same catalogs that make an empty or partial `skills/list` legitimate ([Why May the Listing Be Empty or Partial?](#why-may-the-listing-be-empty-or-partial)) — and a single portable skill can run to 512 files and 16 MiB ([Limits](sep-draft-skills-extension.md#limits)). A host that staged every skill it might use would put load on a server proportional to the catalog rather than to what a session reads, and every connecting host would repeat it. The same argument bounds the cost of deferring archives: a round trip per file scales with the files a session opens, not with the size of the skill. +One reason for this is server load. A listing may be arbitrarily large — these are the same catalogs that make an empty or partial `skills/list` legitimate ([Why May the Listing Be Empty or Partial?](#why-may-the-listing-be-empty-or-partial)) — and a single portable skill can run to 512 files and 16 MiB ([Limits](archive/sep-draft-skills-extension.md#limits)). A host that staged every skill it might use would put load on a server proportional to the catalog rather than to what a session reads, and every connecting host would repeat it. The same argument bounds the cost of deferring archives: a round trip per file scales with the files a session opens, not with the size of the skill. diff --git a/docs/skills-extension-candidates.md b/docs/skills-extension-candidates.md deleted file mode 100644 index badd53a..0000000 --- a/docs/skills-extension-candidates.md +++ /dev/null @@ -1,24 +0,0 @@ -# Skills Extension Candidates - -A tracker of MCP servers, dev tools, SDKs, and skills repositories that are candidates for adopting the skills extension proposed in [SEP-2640](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640). - -**Inclusion criterion.** An entry belongs here if it already ships skills in some non-MCP form (separate install path, plugin marketplace, framework-native provider), pairs an MCP server with a separate skills repo, or has an in-flight SEP-2640 implementation. - -> ℹ️ **Implementations track the SEP by draft revision, and have realigned twice.** SEP-2640 was reworked into a v1 scope between July 8–15, 2026 (see the [2026-07-16 decision record](decisions.md)): archives removed, `skill://index.json` replaced by a `skills/list` method, the single per-entry digest replaced by a per-file `resources` manifest, `skills/get` added, and `resources/directory/read` made optional behind a `directoryRead` capability. As of **2026-08-04 the reference server and client have both caught up** — hf-mcp-server migrated in [#219](https://github.com/huggingface/hf-mcp-server/pull/219) (merged 2026-08-03) and fast-agent pins draft revision [`d7490ec`](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640/commits/d7490ecd1a250f7bc8c3ebb0d65450dfec274bad) — after an earlier realignment round on 2026-06-19 ([hf#174](https://github.com/huggingface/hf-mcp-server/pull/174), [fast-agent#825](https://github.com/evalstate/fast-agent/pull/825), [huggingface/skills#172](https://github.com/huggingface/skills/pull/172)). Both now reject the older `skill://index.json` + archive shape outright — while mcpkit (below) still serves the index-catalog shape, so **the ecosystem is split across draft revisions**. Note that the split runs *within* an implementation, not just between them: mcpkit is current on v1's normative security obligations while deliberately holding its index schema pending WG confirmation. Adoption tracks the SEP section by section, so "which draft does X implement" often has no single answer. Since the SEP is still a draft under review, treat any "implemented" claim here as *implements a pinned draft revision* and re-verify against the revision the SEP is at when you read this. The SEP has since moved to [`0eb05fe`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/0eb05fe9fbd6b4c5e3fbe7e097028dd0b68a10cf/seps/2640-skills-extension.md) (2026-08-05); that delta is editorial for the wire contract — `skills/list`, `skills/get`, and the per-file `resources` manifest are unchanged — so `d7490ec`-pinned implementations remain compatible. It does add one soft constraint (the first `` segment SHOULD be a valid RFC 3986 `reg-name`, since it occupies the authority component), pins the skill root URI as `skill://` with no trailing slash, reopens whether `skills/get` should carry `ttlMs`/`cacheScope`, and makes the security section's host obligations normative rather than a recorded WG position. - -> See also [**client-mcp-support.md**](client-mcp-support.md) for the matching client-side survey: which open-source MCP hosts already let the model load resources by URI (the prerequisite for any client to consume what these candidates would expose). - -## Snapshot - -| Server | Repo | Author / Org | Issue/PR tracker | Notes | -| :--- | :--- | :--- | :--- | :--- | -| FastMCP 3.0 Skills | [jlowin/fastmcp](https://github.com/jlowin/fastmcp) — [docs](https://gofastmcp.com/servers/providers/skills) | FastMCP | [#2694](https://github.com/jlowin/fastmcp/issues/2694) | Framework with its own native skills provider using MCP Resources; doesn't yet reflect SEP-2640 | -| chrome-devtools-mcp | [ChromeDevTools/chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp) | Google (ChromeDevTools) | _none yet_ | Bundles a [`skills/`](https://github.com/ChromeDevTools/chrome-devtools-mcp/tree/main/skills) folder, but requires separate install — not served via MCP | -| hf-mcp-server | [huggingface/hf-mcp-server](https://github.com/huggingface/hf-mcp-server) | Hugging Face | [#219](https://github.com/huggingface/hf-mcp-server/pull/219), [#174](https://github.com/huggingface/hf-mcp-server/pull/174), [#164](https://github.com/huggingface/hf-mcp-server/pull/164) (all merged) | **SEP-2640 v1 implemented (server side).** Verified at [`d794b10`](https://github.com/huggingface/hf-mcp-server/commit/d794b10) (v0.4.6, 2026-08-03). Implements `skills/list`, `skills/get`, `resources/read`, and optional `resources/directory/read`; entries carry `uri` + verbatim `frontmatter` + a per-file `{uri, digest}` `resources` manifest ([`skill-types.ts`](https://github.com/huggingface/hf-mcp-server/blob/main/packages/app/src/server/skills/skill-types.ts), [`skill-resources.ts`](https://github.com/huggingface/hf-mcp-server/blob/main/packages/app/src/server/skills/skill-resources.ts)). Advertises `io.modelcontextprotocol/skills` with `directoryRead: true` plus `resources: { subscribe: false, listChanged: false }` ([`capability-utils.ts`](https://github.com/huggingface/hf-mcp-server/blob/main/packages/app/src/server/utils/capability-utils.ts)). No `skill://index.json`, no archives — both removed by [#219](https://github.com/huggingface/hf-mcp-server/pull/219) (merged 2026-08-03), which migrated from the 2026-06-05 shape that [#174](https://github.com/huggingface/hf-mcp-server/pull/174) had landed. Operational shape: skills come from a prebuilt snapshot (`HF_SKILLS_DIR`) with every digest verified before an atomic in-memory swap, a three-hour freshness TTL with stale-while-revalidate, and **HTTP transports only — skills are not served over long-lived STDIO**. First server we interoperated with end-to-end (against **fast-agent**, see [client-mcp-support.md](client-mcp-support.md)). #164 adds a client denylist (default `cursor-vscode`) after that client's `resources/subscribe` retry-loop flooded the server (~100k req/min). Distribution producer: [huggingface/skills#172](https://github.com/huggingface/skills/pull/172) | -| mcpkit (`ext/skills`) | [panyam/mcpkit](https://github.com/panyam/mcpkit) | Sri Panyam | [#780](https://github.com/panyam/mcpkit/issues/780) (open, index-schema tracking); [#1185](https://github.com/panyam/mcpkit/pull/1185), [#1187](https://github.com/panyam/mcpkit/pull/1187) (merged) | **Partially migrated, and tracking the SEP deliberately.** Go SDK covering both server and host: SKILL.md, `skill://` resources, progressive disclosure via a `skill://index.json` catalog + a host-side `load_skill` tool, per-supporting-file digests with verified reads, resource-fetch size and per-server byte budgets, and `resources/directory/read`; no code-execution surface (enforced by a build-failing test). Released in v0.3.0. **Already on v1 for the security section** — [#1185](https://github.com/panyam/mcpkit/pull/1185) (merged 2026-08-04) implements origin-tagging and per-origin resolve, citing SEP lines L179/L183/L185, i.e. the host obligations `0eb05fe` made normative; [#1187](https://github.com/panyam/mcpkit/pull/1187) adds a SEP-2640 security/conformance harness as a WG demo. **Deliberately holding on the index schema** — [#780](https://github.com/panyam/mcpkit/issues/780) is an explicit tracking vehicle (body rewritten 2026-07-14) that has already absorbed the archives removal and the `resources: [{uri, digest}]` direction, but is waiting on WG confirmation before refactoring; its conformance fork "deliberately holds provenance at pre-PR-97 commit `556154c`." Not yet absorbed: the carrier change — no issue or code references `skills/list`/`skills/get`, so the index-resource → method move is still unbooked. Also **resolved the archive deferral differently from fast-agent**: archives are retained as an explicitly non-spec "extended surface" rather than deleted, a useful counter-case for whether deferring a feature actually removes it from the ecosystem. The only Go implementation tracked, and the only one pairing a server and host in one SDK | -| github-mcp-server | [github/github-mcp-server](https://github.com/github/github-mcp-server) | GitHub | [#2428](https://github.com/github/github-mcp-server/pull/2428) (WIP demo, not for merge) | SEP-2640 demo branch | -| Azure Skills Plugin | [microsoft/azure-skills](https://github.com/microsoft/azure-skills) | Microsoft | _none yet_ | 25 Azure SKILL.md skills bundled with [Azure MCP Server](https://github.com/microsoft/mcp/tree/main/servers/Azure.Mcp.Server) + Foundry MCP; distributed as a plugin, not via MCP | -| Figma MCP | _TBD_ | Figma | _none yet_ | Contact: Discord `adityamuttur` — candidate for SEP-2640 testing | -| Adobe MCP | _TBD_ | Adobe | _none yet_ | Contact: Discord `justinmathew8592` — candidate for SEP-2640 testing | -| Slack | _TBD_ | Slack | _none yet_ | Expressed interest in SEP-2640 — candidate for testing | -| Bloomberg | _internal_ | Bloomberg | _none yet_ | Using skills-over-MCP internally; not public |