Class: Raix::MCP::SseClient

Inherits:
Object
  • Object
show all
Defined in:
lib/mcp/sse_client.rb

Overview

Client for communicating with MCP servers via Server-Sent Events (SSE).

Constant Summary collapse

PROTOCOL_VERSION =
"2024-11-05".freeze
CONNECTION_TIMEOUT =
10
OPEN_TIMEOUT =
30

Instance Method Summary collapse

Constructor Details

#initialize(url, headers: {}) ⇒ SseClient

Creates a new client and establishes SSE connection to discover the JSON-RPC endpoint.

Parameters:

  • url (String)

    the SSE endpoint URL



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/mcp/sse_client.rb', line 19

def initialize(url, headers: {})
  @url = url
  @endpoint_url = nil
  @sse_thread = nil
  @event_queue = Thread::Queue.new
  @buffer = ""
  @closed = false
  @headers = headers

  # Start the SSE connection and discover endpoint
  establish_sse_connection
end

Instance Method Details

#call_tool(name, **arguments) ⇒ Object

Executes a tool with given arguments. Returns text content directly, or JSON-encoded data for other content types.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/mcp/sse_client.rb', line 48

def call_tool(name, **arguments)
  request_id = SecureRandom.uuid
  send_json_rpc(request_id, "tools/call", name:, arguments:)

  # Wait for response through SSE
  response = wait_for_response(request_id)
  content = response[:content]
  return "" if content.nil? || content.empty?

  # Handle different content formats
  first_item = content.first
  case first_item
  when Hash
    case first_item[:type]
    when "text"
      first_item[:text]
    when "image"
      # Return a structured response for images
      {
        type: "image",
        data: first_item[:data],
        mime_type: first_item[:mimeType] || "image/png"
      }.to_json
    else
      # For any other type, return the item as JSON
      first_item.to_json
    end
  else
    first_item.to_s
  end
end

#closeObject

Closes the connection to the server.



81
82
83
84
85
# File 'lib/mcp/sse_client.rb', line 81

def close
  @closed = true
  @sse_thread&.kill
  @connection&.close
end

#toolsObject

Returns available tools from the server.



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/mcp/sse_client.rb', line 33

def tools
  @tools ||= begin
    request_id = SecureRandom.uuid
    send_json_rpc(request_id, "tools/list", {})

    # Wait for response through SSE
    response = wait_for_response(request_id)
    response[:tools].map do |tool_json|
      Tool.from_json(tool_json)
    end
  end
end

#unique_keyObject



87
88
89
90
# File 'lib/mcp/sse_client.rb', line 87

def unique_key
  parametrized_url = @url.parameterize.underscore.gsub("https_", "")
  Digest::SHA256.hexdigest(parametrized_url)[0..2]
end