Class: Clacky::Mcp::HttpTransport
- Defined in:
- lib/clacky/mcp/http_transport.rb
Overview
MCP streamable-http transport (spec 2025-03-26).
One endpoint URL handles both client→server (POST) and server→client (SSE). We POST every JSON-RPC message; the server may respond with either:
- application/json → single response, deliver immediately
- text/event-stream → one or more "data:" SSE events, each a JSON-RPC msg
Session tracking: the server returns Mcp-Session-Id on the initialize response; we echo it on every subsequent request.
Constant Summary collapse
- DEFAULT_OPEN_TIMEOUT =
10- DEFAULT_READ_TIMEOUT =
120
Instance Method Summary collapse
- #alive? ⇒ Boolean
-
#initialize(name:, url:, headers: {}, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT) ⇒ HttpTransport
constructor
A new instance of HttpTransport.
- #on_message(&blk) ⇒ Object
- #send_message(payload) ⇒ Object
- #start ⇒ Object
- #stderr_tail(bytes: 4096) ⇒ Object
- #stop ⇒ Object
Constructor Details
#initialize(name:, url:, headers: {}, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT) ⇒ HttpTransport
Returns a new instance of HttpTransport.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/clacky/mcp/http_transport.rb', line 26 def initialize(name:, url:, headers: {}, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT) @name = name @uri = URI.parse(url) raise TransportError, "MCP server '#{name}' url is not http(s): #{url}" unless %w[http https].include?(@uri.scheme) @extra_headers = (headers || {}).transform_keys(&:to_s).transform_values(&:to_s) @open_timeout = open_timeout @read_timeout = read_timeout @session_id = nil @on_message = nil @lock = Monitor.new @alive = false @last_error = nil end |
Instance Method Details
#alive? ⇒ Boolean
51 52 53 |
# File 'lib/clacky/mcp/http_transport.rb', line 51 def alive? @alive end |
#on_message(&blk) ⇒ Object
74 75 76 |
# File 'lib/clacky/mcp/http_transport.rb', line 74 def (&blk) @on_message = blk end |
#send_message(payload) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/clacky/mcp/http_transport.rb', line 55 def (payload) raise TransportError, "transport stopped" unless @alive body = JSON.generate(payload) is_request = payload.is_a?(Hash) && payload.key?(:id) || (payload.is_a?(Hash) && payload.key?("id")) Thread.new do begin dispatch_post(body, is_request: is_request) rescue StandardError => e @last_error = e @on_message&.call({ "id" => payload[:id] || payload["id"], "error" => { "code" => -32000, "message" => "HTTP transport error: #{e.}" } }) end end end |
#start ⇒ Object
42 43 44 45 |
# File 'lib/clacky/mcp/http_transport.rb', line 42 def start @alive = true self end |
#stderr_tail(bytes: 4096) ⇒ Object
78 79 80 |
# File 'lib/clacky/mcp/http_transport.rb', line 78 def stderr_tail(bytes: 4096) @last_error ? "last error: #{@last_error.class}: #{@last_error.}" : "" end |
#stop ⇒ Object
47 48 49 |
# File 'lib/clacky/mcp/http_transport.rb', line 47 def stop @alive = false end |