Problem
MCP::Client::HTTP builds its Faraday connection internally in a private client method with no way to customize the middleware stack or adapter. This makes it difficult to add observability (request/response recording, failure logging) or swap the HTTP adapter without overriding a private method.
We're using the gem as an MCP client in a Rails app and need to inject Faraday middleware for tracing HTTP requests. Currently we subclass MCP::Client::HTTP and override client, which works but couples us to a private API.
Proposal
Accept an optional block in MCP::Client::HTTP.new that yields the Faraday builder, similar to how Faraday.new itself works:
transport = MCP::Client::HTTP.new(url: "https://example.com/mcp") do |faraday|
faraday.use MyApp::Middleware::HttpRecorder
faraday.adapter :typhoeus
end
The block would be called during Faraday client construction, after the default middleware (JSON request/response, raise_error, headers) is configured. This preserves the defaults while giving consumers a hook for additions.
Current workaround
class MyTransport < MCP::Client::HTTP
private
def client
require_faraday!
@client ||= Faraday.new url do |f|
f.request :json
f.response :json
f.response :raise_error
f.headers['Accept'] = ACCEPT_HEADER
headers.each { |key, value| f.headers[key] = value }
f.use MyApp::Middleware::HttpRecorder
f.adapter :typhoeus
end
end
end
This duplicates the gem's default Faraday setup and will break if the gem changes its internal configuration.
Problem
MCP::Client::HTTPbuilds its Faraday connection internally in a privateclientmethod with no way to customize the middleware stack or adapter. This makes it difficult to add observability (request/response recording, failure logging) or swap the HTTP adapter without overriding a private method.We're using the gem as an MCP client in a Rails app and need to inject Faraday middleware for tracing HTTP requests. Currently we subclass
MCP::Client::HTTPand overrideclient, which works but couples us to a private API.Proposal
Accept an optional block in
MCP::Client::HTTP.newthat yields the Faraday builder, similar to howFaraday.newitself works:The block would be called during Faraday client construction, after the default middleware (JSON request/response, raise_error, headers) is configured. This preserves the defaults while giving consumers a hook for additions.
Current workaround
This duplicates the gem's default Faraday setup and will break if the gem changes its internal configuration.