Feature/issue 66 skill resource loading prototype (#116)

* Add standalone prototype for issue #66 (skill:// discovery/loading)

Builds a from-scratch MCP server + client per the merged SEP-2640 draft
(resources + skill://index.json, no custom methods), exercising flat and
nested skill paths, relative sub-resource references, and the
"enumeration is optional but direct read must still work" baseline.
Findings recorded in docs/experimental-findings.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Trim prototype to essentials

Inline the four skill fixture files into server.mjs (the prototype
demonstrates the transport binding, not filesystem loading) and drop the
prototype README, whose content is already in the PR description.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Add findings from VS Code SEP-2640 skill discovery implementation

Records what implementing skill:// discovery in VS Code proper surfaced:
the client already had the full progressive-disclosure loop and only
lacked an MCP source, its mcp-resource:// FS provider means the loading
half needs no code at all, and a new skill source touches more type
surfaces than expected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Drop prototype code; keep findings only

experimental-ext-skills is a working-group docs repo, so a runnable
Node server/client pair did not belong in it. The actual client-side
implementation for issue #66 now lives in VS Code, and what belongs
here is the write-up of what that surfaced.

Folds the still-transferable observations from the removed prototype
(URI- vs metadata-based identification per #54, and the index digest
doc inconsistency) into the VS Code findings entry.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Add findings from running the VS Code integration against a live server

Records what surfaced once the implementation was run from a source
build against the Hugging Face MCP server, rather than only
type-checked: the index wire format had already moved past the
checked-in draft, per-context-computation discovery is an easy
accidental DoS, a new skill source touches four type surfaces that must
agree, and cross-server name collisions are unspecified by the SEP.

None of the three defects were caught by tsc or the unit tests.

Also corrects the previous entry, which said the work was not verified
against a running server — it now is, for discovery. Model invocation
remains undemonstrated and is called out as such.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Tighten the issue #66 findings entry

Cut ~half the words to match the length of neighbouring entries and
make it reviewable at a glance. Same findings, less prose.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Link the findings entry to the VS Code implementation PR

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Restore the #54 identification note and reframe the digest point

Issue #66 asks explicitly for a URI- vs metadata-based identification
evaluation, so that belongs in the entry. The digest note is reframed
from a doc nitpick into the actionable version: the live server sends a
digest and this client ignores it, so nothing verifies skill integrity.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs: note VS Code findings were written against the pre-v1 draft

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: olaservo <olahungerford@gmail.com>
This commit is contained in:
Oluwatobi Oyewole 2026-08-28 17:51:14 +01:00 • committed by GitHub
commit 420f8ef904
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -4,6 +4,37 @@
> **Contributing findings?** Start with the [experimental findings template](findings-template.md).
## VS Code: MCP-served skills as agent skills (Issue #66)
> Written against the pre-v1 draft (August 2026). The index format, `type: "skill-md"`, archive entries, and resource templates discussed below belong to that draft; v1 replaced the index with `skills/list`/`skills/get`, dropped archives and template entries (decision log, 2026-07-16), and makes digest verification a host MUST.
**Implementation:** [tobi-oye/vscode#1](https://github.com/tobi-oye/vscode/pull/1) — on a [microsoft/vscode](https://github.com/microsoft/vscode) fork (personal exploration, not submitted upstream)
Added `skill://` discovery to VS Code and verified it against the [Hugging Face MCP server](https://github.com/huggingface/hf-mcp-server) (`https://huggingface.co/mcp`). VS Code discovered 8 skills and offered them to the model with no manual attachment.
**Findings:**
- **VS Code already had the whole progressive-disclosure loop; it just had no MCP source.** `findAgentSkills()` → `name`/`description` into a `<skills>` block → a model-facing `skill` tool. Same shape as [skillsdotnet](https://github.com/PederHP/skillsdotnet)'s `SkillCatalog`. Only the MCP origin was missing.
- **The loading half needed no code.** `mcp-resource://` is already registered with VS Code's `IFileService`, so mapping `skill://…/SKILL.md` onto it is enough — the existing skill tool reads it and each read becomes a `resources/read`. "Treat filesystem and MCP skills identically" falls out for free.
- **The index wire format had already moved past the checked-in draft.** The live server serves `{url, digest, frontmatter:{name, description}}`; the draft here specifies top-level `name`/`description` and a required `type: "skill-md"`. A parser written to the draft matches **zero** entries on a real server. Accepting both shapes is three lines.
- **Per-context-computation discovery is an accidental DoS.** `findAgentSkills()` runs on every context rebuild; discovery is two round trips per server. A naive version issued 20 index reads for one chat turn. Same shape as the incident behind hf-mcp-server's client denylist ([#164](https://github.com/huggingface/hf-mcp-server/pull/164), ~100k req/min). Cache the *promise*, keyed on connection state — not just server id, or a lookup made while a server was stopped pins an empty result.
- **Cross-server name collisions are unspecified.** Skill names are a flat namespace. The SEP ties the final URI segment to the frontmatter `name` but says nothing about two servers both serving `deploy`. Local-over-MCP is defensible; MCP-vs-MCP degenerates to discovery order. **Worth an explicit note in the SEP.**
- **Provenance reaches the UI but not the model.** The `<skills>` block emits only `<name>`, `<description>`, `<file>` — and `<file>` encodes an opaque server id. Loading is never ambiguous, but a model reasoning across servers has no legible origin signal.
- **Archives cost 17 of 25 skills.** Archive-only entries have no `url` to a `SKILL.md`, so a resource-reading host skips them. Archives were removed from SEP-2640 (decision log, 2026-07-16); until servers follow, such hosts see a fraction of what is offered.
- **Adding a skill source touched four type surfaces** that must agree (storage enum, a parallel source union, an ext-host DTO, a proposed API type). Missing two produced a runtime throw that broke chat while `tsc` stayed green.
- **Identifying skills by URL alone was enough ([#54](https://github.com/modelcontextprotocol/experimental-ext-skills/issues/54)).** `skill://` prefix plus `/SKILL.md` suffix, no `_meta` read — a two-line filter with nothing to negotiate. Because the last path segment must match the skill name, the name is readable off the URL, so a picker fills without fetching every `SKILL.md`. The tradeoff is that a URL carries no structured metadata; tags, versions or provenance would still need `_meta`.
- **The index ships a `digest` that this client ignores.** The live server sends `sha256:` per entry; nothing here verifies it, so a corrupted or swapped skill loads silently. fast-agent does check it. Worth settling whether verification is the host's job — the draft currently leans on it being "the transport's concern over an authenticated MCP connection".
**Verification:** `tsc` clean; 10 unit tests (incl. `skill://` → `mcp-resource://` round trip and index parsing against verbatim live output); 112 existing promptSyntax tests pass; discovery confirmed against the live server.
**Note:** none of the three defects above were caught by type-checking or unit tests — all surfaced only from running against a real server.
**Open:**
- **Model invocation not demonstrated.** Discovery and contribution are confirmed; no run yet shows the model choosing to load an MCP-served skill. Confounded by source builds being unable to reach the Copilot service (OSS `product.json` ships no OAuth client config) and by a small auto-routed model. Consistent with the adherence problems recorded elsewhere on this page.
- Resource templates parsed but not materialized (need the completion API).
- No `resources/subscribe`, so mid-session skill updates are missed.
## McpGraph: Skills in MCP Server Repo
**Date:** Not documented