Skip to content

SEP-2640: Skills Extension - #2640

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

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

Conversation

@pja-ant

@pja-ant 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
pja-ant requested a review from olaservo April 23, 2026 19:46
@pja-ant
pja-ant force-pushed the sep/skills-extension branch from 1f35055 to 7b35855 Compare April 23, 2026 19:47
@pja-ant pja-ant changed the title SEP: Skills Extension SEP-2640: Skills Extension Apr 23, 2026
@pja-ant pja-ant added SEP draft SEP proposal with a sponsor. extension labels Apr 23, 2026
@pja-ant
pja-ant marked this pull request as ready for review April 23, 2026 19:51
@pja-ant
pja-ant requested review from a team as code owners April 23, 2026 19:51
@pja-ant pja-ant self-assigned this Apr 23, 2026
@olaservo 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
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md
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>
@hleibenko-oai

Copy link
Copy Markdown

Hey folks - we recently rolled out support for a bounded subset of this draft in ChatGPT’s plugin submission flow, and it’s now broadly available. Our current behavior is documented here. Sharing this mainly to open the conversation - we’d be happy to compare notes as the proposal evolves
cc @pja-ant @olaservo

olaservo and others added 2 commits August 4, 2026 20:14
Co-authored-by: Den Delimarsky <53200638+localden@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

