Module: MCPClient::ServerSSE::JsonRpcTransport
- Includes:
- JsonRpcCommon, OriginPolicy
- Included in:
- MCPClient::ServerSSE
- Defined in:
- lib/mcp_client/server_sse/json_rpc_transport.rb
Overview
JSON-RPC request/notification plumbing for SSE transport
Constant Summary collapse
- NO_RESULT =
Returned by #check_for_result when nothing has arrived for the request yet. The stored result is whatever
resultmember the response carried, sonullandfalseare answers the client must deliver (and validate) rather than truthiness the waiter can read as "still outstanding" — doing that waited out the whole read timeout and cancelled a request the server had already answered. Object.new.freeze
Constants included from JsonRpcCommon
JsonRpcCommon::CORE_RESULT_TYPES, JsonRpcCommon::EXTENSION_ID_PATTERN, JsonRpcCommon::INPUT_RETRY_DELAY, JsonRpcCommon::INPUT_RETRY_MAX_DELAY, JsonRpcCommon::LEGACY_RESULT_TYPES, JsonRpcCommon::LOG_LEVELS, JsonRpcCommon::MAX_INPUT_ROUND_TRIPS, JsonRpcCommon::MAX_PEER_LOG_TEXT_LENGTH, JsonRpcCommon::MRTR_METHODS, JsonRpcCommon::NAME_HEADER_SOURCES, JsonRpcCommon::NON_IDEMPOTENT_METHODS, JsonRpcCommon::REMOVED_MODERN_NOTIFICATIONS, JsonRpcCommon::RESULT_TYPE_EXTENSIONS, JsonRpcCommon::TASKS_EXTENSION, JsonRpcCommon::TASK_METHODS
Constants included from MCPClient::SessionPin
MCPClient::SessionPin::SESSION_PINS, MCPClient::SessionPin::WRITE_GUARDS
Constants included from RequestMetadata
RequestMetadata::CACHE_NEUTRAL_META_KEYS, RequestMetadata::META_CLIENT_CAPABILITIES, RequestMetadata::META_CLIENT_INFO, RequestMetadata::META_LOG_LEVEL, RequestMetadata::META_PROTOCOL_VERSION, RequestMetadata::META_SERVER_INFO, RequestMetadata::META_SUBSCRIPTION_ID, RequestMetadata::OPAQUE_PARAMS, RequestMetadata::PROTECTED_META_KEYS, RequestMetadata::UNRECORDED_PARAMS
Constants included from ResultCaching
ResultCaching::CACHE_INIT_LOCK, ResultCaching::LEGACY_ENTRY, ResultCaching::LIST_CHANGE_NOTIFICATIONS, ResultCaching::LIST_METHOD_KINDS, ResultCaching::LIST_VALUE_KINDS, ResultCaching::MAX_CACHED_READS, ResultCaching::MAX_READ_GENERATIONS, ResultCaching::PLACEHOLDER_KINDS
Constants included from InputRoundTrips
InputRoundTrips::INPUT_REQUEST_HANDLERS
Constants included from MCPClient::SubscriptionSupport
MCPClient::SubscriptionSupport::CONTROL_NOTIFICATIONS, MCPClient::SubscriptionSupport::DEFAULT_ACK_TIMEOUT
Constants included from JsonRpcCommon::ErrorBodies
JsonRpcCommon::ErrorBodies::MAX_ERROR_BODY_BYTES
Instance Attribute Summary
Attributes included from JsonRpcCommon
#request_meta, #send_client_info
Instance Method Summary collapse
-
#rpc_notify(method, params = {}) ⇒ void
Send a JSON-RPC notification (no response expected).
-
#rpc_request(method, params = {}, timeout: nil) ⇒ Object
Generic JSON-RPC request: send method with params and return result.
-
#send_cancellation_notification(request_id) ⇒ void
Best-effort notifications/cancelled for a request the client stopped waiting on.
-
#send_one_request(method, params, timeout) ⇒ Object
One request on the wire: build it, send it and wait for its answer.
Methods included from JsonRpcCommon
#accepted_result_types, #apply_discover_result, #begin_era_probe, #build_jsonrpc_notification, #build_jsonrpc_request, #build_named_request_params, #cancellable_request?, #client_capabilities, #client_info_payload, #declare_extension, #declare_sampling_tools, #declared_extensions, #describe_body_size, #describe_jsonrpc_message, #describe_parse_error, #discovery_cache_scope, #discovery_clock, #discovery_fresh?, #encode_header_value, #era_probe_in_flight?, #host_request_meta, #implemented_extension_result_types, #initialization_params, #mcp_name_header_value, #merge_meta_spellings, #modern?, #modern_request_headers, #notify_cache_invalidation, #ping, #process_jsonrpc_response, #protocol_era, #protocol_version, #record_discovery_freshness, #record_server_info, #refused_undeclared_sampling_tools?, #registered_callback?, #reject_task_result_discover!, #reject_task_result_on_unsupported_method!, #request_meta_claim, #required_request_meta, #reserved_meta_supplied?, #resolve_input_round_trips, restore_wire_keys, result_type, #sampling_tools_supported?, #sanitize_log_text, #select_protocol_version, #send_client_info?, #settle_era_probe, #spend_held_request_meta, #split_request_meta, #supported_versions, #suppressed_modern_notification?, #tasks_extension_declared?, #validate_log_level!, #validate_protocol_version!, #validate_result_type!, #with_request_meta, #with_retry
Methods included from MCPClient::SessionPin
#check_session_pin!, #guarded_writes, #pinned_to_session, #unpinned_session
Methods included from RequestMetadata
#adoptable_request_meta_hold, #claimable_request_meta_hold, #close_request_meta_hold, #current_params_fingerprint, #deep_sort_keys, #held_request_meta, #held_request_meta_key, #holding_request_meta, #note_request_params, #note_request_params_pending, #offer_request_meta_hold, #offered_request_meta_key, #open_request_meta_hold, #outside_request_meta_hold, #params_fingerprint_of, #recorded_request_params, #release_held_request_meta, #request_params_fingerprint, #request_params_key, #restore_request_params, #take_offered_request_meta_hold, #withdraw_request_meta_hold
Methods included from ResultCaching
#assume_zero_ttl?, #attach_list_value, #authorization_fingerprint, authorization_header_value, #authorization_header_value, #bind_authorization_context, #bump_cache_epoch, #bump_cache_generation, #cache_entries, #cache_entries_mutex, #cache_entry_for, #cache_entry_fresh?, #cache_entry_hinted?, #cache_entry_token, #cache_epoch, #cache_fresh?, #cache_generation, #cache_info, #cached_list_value, #clear_response_received_at, #clear_result_cache, #discard_paginated_list, #empty_list_copy?, #entry_for_current_params?, #entry_in_current_context?, #entry_matches_authorization?, faraday_headers, #faraday_headers, #fetching_list_page, #forget_served_entries, #forget_transport_thread_state, #fresh_list_value, #hinted_list_value, #invalid_cursor_error?, #invalidate_cache, #invalidate_cache_for_notification, #invalidate_read_cache, #list_cache_epoch, #list_kind_for, #mixed_pages_placeholder, #monotonic_now, #note_legacy_served, #note_response_received_at, #note_served_entry, #on_cache_invalidation, #private_entry_for_current_context, #prune_read_entries, #read_cache_key, #read_resource_with_cache, #record_cache_hint, #record_list_cache_hint, #record_paginated_cache_hint, #recorded_entries_key, #release_serving_request_meta, #remember_recorded_entry, #response_received_at, #response_received_key, #sent_authorization_known?, #served_entries_key, #stale_fallback_for, #stale_list_entry, #stale_list_value, #store_read_entry, #take_served_entry, #transport_thread_local_keys
Methods included from InputRoundTrips
#fulfil_input_request, #fulfil_input_requests, #undeclared_sampling_tool_use?
Methods included from MCPClient::SubscriptionSupport
#await_acknowledgment_deadline, #close_subscription_gracefully, #confirm_resource_subscription, #deliver_subscription_notification, #discard_mapped_resource_subscription, #drop_unacknowledged_resource_subscriptions, #ensure_modern_listen!, #expire_unacknowledged_subscription, #handle_server_cancellation, #handle_subscription_acknowledgment, #handle_subscription_control, #handle_subscription_response, #listen, #live_resource_subscription, #notify_host, #open_listen, #open_resource_subscription, #rearm_acknowledgment_deadline, #recheck_mapped_resource_subscription, #register_subscription, #report_declined_subscription_types, #require_resource_watch, #resource_subscription_mutex, #resource_subscription_mutexes, #resource_subscriptions, #route_notification, #settled_resource_subscription, #subscribe_resource_via_listen, #subscription_ack_timeout, #subscription_by_id, #subscription_delivery_target, #subscription_for_notification, #subscriptions, #subscriptions_mutex, #unmap_resource_subscription, #unregister_subscription, #unregister_subscription_id, #unsubscribe_resource_via_listen
Methods included from DeprecationNotices
#warn_input_request_answer_deprecated, #warn_input_request_deprecated, #warn_logging_deprecated, #warn_request_log_level_deprecated, #warn_roots_deprecated, #warn_sampling_deprecated
Methods included from JsonRpcCommon::InputWaits
#on_input_required_wait, #reject_input_required_discover!, #resume_input_required
Methods included from JsonRpcCommon::ErrorBodies
#decoded_error_body, #gunzip_bounded, #jsonrpc_error_from_http_response, #jsonrpc_error_in_body, #oversized_error_body?
Methods included from OriginPolicy
#origin_of, #reject_cross_origin_redirect!, #same_origin?
Instance Method Details
#rpc_notify(method, params = {}) ⇒ void
This method returns an undefined value.
Send a JSON-RPC notification (no response expected)
74 75 76 77 78 79 80 |
# File 'lib/mcp_client/server_sse/json_rpc_transport.rb', line 74 def rpc_notify(method, params = {}) ensure_initialized notif = build_jsonrpc_notification(method, params) post_json_rpc_request(notif) rescue MCPClient::Errors::ServerError, MCPClient::Errors::ConnectionError, Faraday::ConnectionFailed => e raise MCPClient::Errors::TransportError, "Failed to send notification: #{e.}" end |
#rpc_request(method, params = {}, timeout: nil) ⇒ Object
Generic JSON-RPC request: send method with params and return result
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/mcp_client/server_sse/json_rpc_transport.rb', line 30 def rpc_request(method, params = {}, timeout: nil) ensure_initialized # The multi round-trip resolver sits outside the per-attempt retry, so # a retry carrying inputResponses/requestState keeps them through # transport retries — the same shape as the other transports, so an # input_required answer is validated and fulfilled here as well. resolve_input_round_trips(method, params, timeout) do |attempt_params| with_retry(method) { send_one_request(method, attempt_params, timeout) } end end |
#send_cancellation_notification(request_id) ⇒ void
This method returns an undefined value.
Best-effort notifications/cancelled for a request the client stopped waiting on. Failures are swallowed.
62 63 64 65 66 67 68 |
# File 'lib/mcp_client/server_sse/json_rpc_transport.rb', line 62 def send_cancellation_notification(request_id) notif = build_jsonrpc_notification('notifications/cancelled', { 'requestId' => request_id, 'reason' => 'Request timed out' }) post_json_rpc_request(notif) rescue StandardError => e @logger.debug("Failed to send cancellation notification: #{e.}") end |
#send_one_request(method, params, timeout) ⇒ Object
One request on the wire: build it, send it and wait for its answer.
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/mcp_client/server_sse/json_rpc_transport.rb', line 47 def send_one_request(method, params, timeout) request_id = @mutex.synchronize { @request_id += 1 } request = build_jsonrpc_request(method, params, request_id) send_jsonrpc_request(request, timeout: timeout) rescue MCPClient::Errors::RequestTimeoutError # MCP lifecycle: on timeout the sender SHOULD issue a cancellation # notification for the abandoned request and stop waiting. send_cancellation_notification(request_id) if request_id && cancellable_request?(method, params) raise end |