ruby-mcp-client 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +41 -11
- data/lib/mcp_client/client.rb +125 -26
- data/lib/mcp_client/config_parser.rb +5 -1
- data/lib/mcp_client/errors.rb +4 -0
- data/lib/mcp_client/server_base.rb +20 -0
- data/lib/mcp_client/server_factory.rb +6 -3
- data/lib/mcp_client/server_sse.rb +463 -153
- data/lib/mcp_client/server_stdio.rb +4 -3
- data/lib/mcp_client/tool.rb +22 -4
- data/lib/mcp_client/version.rb +1 -1
- data/lib/mcp_client.rb +20 -9
- metadata +2 -2
@@ -17,9 +17,10 @@ module MCPClient
|
|
17
17
|
# @param retries [Integer] number of retry attempts on transient errors
|
18
18
|
# @param retry_backoff [Numeric] base delay in seconds for exponential backoff
|
19
19
|
# @param read_timeout [Numeric] timeout in seconds for reading responses
|
20
|
+
# @param name [String, nil] optional name for this server
|
20
21
|
# @param logger [Logger, nil] optional logger
|
21
|
-
def initialize(command:, retries: 0, retry_backoff: 1, read_timeout: READ_TIMEOUT, logger: nil)
|
22
|
-
super()
|
22
|
+
def initialize(command:, retries: 0, retry_backoff: 1, read_timeout: READ_TIMEOUT, name: nil, logger: nil)
|
23
|
+
super(name: name)
|
23
24
|
@command = command.is_a?(Array) ? command.join(' ') : command
|
24
25
|
@mutex = Mutex.new
|
25
26
|
@cond = ConditionVariable.new
|
@@ -93,7 +94,7 @@ module MCPClient
|
|
93
94
|
raise MCPClient::Errors::ServerError, err['message']
|
94
95
|
end
|
95
96
|
|
96
|
-
(res.dig('result', 'tools') || []).map { |td| MCPClient::Tool.from_json(td) }
|
97
|
+
(res.dig('result', 'tools') || []).map { |td| MCPClient::Tool.from_json(td, server: self) }
|
97
98
|
rescue StandardError => e
|
98
99
|
raise MCPClient::Errors::ToolCallError, "Error listing tools: #{e.message}"
|
99
100
|
end
|
data/lib/mcp_client/tool.rb
CHANGED
@@ -3,24 +3,40 @@
|
|
3
3
|
module MCPClient
|
4
4
|
# Representation of an MCP tool
|
5
5
|
class Tool
|
6
|
-
|
6
|
+
# @!attribute [r] name
|
7
|
+
# @return [String] the name of the tool
|
8
|
+
# @!attribute [r] description
|
9
|
+
# @return [String] the description of the tool
|
10
|
+
# @!attribute [r] schema
|
11
|
+
# @return [Hash] the JSON schema for the tool
|
12
|
+
# @!attribute [r] server
|
13
|
+
# @return [MCPClient::ServerBase, nil] the server this tool belongs to
|
14
|
+
attr_reader :name, :description, :schema, :server
|
7
15
|
|
8
|
-
|
16
|
+
# Initialize a new Tool
|
17
|
+
# @param name [String] the name of the tool
|
18
|
+
# @param description [String] the description of the tool
|
19
|
+
# @param schema [Hash] the JSON schema for the tool
|
20
|
+
# @param server [MCPClient::ServerBase, nil] the server this tool belongs to
|
21
|
+
def initialize(name:, description:, schema:, server: nil)
|
9
22
|
@name = name
|
10
23
|
@description = description
|
11
24
|
@schema = schema
|
25
|
+
@server = server
|
12
26
|
end
|
13
27
|
|
14
28
|
# Create a Tool instance from JSON data
|
15
29
|
# @param data [Hash] JSON data from MCP server
|
30
|
+
# @param server [MCPClient::ServerBase, nil] the server this tool belongs to
|
16
31
|
# @return [MCPClient::Tool] tool instance
|
17
|
-
def self.from_json(data)
|
32
|
+
def self.from_json(data, server: nil)
|
18
33
|
# Some servers (Playwright MCP CLI) use 'inputSchema' instead of 'schema'
|
19
34
|
schema = data['inputSchema'] || data['schema']
|
20
35
|
new(
|
21
36
|
name: data['name'],
|
22
37
|
description: data['description'],
|
23
|
-
schema: schema
|
38
|
+
schema: schema,
|
39
|
+
server: server
|
24
40
|
)
|
25
41
|
end
|
26
42
|
|
@@ -47,6 +63,8 @@ module MCPClient
|
|
47
63
|
}
|
48
64
|
end
|
49
65
|
|
66
|
+
# Convert tool to Google Vertex AI tool specification format
|
67
|
+
# @return [Hash] Google Vertex AI tool specification with cleaned schema
|
50
68
|
def to_google_tool
|
51
69
|
{
|
52
70
|
name: @name,
|
data/lib/mcp_client/version.rb
CHANGED
data/lib/mcp_client.rb
CHANGED
@@ -19,38 +19,44 @@ module MCPClient
|
|
19
19
|
# @param mcp_server_configs [Array<Hash>] configurations for MCP servers
|
20
20
|
# @param server_definition_file [String, nil] optional path to a JSON file defining server configurations
|
21
21
|
# The JSON may be a single server object or an array of server objects.
|
22
|
+
# @param logger [Logger, nil] optional logger for client operations
|
22
23
|
# @return [MCPClient::Client] new client instance
|
23
|
-
def self.create_client(mcp_server_configs: [], server_definition_file: nil)
|
24
|
+
def self.create_client(mcp_server_configs: [], server_definition_file: nil, logger: nil)
|
24
25
|
require 'json'
|
25
26
|
# Start with any explicit configs provided
|
26
27
|
configs = Array(mcp_server_configs)
|
27
28
|
# Load additional configs from a JSON file if specified
|
28
29
|
if server_definition_file
|
29
30
|
# Parse JSON definitions into clean config hashes
|
30
|
-
parser = MCPClient::ConfigParser.new(server_definition_file)
|
31
|
+
parser = MCPClient::ConfigParser.new(server_definition_file, logger: logger)
|
31
32
|
parsed = parser.parse
|
32
33
|
parsed.each_value do |cfg|
|
33
34
|
case cfg[:type].to_s
|
34
35
|
when 'stdio'
|
35
36
|
# Build command list with args
|
36
37
|
cmd_list = [cfg[:command]] + Array(cfg[:args])
|
37
|
-
configs << MCPClient.stdio_config(command: cmd_list)
|
38
|
+
configs << MCPClient.stdio_config(command: cmd_list, name: cfg[:name], logger: logger)
|
38
39
|
when 'sse'
|
39
40
|
# Use 'url' from parsed config as 'base_url' for SSE config
|
40
|
-
configs << MCPClient.sse_config(base_url: cfg[:url], headers: cfg[:headers] || {}
|
41
|
+
configs << MCPClient.sse_config(base_url: cfg[:url], headers: cfg[:headers] || {}, name: cfg[:name],
|
42
|
+
logger: logger)
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
44
|
-
MCPClient::Client.new(mcp_server_configs: configs)
|
46
|
+
MCPClient::Client.new(mcp_server_configs: configs, logger: logger)
|
45
47
|
end
|
46
48
|
|
47
49
|
# Create a standard server configuration for stdio
|
48
50
|
# @param command [String, Array<String>] command to execute
|
51
|
+
# @param name [String, nil] optional name for this server
|
52
|
+
# @param logger [Logger, nil] optional logger for server operations
|
49
53
|
# @return [Hash] server configuration
|
50
|
-
def self.stdio_config(command:)
|
54
|
+
def self.stdio_config(command:, name: nil, logger: nil)
|
51
55
|
{
|
52
56
|
type: 'stdio',
|
53
|
-
command: command
|
57
|
+
command: command,
|
58
|
+
name: name,
|
59
|
+
logger: logger
|
54
60
|
}
|
55
61
|
end
|
56
62
|
|
@@ -61,8 +67,11 @@ module MCPClient
|
|
61
67
|
# @param ping [Integer] time in seconds after which to send ping if no activity (default: 10)
|
62
68
|
# @param retries [Integer] number of retry attempts (default: 0)
|
63
69
|
# @param retry_backoff [Integer] backoff delay in seconds (default: 1)
|
70
|
+
# @param name [String, nil] optional name for this server
|
71
|
+
# @param logger [Logger, nil] optional logger for server operations
|
64
72
|
# @return [Hash] server configuration
|
65
|
-
def self.sse_config(base_url:, headers: {}, read_timeout: 30, ping: 10, retries: 0, retry_backoff: 1
|
73
|
+
def self.sse_config(base_url:, headers: {}, read_timeout: 30, ping: 10, retries: 0, retry_backoff: 1,
|
74
|
+
name: nil, logger: nil)
|
66
75
|
{
|
67
76
|
type: 'sse',
|
68
77
|
base_url: base_url,
|
@@ -70,7 +79,9 @@ module MCPClient
|
|
70
79
|
read_timeout: read_timeout,
|
71
80
|
ping: ping,
|
72
81
|
retries: retries,
|
73
|
-
retry_backoff: retry_backoff
|
82
|
+
retry_backoff: retry_backoff,
|
83
|
+
name: name,
|
84
|
+
logger: logger
|
74
85
|
}
|
75
86
|
end
|
76
87
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-mcp-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Szymon Kurcab
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-05-
|
11
|
+
date: 2025-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|