FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

SEP-2640: Skills Extension by pja-ant · Pull Request #2640 · modelcontextprotocol/modelcontextprotocol · GitHub

SEP-2640: Skills Extension - #2640

Open
pja-ant wants to merge 44 commits into
mainfrom
sep/skills-extension
Open

SEP-2640: Skills Extension#2640
pja-ant wants to merge 44 commits into
mainfrom
sep/skills-extension

Conversation

pja-ant commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

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.

pja-ant requested a review from olaservo April 23, 2026 19:46
pja-ant force-pushed the sep/skills-extension branch from 1f35055 to 7b35855 Compare April 23, 2026 19:47
pja-ant changed the title SEP: Skills Extension SEP-2640: Skills Extension Apr 23, 2026
pja-ant added SEP draft SEP proposal with a sponsor. extension labels Apr 23, 2026
pja-ant marked this pull request as ready for review April 23, 2026 19:51
pja-ant requested review from a team as code owners April 23, 2026 19:51
pja-ant self-assigned this Apr 23, 2026
olaservo moved this from Backlog to In review in Skills Over MCP Working Group Apr 24, 2026
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread docs/seps/2640-skills-extension.mdx Outdated
Comment thread seps/2640-skills-extension.md Outdated
olaservo added a commit to olaservo/skilljack-mcp that referenced this pull request May 3, 2026
* 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>
wittjosiah added a commit to dxos/dxos that referenced this pull request Aug 13, 2026
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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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

kpavlov Aug 15, 2026
edited
Loading

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

skills/list supports pagination. For partial results response should include nextCursor field. This would be a partial result indicator. Would this work?

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
Comment on lines +290 to +291
"result": {
"skill": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

tiny nit across all of the sample responses: resultType?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@LucaButBoring thanks, added!

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
Comment thread seps/2640-skills-extension.md Outdated
…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

Copy link
Copy Markdown

Maintainer Activity Check

Hi @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:

  • Current status of your review/work
  • Any blockers or concerns
  • Expected timeline for next steps

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.

"name": "git-workflow",
"description": "Follow this team's Git conventions for branching and commits"
},
"resources": [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I am not sure I understand the value for listing resources explicitly here -- IMO, it seems like the intended flow should be:

  • skills/list provides the info necessary to list avaible skills
  • skills/get provides the equivalent of activate_skill tool call -- the content in the skill (including the SKILL.md)

offering this info in skills/list feels like just asking for coordination/caching challenges.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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.

Comment thread seps/2640-skills-extension.md Outdated

**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:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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.

kurtisvg Aug 25, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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.

LucaButBoring Aug 25, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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).

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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

draft SEP proposal with a sponsor. extension SEP

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.


Back | FazBrowse Home | New Git URL