| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
* Align resource layer with SEP-2640 (Skills Extension)
Replace legacy `skill://{name}` and `skill://{name}/` URIs with the SEP-2640
shape: `skill://<skill-path>/SKILL.md` for skill markdown, individual files
addressable as siblings, and a new `skill://index.json` discovery resource.
Declares the `io.modelcontextprotocol/skills` extension in initialize
capabilities, and adds `getSkillPath` / `buildSkillResourceUri` /
`parseSkillResourceUri` / `buildSkillIndex` helpers in skill-discovery.ts.
This is a breaking change to the URI scheme; pre-1.0, draft SEP, no shims.
SEP: modelcontextprotocol/modelcontextprotocol#2640
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Update CLAUDE.md for SEP-2640 resource layer
Document the new URI shapes, the `extensions["io.modelcontextprotocol/skills"]`
capability, and the four SEP helpers in skill-discovery.ts. Note the explicit
`skill://index.json` update notification fired from `refreshSkills()`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
An agent that discovered the projected task/project tools used them without the
workflow's rules — the rules live in a skill delivered as an MCP prompt, and the
specification makes prompts user-controlled ("the user being able to explicitly
select them for use"), so a model can never fetch one on its own. Every write in
a real session failed on conventions the skill would have supplied.
`Operation.mcpTool` gains a `skill` prop: a typed reference (`SkillRef`,
structurally a `Skill.Definition` — the definition itself where the plugin can
import it, a shared key constant where a cross-plugin dependency must not exist,
per the plain-keys idiom of plugin-projects' skills/keys.ts). The key's final
segment is persisted; it doubles as the skill's MCP prompt name. The edge
projection appends a load-the-skill-first pointer to the tool's description and
serves the skill body through a model-invocable `skillLoad` tool.
This follows the direction of the MCP "Skills over MCP" working group: skill
listings carry lightweight metadata and "the host exposes a single skill-loading
tool to the model, keyed by skill name" (SEP-2640) — the same progressive
disclosure Anthropic's Agent Skills use natively (metadata always in context,
body loaded when the model triggers it). Prior art:
- https://modelcontextprotocol.io/community/working-groups/skills-over-mcp
- modelcontextprotocol/modelcontextprotocol#2640
- https://modelcontextprotocol.io/specification/2025-06-18/server/prompts
- https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
The ten task, outline and project verbs annotate `CodeProjectSkill`; the skill
definition and the annotation sites share one key constant so the reference can
never drift from the skill that ships.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
||
| In protocol versions 2026-07-28 and later, the result also carries the base protocol's list-caching attributes — `ttlMs` and `cacheScope`, as defined for `tools/list` and `resources/list` ([SEP-2549]) — with the same semantics: a freshness hint for the listing and a cache-scope marker, not an integrity property. [Integrity and verification](#integrity-and-verification) governs content regardless of how fresh a cached listing is. | ||
|
|
||
| A server whose skill catalog is large, generated on demand, or otherwise unenumerable MAY return an empty or partial listing. Hosts MUST NOT treat an empty or partial listing as proof that a server has no skills. The method serves entries for a server's skills whatever URI scheme they use — enumeration is uniform across schemes. |
There was a problem hiding this comment.
There is no indication that a result is a partial listing, right? Would it be more straightforward to say Hosts must treat any listing result as partial. Alternatively the server could provide some indication that the list is incomplete
Sorry, something went wrong.
There was a problem hiding this comment.
skills/list supports pagination. For partial results response should include nextCursor field. This would be a partial result indicator. Would this work?
Sorry, something went wrong.
Remove the suggestion that hosts may fetch, verify, and cache a skill's entire file set at approval time. Hosts MUST NOT retrieve skill files ahead of need (on connect, on listing, or at approval): SKILL.md is fetched when a skill is loaded and supporting files when they are read. A server with many skills and files would otherwise see load proportional to its catalog from every connecting host. Hosts SHOULD cache what they retrieve, validated against entry digests on reuse. Note that lazy retrieval is compatible with content-bound approval, which binds to the resources set rather than to bytes. Regenerate the rendered SEP docs. No-Verification-Needed: documentation-only change
The file-allowlist rule in Integrity and verification applied "while acting on a skill", but the SEP never said what that meant. Define it as the span from loading the skill's SKILL.md into the model's context until, at the earliest, that SKILL.md leaves context; hosts may keep the window open longer, never shorter, and hold the entry they loaded from for the whole of it. Use the same term in the content-bound approval rule in Security Implications, which previously said "while it holds the approved entry" for the same window. Regenerate the rendered SEP docs. No-Verification-Needed: documentation-only change
…access The SEP encourages hosts to cache skill content on disk but said nothing about keeping that cache honest. Verification at fetch time does not carry over to bytes that may have changed since, so a cache writable by the model, by scripts it runs, or by other users would bypass digest verification entirely. Require hosts that cache on disk to either keep the cache where only the host can write and never modify cached files in place, or recompute the SHA-256 digest from the cached bytes on every access. State explicitly that a stored digest label or modification time is not verification. Regenerate the rendered SEP docs. No-Verification-Needed: documentation-only change
…rialized paths to encode it The SEP said a skill is identified by its URI, which holds only within one server: two connected servers may both serve skill://refunds/SKILL.md, and those are unrelated skills. State that the identity of an MCP-served skill is the pair of the host's identity for the originating server and the skill URI, and that hosts must preserve both halves in the registry, persisted approvals, the cache, and any tool or path the model reaches the skill through. Require any path at which a host materializes skill content, whether a cache directory or a virtual mount, to encode the server identity as well as the URI, so same-URI skills from different servers land at distinct paths and the originating server is recoverable from the path. Note in the host integration sketch that a virtual mount is one root per server. Regenerate the rendered SEP docs. No-Verification-Needed: documentation-only change
resources/read is transport: it returns bytes to whoever asked, via a generic resource tool, a resource browser, or a user inspecting the server. Nothing said that such a read is not a skill load, which left the verification, approval, and acting-on window bypassable by reading the URI directly. State in Reading that a skill is loaded only through the host's own skill-loading path, that a SKILL.md read arriving by any other route grants no approval, opens no window, and confers no standing on the skill's supporting files, and that such content is ordinary resource content. Note in the host integration sketch that read_skill is that path and read_resource on the same URI is not. Regenerate the rendered SEP docs. No-Verification-Needed: documentation-only change
Add a paragraph to Rationale stating that a skills/list entry is intentionally the complete manifest of a skill, verbatim frontmatter plus the full resources set with digests, rather than a summary to be completed by a follow-up call. One pass over the listing gives a host everything it needs to build its registry, present the skill for approval, bind the approval to content, and verify later reads, with no second round-trip per skill. skills/get exists only for what the listing does not serve: refreshing one skill's entry without re-enumerating the catalog, and obtaining an entry for a skill a partial listing omitted. It is never a step needed to complete a listed entry. Regenerate the rendered SEP docs. No-Verification-Needed: documentation-only change
Directory Listing never mentioned the manifest a host already holds for a skill with resources, nor what happens when a directory read lists a child the manifest lacks. Add a subsection covering this: - For a skill with a manifest, the entry already says what files exist; directory reading serves dynamic skills, non-skill trees, and a current server view without first refreshing the entry. - A newly listed child is the stale-snapshot case Integrity and verification already governs. Under the held entry the host must not read it or surface it as a skill file; it refreshes with skills/get, which changes the resources set, revokes any persisted approval, and requires re-approval before the file is readable. Hosts should present this as a changed skill, not a read error. - No shared version or cache token relates a directory result to an entry; the manifest is authoritative and a directory read must not be treated as extending it. - For a dynamic skill without resources, directory reading discovers files but supplies no integrity. Regenerate the rendered SEP docs. No-Verification-Needed: documentation-only change
| "result": { | ||
| "skill": { |
There was a problem hiding this comment.
tiny nit across all of the sample responses: resultType?
Sorry, something went wrong.
There was a problem hiding this comment.
@LucaButBoring thanks, added!
Sorry, something went wrong.
Each resources entry now carries size, the byte length of the file's raw content, the same bytes the digest covers. A host can budget a skill from the entry alone before fetching anything, and a read whose length differs from size is a verification failure equivalent to a digest mismatch. Fix two per-skill limits: 512 resources per skill and 16 MiB (16,777,216 bytes) total file size, the sum of size over resources. Hosts must support skills up to these limits and may support larger ones; servers should not serve skills that exceed them. Both are checkable from the entry before any file is retrieved. The limits bound exposure to one skill and say nothing about catalog size. Update the examples and the SDK guidance accordingly. Regenerate the rendered SEP docs. No-Verification-Needed: documentation-only change
A skill with dynamically generated content previously signalled that by
omitting resources, which a host could not distinguish from a
malformed entry. Make resources required on every entry, taking either
the array of {uri, digest, size} triples or the string "dynamic".
An entry with no resources at all, or with any other value, is invalid
and must not be loaded. A "dynamic" skill keeps its existing standing:
no content integrity, no content-bound approval, and hosts may decline
it. Update every passage that referred to an omitted resources field.
Regenerate the rendered SEP docs.
No-Verification-Needed: documentation-only change
…hape Co-authored-by: Ola Hungerford <olahungerford@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KAMCS66DC3MZWjK8QdBTYX
Maintainer Activity CheckHi @pja-ant! You're assigned to this SEP but there hasn't been any activity from you in 19 days. Please provide an update on:
If you're no longer able to sponsor this SEP, please let us know so we can find another maintainer. This is an automated message from the SEP lifecycle bot. |
Sorry, something went wrong.
| "name": "git-workflow", | ||
| "description": "Follow this team's Git conventions for branching and commits" | ||
| }, | ||
| "resources": [ |
There was a problem hiding this comment.
I am not sure I understand the value for listing resources explicitly here -- IMO, it seems like the intended flow should be:
offering this info in skills/list feels like just asking for coordination/caching challenges.
Sorry, something went wrong.
There was a problem hiding this comment.
Skill contents (SKILL.md and other files) are always in resources and nowhere else. The intended flow is that a client calls skills/list, which provide all metadata and then when it comes time to activate a skill you do the resources/read for the contents. skill/get exists for when you need to either refresh the metadata from skills/list for a single skill (e.g. digest mismatch) or you need to know the metadata for an unlisted skill.
We could just have skills/list return a list of URIs and the clients would have to skills/get to get the resources and then resources/read for the content, but it's an extra hop on the activation path that we'd prefer to avoid.
Sorry, something went wrong.
|
|
||
| **Context.** The host surfaces the `name` and `description` of each enabled registry entry in the model's context — the same list the model already sees for filesystem skills, now with MCP-served entries mixed in. The host's UI presents the same merged list for user inspection and per-skill enable/disable, with provenance shown so users can see which server a skill came from. | ||
|
|
||
| **Loading.** The host exposes a single skill-loading tool to the model, keyed by skill name: |
There was a problem hiding this comment.
Doesn't this conflict with the guidance that it should accept a URI?
if I specify a URI in a different skill, how does the model make the gap from using that URI to access this skill by name? especially if the name might be modify to prevent duplicates by a host
Sorry, something went wrong.
There was a problem hiding this comment.
This is an implementation detail but usually the host will have a unique name for the skill. Claude Code does this for example and it is on them to make sure it is unique:
When a name is collision-qualified (Names), the qualified form is what appears in the model's context and what the model passes as name.
but I agree this is unclear since "skill name" here would more naturally mean "the name provided by the skill" and not the mangled skill name, so it does read as contradictory. I will change to recommend it is keyed by server ID and URI.
Sorry, something went wrong.
There was a problem hiding this comment.
I guess I'm trying to reconcile this with skills/get and the idea that the skills may not be fully enumerated.
My understanding is that the idea was that a skill could list another skill (e.g. one skill says "use skill://migrationto switch from x to y"), but that doesn't seem fully feasible if the name surfaced to the agent/model is different per client.
Sorry, something went wrong.
There was a problem hiding this comment.
This is a problem with all primitives, though - I can already say "Call the get_issue tool after identifying relevant issues with the list_issues tool (for example), but in practice both of those tools will be prefixed with the configured server identifier in most agents. It's an important concern, but I'm not certain it's one that this SEP can do much about.
Sorry, something went wrong.
There was a problem hiding this comment.
The updated sketch is less ambiguous, but I think this will still turn out to be a practical challenge with host-specific implementation decisions either way, and I expect to see varying decisions across the ecosystem regarding it (following it is asking host applications with existing skill support to change their parameter schema just to accommodate MCP; some will, others won't).
Sorry, something went wrong.
The host integration sketch exposed read_skill keyed by skill name, which conflicted with the guidance that hosts accept skill URIs and with collision-qualified names: a URI handed to the model by another skill could not be mapped back to a display name the host may have rewritten. Key read_skill by skill identity instead, the originating server and the SKILL.md URI, matching read_resource. The registry is keyed the same way; name collisions are qualified for display only and never change how a skill is loaded. The context surfaces each entry's identity alongside its name and description. An unlisted skill needs no special tool surface: a read_skill call naming an unseen pair is the trigger for skills/get. Regenerate the rendered SEP docs. No-Verification-Needed: documentation-only change Remote-Dev: homespace
| Back | FazBrowse Home | New Git URL |
Extensions Track SEP defining the skill:// resource convention for serving Agent Skills over MCP. Developed by the Skills Over MCP Working Group; transports the design from experimental-ext-skills#69 with archive distribution per experimental-ext-skills#83.
Extension identifier: io.modelcontextprotocol/skills.
Reference implementations: TypeScript SDK wrappers, host prototypes in gemini-cli/fast-agent/goose/codex/Claude Code, and the GitHub MCP Server.