mcp: add configurable keepalive failure threshold (#982)

mcp: add configurable keepalive failure threshold

Introduce `KeepAliveFailureThreshold` option in both `ClientOptions` and
`ServerOptions` to control how many consecutive keepalive ping failures
are tolerated before closing the session.

This aligns with the MCP spec's guidance that "multiple failed pings MAY
trigger a connection reset," allowing operators to tune resilience
against transient network hiccups without immediately tearing down
otherwise healthy sessions.

A threshold of 0 or 1 (the default) closes on the first failure,
preserving existing behavior. Higher values let isolated misses pass
while still closing the session once consecutive failures reach the
threshold. A successful ping resets the counter.

Tolerated failures are logged at WARN level; the final failure that
closes the session is logged at ERROR level.

This is rework of #979.
This commit is contained in:
Tomas Dabašinskas 2026-05-31 11:25:49 +03:00 • committed by GitHub
commit 8805aa85f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -79,6 +79,13 @@ type ServerOptions struct {
// If the peer fails to respond to pings originating from the keepalive check,
// the session is automatically closed.
KeepAlive time.Duration
// KeepAliveFailureThreshold is the number of consecutive keepalive ping
// failures tolerated before the session is closed. A value of 0 or 1
// closes the session on the first failure (the default). Higher values
// align with the spec's "multiple failed pings MAY trigger a connection
// reset" guidance, letting a transient miss pass without tearing down an
// otherwise live session. Has no effect unless KeepAlive is non-zero.
KeepAliveFailureThreshold int
// Function called when a client session subscribes to a resource.
SubscribeHandler func(context.Context, *SubscribeRequest) error
// Function called when a client session unsubscribes from a resource.
@ -1605,7 +1612,7 @@ func (ss *ServerSession) Wait() error {
// startKeepalive starts the keepalive mechanism for this server session.
func (ss *ServerSession) startKeepalive(interval time.Duration) {
startKeepalive(ss, interval, &ss.keepaliveCancel, ss.server.opts.Logger)
startKeepalive(ss, interval, ss.server.opts.KeepAliveFailureThreshold, &ss.keepaliveCancel, ss.server.opts.Logger)
}
// pageToken is the internal structure for the opaque pagination cursor.