Skills
社区译文;来源: MCP 80041ab0
ext-skills 仓库
包含官方 Skills 扩展(io.modelcontextprotocol/skills)已发布的规范。SEP-2640(英文)
的状态为 Final。
Skills Over MCP 工作组(英文) 负责维护该扩展。SDK 和宿主支持仍在实现中;当前覆盖情况请查看客户端支持矩阵 和实现列表 。
modelcontextprotocol/ext-skills
基于 MCP 的 Skills 规范和文档。
Skills 扩展允许 MCP 服务器向客户端公开工作流指令和支持文件。客户端可以发现可用 Skills、获取其元数据,并使用现有 Resources 原语读取其内容。
一个 Skill 是包含 SKILL.md 文件和可选支持文件的目录,并遵循 Agent Skills 规范
。此扩展定义了通过 MCP 发现和获取 Skills 的方式。
Skills 适合需要组合多个工具或依赖支持资料的可复用工作流,例如代码评审或文档处理。通过 MCP 提供 Skills,可以让这些指令与其描述的服务保持在一起。客户端可从元数据发现可用工作流,并且仅在需要时加载指令和支持文件。
用户交互模型
宿主应用决定如何向模型和用户公开 Skills。模型可以根据 Skill 的名称和描述进行选择,用户也可以显式选择。此扩展不强制规定特定的用户交互模型。
通过 resources/read 读取 SKILL.md 本身并不会激活 Skill。要加载 Skill,宿主需要把读取操作转交给自身的 Skill 加载路径,由该路径验证内容,并在将其载入模型上下文之前应用所有必要的用户审批。
能力
支持 Skills 的服务器**必须(MUST)**在 server/discover
中同时声明 resources 能力和 io.modelcontextprotocol/skills 扩展:
{
"capabilities": {
"resources": {},
"extensions": {
"io.modelcontextprotocol/skills": {
"directoryRead": true
}
}
}
}声明此扩展的服务器**必须(MUST)**实现 skills/list 和 skills/get。Skill 文件通过 resources/read 提供。
可选的 directoryRead 设置表示支持 resources/directory/read,默认值为 false。空的扩展对象表示支持该扩展,但不支持读取目录。客户端只有在观察到服务器声明后,才会发出 skills/list 和 skills/get 请求。
协议消息
列出 Skills
客户端发送 skills/list 请求以发现可用 Skills。此操作支持分页
和缓存
。
请求:
{
"jsonrpc": "2.0",
"id": 1,
"method": "skills/list",
"params": {}
}响应:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"skills": [
{
"uri": "skill://code-review/SKILL.md",
"frontmatter": {
"name": "code-review",
"description": "Review code using the team's checklist."
},
"resources": [
{
"uri": "skill://code-review/SKILL.md",
"digest": "sha256:d2489d6c182e8df9c178563ff9f2eac7998a0c1bb1278c52a7fd5306e4259160",
"size": 149
},
{
"uri": "skill://code-review/references/checklist.md",
"digest": "sha256:dbab2de7bf7db9cc95cb6ce681c3690b26184db39f75b958a0287ca6d9e24e20",
"size": 65
}
]
}
],
"ttlMs": 300000,
"cacheScope": "public"
}
}每个条目包含:
| 字段 | 含义 |
|---|---|
uri | Skill 的 SKILL.md 资源 URI。 |
frontmatter | 原样保留的所有 YAML frontmatter 字段,包括 name 和 description。 |
resources | 完整文件清单;对于生成的内容则为 "dynamic"。 |
清单**必须(MUST)**包含 SKILL.md 和每个支持文件,并为每个文件提供 URI、SHA-256 摘要和字节大小。skills/list 返回的每个条目都是完整的,客户端无需再调用 skills/get 获取其他元数据。
响应包含 nextCursor 时,客户端将其作为 params.cursor 传入以获取下一页。列表和获取结果**必须(MUST)**包含 resultType: "complete"、ttlMs 和 cacheScope。缓存字段描述新鲜度和共享范围,不提供内容完整性保证。
Skill 身份由来源服务器的身份和 Skill URI 共同构成。名称只是标签,不保证唯一。宿主**必须(MUST)在注册表、审批和缓存中同时保留服务器身份与 URI。服务器应该(SHOULD)使用 skill:// 方案,但也可以(MAY)使用其他方案。宿主不得(MUST NOT)**仅根据 URI 方案把资源识别为 Skill。
获取 Skill
客户端发送 skills/get 请求,按 URI 获取 Skill 条目。URI 可能由用户、另一个 Skill 或服务器指令提供。
请求:
{
"jsonrpc": "2.0",
"id": 2,
"method": "skills/get",
"params": {
"uri": "skill://code-review/SKILL.md"
}
}响应在 result.skill 下包含一个 Skill 条目,其结构与 skills/list 中的条目相同,并同时包含 resultType: "complete"、ttlMs 和 cacheScope。客户端也可以使用此方法刷新现有条目。
服务器**可以(MAY)返回空列表或部分列表,但对于其提供的每个 Skill,都必须(MUST)响应 skills/get。宿主必须(MUST)**支持按 URI 加载,包括未出现在列表中的 Skills。
读取 Skill 内容
客户端发送 resources/read
请求以获取 Skill 指令或支持文件。以下示例获取前述列表中的 SKILL.md。
请求:
{
"jsonrpc": "2.0",
"id": 3,
"method": "resources/read",
"params": {
"uri": "skill://code-review/SKILL.md"
}
}响应:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"resultType": "complete",
"contents": [
{
"uri": "skill://code-review/SKILL.md",
"mimeType": "text/markdown",
"text": "---\nname: code-review\ndescription: Review code using the team's checklist.\n---\n\n# Code review\n\nRead `references/checklist.md`, then review the diff.\n"
}
],
"ttlMs": 300000,
"cacheScope": "public"
}
}SKILL.md 文件**必须(MUST)以包含 name 和 description 的 YAML frontmatter 开头。其父目录路径的最后一个片段必须(MUST)**与 name 匹配。
客户端相对于 Skill 根目录解析相对引用。在此示例中,references/checklist.md 解析为 skill://code-review/references/checklist.md。支持文件从同一服务器通过 resources/read 获取,内容如下:
# Review checklist
Check correctness, tests, and compatibility.两个示例文件都以换行符结尾;其摘要和大小与清单一致。宿主**不得(MUST NOT)**提前获取文件,包括连接、列出或审批阶段。审批绑定到清单,但不要求实际获取文件。
读取目录
客户端发送 resources/directory/read 请求以列出目录的直接子项。此方法是可选的。除非服务器声明 directoryRead: true,否则客户端**不得(MUST NOT)**调用它。
请求:
{
"jsonrpc": "2.0",
"id": 4,
"method": "resources/directory/read",
"params": {
"uri": "skill://code-review/references"
}
}响应:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"resultType": "complete",
"resources": [
{
"uri": "skill://code-review/references/checklist.md",
"name": "checklist.md",
"mimeType": "text/markdown"
}
]
}
}目录 URI 不以斜杠结尾。子目录使用 mimeType: "inode/directory"。客户端通过对子目录发出另一个请求继续向下遍历。结果支持 cursor / nextCursor 分页,并且只包含直接子项。
对于带清单的 Skills,宿主**可以(MAY)直接从清单回答目录查询。目录读取也支持动态 Skills 和其他资源树。宿主不得(MUST NOT)**把实时目录结果视为对已保留清单的扩展,也不得将新列出的文件作为 Skill 的一部分公开。访问这些文件需要刷新条目,并重新完成任何必要的用户审批。
消息流
以下示例展示在发现服务器能力后,如何加载带文件清单的 Skill。宿主的 MCP 客户端发送协议请求;Skill 选择和用户审批属于宿主交互。
sequenceDiagram
actor User
participant Model
participant Host
participant Server
opt Discover a catalog
Host->>Server: skills/list
Server-->>Host: Skill entries with frontmatter and manifests
Host->>Model: Available skills and their origins
Host->>User: Available skills and their origins
end
alt Model selects a skill
Model->>Host: Load skill (server, URI)
else User selects a skill
User->>Host: Load skill (server, URI)
end
opt Host has only a URI
Host->>Server: skills/get (URI)
Server-->>Host: Skill entry or error
end
break Lookup failed
Note over Host,Server: Stop loading (unknown skill: -32602)
end
Note over Host: Retain entry (server, URI)
opt User approval required
Host->>User: Request approval for this skill and manifest
User-->>Host: Approve
end
Host->>Server: resources/read (SKILL.md URI)
Server-->>Host: SKILL.md content
Host->>Host: Verify byte size, digest, and frontmatter
Host->>Model: Load verified instructions with server origin
loop Supporting files requested while the skill is active
Model->>Host: Read a supporting file
Host->>Host: Resolve URI within the retained manifest
Host->>Server: resources/read (file URI)
Server-->>Host: File content
Host->>Host: Verify byte size and digest
Host->>Model: Verified content with server origin
end
无需先列出,即可加载已知 URI。可以复用 skills/list 返回的条目;否则宿主调用 skills/get。未列出的 Skill 仍可能存在,但未知 URI 会返回 -32602(Invalid params)并停止加载。所有 Skill 读取都使用来源服务器。
如果查找失败、审批被拒或验证失败,宿主不会加载或使用内容。要从已更改的清单恢复,必须刷新条目,并按下文所述重新获得必要的审批。
完整性与验证
宿主在使用 Skill 时,保留加载该 Skill 所依据的条目。该时段至少持续到 Skill 的 SKILL.md 离开模型上下文。对于带清单的 Skills,宿主必须(MUST):
- 将文件读取限制在已保留清单中的 URI。
- 使用每个文件前,验证原始字节大小和 SHA-256 摘要。
- 解析
SKILL.mdfrontmatter,并与条目的frontmatter逐字段比较。
宿主**不得(MUST NOT)使用验证失败的内容。要从过期元数据恢复,宿主使用 skills/get 刷新条目。持久化审批必须(MUST)绑定到完整的文件 URI 与摘要集合。任何文件发生更改、新增或删除,都会撤销该审批;宿主在加载或执行前必须(MUST)**重新获得批准。
宿主**应该(SHOULD)按需缓存已验证的内容。磁盘缓存必须(MUST)防止模型、模型工具或其他用户修改,并保持文件不可变;否则就必须在每次访问时验证缓存字节。宿主必须(MUST)**将缓存文件排除在文件系统 Skill 的发现路径之外,并在重启后继续保留其 MCP 来源。
"resources": "dynamic"。宿主**可以(MAY)拒绝这些 Skills。如果接受,宿主仍然必须(MUST)验证 frontmatter,并且不得(MUST NOT)**把持久化审批视为覆盖任意未来内容。实现要求
服务器
服务器必须(MUST):
- 提供有效的 Agent Skills,并实现已声明的方法,包括基础 Resources 支持。
- 保留所有 frontmatter 字段,并发布根据实际提供字节计算的完整清单,除非 Skill 的资源声明为
"dynamic"。 - 独立于列表支持直接查找。每个 Skill 条目都是原子的,其清单**不得(MUST NOT)**拆分到多页。
- 声明
directoryRead: true时,支持所提供 Skill 命名空间中的每个目录。
服务器**不应该(SHOULD NOT)让单个 Skill 超过 512 个文件或 16 MiB,其中包括 SKILL.md。宿主必须(MUST)支持不超过这些限制的 Skills,也可以(MAY)**支持更大的 Skills。
安全注意事项
宿主必须(MUST):
- 防止名称相同的 Skills 静默替换彼此。
- 使用宿主分配的标签标记已加载内容的来源服务器,并将资源读取绑定到该服务器。跨服务器读取需要逐次明确批准,并指出两个服务器。
- 将 Skill 内容视为不可信输入。宿主侧代码执行以及
allowed-tools等权限授予,需要用户针对每个 Skill 明确批准。 - 激活嵌套 Skill 前重新获得用户同意。把其
SKILL.md作为支持内容读取,并不会激活该 Skill 或其 frontmatter。
完整的审批、来源和缓存规则请参阅安全要求 。
错误处理
| 条件 | 处理方式 |
|---|---|
| 未知 Skill/文件,或无效目录 URI | JSON-RPC -32602(Invalid params)。 |
| 服务器内部故障 | JSON-RPC -32603(Internal error)。 |
| 摘要、大小、frontmatter 或清单不匹配 | 宿主拒绝内容并刷新条目。 |
验证失败属于宿主侧条件,而不是协议错误。处理方式见完整性与验证 。
客户端支持
Skills 支持情况及实现文档链接请参阅客户端矩阵 。
规范
完整规范位于 ext-skills 仓库 。开发工作由 Skills Over MCP 工作组(英文) 协调。