diff --git a/README.md b/README.md index c496c7b..a45d333 100644 --- a/README.md +++ b/README.md @@ -1401,6 +1401,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 24c7831..1637b0e 100644 --- a/lib/mcp/client/http.rb +++ b/lib/mcp/client/http.rb @@ -7,9 +7,10 @@ module MCP 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 @@ module MCP 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 fffda7f..081f0e6 100644 --- a/test/mcp/client/http_test.rb +++ b/test/mcp/client/http_test.rb @@ -242,6 +242,31 @@ module MCP 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",