## 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.
49 lines
2.5 KiB
Markdown
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.
|