Skip to content

Support Capability Extensions per SEP-2133#405

Merged
koic merged 1 commit into
modelcontextprotocol:mainfrom
koic:capability_extensions
Jun 14, 2026
Merged

Support Capability Extensions per SEP-2133#405
koic merged 1 commit into
modelcontextprotocol:mainfrom
koic:capability_extensions

Conversation

@koic

@koic koic commented Jun 14, 2026

Copy link
Copy Markdown
Member

Motivation and Context

SEP-2133 (modelcontextprotocol/modelcontextprotocol#2133, merged for the 2026-07-28 spec release) establishes the extensions framework for MCP: both ClientCapabilities and ServerCapabilities gain an optional extensions member keyed by reverse-DNS extension identifiers
(e.g. "io.modelcontextprotocol/tasks", "com.example/feature"), with arbitrary extension-defined configuration objects as values and an empty object meaning "supported with no settings". Official extensions such as MCP Apps (SEP-1865) and the Tasks extension (SEP-2663) are layered on this field.

This mirrors the shape the TypeScript SDK merged (typescript-sdk#1630): plain declaration and passthrough, no registrar API and no key-format validation (the naming convention is documented instead).

  • MCP::Server::Capabilities gains support_extensions (repeated calls merge), accepts an :extensions key in its constructor hash, and includes extensions in to_h. The class was previously dead code: it was never required and Server.new only took plain hashes. It is now required by lib/mcp/server.rb, and Server.new(capabilities:) accepts either a plain Hash (as before) or a Capabilities instance.
  • Server-declared extensions appear in the initialize result; extensions the client declares during initialize were already stored verbatim and are readable via Server#client_capabilities[:extensions] and ServerSession#client_capabilities[:extensions] (now covered by tests).
  • MCP::Client#connect(capabilities:) already passes capabilities through verbatim; its documentation now covers the extensions member.

Resolves #378.

How Has This Been Tested?

  • New test/mcp/server/capabilities_test.rb covers the previously untested Capabilities class: empty default, constructor round-trip, extensions via constructor and support_extensions, merge semantics, nil tolerance, and omission from to_h when never declared.
  • New tests in test/mcp/server_test.rb assert that the initialize result carries declared extensions (from both a plain hash and a Capabilities instance) and that client-declared extensions are readable via Server#client_capabilities and ServerSession#client_capabilities.

Breaking Changes

None. extensions is additive and appears on the wire only when declared; servers constructed with plain capability hashes behave exactly as before.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

## Motivation and Context

SEP-2133 (modelcontextprotocol/modelcontextprotocol#2133, merged for
the 2026-07-28 spec release) establishes the extensions framework for MCP:
both `ClientCapabilities` and `ServerCapabilities` gain an optional `extensions`
member keyed by reverse-DNS extension identifiers
(e.g. `"io.modelcontextprotocol/tasks"`, `"com.example/feature"`), with arbitrary
extension-defined configuration objects as values and an empty object meaning
"supported with no settings". Official extensions such as MCP Apps (SEP-1865)
and the Tasks extension (SEP-2663) are layered on this field.

This mirrors the shape the TypeScript SDK merged (typescript-sdk#1630):
plain declaration and passthrough, no registrar API and no key-format validation
(the naming convention is documented instead).

- `MCP::Server::Capabilities` gains `support_extensions` (repeated calls merge),
  accepts an `:extensions` key in its constructor hash, and includes `extensions`
  in `to_h`. The class was previously dead code: it was never required and
  `Server.new` only took plain hashes. It is now required by `lib/mcp/server.rb`,
  and `Server.new(capabilities:)` accepts either a plain Hash (as before) or
  a `Capabilities` instance.
- Server-declared extensions appear in the `initialize` result;
  extensions the client declares during `initialize` were already stored verbatim and
  are readable via `Server#client_capabilities[:extensions]` and
  `ServerSession#client_capabilities[:extensions]` (now covered by tests).
- `MCP::Client#connect(capabilities:)` already passes capabilities through verbatim;
  its documentation now covers the `extensions` member.

Resolves modelcontextprotocol#378.

## How Has This Been Tested?

- New `test/mcp/server/capabilities_test.rb` covers the previously untested
  `Capabilities` class: empty default, constructor round-trip, extensions via
  constructor and `support_extensions`, merge semantics, nil tolerance,
  and omission from `to_h` when never declared.
- New tests in `test/mcp/server_test.rb` assert that the `initialize` result
  carries declared extensions (from both a plain hash and a `Capabilities` instance)
  and that client-declared extensions are readable via `Server#client_capabilities`
  and `ServerSession#client_capabilities`.

## Breaking Changes

None. `extensions` is additive and appears on the wire only when declared;
servers constructed with plain capability hashes behave exactly as before.
@koic koic merged commit 7f266d4 into modelcontextprotocol:main Jun 14, 2026
11 checks passed
@koic koic deleted the capability_extensions branch June 14, 2026 15:09
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.

SEP-2133: Extensions framework for MCP

2 participants