Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PATH
faraday-multipart (>= 1)
faraday-net_http (>= 1)
faraday-retry (>= 1)
ruby_llm (~> 1.2)
ruby_llm (~> 1.3)
zeitwerk (~> 2)

GEM
Expand Down Expand Up @@ -40,6 +40,7 @@ GEM
language_server-protocol (3.17.0.5)
lint_roller (1.1.0)
logger (1.7.0)
marcel (1.0.4)
multipart-post (2.4.1)
net-http (0.6.0)
uri
Expand Down Expand Up @@ -96,13 +97,14 @@ GEM
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
ruby-progressbar (1.13.0)
ruby_llm (1.2.0)
ruby_llm (1.3.0)
base64
event_stream_parser (~> 1)
faraday (~> 2)
faraday-multipart (~> 1)
faraday-net_http (~> 3)
faraday-retry (~> 2)
faraday (>= 1.10.0)
faraday-multipart (>= 1)
faraday-net_http (>= 1)
faraday-retry (>= 1)
marcel (~> 1.0)
zeitwerk (~> 2)
stringio (3.1.7)
unicode-display_width (3.1.4)
Expand Down
2 changes: 1 addition & 1 deletion examples/test_sse_mcp_tool_call.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

client = RubyLLM::MCP.client(
name: "local_mcp",
transport_type: "sse",
transport_type: :sse,
config: {
url: "http://localhost:9292/mcp/sse"
}
Expand Down
2 changes: 1 addition & 1 deletion examples/test_sse_mcp_with_gpt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

client = RubyLLM::MCP.client(
name: "local_mcp",
transport_type: "sse",
transport_type: :sse,
config: {
url: "http://localhost:9292/mcp/sse"
}
Expand Down
9 changes: 3 additions & 6 deletions examples/test_streamable_mcp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@
# Test with streamable HTTP transport
client = RubyLLM::MCP.client(
name: "streamable_mcp",
transport_type: "streamable",
transport_type: :streamable,
config: {
url: "http://localhost:3005/mcp",
headers: {
"User-Agent" => "RubyLLM-MCP/1.0"
}
url: "http://localhost:3005/mcp"
}
)

Expand All @@ -29,7 +26,7 @@
puts tools.map { |tool| " - #{tool.name}: #{tool.description}" }.join("\n")
puts "-" * 50

chat = RubyLLM.chat(model: "gpt-4")
chat = RubyLLM.chat(model: "gpt-4.1")
chat.with_tools(*client.tools)

message = "Can you use one of the available tools to help me with a task? can you add 1 and 3 and output the result?"
Expand Down
28 changes: 5 additions & 23 deletions lib/ruby_llm/mcp/transport/streamable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,6 @@ def request(body, wait_for_response: true)
handle_response(response, request_id, response_queue, wait_for_response)
end

def get_sse_stream(last_event_id: nil)
headers = build_headers
headers["Accept"] = "text/event-stream"
headers["Last-Event-ID"] = last_event_id if last_event_id

response = @connection.get do |req|
headers.each { |key, value| req.headers[key] = value }
end

if response.status == 200 && response.headers["content-type"]&.include?("text/event-stream")
process_sse_stream(response.body)
elsif response.status == 405
raise "Server does not support SSE streams via GET"
else
raise "Failed to establish SSE connection: #{response.status}"
end
end

def close
@running = false
@sse_mutex.synchronize do
Expand Down Expand Up @@ -250,9 +232,9 @@ def process_sse_for_request(sse_body, request_id, response_queue)

def process_sse_stream(sse_body)
Thread.new do
process_sse_events(sse_body) do |event_id, event_data|
process_sse_events(sse_body) do |event_data|
# Handle server-initiated requests/notifications
handle_server_message(event_id, event_data) if event_data.is_a?(Hash)
handle_server_message(event_data) if event_data.is_a?(Hash)
end
rescue StandardError => e
puts "Error processing SSE stream: #{e.message}"
Expand All @@ -271,7 +253,7 @@ def process_sse_events(sse_body)
unless event_buffer.empty?
begin
event_data = JSON.parse(event_buffer)
yield [event_id, event_data]
yield event_data
rescue JSON::ParserError
puts "Warning: Failed to parse SSE event data: #{event_buffer}"
end
Expand All @@ -289,10 +271,10 @@ def process_sse_events(sse_body)
end
end

def handle_server_message(event_id, message)
def handle_server_message(message)
# Handle server-initiated requests and notifications
# This would typically be passed to a message handler
puts "Received server message: #{event_id} #{message.inspect}"
puts "Received server message: #{message.inspect}"
end

def wait_for_response_with_timeout(request_id, response_queue)
Expand Down
2 changes: 1 addition & 1 deletion ruby_llm-mcp.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Gem::Specification.new do |spec|
spec.add_dependency "faraday-multipart", ">= 1"
spec.add_dependency "faraday-net_http", ">= 1"
spec.add_dependency "faraday-retry", ">= 1"
spec.add_dependency "ruby_llm", "~> 1.2"
spec.add_dependency "ruby_llm", "~> 1.3"
spec.add_dependency "zeitwerk", "~> 2"
end
# rubocop:enable Metrics/BlockLength