Class: LittleGhost::MCP::HTTPTransport
- Inherits:
-
Object
- Object
- LittleGhost::MCP::HTTPTransport
- Defined in:
- lib/little_ghost/mcp/client.rb
Overview
HTTPTransport sends MCP JSON-RPC messages over Streamable HTTP. It applies time and response-size limits and keeps the negotiated MCP session ID.
Security and trust
HTTPS is required by default. allow_insecure_http is only for an
explicitly trusted local development endpoint. Scope caller-supplied
credential headers to the target server. Response bodies and negotiated
session IDs are validated before use.
One transport instance retains one negotiated MCP session ID and sends it with later requests. Scope the transport and its Client to one trusted server and one authenticated principal; never share that pair across tenants. LittleGhost does not send MCP session-termination DELETE requests, so configure server-side expiry or manage that lifecycle outside this transport when the server requires explicit cleanup.
Constant Summary collapse
- DEFAULT_MAX_RESPONSE_BYTES =
Default upper bound for one MCP response body (10 MiB).
10 * 1024 * 1024
- SESSION_ID_PATTERN =
:nodoc:
/\A[\x21-\x7e]{1,256}\z/
Instance Method Summary collapse
-
#initialize(url:, headers: {}, timeout: 60, signer: nil, allow_insecure_http: false, max_response_bytes: DEFAULT_MAX_RESPONSE_BYTES) ⇒ HTTPTransport
constructor
Configures time and response-size limits.
-
#send(payload, context: nil) ⇒ Object
Sends one JSON-RPC payload.
Constructor Details
#initialize(url:, headers: {}, timeout: 60, signer: nil, allow_insecure_http: false, max_response_bytes: DEFAULT_MAX_RESPONSE_BYTES) ⇒ HTTPTransport
Configures time and response-size limits. signer, when
supplied, is called with each Net::HTTP request before it is sent.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/little_ghost/mcp/client.rb', line 38 def initialize(url:, headers: {}, timeout: 60, signer: nil, allow_insecure_http: false, max_response_bytes: DEFAULT_MAX_RESPONSE_BYTES) @uri = URI(url) unless %w[http https].include?(@uri.scheme) && @uri.host raise ConfigurationError, "MCP URL must be an HTTP(S) URL" end if @uri.scheme == "http" && !allow_insecure_http raise ConfigurationError, "MCP URL must use HTTPS unless allow_insecure_http is enabled" end @headers = headers.transform_keys(&:to_s).freeze @timeout = Float(timeout) raise ArgumentError, "timeout must be positive" unless @timeout.positive? @max_response_bytes = Integer(max_response_bytes) raise ArgumentError, "max_response_bytes must be positive" unless @max_response_bytes.positive? @signer = signer @session_id = nil end |
Instance Method Details
#send(payload, context: nil) ⇒ Object
Sends one JSON-RPC payload. A RunContext supplies cancellation and a deadline; without it the configured timeout applies.
61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/little_ghost/mcp/client.rb', line 61 def send(payload, context: nil) return perform_send(payload, timeout: @timeout) unless context response = nil stream = Support::InterruptibleStream.new( cancellation_token: context.cancellation_token, deadline: context.deadline ) do |emit| emit.call(perform_send(payload, timeout: context.remaining_time(@timeout))) end stream.each { |value| response = value } response end |