ruby-sdk/docs/_client/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

49 lines
2.5 KiB
Markdown

---
layout: default
title: Ping
nav_order: 6
---
# Ping
The [MCP `ping` utility](https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/ping)
allows either side of the connection to verify that the peer is still responsive.
{: .note }
> MCP 2026-07-28 removes `ping` from the protocol (SEP-2575): requests of
> the [modern lifecycle](/client/lifecycle/) are single POST exchanges whose connection itself
> signals liveness. `#ping` sends the request regardless of the negotiated lifecycle,
> so on a modern connection a conforming server (the Ruby SDK server included) rejects it
> with `-32601` Method not found and `ServerError` is raised; ping is a handshake-lifecycle utility.
`MCP::Client` exposes `ping` to send a ping to the server:
```ruby
client = MCP::Client.new(transport: transport)
client.ping # => {} on success
```
`#ping` raises `MCP::Client::ServerError` when the server returns a JSON-RPC error.
It raises `MCP::Client::ValidationError` when the response `result` is missing or
is not a Hash (matching the spec requirement that `result` be an object).
Transport-level errors (for example, `MCP::Client::Stdio`'s `read_timeout:` firing)
propagate as exceptions raised by the transport layer.
## Answering Server Pings
On handshake-lifecycle connections a server may ping the client the same way, and the client answers automatically with
the empty result - no handler is needed. Over HTTP a ping reaches the client only on a stream that is already open
(the SSE response of an in-flight POST, or the GET listening stream); the client never opens a stream just to receive pings.
Over stdio, a ping that arrives while a response is awaited is answered inline; between requests it is answered when
the next request starts reading. The answer is best effort: a pong that cannot be written (for example, over a broken pipe) is
dropped rather than failing the request whose response is being read. Independently of pings, consider setting `read_timeout:`
on `MCP::Client::Stdio`, since a server that never answers otherwise holds the read until the process exits.
To answer pings yourself, register `transport.on_server_request("ping")` on `MCP::Client::HTTP`; it replaces
the automatic answer and, like any handler registered there, opens the standalone GET listening stream on `connect`,
as described on the [Transports](/client/transports/#server-to-client-requests-elicitation) page.
## Server Side
How servers answer `ping` requests and ping the client themselves is documented on
the server [Ping](/server/ping/) page.