Merge pull request #358 from koic/ping_server_to_client
Support server-to-client `ping` per MCP specification
This commit is contained in:
commit
aee8a0bfb6
3 changed files with 171 additions and 0 deletions
|
|
@ -67,6 +67,11 @@ module MCP
|
|||
end
|
||||
end
|
||||
|
||||
# Raised when a client response fails server-side validation, e.g., a success response
|
||||
# whose `result` field is missing or has the wrong type. This is distinct from a
|
||||
# client-returned JSON-RPC error.
|
||||
class ValidationError < StandardError; end
|
||||
|
||||
include Instrumentation
|
||||
include Pagination
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,28 @@ module MCP
|
|||
end
|
||||
end
|
||||
|
||||
# Sends a `ping` request to the originating client to verify it is still responsive.
|
||||
# Per the MCP spec, the client MUST respond promptly with an empty result.
|
||||
#
|
||||
# @return [Hash] An empty hash on success.
|
||||
# @raise [Server::ValidationError] If the response `result` is not a Hash.
|
||||
# @raise [NoMethodError] If the session does not support sending pings.
|
||||
#
|
||||
# @example
|
||||
# def self.call(server_context:)
|
||||
# server_context.ping # => {}
|
||||
# # ...
|
||||
# end
|
||||
#
|
||||
# @see https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/ping
|
||||
def ping
|
||||
if @notification_target.respond_to?(:ping)
|
||||
@notification_target.ping(related_request_id: @related_request_id)
|
||||
else
|
||||
raise NoMethodError, "undefined method 'ping' for #{self}"
|
||||
end
|
||||
end
|
||||
|
||||
# Delegates to the session so the request is scoped to the originating client.
|
||||
# Falls back to `@context` (via `method_missing`) when `@notification_target`
|
||||
# does not support sampling.
|
||||
|
|
|
|||
|
|
@ -106,6 +106,14 @@ module MCP
|
|||
send_to_transport_request(Methods::ROOTS_LIST, nil, related_request_id: related_request_id)
|
||||
end
|
||||
|
||||
# Sends a `ping` request scoped to this session.
|
||||
def ping(related_request_id: nil)
|
||||
result = send_to_transport_request(Methods::PING, nil, related_request_id: related_request_id)
|
||||
raise Server::ValidationError, "Response validation failed: invalid `result`" unless result.is_a?(Hash)
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
# Sends a `sampling/createMessage` request scoped to this session.
|
||||
def create_sampling_message(related_request_id: nil, **kwargs)
|
||||
params = @server.build_sampling_params(client_capabilities, **kwargs)
|
||||
|
|
|
|||
Loading…
Reference in a new issue