|
| 1 | +# SEP: Skills as Groups |
| 2 | + |
| 3 | +## 1. Capability Declaration |
| 4 | + |
| 5 | +**No new capability:** A server signals support by: |
| 6 | + |
| 7 | +- Declaring SEP-2640's `extensions.io.modelcontextprotocol/skills` capability during initialization, and |
| 8 | +- Including one or more of the reserved `io.modelcontextprotocol/*` keys (defined in §2) in the frontmatter of one or more skills. |
| 9 | + |
| 10 | +```json |
| 11 | +{ |
| 12 | + "capabilities": { |
| 13 | + "extensions": { |
| 14 | + "io.modelcontextprotocol/skills": {} |
| 15 | + } |
| 16 | + } |
| 17 | +} |
| 18 | +``` |
| 19 | + |
| 20 | +## 2. Skill Frontmatter Schema |
| 21 | + |
| 22 | +A skill MAY declare its MCP-primitive dependencies via the following reserved keys under the agent-skills `metadata` block. |
| 23 | + |
| 24 | +| Key | Value format | Resolves against | |
| 25 | +| ----------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------ | |
| 26 | +| `io.modelcontextprotocol/tools` | Tool name | `Tool.name` from `tools/list` on the server hosting the skill | |
| 27 | +| `io.modelcontextprotocol/prompts` | Prompt name | `Prompt.name` from `prompts/list` | |
| 28 | +| `io.modelcontextprotocol/resources` | URI or URI Template | `Resource.uri` from `resources/list` or `ResourceTemplate.uriTemplate` from `resources/templates/list` | |
| 29 | + |
| 30 | +**Question:** Should we support hierarchical nesting? Support `io.modelcontextprotocol/skills` as a separate category? |
| 31 | + |
| 32 | +## 3. Notifications |
| 33 | + |
| 34 | +**No new notifications:** Every dynamism scenario, e.g., skill added, skill removed, skill frontmatter modified, primitive added, primitive removed, falls naturally onto existing MCP notifications: |
| 35 | + |
| 36 | +- Skill lifecycle events emit `notifications/resources/list_changed` and `notifications/resources/updated` because skills are MCP resources per SEP-2640. |
| 37 | +- Primitive lifecycle events emit the existing `notifications/tools/list_changed`, `notifications/prompts/list_changed`, and `notifications/resources/list_changed`. |
| 38 | + |
| 39 | +## 4. Server Obligations |
| 40 | + |
| 41 | +Servers exposing skills with `io.modelcontextprotocol/*` metadata are bound by the following normative rules: |
| 42 | + |
| 43 | +- Servers **SHOULD** keep skill frontmatter consistent with currently-exposed primitives. When a tool, prompt, or resource is removed from the server's listings, the server SHOULD update or remove corresponding frontmatter tokens in any skills it serves and emit the appropriate `notifications/resources/updated` for affected `skill://<path>/SKILL.md` URIs (per existing subscription semantics). |
| 44 | +- Servers **MUST NOT** use frontmatter membership as an access-control mechanism. Authorization remains the server's responsibility on each primitive call, regardless of which skill (if any) declared the primitive. |
| 45 | + |
| 46 | +## 5. Client Behavior |
| 47 | + |
| 48 | +Clients are free to use the metadata however suits their UX and use case: |
| 49 | + |
| 50 | +- Filter `tools/list`, `prompts/list`, and `resources/list` results before presenting them to an LLM, based on which skills are "active" in some client-defined sense (progressive disclosure). |
| 51 | +- Surface skills as user-selectable in a UI, where selection determines the primitive set. |
| 52 | +- Provide an agent-callable meta-tool (for example, `activate_skill(name_or_uri)`) that lets the model itself manage which skills are in the active set. |
| 53 | +- Ignore the metadata entirely. |
| 54 | + |
| 55 | +The baseline pre-activation primitive set, the activation lifecycle, the algorithm for combining multiple active skills' primitive lists, and the handling of cross-server resolution are all client concerns and are not mandated. |
| 56 | + |
| 57 | +## 6. Examples |
| 58 | + |
| 59 | +**Example 1 — Basic case:** |
| 60 | + |
| 61 | +```yaml |
| 62 | +--- |
| 63 | +name: github-pr-review |
| 64 | +description: Review pull requests on GitHub. Use when reviewing PR code, leaving comments, or approving changes. |
| 65 | +metadata: |
| 66 | + io.modelcontextprotocol/tools: "get_pr list_comments post_comment approve_pr" |
| 67 | + io.modelcontextprotocol/prompts: "pr-review-template" |
| 68 | + io.modelcontextprotocol/resources: "github://pr/{number} github://pr/{number}/diff" |
| 69 | +--- |
| 70 | +``` |
| 71 | + |
| 72 | +**Example 2 — Multi-skill membership (`spell_check` appears in two skills):** A primitive (tool, prompt, resource) **MAY** appear in any number of skills' declared lists. The relationship is many-to-many. |
| 73 | + |
| 74 | +```yaml |
| 75 | +# skills/compose-email/SKILL.md |
| 76 | +--- |
| 77 | +name: compose-email |
| 78 | +description: Compose an email with proper tone and grammar. |
| 79 | +metadata: |
| 80 | + io.modelcontextprotocol/tools: "draft_email spell_check send_email" |
| 81 | +--- |
| 82 | +``` |
| 83 | + |
| 84 | +```yaml |
| 85 | +# skills/compose-document/SKILL.md |
| 86 | +--- |
| 87 | +name: compose-document |
| 88 | +description: Compose a long-form document. |
| 89 | +metadata: |
| 90 | + io.modelcontextprotocol/tools: "draft_section spell_check format_doc export_pdf" |
| 91 | +--- |
| 92 | +``` |
| 93 | + |
| 94 | +Here `spell_check` is declared by both skills. A host that activates either skill sees `spell_check` available; activating both adds it once. |
| 95 | + |
| 96 | +**Client Flow:** For illustration only, one reasonable client flow is: |
| 97 | + |
| 98 | +1. On initialize, observe `extensions.io.modelcontextprotocol/skills` in `ServerCapabilities.extensions`. |
| 99 | +2. List `skill://` resources (via `resources/list` filtering by URI scheme, or via SEP-2640's optional `skill://index.json`). |
| 100 | +3. For each skill, read the `SKILL.md` resource and parse its frontmatter. |
| 101 | +4. Build a map from each skill to its declared primitives by resolving the `io.modelcontextprotocol/*` tokens against the server's `tools/list`, `prompts/list`, `resources/list`, and `resources/templates/list` results. |
| 102 | +5. Track "active skills" as client-local state; recompute the union of declared primitives when the set changes. |
| 103 | +6. Filter LLM-visible primitive lists to the computed set (plus any always-on baseline the client chooses to maintain). |
| 104 | +7. Subscribe via `resources/subscribe` to the relevant `skill://` URIs to track changes. |
0 commit comments