This section sketches one way a host might wire MCP-served skills into an existing skills implementation. It is illustrative, not prescriptive — hosts are free to structure tools, naming, and routing however suits their architecture. The goal is that an MCP-served skill flows through the same loading and reading mechanics as a filesystem skill — while remaining origin-tagged, per [Security Implications](#security-implications).

**Registry.** At startup and on connection change, the host assembles a single internal skill registry from every origin it supports: filesystem skill directories, and `skills/list` results from each connected MCP server that declares the `io.modelcontextprotocol/skills` extension. Each registry entry records the skill's `name` and `description` (from the entry's `frontmatter`) and its origin — for a filesystem skill, the local directory; for an MCP skill, the server identity and the `SKILL.md` resource URI. Because names collide within and across origins ([Names](#names)), the registry keys entries by origin and name together, qualifying colliding names for display and invocation rather than dropping either entry.

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.

This all makes sense, Caching becomes really important here to minimize startup costs, and etags can also help. I do think this will also cause folks to start asking for versions on Skills themselves to assist with not having to download these files every time, but outside the scope of MCP

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.

In think the etag adjacent work we are doing in transports should be broadly able to cover this.

The problem with versioning is perhaps that it is at least mildly in conflict with server deploy/versioning considering a key benefit of skills over MCP is that they can correctly reference the server they describe and be always up to date.

Then again if the broader concept of versioning arrives, skills being part of that makes complete sense.

kpavlov added a commit to kpavlov/tachyon that referenced this pull request Aug 6, 2026
## Summary

#206 Adds a `tachyon-extensions` module implementing the MCP
[SEP-2640](modelcontextprotocol/modelcontextprotocol#2640)
**Agent Skills** extension: serve `SKILL.md`-based skills as `skill://`
resources and answer `skills/list`, `skills/get`, and
`resources/directory/read`. Also introduces a shared, classpath-driven
`MimeTypes` table in `tachyon-core` and fixes Kotlin DSL builders to
default `mimeType` from the resource URI/filename instead of `null`.

## What's new

### `SkillsExtension` (`tachyon-extensions`)
- `SkillsExtension.builder().registry(...)` wires one or more
`SkillsRegistry` sources (filesystem via `PathSkillsRegistry`, classpath
via `ClasspathSkillsRegistry`, or a custom implementation) and registers
every skill file as an extension-owned `skill://` resource.
- Handlers: `skills/list` (no pagination — catalogs are bounded),
`skills/get`, `resources/directory/read` (walks nested skill
directories, including subdirectories inside a skill, not just skill
roots).
- `CompositeSkillsRegistry` merges multiple registries, rejecting
duplicate skill paths instead of silently overwriting them.
- `FrontmatterParser` parses the YAML frontmatter of `SKILL.md` using a
`SafeConstructor`-based SnakeYAML loader (no arbitrary object
instantiation), requiring non-blank `name`/`description`.
- Filesystem-backed skill files are re-read from disk on demand rather
than cached at scan time, so on-disk edits are reflected without a
restart; classpath-backed files stay cached.
- `docs/extensions/mcp-skills.md` documents the extension end to end
(directory layout, registries, methods, SEP-2133 negotiation).

### `MimeTypes` (`tachyon-core`, new)
- Classpath-bundled `mime-types.csv` drives filename → MIME type + a
per-type `isText` flag, replacing ad hoc suffix checks (`.json`,
`.yaml`, `.toml`, `.csv`, `.html`, images, etc. now resolve correctly
instead of falling back to `application/octet-stream`/base64 blobs).
- `MimeTypes.isText(mimeType)` consults the table first, falling back to
a `text/` prefix check only for unknown types (e.g. caller-supplied
overrides).
- Kotlin DSL factories/builders (`Icon`, `TextResourceContents`,
`BlobResourceContents`, `ResourceLink`, `ResourceDescriptor`, and their
scope equivalents) now default `mimeType` to `MimeTypes.guess(uri)`
instead of `null`, matching the Java builders.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
@danteoh-toast

Copy link
Copy Markdown

Proposal: a dependencies field for declaring a skill's tool prerequisites

Hi all - wanted to add a comment (and suggestion) here related to the interrelatedness of skills and tools. Sometimes a skill doesn't require a skill (here's how to think about X), but more often than not, skills are put in place because they fit naturally on the interplay of tools themselves (you first fetch an order to then be able to know what to update the status to, etc).

The real problem (from a production MCP server)

We run an MCP server whose tools are often gated per-user and per-location: individual tools are enabled/disabled based on feature flags, product entitlements (ie are they paying for that product), and permissions. Two users connected to the same server see different tools/list results.

Skills over MCP is exactly what we want for packaging our multi-step workflows — but as drafted, a skill is listed and loaded independent of whether the tools it orchestrates are actually available to that user. The failure mode kind of stinks: a user loads a "process a refund" skill, the agent reads the whole workflow into context, then hits an entitlement denial on the first tool call. It's wasted context, confusing dead-end - and as we've seen it happen, the llm will actually hallucinate that it can do something (often because the language of the skill describes a capability that the llm supposedly now has).

allowed-tools doesn't solve this — SEP-2640 correctly treats it as a permission request (grant access), not a requirement check (is this even available). Those are opposite directions.

Proposed shape

A dependencies field in frontmatter, type-tagged, with all/any groups, with a concrete example:

name: refund-workflow
description: Dispute a chargeback on an order
dependencies:
  tools:
    all: [get_order, get_check_details]
    any: [dispute_chargeback, dispute_chargeback_v2]

  • all — every entry must resolve to an available tool.
  • any — at least one must.
  • A bare list defaults to all.
  • Type-tagged (tools:) so the same field can later express resources: / prompts: deps without a schema change.

The any group isn't hypothetical: versioned tool pairs are common (get_order/get_order_v2, and similar). A skill needs the capability, satisfiable by either version — any expresses that directly.

I'd love if we could consider this - I was in an auth WG meeting last week and Max and team framed the concept well - is what we're sending over the wire optional or necessary for clients to implement to conformant. I think this is a necessary level of support to make skills truly effective at scale, in particular in any environment where tools/list is dependent on the caller's privileges. We know for a fact that if a skill is exposed to the llm but does not have the requisite tools, its a degraded experience full-stop and erodes trust in the product.

@jamespbrink

Copy link
Copy Markdown

I second this problem emphatically. This is something that I think skills have been materially lacking... but this unfortunately might not be the right surface to solve it. Changes to the frontmatter speak more broadly to the standard as a whole. I think skills over MCP gives some relief to the "batteries not included" problem. I've been searching for a method for a while to make an agent loop fail fast when it doesn't have access to a tool needed within a skill. We don't get import errors like we do when libraries are missing in the code, often your agent says "let me try this instead..." which is so much worse than failing completely.

I'm very much in favor of the front matter changes proposed here but they probably need more broad adoption amongst clients and not just within MCP. For what its worth, you probably also need to provide server urls along with the tools as "get_orders" might be a tool present on multiple servers. You could validate exclusively against tools within the server where the skills is being served over MCP but then you have the limiting aspect of not using tools from other servers.

"https://www.example.com/mcp:get_orders" might be a better convention for tools.

Proposal: a dependencies field for declaring a skill's tool prerequisites

Hi all - wanted to add a comment (and suggestion) here related to the interrelatedness of skills and tools. Sometimes a skill doesn't require a skill (here's how to think about X), but more often than not, skills are put in place because they fit naturally on the interplay of tools themselves (you first fetch an order to then be able to know what to update the status to, etc).

The real problem (from a production MCP server)

We run an MCP server whose tools are often gated per-user and per-location: individual tools are enabled/disabled based on feature flags, product entitlements (ie are they paying for that product), and permissions. Two users connected to the same server see different tools/list results.

Skills over MCP is exactly what we want for packaging our multi-step workflows — but as drafted, a skill is listed and loaded independent of whether the tools it orchestrates are actually available to that user. The failure mode kind of stinks: a user loads a "process a refund" skill, the agent reads the whole workflow into context, then hits an entitlement denial on the first tool call. It's wasted context, confusing dead-end - and as we've seen it happen, the llm will actually hallucinate that it can do something (often because the language of the skill describes a capability that the llm supposedly now has).

allowed-tools doesn't solve this — SEP-2640 correctly treats it as a permission request (grant access), not a requirement check (is this even available). Those are opposite directions.

Proposed shape

A dependencies field in frontmatter, type-tagged, with all/any groups, with a concrete example:

name: refund-workflow
description: Dispute a chargeback on an order
dependencies:
  tools:
    all: [get_order, get_check_details]
    any: [dispute_chargeback, dispute_chargeback_v2]
  • all — every entry must resolve to an available tool.
  • any — at least one must.
  • A bare list defaults to all.
  • Type-tagged (tools:) so the same field can later express resources: / prompts: deps without a schema change.

The any group isn't hypothetical: versioned tool pairs are common (get_order/get_order_v2, and similar). A skill needs the capability, satisfiable by either version — any expresses that directly.

I'd love if we could consider this - I was in an auth WG meeting last week and Max and team framed the concept well - is what we're sending over the wire optional or necessary for clients to implement to conformant. I think this is a necessary level of support to make skills truly effective at scale, in particular in any environment where tools/list is dependent on the caller's privileges. We know for a fact that if a skill is exposed to the llm but does not have the requisite tools, its a degraded experience full-stop and erodes trust in the product.

@danteoh-toast

danteoh-toast commented Aug 7, 2026

Copy link
Copy Markdown

@jamespbrink yeah i'm literally drafting a similar comment up for agentskills repo as a proposal to your point about broader adoption.

@jamespbrink

Copy link
Copy Markdown

@jamespbrink yeah i'm literally drafting a similar comment up for agentskills repo as a proposal to your point about broader adoption.

@danteoh-toast please reference this thread... I'd love to follow along with that.

@danteoh-toast

Copy link
Copy Markdown

@jamespbrink posted here: agentskills/agentskills#485

@dsp-ant dsp-ant left a comment

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.

I have to comment iwth some old review comments since the diff renderer in Github now says the diff is too large and I can't add comments anymore.

Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md Outdated
Comment thread seps/2640-skills-extension.md
Comment thread seps/2640-skills-extension.md Outdated
"description": "Extract, fill, and assemble PDF documents",
"metadata": { "version": "2.1.0" }
},
"resources": [

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.

We are not suggesting any limitations . I assume that any client wants to limit the read on files like this. I wonder if we should suggest a limit, e.g. Client implementors SHOULD limit reads of individual files 1024kb and the amount of files to 256 when choosing limits. This way we encourage some form of consistency in the ecosystem and give a bit more predictability to server authors.

Comment on lines +192 to +195
{
"uri": "skill://pdf-processing/templates/regional/eu-invoice.md",
"digest": "sha256:c0d1e2f3..."
}

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.

I am still not sure if we shouldn't include a size to limit the read.

- When present, `resources` MUST be complete: it lists every file of the skill, each exactly once, including an entry matching the skill's top-level `uri` — that entry carries the digest of `SKILL.md` itself.
- Each `uri` MUST be the skill's `SKILL.md` or a file within the skill's directory.
- Completeness extends to nested skills: from the enclosing skill's perspective their files are supporting files ([Nested skills](#nested-skills)), so the enclosing skill's `resources` lists them too, and the same file may appear in both the enclosing and the nested skill's entries. A change to a nested skill is therefore a change to the enclosing skill's set.
- `resources` MAY be omitted only when a skill's content is generated dynamically, such that stable digests cannot be published. A skill without `resources` offers no content integrity and cannot be content-bound ([Security Implications](#security-implications)). Hosts MAY decline to load such skills, and server authors SHOULD expect that some hosts will.

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.

I personally prefer to be somewhat explicit about these, e.g. either send resources: [...] or resources: "dynamic" or resources and dyanmicResources or something. This way, a few months down the line, a person or agent looking at the trace can easily understand the meaning without having to know from the spec what a missing resources means. The principle here is being self-documenting.

…e doc

The full rationale text was migrated to the Working Group repository in
modelcontextprotocol/experimental-ext-skills#121 (docs/rationale.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Credit for prompting skills/get and sustained design review.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: olaservo <olahungerford@gmail.com>
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
Status: In review

Development

Successfully merging this pull request may close these issues.