Skip to content

Add draft SEP for Skills Extension#69

Open
pja-ant wants to merge 6 commits intomainfrom
sep-draft-skills-extension
Open

Add draft SEP for Skills Extension#69
pja-ant wants to merge 6 commits intomainfrom
sep-draft-skills-extension

Conversation

@pja-ant
Copy link
Copy Markdown
Contributor

@pja-ant pja-ant commented Mar 17, 2026

Pre-submission Extensions Track SEP defining the skill:// resource convention.

Summary

Skills are MCP Resources following the Agent Skills spec. Each file in a skill directory is exposed as a resource, conventionally under skill://<skill-path>/<file-path> with SKILL.md explicit in the URI. A well-known skill://index.json resource enumerates skills and skill templates. The skill format itself (YAML frontmatter, naming, directory layout, progressive disclosure) is delegated entirely to agentskills.io — this SEP is a transport binding only.

Key design decisions

  • skill:// scheme is SHOULD, not MUST. Servers may serve skills under a domain-native scheme (github://, etc.) provided they're listed in the index. The index is the authoritative record of which resources are skills; the scheme prefix is how hosts recognize skills that aren't indexed. Structural constraints apply regardless of scheme.
  • Final path segment MUST equal frontmatter name. Paths may be nested (acme/billing/refunds) but the last segment is the skill name, mirroring agentskills.io's parent-directory rule. Prefix segments are the server's organizational choice.
  • Direct readability is the baseline. A skill URI is always valid for resources/read whether or not it appears in any index. The index is layered on top.
  • Enumeration via skill://index.json. Optional well-known resource whose format mirrors the Agent Skills discovery index. Entries carry exactly one of url (concrete skill) or urlTemplate (parameterized namespace); type is "skill-md" either way. digest is omitted. Template entries wire to the MCP completion API for interactive browsing.
  • Zero protocol dependencies. No new methods, no schema changes, no dependency on scoped resources/list. skill://index.json is the one fixed URI.

Security

Skill content MUST be treated as untrusted model input. Hosts MUST NOT honor local-execution mechanisms (hooks, pre/post scripts, shell-in-frontmatter) from MCP-served skills without explicit per-skill user opt-in — silently executing server-provided code is an RCE vector. Hosts SHOULD let users inspect skill content before loading.

Implementation guidelines

  • Hosts provide a read_resource(server, uri) tool for model-driven loading (signature illustrative; prefix-on-conflict or other disambiguation is fine).
  • Hosts SHOULD load skill frontmatter into model context and surface skills in UI for inspect/enable/disable.
  • Filesystem and MCP skills treated identically — same discovery surface, same loading tool, same relative-path resolution.
  • SDK wrappers: @server.skill(path) decorator, client.list_skills(), client.read_skill_uri().

Extension identifier: io.modelcontextprotocol/skills.

pja-ant added 2 commits March 17, 2026 15:34
Pre-submission Extensions Track SEP defining the skill:// resource
convention: skills as MCP resources following the Agent Skills spec,
discovered via scoped resources/list (SEP-2093). Includes implementation
guidelines for host-provided read_resource tools, virtual-filesystem
unification with local skills, and SDK convenience wrappers.
- skill-path may be arbitrarily nested and need not match the
  frontmatter name; the URI is a locator, identity lives in SKILL.md
- resources/list(uri="skill://") is SHOULD not MUST; response is
  SKILL.md entries only, supporting files excluded
- resource templates are MAY, framed as user-facing (completion API)
- direct URI readability is the baseline; hosts must support loading
  skills they have never seen listed
- SEP-2093 dependency is now conditional on whether the server
  supports enumeration
@pja-ant pja-ant requested a review from a team as a code owner March 17, 2026 19:12
Comment thread docs/sep-draft-skills-extension.md Outdated

The resource for the skill's required `SKILL.md` is therefore always addressable as `skill://<skill-path>/SKILL.md`, and the skill's root directory is the URI obtained by stripping the trailing `SKILL.md`.

The `<skill-path>` is a locator, not an identifier. It need not match the skill's `name` (which comes from frontmatter), and servers MAY organize skills hierarchically by domain, team, version, or any other axis. Two constraints follow:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is a bit odd that the skill name doesn't have to match the skill path, given the skill URI is used to access the resource.

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.

This is fair, originally they did match, but we wanted to support nested skills (a request from github), e.g. skill://foo/bar/code-review/SKILL.md and skill names cannot contain / so you're either forced to not have nested skills, or replace the / with :. You could perhaps use the last path segment as the skill name (code-review). wdyt @SamMorrowDrums

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Last path segment as name seems totally reasonable to me. You cannot assume all servers are going to be able to be to find skills in certain places if you cannot provide the completions.

That would rule out skill discovery via resource templates entirely. Which is a valid approach, but it doesn't feel complex enough of an idea to reject.

Why shouldn't the spec let somebody install a skill from a known repo this way for example? GH server cannot enumerate them all.

The main alternative we discussed still has this problem, which is resource links could be returned from tools providing skill search but still need paths.


- `mimeType` SHOULD be `text/markdown`.
- `name` SHOULD be set from the `name` field of the `SKILL.md` YAML frontmatter.
- `description` SHOULD be set from the `description` field of the `SKILL.md` YAML frontmatter.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: Why SHOULD vs MUST? Is there a potential that you might have a description that doesn't match the frontmatter that a user could load that would be deceptively?

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.

I could be convinced. I think if we say MUST then we need to decide what to do when they don't match. Is that an error and you can't use the skill? If it is an error, it feels like a bit of an unnecessary footgun. If it's not an error, is the MUST accomplishing anything?

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 don't we gain anything by enforcing a mimeType, and we add compatible with patterns like zipped skills if we don't. Clients will still validate skills. I think SHOULD serves the purpose. It goes for all resources that they should have the correct mimeType for what they actually are.

"inputSchema": {
"type": "object",
"properties": {
"server": { "type": "string", "description": "Name of the connected MCP server" },
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

AFAIK, it's atypical for the client to expose the server names to the agent.

The way this is handled for tools, is server names are prefixed only if there is a conflict. Would it be better to follow this standard and only expose resource names, and prefix server name if a conflict occurs?

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.

FWIW, this section is just guidelines and clients are free to expose resource reading in whatever way they find appropriate. The intent was to just guide people to consider that URIs could conflict, so you need some server disambiguation. I could make that clearer. Your suggestion is also fine.

Copy link
Copy Markdown
Member

@PederHP PederHP Mar 22, 2026

Choose a reason for hiding this comment

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

@kurtisvg This used to be atypical, but I've noticed that with many clients prefixing server names to tools, the models will infer the name of the server quite often - even if it is not explicitly stated.

As for resource reading - they differ from tools in that that aliasing via name-spacing is awkward, so in many cases a client-side list resource tool will include the server name, as otherwise resolving a resource name conflict is impossible.

So I would agree if this was about tools, where server names are very rarely explicitly stated, but for resources it seems the pattern is to expose server names. At least in the agents I'm most familiar with.

Comment thread docs/sep-draft-skills-extension.md Outdated

### Why Resources Instead of a New Primitive?

The Interest Group's [decision log](decisions.md#2026-02-26-prioritize-skills-as-resources-with-client-helper-tools) records this as settled. Skills are files; Resources exist to expose files. Reusing Resources inherits URI addressability, `resources/read`, `resources/subscribe`, templates, and the existing client tooling for free. A new primitive would duplicate most of this and add [ecosystem complexity the community has explicitly pushed back on](https://github.com/modelcontextprotocol/experimental-ext-skills/issues/14).
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

My 2c is it feels like there's more complexity being added by the use of resources for everything vs and a new primitive. (I also think that 1 open issue is not necessarily "community pushback").

E.g. using resources as the distribution mechanism, we lose the ability to have resources that are used for other things being included in a skill. We also have to list every file in skill individually, before the skill is even activated (which is very verbose). There are also the conflicts with how resources are used in existing applications today.

In contrast, a new primitive is clear and unambiguous in it's intent, and could include non-file objects such as tools, resources, and prompts.

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.

My 2c is it feels like there's more complexity being added by the use of resources for everything vs and a new primitive. (I also think that 1 open issue is not necessarily "community pushback").

I agree that 1 issue is sparse evidence on its own, but the sentiment behind it seems common.

E.g. using resources as the distribution mechanism, we lose the ability to have resources that are used for other things being included in a skill.

I'm not sure this follows? The skill:// URI scheme scopes skill content specifically. A server can still expose other resources under any other URI scheme (file://, db://, etc.), and skills can reference those as dependencies in their frontmatter or content. The skill is a resource and the things it orchestrates like tools, other resources, prompts are still separate and fully available.

There are also the conflicts with how resources are used in existing applications today.

Could you elaborate on which specific conflicts you're seeing? it seems like structured markdown context fits naturally within modeling other entities like databases, ui views, repos, etc. The skill:// URI scheme exists to scope skill content away from other resource usage.

In contrast, a new primitive is clear and unambiguous in it's intent, and could include non-file objects such as tools, resources, and prompts.

A skill referencing tools, resources, and prompts as dependencies seems like it would work the same way regardless of whether the skill itself is delivered as a resource or a new primitive. The SKILL.md frontmatter declares what the skill needs and the host mediates availability. The transport mechanism for the skill content doesn't seem like it would change this.

Also noting a couple of the MCP design principles that seem especially relevant here:

  • Composability over specificity: "MCP provides foundational primitives: resources, tools, prompts, and tasks. We don't add protocol features for use cases that can be constructed from these existing building blocks." Skills are structured context for language models, which seems like exactly what resources are designed to deliver.

  • Standardization over innovation: "MCP standardizes patterns that have already proven valuable. We look for conventions that work across multiple implementations and codify them, rather than inventing new paradigms." Multiple implementations have independently referenced skill:// resources, and it seems like skills are commonly used because they're just files (a.k.a. simple resources) and not an abstract concept.

I think the bar for introducing a new primitive should be demonstrating something that resources genuinely can't do based on evidence in real implementations. Part of this proposal allows for experimenting with resources to be more accessible in general, for example by suggesting common client tools to interact with them. It also allows clients to follow progressive disclosure patterns and prioritize resources using existing annotations (which follows the other unique properties of skills). If there are specific capabilities we think require a new primitive, would love to dig into those concretely.

The previous draft fully decoupled <skill-path> from the skill name,
which meant the name could not be read from the URI without fetching
and parsing SKILL.md.

Now: the final segment of <skill-path> MUST equal the frontmatter
name. Preceding segments remain an optional server-chosen prefix for
organizational hierarchy. This keeps the hierarchy capability while
making the skill name recoverable from the URI alone.
Comment thread docs/sep-draft-skills-extension.md Outdated

On top of that baseline, three discovery mechanisms are defined. A server MAY support any combination.

#### Enumeration via `resources/list`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should we have a initialize as well which is called on server initialize where the client would know what this Skills MCP server is about and what it contains?
Example, I might have a 3 Skills MCP servers included and which server brings which skills would be important without loading all the list of skills

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 don't think we should tie this explicitly to connection initialization (I assume that is what you reference). Tools also leave it up to the client when to do this. Having primitives enumerated on server initialized isn't done for any other primitives.

This would also be in conflict with stateless MCP where there are no connections. Enumeration should be a host-design decision. (in practice it often happens after initializing the connection, but it shouldn't have to)

Comment thread docs/sep-draft-skills-extension.md Outdated

Including the server name disambiguates identical `skill://` URIs served by different connected servers. This tool is general-purpose — it reads any MCP resource — and benefits resource use cases beyond skills.

A typical flow: the host calls `resources/list(uri="skill://")` on each connected server at initialization and surfaces any returned skill entries in the model's context. The model calls `read_resource` with a concrete URI — one returned by enumeration, one handed to it by the user (who may have found it via a `skill://` resource template in the host UI), or one obtained out-of-band — when a skill is relevant to the task.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

the host calls resources/list(uri="skill://") on each connected server at initialization and surfaces any returned skill entries in the model's context.

Isn't this causing a lot of bloat for the LLM that it would read all the skills even though its not required? Like for a question about git-workflows the LLM would only want to list git-workflows and not skills for acme workflow

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.

The results of the list call aren't put into context as-is, the frontmatter is. Most hosts would make it possible to enable/disable skills - similar to tools. And the frontmatter is required for a model to know if a skill is relevant to load, so if it is not in the frontmatter it cannot be accessed at all - regardless of relevance, unless it done in a non-skill like way (ie direct resource reads without progressive disclosure).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Got it. I am curious to know how would use this in practice when we want to wrap a stateless agent with MCP servers. Example: I have build a marketing agent which has access to Facebook skills and tools + Youtube Skills and tools. When a question comes in about facebook marketing, how would the agent know to only get facebook skills and tools into the context and not anything else without know which MCP server is for what without reading the tools description. The way that it works right now is that agents call the initialization here to know the description of the MCP server to know what this server does.
But I am curious if this can be solved differently. :) thank you for your insights


Hosts SHOULD expose a tool to the model that reads MCP resources by server and URI, enabling the model to load skill content on demand:

```json
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should we include a standard response format to share what dependencies and scopes that might be required to run this skill?

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "contents": [
      {
        "uri": "file:///project/src/main.py",
        "mimeType": "text/x-python",
        "dependencies": [
          {
            "name": "requests",
            "version": ">=2.0.0",
            "description": "Used to make HTTP requests to external APIs such as GitHub"
          }
        ],
        "scopes": [
          {
            "name": "github:repo:read",
            "description": "Allows reading repository metadata and contents from GitHub"
          }
        ],
        "text": "# Example: Fetch repository details from GitHub API\n\nimport requests\n\nrepo = \"octocat/Hello-World\"\nurl = f\"https://api.github.com/repos/{repo}\"\n\nresponse = requests.get(url)\nif response.status_code == 200:\n    data = response.json()\n    print(f\"Repo: {data['full_name']}\")\n    print(f\"Stars: {data['stargazers_count']}\")\nelse:\n    print(\"Failed to fetch repository data\")\n"
      }
    ]
  }
}

It might add new optional primitives to the MCP spec for resources. But it might be good to add them?

Comment thread docs/sep-draft-skills-extension.md Outdated

## Abstract

This SEP defines a convention for serving [Agent Skills](https://agentskills.io/) over MCP using the existing Resources primitive. A _skill_ is a directory of files (minimally a `SKILL.md`) that provides structured workflow instructions to an agent. This extension specifies that each file in a skill directory is exposed as an MCP resource under the `skill://` URI scheme. Skills are addressed by URI and may be read directly; enumeration via `resources/list` and discovery via resource templates are supported but not required, accommodating servers whose skill catalogs are large, generated, or otherwise unenumerable. The skill format itself — directory structure, YAML frontmatter, naming rules — is delegated entirely to the [Agent Skills specification](https://agentskills.io/specification); this SEP defines only the transport binding.
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.

Suggest changing directory to folder to match agentskills.io verbiage.


> This document is a pre-submission draft maintained by the [Skills Over MCP Interest Group](https://github.com/modelcontextprotocol/experimental-ext-skills). It has not yet been submitted to the main MCP repository. Discussion welcome via [GitHub Issues](https://github.com/modelcontextprotocol/experimental-ext-skills/issues) or [Discord #skills-over-mcp-ig](https://discord.com/channels/1358869848138059966/1464745826629976084).

## Abstract
Copy link
Copy Markdown
Member

@PederHP PederHP Mar 22, 2026

Choose a reason for hiding this comment

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

I think we should mention that the skill format has design that facilitates progressive disclosure, whether this is implemented and if so, how, is up to the client host.

I think we should use client host over agent to match general MCP verbiage. I could be mistaken, but I don't think we use agent elsewhere to describe client host? (It might actually be a good idea, though - as client and client host are so often conflated).


### Hosts: Model-Driven Resource Loading

Hosts SHOULD expose a tool to the model that reads MCP resources by server and URI, enabling the model to load skill content on demand:
Copy link
Copy Markdown
Member

@PederHP PederHP Mar 22, 2026

Choose a reason for hiding this comment

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

I think we need to mention frontmatter loading if we begin to give guidance on implementation.

Something like

Hosts SHOULD load the frontmatter of all available and enabled tools into model context in an implementation-specific manner, so that the model has the server and URI information to be able call the exposed tool when a skill is relevant.

Hosts SHOULD make expose the available tools to the user so they can be inspected and enabled/disabled in a similar manner to tools.

@PederHP
Copy link
Copy Markdown
Member

PederHP commented Mar 22, 2026

I think a security guidance section for client hosts would be good. Skills are high risk in that they are context injection. Users should as a minimum be able to inspect skills from connected servers if the host loads them into context / makes them available to the model. In some cases HITL approval before even making the skills available is advisably.

Malicious skills are very common, and while connecting to an MCP server is always a high-trust action, I think we should make an effort to mitigate unsafe use of skills as that is currently happening a lot in the wild with npm based skill distribution.

Comment thread docs/sep-draft-skills-extension.md Outdated
Comment thread docs/sep-draft-skills-extension.md Outdated
Enumeration now uses a well-known skill://index.json resource whose
format mirrors the Agent Skills .well-known discovery index: same
$schema, same skills[] shape. Two deltas from the HTTP index: url
holds the full skill:// URI, and digest is omitted (transport handles
integrity over an authenticated connection). type MUST be "skill-md"
since archives don't apply when every file is individually
addressable.

This drops the SEP-2093 dependency entirely — the extension now has
zero protocol dependencies beyond resources/read.

Also includes review feedback from PR #69:
- Security: skill content MUST be treated as untrusted input; hosts
  MUST NOT honor local-execution mechanisms (hooks, scripts) without
  explicit opt-in; "more harm" softened to "as much harm"; user
  inspection SHOULD be supported
- Cite agentskills.io parent-directory rule for the final-segment
  constraint
- No-nesting constraint reworded per cliffhall suggestion
- Abstract mentions progressive disclosure as delegated concern
- Hosts section: SHOULD load frontmatter into context, SHOULD surface
  skills for user enable/disable
- read_resource signature marked illustrative
- "community has explicitly pushed back" softened
@pja-ant
Copy link
Copy Markdown
Contributor Author

pja-ant commented Mar 24, 2026

Updated to use a skill://index.json file instead of resources/list("skill://") to remove dependency on next spec version (and unaccepted SEP). Address many comments.

olaservo added a commit that referenced this pull request Mar 29, 2026
Align the reference implementation with PR #69's SEP spec, which defines
skill://index.json as the primary enumeration mechanism and requires zero
protocol dependencies beyond resources/read.

Added:
- skill://index.json well-known discovery index (Agent Skills format)
- generateSkillIndex() server-side, listSkillsFromIndex() client-side
- SkillIndex/SkillIndexEntry types and INDEX_JSON_URI constant
- 53 tests across URI utilities, index round-trip, and client parsing

Removed (SEP-2093 features not in the SEP):
- resources/metadata handler and fetchSkillMetadata()
- Scoped resources/list(uri=...) and listSkillsScoped()
- Per-resource _meta capabilities on all resource registrations
- ResourceCapabilities/ResourceMetadataResult types
- Zod schemas and RequestHandlerRegistrar interface

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pja-ant added 2 commits March 30, 2026 13:26
The index is now the authoritative record of which resources are
skills, so the scheme prefix is no longer required for identification.
Servers SHOULD use skill:// but MAY serve skills under a
domain-native scheme (github://, etc.) provided they're listed in
skill://index.json. Structural constraints (final segment = name,
explicit SKILL.md, no nesting) apply regardless of scheme.

Index entries now carry exactly one of url or urlTemplate. type stays
"skill-md" either way — it describes what the resolved URL points to,
not whether the entry is parameterized. Template entries omit name.
Servers SHOULD register the same urlTemplate as an MCP resource
template so the completion API works.

The Resource Templates subsection is deleted; templates are now an
index feature (a "template entry") rather than a parallel discovery
mechanism. Discovery is down to two mechanisms: the index and server
instructions.

skill://index.json remains the one fixed URI.
Template entries now reuse the url field with type as the
discriminator, rather than a separate urlTemplate field. This is
consistent with the upstream schema where type already discriminates
how to interpret url (skill-md vs archive). The mcp-resource-template
type is namespaced so upstream consumers skip it safely per the
existing unrecognized-type rule.
@SamMorrowDrums
Copy link
Copy Markdown

I think a security guidance section for client hosts would be good. Skills are high risk in that they are context injection. Users should as a minimum be able to inspect skills from connected servers if the host loads them into context / makes them available to the model. In some cases HITL approval before even making the skills available is advisably.

Malicious skills are very common, and while connecting to an MCP server is always a high-trust action, I think we should make an effort to mitigate unsafe use of skills as that is currently happening a lot in the wild with npm based skill distribution.

I posted on the pr to make model direct resource access a SHOULD in the spec something that applies here also:

Without resource annotations, resources should be treated as open world by default and in many clients that invokes response inspection.

With annotations then we could at least provide some indication of origin.

olaservo added a commit to olaservo/experimental-ext-skills that referenced this pull request Apr 13, 2026
The "MCP Skills Convention v0.1" (issue modelcontextprotocol#43, now closed) graduated into
the draft Skills Extension SEP (PR modelcontextprotocol#69). Update docs to reflect this:

- README: work tracking row now shows SEP with Peter as champion,
  success criteria notes the SEP as current direction
- approaches.md: status note under Central Tension, status banner on
  Approach 6 noting it graduated to the SEP
- skill-uri-scheme.md: status updated from Draft to incorporated into
  SEP, removed outdated "MCP Skills Convention" phrasing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
olaservo added a commit to olaservo/experimental-ext-skills that referenced this pull request Apr 14, 2026
The "MCP Skills Convention v0.1" (issue modelcontextprotocol#43, now closed) graduated into
the draft Skills Extension SEP (PR modelcontextprotocol#69). Update docs to reflect this:

- README: work tracking row now shows SEP with Peter as champion,
  success criteria notes the SEP as current direction
- approaches.md: status note under Central Tension, status banner on
  Approach 6 noting it graduated to the SEP
- skill-uri-scheme.md: status updated from Draft to incorporated into
  SEP, removed outdated "MCP Skills Convention" phrasing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
olaservo added a commit that referenced this pull request Apr 14, 2026
Align the reference implementation with PR #69's SEP spec, which defines
skill://index.json as the primary enumeration mechanism and requires zero
protocol dependencies beyond resources/read.

Added:
- skill://index.json well-known discovery index (Agent Skills format)
- generateSkillIndex() server-side, listSkillsFromIndex() client-side
- SkillIndex/SkillIndexEntry types and INDEX_JSON_URI constant
- 53 tests across URI utilities, index round-trip, and client parsing

Removed (SEP-2093 features not in the SEP):
- resources/metadata handler and fetchSkillMetadata()
- Scoped resources/list(uri=...) and listSkillsScoped()
- Per-resource _meta capabilities on all resource registrations
- ResourceCapabilities/ResourceMetadataResult types
- Zod schemas and RequestHandlerRegistrar interface

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- **Provenance and inspection.** Hosts SHOULD indicate which server a skill originates from when presenting it, SHOULD let users inspect a skill's content before it is loaded into model context, and MAY gate loading behind per-skill or per-server user approval.
- **Not a third-party marketplace.** This extension is for servers to ship skills that describe their own tools, not for distributing arbitrary third-party content through a connected server.

The instructor-only scope of this extension ([decisions.md, 2026-02-14](decisions.md#2026-02-14-skills-served-over-mcp-use-the-instructor-format)) deliberately excludes the helper model. A filesystem skill might reasonably carry scripts the user has audited; an MCP skill arrives from a remote party and MUST be handled as text that influences model behavior, not as code that executes on the host.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I noticed that relying on remotely served scripts introduces a multi-hop inefficiency for the agent. MCP tools look like a great solution here. That said, the current SEP doesn't propose a dependency strategy between skills and tools (for instance, having Tool B being progressively loaded when Skill A is invoked). Are we planning to address this mapping in a future update?


The Interest Group's [decision log](decisions.md#2026-02-26-prioritize-skills-as-resources-with-client-helper-tools) records this as settled. Skills are files; Resources exist to expose files. Reusing Resources inherits URI addressability, `resources/read`, `resources/subscribe`, templates, and the existing client tooling for free. A new primitive would duplicate most of this and add ecosystem complexity — a concern raised in [community discussion](https://github.com/modelcontextprotocol/experimental-ext-skills/issues/14).

[SEP-2076] proposes the new-primitive alternative. That approach offers cleaner capability negotiation and dedicated list-changed notifications, but at the cost of flattening skills to name-addressed blobs — losing the directory model that the Agent Skills specification defines and that supporting files depend on.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm curious if using an extension here might obscure future capabilities, such as the skill-to-tool dependencies I brought up in my other comment. Would introducing a new primitive make those features easier to support?


Clients SHOULD ignore unrecognized fields and SHOULD skip entries with an unrecognized `type`.

**Template entries** (`type: "mcp-resource-template"`) describe a parameterized skill namespace without materializing every entry. A server SHOULD register the same `url` value as an MCP [resource template](https://modelcontextprotocol.io/specification/2025-11-25/server/resources#resource-templates) so hosts can wire template variables to the [completion API](https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/completion). Hosts SHOULD surface template entries in their UI as interactive discovery points: the user fills in variables via completion, selects a skill, and the host passes the resolved URI into the conversation. This scales to servers with unbounded skill catalogs.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Wondering how would autonomous agent handle the fuzzy matching problem? It seems that clients are forced into a trial-and-error pattern or must rely on the host to provide specialized tools for discovery.

Comment thread docs/sep-draft-skills-extension.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

8 participants