Skip to content

Support customizing the Faraday client in MCP::Client::HTTP #303

@kstevens715

Description

@kstevens715

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions