diff --git a/README.md b/README.md index dba8f942..741d707e 100644 --- a/README.md +++ b/README.md @@ -1405,6 +1405,18 @@ client.tools # will make the call using Bearer auth You can add any custom headers needed for your authentication scheme, or for any other purpose. The client will include these headers on every request. +#### Customizing the Faraday Connection + +You can pass a block to `MCP::Client::HTTP.new` to customize the underlying Faraday connection. +The block is called after the default middleware is configured, so you can add middleware or swap the HTTP adapter: + +```ruby +http_transport = MCP::Client::HTTP.new(url: "https://api.example.com/mcp") do |faraday| + faraday.use MyApp::Middleware::HttpRecorder + faraday.adapter :typhoeus +end +``` + ### Tool Objects The client provides a wrapper class for tools returned by the server: diff --git a/lib/mcp/client/http.rb b/lib/mcp/client/http.rb index 24c7831a..1637b0ee 100644 --- a/lib/mcp/client/http.rb +++ b/lib/mcp/client/http.rb @@ -7,9 +7,10 @@ class HTTP attr_reader :url - def initialize(url:, headers: {}) + def initialize(url:, headers: {}, &block) @url = url @headers = headers + @faraday_customizer = block end def send_request(request:) @@ -78,6 +79,8 @@ def client headers.each do |key, value| faraday.headers[key] = value end + + @faraday_customizer&.call(faraday) end end diff --git a/test/mcp/client/http_test.rb b/test/mcp/client/http_test.rb index fffda7f6..081f0e6a 100644 --- a/test/mcp/client/http_test.rb +++ b/test/mcp/client/http_test.rb @@ -242,6 +242,31 @@ def test_send_request_raises_internal_error assert_equal({ method: "tools/list", params: nil }, error.request) end + def test_block_customizes_faraday_connection + custom_client = HTTP.new(url: url) do |faraday| + faraday.headers["X-Custom"] = "test-value" + end + + request = { + jsonrpc: "2.0", + id: "test_id", + method: "tools/list", + } + + stub_request(:post, url).with( + headers: { + "X-Custom" => "test-value", + "Accept" => "application/json, text/event-stream", + }, + ).to_return( + status: 200, + headers: { "Content-Type" => "application/json" }, + body: { result: { tools: [] } }.to_json, + ) + + custom_client.send_request(request: request) + end + def test_send_request_raises_error_for_non_json_response request = { jsonrpc: "2.0",