Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Support the Skills extension (SEP-2640)

未关闭
#1,391 1 条评论 0 个 reaction 已指派 1 人 在 GitHub 查看

维护者通常 3 天内回复

@DaleSeo 已经在做这个了。

开始于 2026年10月23日。

  • #1392 来自 @DaleSeo —— 未关闭

评估

这个 Issue 还没有评估数据。

描述

enhancement P2 ready for work T-enhancement T-handler T-model T-service

Summary

Add support for the Skills extension (SEP-2640, io.modelcontextprotocol/skills) to rmcp. The extension adds three methods: skills/list, skills/get, and the optional resources/directory/read. This issue covers both the server side and the client side.

Requirements

A server built with rmcp can:

  • Declare the extension in capabilities.extensions, with directoryRead only when it serves resources/directory/read.
  • Answer skills/list and skills/get with typed results, and resources/directory/read when declared.
  • Serve the files of a skill through resources/read, so that the bytes match the size and digest in the manifest.
  • Return the error codes that the spec defines: -32601 for a method it does not serve, -32602 for an unknown skill or a non-directory URI.
  • Send ttlMs and cacheScope to peers on protocol version 2026-07-28.

A client built with rmcp can:

  • Detect the extension and its directoryRead setting from the server capabilities.
  • Call the three methods through typed Peer methods, and receive server errors unchanged.
  • Verify a fetched file against the size and digest in the manifest.

Both sides pass the sep-2640-* conformance scenarios.

The spec targets protocol revision 2026-07-28 or later. rmcp also serves the methods to peers on an older revision and removes the cache hints from those responses, the same as the TypeScript, Python, and Go SDKs do. This needs the legacy strip helper to clear ttlMs and cacheScope as well as resultType, which also closes the same gap for the existing list results.

Proposal

This is how I plan to design and implement it. The choices below are open for discussion.

PR 1: protocol surface

Everything the spec defines, wired the same way as the tasks extension and without a feature flag.

  • Model types for the skill manifest and the three methods in model/skill.rs, with the matching ClientRequest and ServerResult variants. ReadResourceDirectoryResult is a type alias for ListResourcesResult, and ServerResult reuses the existing ListResourcesResult variant for it. No new directory variant: the two schemas are identical and the untagged ServerResult cannot tell them apart (see #771).
  • Three ServerHandler methods with capability-gated dispatch. Dispatch checks what the result object alone can show: the skill URI matches the request, the name matches the last URI segment, the manifest contains SKILL.md and no duplicate URIs, and every digest has the sha256: form. A result that fails these checks returns -32603. Whether the bytes behind each URI match the manifest is checked by the catalog (PR 2) and by the host that reads them, not by dispatch.
  • enable_skills() and enable_skills_with_directory_read() on the capability builder, with the matching supports_* getters. Skills requests fail with -32603 when the server declares skills without resources, because the extension serves its files through resources/read.
  • The matching Peer methods for the client. They accept a 2026-07-28 response that omits the cache hints, the same as list_tools does today; the TypeScript and Go clients reject such a response, rmcp does not. SkillResource::verify(&[u8]) checks the size and the sha256: digest of one file. Frontmatter verification against skills/get is left to the host. sha2 becomes a regular dependency of rmcp: it is pure Rust, already in the tree for request-state, and a client must not have to enable a filesystem feature to verify a download.
  • Integration tests through Peer over a real transport: pagination across skills/list, a -32602 from skills/get arriving unchanged, read_resource_directory not sent when directoryRead is absent, the directory result arriving as ListResourcesResult, and verify failing on a wrong size and on a wrong digest.
  • Conformance fixtures with a nested skill, a subdirectory, and a "dynamic" skill, and the scenarios in conformance.yml.
PR 2: filesystem catalog

Behind a skills-fs feature. SkillCatalog::from_dir walks a directory tree and builds the manifests.

  • The catalog is a snapshot. It holds the file bytes and their digests, so resources/read serves the same bytes that the manifest describes, even if the files change on disk later.
  • reload() builds a new snapshot and swaps it in. If the rebuild fails, the old snapshot stays.
  • The walk rejects paths that leave the root, including through symlinks, and validates that each skill name matches its directory name. It warns at 512 files or 16 MiB.
  • A nested skill appears in the listing on its own, and its files also appear in the manifest of the parent skill.
Follow-ups, not blocking
  • PR 1 adds the two new results to the hand-written lists in strip_result_type_for_legacy_peer and fill_missing_cache_hints. A non-breaking refactor right after PR 1 replaces both lists with a trait on each cacheable result and a dispatch that ts_union! generates, since the macro already enumerates every ServerResult variant.
  • A ResultEnvelope { result_type, meta, ttl_ms, cache_scope } flattened into each cacheable result, with the result structs marked #[non_exhaustive], so that the next mixin field from the spec is not a major release. Breaking, so it waits for the next major batch.
  • An Extension trait for declaring and reading extension capabilities, so that each extension adds one impl instead of four functions. Skills and tasks move onto it. Non-breaking.

Acceptance

  • The sep-2640-* conformance checks pass on the fixture server. The PR body lists the numbers.
  • Goose can list, fetch, and verify remote skills through Peer without custom requests.
  • For PR 2: a file served through resources/read always matches the manifest, a path outside the root is never served, and the files of a nested skill are listed in both manifests.
主要语言
Rust
星标
4.1k
派生
680
平均合并
3 天 20 小时
30 天内合并 PR
32

环境准备

在 Codespaces 中打开

在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

modelcontextprotocol/rust-sdk 的其他 Issue

查看 modelcontextprotocol/rust-sdk 的全部 Issue

相似的 Issue

更多 Rust Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。