Class: MCPClient::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/mcp_client/client.rb

Overview

MCP Client for integrating with the Model Context Protocol This is the main entry point for using MCP tools

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mcp_server_configs: [], logger: nil) ⇒ Client

Initialize a new MCPClient::Client

Parameters:

  • mcp_server_configs (Array<Hash>) (defaults to: [])

    configurations for MCP servers

  • logger (Logger, nil) (defaults to: nil)

    optional logger, defaults to STDOUT



20
21
22
23
24
25
26
27
# File 'lib/mcp_client/client.rb', line 20

def initialize(mcp_server_configs: [], logger: nil)
  @logger = logger || Logger.new($stdout, level: Logger::WARN)
  @servers = mcp_server_configs.map do |config|
    @logger.debug("Creating server with config: #{config.inspect}")
    MCPClient::ServerFactory.create(config)
  end
  @tool_cache = {}
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



15
# File 'lib/mcp_client/client.rb', line 15

attr_reader :servers, :tool_cache, :logger

#serversArray<MCPClient::ServerBase> (readonly)

Returns list of servers.

Returns:



15
16
17
# File 'lib/mcp_client/client.rb', line 15

def servers
  @servers
end

#tool_cacheHash<String, MCPClient::Tool> (readonly)

Returns cache of tools by name.

Returns:



15
# File 'lib/mcp_client/client.rb', line 15

attr_reader :servers, :tool_cache, :logger

Instance Method Details

#call_tool(tool_name, parameters) ⇒ Object

Calls a specific tool by name with the given parameters

Parameters:

  • tool_name (String)

    the name of the tool to call

  • parameters (Hash)

    the parameters to pass to the tool

Returns:

  • (Object)

    the result of the tool invocation

Raises:



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/mcp_client/client.rb', line 50

def call_tool(tool_name, parameters)
  tools = list_tools
  tool = tools.find { |t| t.name == tool_name }

  raise MCPClient::Errors::ToolNotFound, "Tool '#{tool_name}' not found" unless tool

  # Validate parameters against tool schema
  validate_params!(tool, parameters)

  # Find the server that owns this tool
  server = find_server_for_tool(tool)
  raise MCPClient::Errors::ServerNotFound, "No server found for tool '#{tool_name}'" unless server

  server.call_tool(tool_name, parameters)
end

#call_tool_streaming(tool_name, parameters) ⇒ Enumerator

Stream call of a specific tool by name with the given parameters. Returns an Enumerator yielding streaming updates if supported.

Parameters:

  • tool_name (String)

    the name of the tool to call

  • parameters (Hash)

    the parameters to pass to the tool

Returns:

  • (Enumerator)

    streaming enumerator or single-value enumerator

Raises:



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/mcp_client/client.rb', line 126

def call_tool_streaming(tool_name, parameters)
  tools = list_tools
  tool = tools.find { |t| t.name == tool_name }
  raise MCPClient::Errors::ToolNotFound, "Tool '#{tool_name}' not found" unless tool

  # Validate parameters against tool schema
  validate_params!(tool, parameters)
  # Find the server that owns this tool
  server = find_server_for_tool(tool)
  raise MCPClient::Errors::ServerNotFound, "No server found for tool '#{tool_name}'" unless server

  if server.respond_to?(:call_tool_streaming)
    server.call_tool_streaming(tool_name, parameters)
  else
    Enumerator.new do |yielder|
      yielder << server.call_tool(tool_name, parameters)
    end
  end
end

#call_tools(calls) ⇒ Array<Object>

Call multiple tools in batch

Parameters:

  • calls (Array<Hash>)

    array of calls in the form { name: tool_name, parameters: … }

Returns:

  • (Array<Object>)

    array of results for each tool invocation



113
114
115
116
117
118
119
# File 'lib/mcp_client/client.rb', line 113

def call_tools(calls)
  calls.map do |call|
    name = call[:name] || call['name']
    params = call[:parameters] || call['parameters'] || {}
    call_tool(name, params)
  end
end

#cleanupObject

Clean up all server connections



85
86
87
# File 'lib/mcp_client/client.rb', line 85

def cleanup
  servers.each(&:cleanup)
end

#clear_cachevoid

This method returns an undefined value.

Clear the cached tools so that next list_tools will fetch fresh data



91
92
93
# File 'lib/mcp_client/client.rb', line 91

def clear_cache
  @tool_cache.clear
end

#find_tool(pattern) ⇒ MCPClient::Tool?

Find the first tool whose name matches the given pattern

Parameters:

  • pattern (String, Regexp)

    pattern to match tool names

Returns:



106
107
108
# File 'lib/mcp_client/client.rb', line 106

def find_tool(pattern)
  find_tools(pattern).first
end

#find_tools(pattern) ⇒ Array<MCPClient::Tool>

Find all tools whose name matches the given pattern (String or Regexp)

Parameters:

  • pattern (String, Regexp)

    pattern to match tool names

Returns:



98
99
100
101
# File 'lib/mcp_client/client.rb', line 98

def find_tools(pattern)
  rx = pattern.is_a?(Regexp) ? pattern : /#{Regexp.escape(pattern)}/
  list_tools.select { |t| t.name.match(rx) }
end

#list_tools(cache: true) ⇒ Array<MCPClient::Tool>

Lists all available tools from all connected MCP servers

Parameters:

  • cache (Boolean) (defaults to: true)

    whether to use cached tools or fetch fresh

Returns:



32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/mcp_client/client.rb', line 32

def list_tools(cache: true)
  return @tool_cache.values if cache && !@tool_cache.empty?

  tools = []
  servers.each do |server|
    server.list_tools.each do |tool|
      @tool_cache[tool.name] = tool
      tools << tool
    end
  end

  tools
end

#to_anthropic_tools(tool_names: nil) ⇒ Array<Hash>

Convert MCP tools to Anthropic Claude tool specifications

Parameters:

  • tool_names (Array<String>, nil) (defaults to: nil)

    optional list of tool names to include, nil means all tools

Returns:

  • (Array<Hash>)

    Anthropic Claude tool specifications



78
79
80
81
82
# File 'lib/mcp_client/client.rb', line 78

def to_anthropic_tools(tool_names: nil)
  tools = list_tools
  tools = tools.select { |t| tool_names.include?(t.name) } if tool_names
  tools.map(&:to_anthropic_tool)
end

#to_openai_tools(tool_names: nil) ⇒ Array<Hash>

Convert MCP tools to OpenAI function specifications

Parameters:

  • tool_names (Array<String>, nil) (defaults to: nil)

    optional list of tool names to include, nil means all tools

Returns:

  • (Array<Hash>)

    OpenAI function specifications



69
70
71
72
73
# File 'lib/mcp_client/client.rb', line 69

def to_openai_tools(tool_names: nil)
  tools = list_tools
  tools = tools.select { |t| tool_names.include?(t.name) } if tool_names
  tools.map(&:to_openai_tool)
end