Skip to content

Support server-to-client ping per MCP specification#358

Open
koic wants to merge 1 commit into
modelcontextprotocol:mainfrom
koic:ping_server_to_client
Open

Support server-to-client ping per MCP specification#358
koic wants to merge 1 commit into
modelcontextprotocol:mainfrom
koic:ping_server_to_client

Conversation

@koic
Copy link
Copy Markdown
Member

@koic koic commented May 22, 2026

Motivation and Context

The MCP specification defines ping as a bidirectional utility: either party may issue it. https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/ping

The previous PR added MCP::Client#ping. This PR adds the symmetric server-side send capability, ServerSession#ping.

This aligns the Ruby SDK with the Python SDK (ServerSession.send_ping) and the TypeScript SDK (Server.ping()), both of which expose a server-initiated ping. In practice this enables a Ruby MCP server to health-check non-Ruby clients (e.g., Claude Desktop, the Python or TypeScript SDK client) during long-running tool operations.

Scope is intentionally server-only: this PR does not add client-side inbound request dispatch, which is a larger refactor outside the ping utility. A Ruby MCP::Client therefore still cannot receive a server-initiated ping; that gap is tracked as a separate follow-up.

How Has This Been Tested?

New file test/mcp/server_session_ping_test.rb covers:

  • success (empty result returned)
  • related_request_id propagated through the transport when a session ID is set
  • ValidationError when the transport returns nil
  • ValidationError when the transport returns a non-Hash result
  • transport-level errors propagate unchanged
  • ping succeeds without any client capability declaration (per spec, ping has no capability gate)

test/mcp/server_context_test.rb adds two tests for ServerContext#ping delegation (happy path and NoMethodError when the session lacks #ping).

The existing server-side ping handler tests continue to pass unchanged.

Breaking Changes

None. MCP::ServerContext#ping and MCP::Server::ValidationError are purely additive.

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

The MCP specification defines `ping` as a bidirectional utility: either party may issue it.
https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/ping

The previous PR added `MCP::Client#ping`. This PR adds the symmetric server-side send capability,
`ServerSession#ping`.

This aligns the Ruby SDK with the Python SDK (`ServerSession.send_ping`) and
the TypeScript SDK (`Server.ping()`), both of which expose a server-initiated ping.
In practice this enables a Ruby MCP server to health-check non-Ruby clients
(e.g., Claude Desktop, the Python or TypeScript SDK client) during long-running tool operations.

Scope is intentionally server-only: this PR does not add client-side inbound request dispatch,
which is a larger refactor outside the ping utility. A Ruby `MCP::Client` therefore still cannot receive
a server-initiated ping; that gap is tracked as a separate follow-up.

## How Has This Been Tested?

New file `test/mcp/server_session_ping_test.rb` covers:

- success (empty `result` returned)
- `related_request_id` propagated through the transport when a session ID is set
- `ValidationError` when the transport returns `nil`
- `ValidationError` when the transport returns a non-Hash `result`
- transport-level errors propagate unchanged
- ping succeeds without any client capability declaration (per spec, ping has no capability gate)

`test/mcp/server_context_test.rb` adds two tests for `ServerContext#ping` delegation
(happy path and `NoMethodError` when the session lacks `#ping`).

The existing server-side `ping` handler tests continue to pass unchanged.

## Breaking Changes

None. `MCP::ServerContext#ping` and `MCP::Server::ValidationError` are purely additive.
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