Skip to content

skills: add SEP-2640 protocol support - #1238

Open
sambhav wants to merge 16 commits into
modelcontextprotocol:mainfrom
sambhav:skills-sep-2640
Open

sambhav wants to merge 16 commits into
modelcontextprotocol:mainfrom
sambhav:skills-sep-2640

Conversation

@sambhav

@sambhav sambhav commented Sep 4, 2026 •

Copy link
Copy Markdown
Member

Summary

Add opt-in Go support for the Skills extension: skills/list, skills/get, optional resources/directory/read, manifests, pagination, and content verification.

This is PR 1 of 2. Draft #1240 now includes this revision and preserves the optional filesystem provider. Its helper-only comparison contains only filesystem code, tests, and documentation.

Review changes

  • Replace skills.Client and AddMethods with context-first package functions: List, Get, ReadDirectory, All, and DirectoryEntries, accepting an mcp.ClientSession.
  • CallCustomMethod registers absent methods under the client lock, preserves existing registrations, rejects incompatible result types and standard-method shadowing, and snapshots the sending-method map for concurrent reads. Explicit AddSendingCustomMethod remains supported.
  • List rejects malformed entries by default. Pass ListOptions{SkipInvalidSkills: true} to retain valid entries. InvalidSkills records original indices, URIs when recoverable, and errors; OnInvalidSkill reports skips during iteration. Decoding failures are isolated per entry, all entries with duplicate URIs are excluded, and page cursors remain intact, including entirely invalid pages. Invalid response envelopes still fail. Get and server output validation remain strict.
  • Remove configurable client manifest caps. Clients structurally validate and accept the required 512-file / 16-MiB baseline and larger manifests. ServerOptions.Limits remains an independent publication policy; dynamic download budgets belong to the host.
  • AddHandlers checks the server's effective resources capability before registering methods or advertising the extension. Register resources/templates first, or declare Resources explicitly. Server.Capabilities returns an isolated snapshot.

Compatibility and scope

On protocol 2026-07-28 and later, list/get include required cache hints and all three methods return resultType: complete. The compatibility backport omits these fields on earlier protocols. Verification remains lazy and checks manifest membership, sizes, digests, and all frontmatter fields. Entries remain scoped to their originating server.

Removed the conformance runner changes and fixture, CONTRIBUTING edits, unrelated auth/extauth bullets, documentation intro/pagination changes, and x/sync reclassification. The only added dependency is gopkg.in/yaml.v3, used by Skills frontmatter verification. Skills documentation sources and generated files are updated together.

Validation

Both protocol and helper trees passed full Go tests and Skills race tests. Automatic registration concurrency and capability snapshots have MCP regression/race coverage. Vet, build, formatting, and generated documentation were checked; the helper worktree required disabling VCS stamping for vet/build.

Standard conformance: 40 server checks and 239 client checks passed, zero failures.

Skills scenarios were rerun using conformance #330's chore/sep-2640-yaml branch at c4d79493f8013f18a7eb0bbe8aef584cff7b31aa, with temporary fixtures outside this PR:

Layer Protocol / HTTP mode Enumeration Manifest Directory Total
Protocol 2025-11-25 / stateful 30 6 7 43
Protocol 2026-07-28 / stateless 32 6 7 45
Filesystem helper 2025-11-25 / stateful 30 6 7 43
Filesystem helper 2026-07-28 / stateless 32 6 7 45

Zero failures or warnings. Legacy enumeration also has two version-conditioned skips.

@sambhav
sambhav force-pushed the skills-sep-2640 branch 3 times, most recently from adc1ddf to ca89d93 Compare September 4, 2026 17:02
@panyam

panyam commented Sep 4, 2026

Copy link
Copy Markdown

Woooot great to see this @sambhav. I ran the SEP-2640 conformance scenarios against this branch (conformance PR 330, the traceability extraction and server scenarios Il share soon for the skills extension). 41 checks, 0 failures.

Scenario Result
sep-2640-skills-enumeration 30/30
sep-2640-skills-manifest 4/4, 2 untestable
sep-2640-skills-directory 7/7

Repro, pointing a minimal skills.AddDirectory server at any skills tree:

node dist/index.js server --url http://localhost:18299/ \
  --scenario sep-2640-skills-enumeration --spec-version 2025-11-25 --force

Got three tiny notes (none blocking):

1. ttlMs and cacheScope are emitted on protocol 2025-11-25. In the SEP - "In protocol versions 2026-07-28 and later, the result also carries the base protocol's list-caching attributes". ttlMs does not appear in the 2025-11-25 schema at all, so this is emitting a field that is not defined in the negotiated version. We might want a version guard if it was not deliberate? If it was, this is a nice data point. I pointed out in PR 138 that it dropped the condition and was wondering if it was intention so looks like two efforts came to this point independently. So the condition itself may need to be removed instead of changing impls.

2. Two untestable SHOULD rows instead of passing. sep-2640-skillmd-metadata-name and -description check that the SKILL.md resource carries name and description from frontmatter. Since the dir utility serves through resource-template dispatch, SKILL.md is not in resources/list, so the metadata is not observable. I dont think this is a bug and I also do not think it needs changing, but figured Id flag it. A server registering SKILL.md as a listed resource does/would exercise those two.

3. Possible doc gap dueto needing flags against this branch. The runner defaults to the draft stateless wire. here it asserts MCP-Protocol-Version: 2026-07-28 with no handshake, so the server correctly refuses with -32022. --spec-version 2025-11-25 --force and selects the stateful wire and overrides the extension-applicability skip. The scenarios themselves are version-portable, they just do not advertise that. Just wanted to call this out.

