Skip to content

Commit 7e507f2

Browse files
committed
[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.
1 parent 91ee5a2 commit 7e507f2

4 files changed

Lines changed: 18 additions & 3 deletions

File tree

‎docs/_client/index.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ This class supports:
1717
- Lifecycle negotiation and connection via `MCP::Client#connect`, adopting the modern lifecycle
1818
when the server serves it; see [Lifecycle](/client/lifecycle/)
1919
- Server discovery via the `server/discover` method (`MCP::Client#discover`); see [Explicit Discovery](/client/lifecycle/#explicit-discovery)
20-
- Liveness check via the `ping` method (`MCP::Client#ping`)
20+
- Liveness check via the `ping` method (`MCP::Client#ping`), and automatic answers to server pings;
21+
see [Answering Server Pings](/client/ping/#answering-server-pings)
2122
- Tool listing via the `tools/list` method (`MCP::Client#tools`)
2223
- Tool invocation via the `tools/call` method (`MCP::Client#call_tool`)
2324
- Resource listing via the `resources/list` method (`MCP::Client#resources`)

‎docs/_client/ping.md‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@ propagate as exceptions raised by the transport layer.
3232
## Answering Server Pings
3333

3434
On handshake-lifecycle connections a server may ping the client the same way, and the client answers automatically with
35-
the empty result - no handler is needed. Registering `transport.on_server_request("ping")` on `MCP::Client::HTTP` replaces
36-
the automatic answer.
35+
the empty result - no handler is needed. Over HTTP a ping reaches the client only on a stream that is already open
36+
(the SSE response of an in-flight POST, or the GET listening stream); the client never opens a stream just to receive pings.
3737
Over stdio, a ping that arrives while a response is awaited is answered inline; between requests it is answered when
3838
the next request starts reading. The answer is best effort: a pong that cannot be written (for example, over a broken pipe) is
3939
dropped rather than failing the request whose response is being read. Independently of pings, consider setting `read_timeout:`
4040
on `MCP::Client::Stdio`, since a server that never answers otherwise holds the read until the process exits.
4141

42+
To answer pings yourself, register `transport.on_server_request("ping")` on `MCP::Client::HTTP`; it replaces
43+
the automatic answer and, like any handler registered there, opens the standalone GET listening stream on `connect`,
44+
as described on the [Transports](/client/transports/#server-to-client-requests-elicitation) page.
45+
4246
## Server Side
4347

4448
How servers answer `ping` requests and ping the client themselves is documented on

‎docs/_client/transports.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ The stdio transport automatically handles:
5959
- Spawning the server process with `Open3.popen3`
6060
- MCP protocol initialization handshake (`initialize` request + `notifications/initialized`)
6161
- JSON-RPC 2.0 message framing over newline-delimited JSON
62+
- Answering server `ping` requests; see [Answering Server Pings](/client/ping/#answering-server-pings)
63+
64+
{: .note }
65+
> `ping` is the only server-to-client request answered over stdio. A wire-level `elicitation/create`
66+
> or `sampling/createMessage` is ignored on this transport, so a server that sends one waits for an answer
67+
> that never comes; use Streamable HTTP for those, as described below. The SEP-2322 `input_required` route,
68+
> which is how the modern lifecycle asks for the same input, works on every transport, so `on_elicitation`
69+
> and `on_sampling` handlers still fire over stdio; see [Multi Round-Trip Requests](/client/mrtr/).
6270
6371
## HTTP Transport Layer
6472

‎docs/_server/ping.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,5 @@ Server-to-client requests are bounded by a timeout on the Streamable HTTP transp
4848
## Client Side
4949

5050
Pinging the server with `MCP::Client#ping` is documented on the client [Ping](/client/ping/) page.
51+
The Ruby client answers the pings sent with `ServerSession#ping` automatically;
52+
see [Answering Server Pings](/client/ping/#answering-server-pings).

0 commit comments

Comments
 (0)