What it does
The ping method is a no-op health check that either side of an MCP connection can send at any time. The sender constructs a standard JSON-RPC 2.0 request with method "ping" and an empty params object (or omits params entirely), then waits for the peer to echo back an empty result object. No capability negotiation is required before sending ping — it is available from the moment the transport layer is connected, even before the initialize/initialized handshake completes. The full request/response cycle is minimal: the sender emits {"jsonrpc":"2.0","id":"<id>","method":"ping"} and the receiver must respond with {"jsonrpc":"2.0","id":"<id>","result":{}}. The round-trip confirms that the peer process is alive, the transport is not deadlocked, and the message loop is processing requests. Because the result object is always empty, any non-empty result field should be treated as a protocol violation and the connection should be considered suspect. Ping is especially valuable on long-poll or SSE transports where the underlying HTTP connection can silently drop without a TCP RST. Clients and servers typically schedule periodic pings (every 15–30 seconds of inactivity) rather than sending them on every request. If a ping times out, the caller should close the transport and attempt a reconnect rather than queuing further requests behind a stalled channel.
When to use
On suspected stale connections or for keepalive.
When NOT to use
On every request — it's a heartbeat, not telemetry.
Notes
No capability gating required
Unlike tools, resources, or prompts, ping does not require any entry in the server's or client's capabilities object returned during initialization. It is always legal to send, so you do not need to check a feature flag before issuing a keepalive ping.
Timeout and retry behavior
Set a short, fixed timeout on ping (1–5 seconds is typical). If the peer does not respond within that window, do not retry the same ping — treat the connection as dead and tear it down. Retrying a timed-out ping only delays failure detection and can mask a fully stalled message loop.
Error responses are protocol violations
A conforming peer must never return a JSON-RPC error in response to ping. If you receive an error object (any code) the remote implementation is non-conformant; log the anomaly and reconnect. The only valid response is a success result with an empty object {}.
Ordering with in-flight requests
Ping is a normal JSON-RPC request and shares the same message queue as all other requests. Sending a ping while other requests are in-flight is safe — each is matched by its own id field. However, a ping that receives a response proves only that the message loop reached that id, not that earlier in-flight requests have been processed.
Keepalive interval tuning
On SSE or streaming HTTP transports, idle connections are often closed by load balancers or proxies after 30–60 seconds. Send a ping every 15–20 seconds of inactivity (reset the timer on any real traffic) to stay well inside that window. On stdio transports pings are rarely needed because the child process exit is immediately observable via the OS.
Examples
Ping/Pong
{ "jsonrpc": "2.0", "id": 1, "method": "ping" } → { "jsonrpc": "2.0", "id": 1, "result": {} }
Common mistakes
❌ Pinging in a tight loop
✅ Use sparingly — once every 30–60s is plenty.