@sambhav
sambhav force-pushed the skills-sep-2640 branch 2 times, most recently from 60744e4 to 36000a2 Compare September 4, 2026 21:59
@sambhav sambhav changed the title skills: add SEP-2640 support skills: add SEP-2640 protocol support Sep 4, 2026
@sambhav

sambhav commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

Thanks for running the SEP scenarios. The PR is now split so this one contains only the generic protocol layer. I addressed note 1 in the latest revision: skills/list now omits ttlMs and cacheScope before protocol version 2026-07-28, with regression coverage. Notes 2 and 3 make sense and do not require changes in this generic layer; the filesystem metadata behavior and usage notes will remain explicit in the follow-up helper PR.

@sambhav

sambhav commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

I reran conformance PR 330 locally against the split filesystem helper. It caught a nested YAML mapping normalization bug (metadata decoded to a non-JSON concrete map shape), now fixed with regression coverage. Final 2025-11-25 results: enumeration 29/29, manifest 4/4 with the two expected untestable metadata SHOULDs, and directory 7/7; no failures. The runner still needs --spec-version 2025-11-25 --force for this stateful fixture, as documented in conformance PR 330.

@sambhav

sambhav commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

The optional filesystem layer is now advertised as upstream draft #1240. While #1238 is pending, its GitHub Files changed view necessarily includes both stack commits; the clean helper-only diff is sambhav#1. I will rebase #1240 onto upstream main after this PR merges, then mark it ready.

@sambhav

sambhav commented Sep 5, 2026

Copy link
Copy Markdown
Member Author

@guglielmo-san 🙏 this is ready. There is another PR stacked on top which provides a neater abstraction and utility for skills with filesystems (#1240). Would appreciate it if we can land this one first and the other one as a quick follow.

Comment thread skills/client.go Outdated
Comment thread skills/client.go Outdated
Comment thread skills/server.go Outdated
Comment thread skills/client.go Outdated
Comment thread skills/server.go Outdated
Comment thread skills/server.go Outdated
Comment thread skills/validation.go Outdated
sambhav and others added 9 commits September 11, 2026 04:00
Replace the repeated result-type and cache-hint assignments in AddHandlers
with a single stampEnvelope helper that also validates the hints it settles
on, and route the protocol version, result type, and cache scope through
named constants instead of repeated literals.

paginate now skips the clone-and-sort when the catalog is already ordered,
and resolves a cursor with a binary search rather than a linear scan.
allPages allocates its seen set only once a server hands out a second
cursor, and rejects a cursor equal to the initial one.

parseSkillURI returns the parsed URL so validateResourceURI can reuse it
instead of reparsing the skill root for every resource.

mcp: factor the SDK default capabilities into defaultCapabilities so that
AddExtension and capabilities cannot drift apart.

conformance/skills-server: index skills by URI instead of rescanning the
entry slice, and use path.Base for display names.

scripts: factor the repeated argument check into require_value and simplify
the work-directory setup.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mcp/mrtr.go imports golang.org/x/sync/errgroup directly, so the "// indirect"
marking was stale and `go mod tidy -diff` reported a pending change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Group the package tests by what they exercise: validation_test.go holds the
pure unit tables, protocol_test.go the wire behavior, skills_test.go the
shared helpers and API contracts, and limits_test.go the manifest caps.

The limits matrix now calls ValidateSkillWithLimits directly instead of
standing up a streamable HTTP server per combination, taking that test from
24 connections to 4. TestLimitsArePlumbed keeps one end-to-end case per side
to prove Client.Limits and ServerOptions.Limits reach validation.

TestSpecErrorScenarios collects the cases that the sep-2640-skills-*
conformance scenarios also cover behind a single server, and carries a note
to delete it once those scenarios run in CI against ./conformance/skills-server.

Statement coverage rises from 82.2% to 90.8%.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@guglielmo-san

Copy link
Copy Markdown
Contributor

There are some changes that are unrelated to the skills SEP, can you remove them from this PR to allow an easier review?

  • scripts/server-conformance.sh
  • conformance/skills-server/main.go
  • CONTRIBUTING.md / internal/readme/contributing.src.md
  • auth/extauth bullet in README.md, internal/readme/README.src.md, docs/README.md and internal/docs/README.src.md: unrelated. Keep only the skills bullet.
  • Intro paragraph of internal/docs/README.src.md
  • Pagination section of internal/docs/server.src.md
  • go.mod: moving golang.org/x/sync from indirect to direct concerns mcp/mrtr.go, not Skills. Only the gopkg.in/yaml.v3 addition is needed.

@yarolegovich yarolegovich self-assigned this Oct 7, 2026
Comment thread skills/validation.go
Comment thread skills/server.go
Comment thread skills/client.go Outdated
Comment thread skills/client.go Outdated
… resource checks

Accept opt-in SkipInvalidSkills with diagnostics, require resource capabilities,
remove configurable client caps, and register custom methods automatically.
Update against main and remove unrelated conformance, documentation, and
x/sync classification changes from the protocol PR.

sambhav commented Oct 9, 2026

Copy link
Copy Markdown
Member Author

Addressed the scope cleanup from 4 October in 21ad3c2: removed the conformance runner/fixture, CONTRIBUTING edits, unrelated auth/extauth bullets, docs intro/pagination edits, and x/sync reclassification. Only Skills documentation and its YAML dependency remain. Updated #1240 to include this protocol revision while preserving the filesystem provider; the helper-only comparison is now seven files. Both branches preserve their previous heads without force-pushing. Replied separately to all four current review threads. Full Go/race checks and standard + Skills conformance pass.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants