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 请求。

这些示例使用协议修订版 2026-07-28 或更高版本。为简洁起见,请求示例省略了 _meta。每个请求都**必须(MUST)**包含必需的请求元数据。

协议消息

列出 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"
  }
}

每个条目包含:

字段含义
uriSkill 的 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):

  1. 将文件读取限制在已保留清单中的 URI。
  2. 使用每个文件前,验证原始字节大小和 SHA-256 摘要。
  3. 解析 SKILL.md frontmatter,并与条目的 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/文件,或无效目录 URIJSON-RPC -32602(Invalid params)。
服务器内部故障JSON-RPC -32603(Internal error)。
摘要、大小、frontmatter 或清单不匹配宿主拒绝内容并刷新条目。

验证失败属于宿主侧条件,而不是协议错误。处理方式见完整性与验证。

客户端支持

Skills 支持情况及实现文档链接请参阅客户端矩阵。

规范

完整规范位于 ext-skills 仓库。开发工作由 Skills Over MCP 工作组(英文)协调。