Skip to content

Commit f7952e8

Browse files
committed
Support customizing the Faraday client in MCP::Client::HTTP
## Motivation and Context `MCP::Client::HTTP` builds its Faraday connection internally in a private `client` method with no way to customize the middleware stack or adapter. Users who need observability (request/response recording, failure logging) or a different HTTP adapter must override a private method, coupling to an internal API. This accepts an optional block in `MCP::Client::HTTP.new` that yields the Faraday builder after default middleware is configured, allowing users to add custom middleware or swap the HTTP adapter. ## How Has This Been Tested? Added a test that verifies custom headers set via the block are included in requests. All existing tests continue to pass. ## Breaking Changes None. The block argument is optional, so existing code is unaffected. Resolves modelcontextprotocol#303
1 parent 2822e00 commit f7952e8

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,6 +1405,18 @@ client.tools # will make the call using Bearer auth
14051405

14061406
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.
14071407

1408+
#### Customizing the Faraday Connection
1409+
1410+
You can pass a block to `MCP::Client::HTTP.new` to customize the underlying Faraday connection.
1411+
The block is called after the default middleware is configured, so you can add middleware or swap the HTTP adapter:
1412+
1413+
```ruby
1414+
http_transport = MCP::Client::HTTP.new(url: "https://api.example.com/mcp") do |faraday|
1415+
faraday.use MyApp::Middleware::HttpRecorder
1416+
faraday.adapter :typhoeus
1417+
end
1418+
```
1419+
14081420
### Tool Objects
14091421

14101422
The client provides a wrapper class for tools returned by the server:

lib/mcp/client/http.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ class HTTP
77

88
attr_reader :url
99

10-
def initialize(url:, headers: {})
10+
def initialize(url:, headers: {}, &block)
1111
@url = url
1212
@headers = headers
13+
@faraday_customizer = block
1314
end
1415

1516
def send_request(request:)
@@ -78,6 +79,8 @@ def client
7879
headers.each do |key, value|
7980
faraday.headers[key] = value
8081
end
82+
83+
@faraday_customizer&.call(faraday)
8184
end
8285
end
8386

test/mcp/client/http_test.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,31 @@ def test_send_request_raises_internal_error
242242
assert_equal({ method: "tools/list", params: nil }, error.request)
243243
end
244244

245+
def test_block_customizes_faraday_connection
246+
custom_client = HTTP.new(url: url) do |faraday|
247+
faraday.headers["X-Custom"] = "test-value"
248+
end
249+
250+
request = {
251+
jsonrpc: "2.0",
252+
id: "test_id",
253+
method: "tools/list",
254+
}
255+
256+
stub_request(:post, url).with(
257+
headers: {
258+
"X-Custom" => "test-value",
259+
"Accept" => "application/json, text/event-stream",
260+
},
261+
).to_return(
262+
status: 200,
263+
headers: { "Content-Type" => "application/json" },
264+
body: { result: { tools: [] } }.to_json,
265+
)
266+
267+
custom_client.send_request(request: request)
268+
end
269+
245270
def test_send_request_raises_error_for_non_json_response
246271
request = {
247272
jsonrpc: "2.0",

0 commit comments

Comments
 (0)