Skip to content

Remove Server#create_sampling_message direct call#311

Merged
koic merged 1 commit intomodelcontextprotocol:mainfrom
koic:remove_server_sampling_direct_call
Apr 14, 2026
Merged

Remove Server#create_sampling_message direct call#311
koic merged 1 commit intomodelcontextprotocol:mainfrom
koic:remove_server_sampling_direct_call

Conversation

@koic
Copy link
Copy Markdown
Member

@koic koic commented Apr 12, 2026

Motivation and Context

Sampling is a one-to-one request/response interaction between a server and a specific client. Server#create_sampling_message does not scope requests to a specific session, which could lead to unintended broadcasts on multi-client transports. ServerSession#create_sampling_message should be used instead, as it routes the request to the correct client session.

This aligns with the Python SDK, which also exposes sampling only at the session level.

How Has This Been Tested?

Existing tests updated to call ServerSession#create_sampling_message instead of Server#create_sampling_message. All tests pass (rake test), RuboCop is clean, and conformance tests pass.

Breaking Changes

Server#create_sampling_message is removed without a deprecation warning. The sampling feature was released recently and the method was not intended to be the primary API for this feature.

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

Sampling is a one-to-one request/response interaction between a server and a specific client.
`Server#create_sampling_message` does not scope requests to a specific session, which could
lead to unintended broadcasts on multi-client transports. `ServerSession#create_sampling_message`
should be used instead, as it routes the request to the correct client session.

This aligns with the Python SDK, which also exposes sampling only at the session level.

## How Has This Been Tested?

Existing tests updated to call `ServerSession#create_sampling_message` instead of
`Server#create_sampling_message`. All tests pass (`rake test`), RuboCop is clean,
and conformance tests pass.

## Breaking Changes

`Server#create_sampling_message` is removed without a deprecation warning.
The sampling feature was released recently and the method was not intended
to be the primary API for this feature.
Copy link
Copy Markdown
Member

@jonathanhefner jonathanhefner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vibe-reviewed. Claude says: "Clean, well-motivated change that aligns the Ruby SDK with the Python SDK's session-scoped sampling design. The removal eliminates a real footgun (server-level sampling on multi-client transports), the test coverage is properly updated, and the diff is net-negative (26 additions, 287 deletions)."

@koic koic merged commit 7a3259d into modelcontextprotocol:main Apr 14, 2026
11 checks passed
@koic koic deleted the remove_server_sampling_direct_call branch April 14, 2026 17:33
koic added a commit that referenced this pull request Apr 17, 2026
## Motivation and Context

MCP spec (2025-11-25) defines Roots as a mechanism for clients to expose filesystem boundaries
(directories and files) to servers:
https://modelcontextprotocol.io/specification/2025-11-25/client/roots

This enables servers to understand which parts of the filesystem they can operate on.

This adds support for the two roots protocol interactions:

- `roots/list` -- server-to-client request to retrieve the client's filesystem roots
- `notifications/roots/list_changed` -- client-to-server notification when roots change

`roots/list` is a one-to-one request between a server and a specific client,
so `list_roots` is exposed only at the session level
(`ServerSession#list_roots`), matching the Python SDK approach and aligning with PR #311 for sampling.

`Server#on_roots_list_changed` registers a callback for the client notification,
which is server-wide and does not require session scoping.

Also fixes `notifications/roots/list_changed` capability checking: as a client-originated notification,
it should not require server-side capability declaration.

## How Has This Been Tested?

New test file `test/mcp/server_roots_test.rb` with 8 test cases covering session-scoped `list_roots`,
capability validation and fallback, `on_roots_list_changed` callback registration, and client capability storage.
Updated `test/mcp/methods_test.rb` to reflect the corrected capability checks. All tests pass (`rake test`),
RuboCop is clean.

## Breaking Changes

None.
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.

2 participants