Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Support the Skills extension (SEP-2640)

Abierto
#1,391 1 comentario 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 3 días

@DaleSeo ya está trabajando en esto.

Desde el 23/10/2026.

  • #1392 de @DaleSeo — abierto

Evaluación

Este issue todavía no se ha evaluado.

Descripción

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. Whether the builder rejects skills without resources or only documents it is open.
  • 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.
Lenguaje dominante
Rust
Estrellas
4.1k
Forks
680
Merge medio
4 d 1 h
PR fusionados (30 d)
35

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de modelcontextprotocol/rust-sdk

Todos los issues de modelcontextprotocol/rust-sdk

Issues similares

Más issues de Rust

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.