ruby-mcp-client 0.5.3 → 0.6.1
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/json_rpc_common.rb +84 -0
- data/lib/mcp_client/server_base.rb +20 -0
- data/lib/mcp_client/server_factory.rb +54 -17
- data/lib/mcp_client/server_sse/json_rpc_transport.rb +246 -0
- data/lib/mcp_client/server_sse/reconnect_monitor.rb +226 -0
- data/lib/mcp_client/server_sse/sse_parser.rb +131 -0
- data/lib/mcp_client/server_sse.rb +174 -489
- data/lib/mcp_client/server_stdio/json_rpc_transport.rb +122 -0
- data/lib/mcp_client/server_stdio.rb +36 -127
- data/lib/mcp_client/tool.rb +22 -4
- data/lib/mcp_client/version.rb +4 -1
- data/lib/mcp_client.rb +27 -10
- metadata +7 -2
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mcp_client/json_rpc_common'
|
4
|
+
|
5
|
+
module MCPClient
|
6
|
+
class ServerStdio
|
7
|
+
# JSON-RPC request/notification plumbing for stdio transport
|
8
|
+
module JsonRpcTransport
|
9
|
+
include JsonRpcCommon
|
10
|
+
# Ensure the server process is started and initialized (handshake)
|
11
|
+
# @return [void]
|
12
|
+
# @raise [MCPClient::Errors::ConnectionError] if initialization fails
|
13
|
+
def ensure_initialized
|
14
|
+
return if @initialized
|
15
|
+
|
16
|
+
connect
|
17
|
+
start_reader
|
18
|
+
perform_initialize
|
19
|
+
|
20
|
+
@initialized = true
|
21
|
+
end
|
22
|
+
|
23
|
+
# Handshake: send initialize request and initialized notification
|
24
|
+
# @return [void]
|
25
|
+
# @raise [MCPClient::Errors::ConnectionError] if initialization fails
|
26
|
+
def perform_initialize
|
27
|
+
# Initialize request
|
28
|
+
init_id = next_id
|
29
|
+
init_req = build_jsonrpc_request('initialize', initialization_params, init_id)
|
30
|
+
send_request(init_req)
|
31
|
+
res = wait_response(init_id)
|
32
|
+
if (err = res['error'])
|
33
|
+
raise MCPClient::Errors::ConnectionError, "Initialize failed: #{err['message']}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Send initialized notification
|
37
|
+
notif = build_jsonrpc_notification('notifications/initialized', {})
|
38
|
+
@stdin.puts(notif.to_json)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Generate a new unique request ID
|
42
|
+
# @return [Integer] a unique request ID
|
43
|
+
def next_id
|
44
|
+
@mutex.synchronize do
|
45
|
+
id = @next_id
|
46
|
+
@next_id += 1
|
47
|
+
id
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Send a JSON-RPC request and return nothing
|
52
|
+
# @param req [Hash] the JSON-RPC request
|
53
|
+
# @return [void]
|
54
|
+
# @raise [MCPClient::Errors::TransportError] on write errors
|
55
|
+
def send_request(req)
|
56
|
+
@logger.debug("Sending JSONRPC request: #{req.to_json}")
|
57
|
+
@stdin.puts(req.to_json)
|
58
|
+
rescue StandardError => e
|
59
|
+
raise MCPClient::Errors::TransportError, "Failed to send JSONRPC request: #{e.message}"
|
60
|
+
end
|
61
|
+
|
62
|
+
# Wait for a response with the given request ID
|
63
|
+
# @param id [Integer] the request ID
|
64
|
+
# @return [Hash] the JSON-RPC response message
|
65
|
+
# @raise [MCPClient::Errors::TransportError] on timeout
|
66
|
+
def wait_response(id)
|
67
|
+
deadline = Time.now + @read_timeout
|
68
|
+
@mutex.synchronize do
|
69
|
+
until @pending.key?(id)
|
70
|
+
remaining = deadline - Time.now
|
71
|
+
break if remaining <= 0
|
72
|
+
|
73
|
+
@cond.wait(@mutex, remaining)
|
74
|
+
end
|
75
|
+
msg = @pending[id]
|
76
|
+
@pending[id] = nil
|
77
|
+
raise MCPClient::Errors::TransportError, "Timeout waiting for JSONRPC response id=#{id}" unless msg
|
78
|
+
|
79
|
+
msg
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Stream tool call fallback for stdio transport (yields single result)
|
84
|
+
# @param tool_name [String] the name of the tool to call
|
85
|
+
# @param parameters [Hash] the parameters to pass to the tool
|
86
|
+
# @return [Enumerator] a stream containing a single result
|
87
|
+
def call_tool_streaming(tool_name, parameters)
|
88
|
+
Enumerator.new do |yielder|
|
89
|
+
yielder << call_tool(tool_name, parameters)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Generic JSON-RPC request: send method with params and wait for result
|
94
|
+
# @param method [String] JSON-RPC method
|
95
|
+
# @param params [Hash] parameters for the request
|
96
|
+
# @return [Object] result from JSON-RPC response
|
97
|
+
# @raise [MCPClient::Errors::ServerError] if server returns an error
|
98
|
+
# @raise [MCPClient::Errors::TransportError] on transport errors
|
99
|
+
# @raise [MCPClient::Errors::ToolCallError] on tool call errors
|
100
|
+
def rpc_request(method, params = {})
|
101
|
+
ensure_initialized
|
102
|
+
with_retry do
|
103
|
+
req_id = next_id
|
104
|
+
req = build_jsonrpc_request(method, params, req_id)
|
105
|
+
send_request(req)
|
106
|
+
res = wait_response(req_id)
|
107
|
+
process_jsonrpc_response(res)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Send a JSON-RPC notification (no response expected)
|
112
|
+
# @param method [String] JSON-RPC method
|
113
|
+
# @param params [Hash] parameters for the notification
|
114
|
+
# @return [void]
|
115
|
+
def rpc_notify(method, params = {})
|
116
|
+
ensure_initialized
|
117
|
+
notif = build_jsonrpc_notification(method, params)
|
118
|
+
@stdin.puts(notif.to_json)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -8,18 +8,31 @@ require 'logger'
|
|
8
8
|
module MCPClient
|
9
9
|
# JSON-RPC implementation of MCP server over stdio.
|
10
10
|
class ServerStdio < ServerBase
|
11
|
-
|
11
|
+
require 'mcp_client/server_stdio/json_rpc_transport'
|
12
|
+
|
13
|
+
include JsonRpcTransport
|
14
|
+
|
15
|
+
# @!attribute [r] command
|
16
|
+
# @return [String, Array] the command used to launch the server
|
17
|
+
# @!attribute [r] env
|
18
|
+
# @return [Hash] environment variables for the subprocess
|
19
|
+
attr_reader :command, :env
|
12
20
|
|
13
21
|
# Timeout in seconds for responses
|
14
22
|
READ_TIMEOUT = 15
|
15
23
|
|
24
|
+
# Initialize a new ServerStdio instance
|
16
25
|
# @param command [String, Array] the stdio command to launch the MCP JSON-RPC server
|
26
|
+
# For improved security, passing an Array is recommended to avoid shell injection issues
|
17
27
|
# @param retries [Integer] number of retry attempts on transient errors
|
18
28
|
# @param retry_backoff [Numeric] base delay in seconds for exponential backoff
|
19
29
|
# @param read_timeout [Numeric] timeout in seconds for reading responses
|
30
|
+
# @param name [String, nil] optional name for this server
|
20
31
|
# @param logger [Logger, nil] optional logger
|
21
|
-
|
22
|
-
|
32
|
+
# @param env [Hash] optional environment variables for the subprocess
|
33
|
+
def initialize(command:, retries: 0, retry_backoff: 1, read_timeout: READ_TIMEOUT, name: nil, logger: nil, env: {})
|
34
|
+
super(name: name)
|
35
|
+
@command_array = command.is_a?(Array) ? command : nil
|
23
36
|
@command = command.is_a?(Array) ? command.join(' ') : command
|
24
37
|
@mutex = Mutex.new
|
25
38
|
@cond = ConditionVariable.new
|
@@ -29,22 +42,36 @@ module MCPClient
|
|
29
42
|
@logger = logger || Logger.new($stdout, level: Logger::WARN)
|
30
43
|
@logger.progname = self.class.name
|
31
44
|
@logger.formatter = proc { |severity, _datetime, progname, msg| "#{severity} [#{progname}] #{msg}\n" }
|
32
|
-
@max_retries
|
45
|
+
@max_retries = retries
|
33
46
|
@retry_backoff = retry_backoff
|
34
|
-
@read_timeout
|
47
|
+
@read_timeout = read_timeout
|
48
|
+
@env = env || {}
|
35
49
|
end
|
36
50
|
|
37
51
|
# Connect to the MCP server by launching the command process via stdout/stdin
|
38
52
|
# @return [Boolean] true if connection was successful
|
39
53
|
# @raise [MCPClient::Errors::ConnectionError] if connection fails
|
40
54
|
def connect
|
41
|
-
|
55
|
+
if @command_array
|
56
|
+
if @env.any?
|
57
|
+
@stdin, @stdout, @stderr, @wait_thread = Open3.popen3(@env, *@command_array)
|
58
|
+
else
|
59
|
+
@stdin, @stdout, @stderr, @wait_thread = Open3.popen3(*@command_array)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
if @env.any?
|
63
|
+
@stdin, @stdout, @stderr, @wait_thread = Open3.popen3(@env, @command)
|
64
|
+
else
|
65
|
+
@stdin, @stdout, @stderr, @wait_thread = Open3.popen3(@command)
|
66
|
+
end
|
67
|
+
end
|
42
68
|
true
|
43
69
|
rescue StandardError => e
|
44
70
|
raise MCPClient::Errors::ConnectionError, "Failed to connect to MCP server: #{e.message}"
|
45
71
|
end
|
46
72
|
|
47
73
|
# Spawn a reader thread to collect JSON-RPC responses
|
74
|
+
# @return [Thread] the reader thread
|
48
75
|
def start_reader
|
49
76
|
@reader_thread = Thread.new do
|
50
77
|
@stdout.each_line do |line|
|
@@ -58,6 +85,7 @@ module MCPClient
|
|
58
85
|
# Handle a line of output from the stdio server
|
59
86
|
# Parses JSON-RPC messages and adds them to pending responses
|
60
87
|
# @param line [String] line of output to parse
|
88
|
+
# @return [void]
|
61
89
|
def handle_line(line)
|
62
90
|
msg = JSON.parse(line)
|
63
91
|
@logger.debug("Received line: #{line.chomp}")
|
@@ -93,7 +121,7 @@ module MCPClient
|
|
93
121
|
raise MCPClient::Errors::ServerError, err['message']
|
94
122
|
end
|
95
123
|
|
96
|
-
(res.dig('result', 'tools') || []).map { |td| MCPClient::Tool.from_json(td) }
|
124
|
+
(res.dig('result', 'tools') || []).map { |td| MCPClient::Tool.from_json(td, server: self) }
|
97
125
|
rescue StandardError => e
|
98
126
|
raise MCPClient::Errors::ToolCallError, "Error listing tools: #{e.message}"
|
99
127
|
end
|
@@ -127,6 +155,7 @@ module MCPClient
|
|
127
155
|
|
128
156
|
# Clean up the server connection
|
129
157
|
# Closes all stdio handles and terminates any running processes and threads
|
158
|
+
# @return [void]
|
130
159
|
def cleanup
|
131
160
|
return unless @stdin
|
132
161
|
|
@@ -143,125 +172,5 @@ module MCPClient
|
|
143
172
|
ensure
|
144
173
|
@stdin = @stdout = @stderr = @wait_thread = @reader_thread = nil
|
145
174
|
end
|
146
|
-
|
147
|
-
private
|
148
|
-
|
149
|
-
# Ensure the server process is started and initialized (handshake)
|
150
|
-
def ensure_initialized
|
151
|
-
return if @initialized
|
152
|
-
|
153
|
-
connect
|
154
|
-
start_reader
|
155
|
-
perform_initialize
|
156
|
-
|
157
|
-
@initialized = true
|
158
|
-
end
|
159
|
-
|
160
|
-
# Handshake: send initialize request and initialized notification
|
161
|
-
def perform_initialize
|
162
|
-
# Initialize request
|
163
|
-
init_id = next_id
|
164
|
-
init_req = {
|
165
|
-
'jsonrpc' => '2.0',
|
166
|
-
'id' => init_id,
|
167
|
-
'method' => 'initialize',
|
168
|
-
'params' => {
|
169
|
-
'protocolVersion' => '2024-11-05',
|
170
|
-
'capabilities' => {},
|
171
|
-
'clientInfo' => { 'name' => 'ruby-mcp-client', 'version' => MCPClient::VERSION }
|
172
|
-
}
|
173
|
-
}
|
174
|
-
send_request(init_req)
|
175
|
-
res = wait_response(init_id)
|
176
|
-
if (err = res['error'])
|
177
|
-
raise MCPClient::Errors::ConnectionError, "Initialize failed: #{err['message']}"
|
178
|
-
end
|
179
|
-
|
180
|
-
# Send initialized notification
|
181
|
-
notif = { 'jsonrpc' => '2.0', 'method' => 'notifications/initialized', 'params' => {} }
|
182
|
-
@stdin.puts(notif.to_json)
|
183
|
-
end
|
184
|
-
|
185
|
-
def next_id
|
186
|
-
@mutex.synchronize do
|
187
|
-
id = @next_id
|
188
|
-
@next_id += 1
|
189
|
-
id
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
def send_request(req)
|
194
|
-
@logger.debug("Sending JSONRPC request: #{req.to_json}")
|
195
|
-
@stdin.puts(req.to_json)
|
196
|
-
rescue StandardError => e
|
197
|
-
raise MCPClient::Errors::TransportError, "Failed to send JSONRPC request: #{e.message}"
|
198
|
-
end
|
199
|
-
|
200
|
-
def wait_response(id)
|
201
|
-
deadline = Time.now + @read_timeout
|
202
|
-
@mutex.synchronize do
|
203
|
-
until @pending.key?(id)
|
204
|
-
remaining = deadline - Time.now
|
205
|
-
break if remaining <= 0
|
206
|
-
|
207
|
-
@cond.wait(@mutex, remaining)
|
208
|
-
end
|
209
|
-
msg = @pending[id]
|
210
|
-
@pending[id] = nil
|
211
|
-
raise MCPClient::Errors::TransportError, "Timeout waiting for JSONRPC response id=#{id}" unless msg
|
212
|
-
|
213
|
-
msg
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
# Stream tool call fallback for stdio transport (yields single result)
|
218
|
-
# @param tool_name [String]
|
219
|
-
# @param parameters [Hash]
|
220
|
-
# @return [Enumerator]
|
221
|
-
def call_tool_streaming(tool_name, parameters)
|
222
|
-
Enumerator.new do |yielder|
|
223
|
-
yielder << call_tool(tool_name, parameters)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
# Generic JSON-RPC request: send method with params and wait for result
|
228
|
-
# @param method [String] JSON-RPC method
|
229
|
-
# @param params [Hash] parameters for the request
|
230
|
-
# @return [Object] result from JSON-RPC response
|
231
|
-
def rpc_request(method, params = {})
|
232
|
-
ensure_initialized
|
233
|
-
attempts = 0
|
234
|
-
begin
|
235
|
-
req_id = next_id
|
236
|
-
req = { 'jsonrpc' => '2.0', 'id' => req_id, 'method' => method, 'params' => params }
|
237
|
-
send_request(req)
|
238
|
-
res = wait_response(req_id)
|
239
|
-
if (err = res['error'])
|
240
|
-
raise MCPClient::Errors::ServerError, err['message']
|
241
|
-
end
|
242
|
-
|
243
|
-
res['result']
|
244
|
-
rescue MCPClient::Errors::ServerError, MCPClient::Errors::TransportError, IOError, Errno::ETIMEDOUT,
|
245
|
-
Errno::ECONNRESET => e
|
246
|
-
attempts += 1
|
247
|
-
if attempts <= @max_retries
|
248
|
-
delay = @retry_backoff * (2**(attempts - 1))
|
249
|
-
@logger.debug("Retry attempt #{attempts} after error: #{e.message}, sleeping #{delay}s")
|
250
|
-
sleep(delay)
|
251
|
-
retry
|
252
|
-
end
|
253
|
-
raise
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
# Send a JSON-RPC notification (no response expected)
|
258
|
-
# @param method [String] JSON-RPC method
|
259
|
-
# @param params [Hash] parameters for the notification
|
260
|
-
# @return [void]
|
261
|
-
def rpc_notify(method, params = {})
|
262
|
-
ensure_initialized
|
263
|
-
notif = { 'jsonrpc' => '2.0', 'method' => method, 'params' => params }
|
264
|
-
@stdin.puts(notif.to_json)
|
265
|
-
end
|
266
175
|
end
|
267
176
|
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,50 @@ 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
|
-
# Build command list with args
|
36
|
+
# Build command list with args and propagate environment
|
36
37
|
cmd_list = [cfg[:command]] + Array(cfg[:args])
|
37
|
-
configs << MCPClient.stdio_config(
|
38
|
+
configs << MCPClient.stdio_config(
|
39
|
+
command: cmd_list,
|
40
|
+
name: cfg[:name],
|
41
|
+
logger: logger,
|
42
|
+
env: cfg[:env]
|
43
|
+
)
|
38
44
|
when 'sse'
|
39
45
|
# Use 'url' from parsed config as 'base_url' for SSE config
|
40
|
-
configs << MCPClient.sse_config(base_url: cfg[:url], headers: cfg[:headers] || {}
|
46
|
+
configs << MCPClient.sse_config(base_url: cfg[:url], headers: cfg[:headers] || {}, name: cfg[:name],
|
47
|
+
logger: logger)
|
41
48
|
end
|
42
49
|
end
|
43
50
|
end
|
44
|
-
MCPClient::Client.new(mcp_server_configs: configs)
|
51
|
+
MCPClient::Client.new(mcp_server_configs: configs, logger: logger)
|
45
52
|
end
|
46
53
|
|
47
54
|
# Create a standard server configuration for stdio
|
48
55
|
# @param command [String, Array<String>] command to execute
|
56
|
+
# @param name [String, nil] optional name for this server
|
57
|
+
# @param logger [Logger, nil] optional logger for server operations
|
49
58
|
# @return [Hash] server configuration
|
50
|
-
def self.stdio_config(command:)
|
59
|
+
def self.stdio_config(command:, name: nil, logger: nil, env: {})
|
51
60
|
{
|
52
61
|
type: 'stdio',
|
53
|
-
command: command
|
62
|
+
command: command,
|
63
|
+
name: name,
|
64
|
+
logger: logger,
|
65
|
+
env: env || {}
|
54
66
|
}
|
55
67
|
end
|
56
68
|
|
@@ -61,8 +73,11 @@ module MCPClient
|
|
61
73
|
# @param ping [Integer] time in seconds after which to send ping if no activity (default: 10)
|
62
74
|
# @param retries [Integer] number of retry attempts (default: 0)
|
63
75
|
# @param retry_backoff [Integer] backoff delay in seconds (default: 1)
|
76
|
+
# @param name [String, nil] optional name for this server
|
77
|
+
# @param logger [Logger, nil] optional logger for server operations
|
64
78
|
# @return [Hash] server configuration
|
65
|
-
def self.sse_config(base_url:, headers: {}, read_timeout: 30, ping: 10, retries: 0, retry_backoff: 1
|
79
|
+
def self.sse_config(base_url:, headers: {}, read_timeout: 30, ping: 10, retries: 0, retry_backoff: 1,
|
80
|
+
name: nil, logger: nil)
|
66
81
|
{
|
67
82
|
type: 'sse',
|
68
83
|
base_url: base_url,
|
@@ -70,7 +85,9 @@ module MCPClient
|
|
70
85
|
read_timeout: read_timeout,
|
71
86
|
ping: ping,
|
72
87
|
retries: retries,
|
73
|
-
retry_backoff: retry_backoff
|
88
|
+
retry_backoff: retry_backoff,
|
89
|
+
name: name,
|
90
|
+
logger: logger
|
74
91
|
}
|
75
92
|
end
|
76
93
|
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.1
|
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-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -108,10 +108,15 @@ files:
|
|
108
108
|
- lib/mcp_client/client.rb
|
109
109
|
- lib/mcp_client/config_parser.rb
|
110
110
|
- lib/mcp_client/errors.rb
|
111
|
+
- lib/mcp_client/json_rpc_common.rb
|
111
112
|
- lib/mcp_client/server_base.rb
|
112
113
|
- lib/mcp_client/server_factory.rb
|
113
114
|
- lib/mcp_client/server_sse.rb
|
115
|
+
- lib/mcp_client/server_sse/json_rpc_transport.rb
|
116
|
+
- lib/mcp_client/server_sse/reconnect_monitor.rb
|
117
|
+
- lib/mcp_client/server_sse/sse_parser.rb
|
114
118
|
- lib/mcp_client/server_stdio.rb
|
119
|
+
- lib/mcp_client/server_stdio/json_rpc_transport.rb
|
115
120
|
- lib/mcp_client/tool.rb
|
116
121
|
- lib/mcp_client/version.rb
|
117
122
|
homepage: https://github.com/simonx1/ruby-mcp-client
|