ruby-sdk/docs/_server/ping.md
Koichi ITO 7e507f2963 [Doc] Document the client's ping answers and the stdio request limit
## Motivation and Context

The client answers server pings automatically, but the docs leave out where that applies and what the stdio transport
does with the other server-to-client requests.

The client Transports page now lists the automatic ping answer among the things the stdio transport handles,
and a note states that `ping` is the only server-to-client request answered there: a wire-level `elicitation/create`
or `sampling/createMessage` is ignored over stdio, so a server that sends one waits for an answer that never comes,
while the SEP-2322 `input_required` route works on every transport and keeps `on_elicitation` and `on_sampling` handlers
working over stdio. Without this note, the only trace of the limitation is a hung tool call.

The client Ping page now says that over HTTP a ping reaches the client only on a stream that is already open
and that the client never opens one to receive pings, so a server can only ping a client that has a stream open.
Registering `on_server_request("ping")` moves to the end of the section as the advanced option it is, together with
its side effect of opening the GET listening stream on `connect`.

The client overview mentions the automatic answer next to `MCP::Client#ping`,
and the server Ping page's Client Side section points at it.

## How Has This Been Tested?

Documentation only; the linked headings and pages exist.

## Breaking Changes

None.
2026-09-12 00:02:36 +09:00

52 lines
2.3 KiB
Markdown

---
layout: default
title: Ping
nav_order: 15
---
# Ping
The MCP Ruby SDK supports
the [MCP `ping` utility](https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/ping),
which allows either side of the connection to verify that the peer is still responsive.
A `ping` request has no parameters, and the receiver MUST respond promptly with an empty result.
{: .note }
> `ping` belongs to the handshake lifecycle: MCP 2026-07-28 removes the method altogether (SEP-2575),
> since requests of the [modern lifecycle](/server/discover/#the-stateless-modern-lifecycle) are single POST exchanges whose connection
> itself signals liveness, leaving nothing to probe between requests. The server answers `ping` on
> the handshake lifecycle only - a modern request naming it is rejected with `-32601` Method not found -
> and calling `ping` on a `server_context` while serving a modern request raises an error. The long-lived
> [`subscriptions/listen`](/server/subscriptions/) stream is kept alive by SSE keepalive
> frames instead.
Servers respond to incoming `ping` requests automatically - no setup is required.
Any `MCP::Server` instance replies with an empty result.
Servers can also send `ping` requests to the client via `ServerSession#ping`.
`ping` is exempt from the SEP-2260 association requirement, so it may also be sent outside a handler.
Inside a tool handler that receives [`server_context:`](/server/server-context/), call `ping` on it:
```ruby
class HealthCheckTool < MCP::Tool
description "Verifies the client is still responsive"
def self.call(server_context:)
server_context.ping # => {} on success
MCP::Tool::Response.new([{ type: "text", text: "client is alive" }])
end
end
```
`#ping` raises `MCP::Server::ValidationError` when the client returns a `result`
that is not a Hash. Transport-level errors (e.g., the client returning a JSON-RPC error)
propagate as exceptions raised by the transport layer.
Server-to-client requests are bounded by a timeout on the Streamable HTTP transport; see [Timeouts](/server/elicitation/#timeouts).
## Client Side
Pinging the server with `MCP::Client#ping` is documented on the client [Ping](/client/ping/) page.
The Ruby client answers the pings sent with `ServerSession#ping` automatically;
see [Answering Server Pings](/client/ping/#answering-server-pings).