ruby-mcp-client 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5249d2aeec436453cf92fb92a9d84468a3042d046d663d03eebffb734b16abd2
4
- data.tar.gz: 30ece04171450241424fd81a95ef2f69d73e53300044d28d98796ecea88ba20b
3
+ metadata.gz: 233c83227145cb76167e75784b7eaecef56828743f65f6256c84062bb2290b1e
4
+ data.tar.gz: 4fb49b0cc82f5bd2b07d15ec200da4f9dced0fce52ddfacd4860a5a689152328
5
5
  SHA512:
6
- metadata.gz: 2c002ae531ff4ebfdb733638b9fe0a40ed4452a33bda9a7fac82b69395c662749b937f21d155bf9b9a6702a50c38bfa172c2ba59c3adad241a37495aa8d654d9
7
- data.tar.gz: 4664e938db65412dc5aa7847dc7914b1e423d1f0a96e3dea65565138b494cb44b5449fd0be49be505e4170792a68e239b80da9a969fec9e620748b578a16c3c6
6
+ metadata.gz: bdd2b7223f25e4e8516f9bad648854a8e935b823d269762d769a545571960041041082f861a85e559a637e00bb9357541548bd87155bbe9df490c501fb755ade
7
+ data.tar.gz: 3aef9c1fd10b846e46cc183c072443946a5aa39bfae43245949204e15e89a132df676af927cdabd4cae9c65e4052d220d4012bf0dadaffeb988cddf2a5ab7cfc
data/README.md CHANGED
@@ -30,7 +30,6 @@ via different transport mechanisms:
30
30
 
31
31
  - **Standard I/O**: Local processes implementing the MCP protocol
32
32
  - **Server-Sent Events (SSE)**: Remote MCP servers over HTTP with streaming support
33
- - **HTTP JSON-RPC**: Remote MCP servers over standard HTTP
34
33
 
35
34
  The core client resides in `MCPClient::Client` and provides helper methods for integrating
36
35
  with popular AI services with built-in conversions:
@@ -53,12 +52,6 @@ client = MCPClient.create_client(
53
52
  MCPClient.sse_config(
54
53
  base_url: 'https://api.example.com/sse',
55
54
  headers: { 'Authorization' => 'Bearer YOUR_TOKEN' },
56
- read_timeout: 30 # Optional timeout in seconds (default: 30)
57
- ),
58
- # Remote HTTP JSON-RPC server
59
- MCPClient.http_config(
60
- base_url: 'https://api.example.com/jsonrpc',
61
- headers: { 'Authorization' => 'Bearer YOUR_TOKEN' },
62
55
  read_timeout: 30, # Optional timeout in seconds (default: 30)
63
56
  retries: 3, # Optional number of retry attempts (default: 0)
64
57
  retry_backoff: 1 # Optional backoff delay in seconds (default: 1)
@@ -205,15 +198,6 @@ The SSE client implementation provides these key features:
205
198
  - **JSON-RPC over SSE**: Full implementation of JSON-RPC 2.0 over SSE transport
206
199
  - **Streaming support**: Native streaming for real-time updates
207
200
 
208
- ### HTTP JSON-RPC Implementation
209
-
210
- The HTTP client implementation provides these key features:
211
-
212
- - **Resilient connection handling**: Manages HTTP/HTTPS connections with configurable timeouts
213
- - **Retry mechanism**: Configurable retry attempts with exponential backoff for transient errors
214
- - **Error handling**: Comprehensive error handling for network issues, timeouts, and malformed responses
215
- - **JSON-RPC over HTTP**: Standard JSON-RPC 2.0 implementation
216
-
217
201
  ## Requirements
218
202
 
219
203
  - Ruby >= 2.7.0
@@ -19,15 +19,6 @@ module MCPClient
19
19
  retry_backoff: config[:retry_backoff] || 1,
20
20
  logger: config[:logger]
21
21
  )
22
- when 'http'
23
- MCPClient::ServerHTTP.new(
24
- base_url: config[:base_url],
25
- headers: config[:headers] || {},
26
- read_timeout: config[:read_timeout] || 30,
27
- retries: config[:retries] || 0,
28
- retry_backoff: config[:retry_backoff] || 1,
29
- logger: config[:logger]
30
- )
31
22
  else
32
23
  raise ArgumentError, "Unknown server type: #{config[:type]}"
33
24
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module MCPClient
4
4
  # Current version of the MCP client gem
5
- VERSION = '0.2.0'
5
+ VERSION = '0.3.0'
6
6
  end
data/lib/mcp_client.rb CHANGED
@@ -6,7 +6,6 @@ require_relative 'mcp_client/tool'
6
6
  require_relative 'mcp_client/server_base'
7
7
  require_relative 'mcp_client/server_stdio'
8
8
  require_relative 'mcp_client/server_sse'
9
- require_relative 'mcp_client/server_http'
10
9
  require_relative 'mcp_client/server_factory'
11
10
  require_relative 'mcp_client/client'
12
11
  require_relative 'mcp_client/version'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-mcp-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Szymon Kurcab
@@ -81,7 +81,6 @@ files:
81
81
  - lib/mcp_client/errors.rb
82
82
  - lib/mcp_client/server_base.rb
83
83
  - lib/mcp_client/server_factory.rb
84
- - lib/mcp_client/server_http.rb
85
84
  - lib/mcp_client/server_sse.rb
86
85
  - lib/mcp_client/server_stdio.rb
87
86
  - lib/mcp_client/tool.rb
@@ -1,121 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'uri'
4
- require 'net/http'
5
- require 'json'
6
- require 'openssl'
7
- require 'logger'
8
-
9
- module MCPClient
10
- # Implementation of MCP server over HTTP JSON-RPC
11
- class ServerHTTP < ServerBase
12
- attr_reader :base_url, :headers, :read_timeout, :max_retries, :retry_backoff, :logger
13
-
14
- # @param base_url [String] The base URL of the MCP HTTP server
15
- # @param headers [Hash] HTTP headers to include in requests
16
- # @param read_timeout [Integer] Read timeout in seconds
17
- # @param retries [Integer] number of retry attempts on transient errors
18
- # @param retry_backoff [Numeric] base delay in seconds for exponential backoff
19
- # @param logger [Logger, nil] optional logger
20
- def initialize(base_url:, headers: {}, read_timeout: 30, retries: 0, retry_backoff: 1, logger: nil)
21
- super()
22
- @base_url = base_url
23
- @headers = headers
24
- @read_timeout = read_timeout
25
- @max_retries = retries
26
- @retry_backoff = retry_backoff
27
- @logger = logger || Logger.new($stdout, level: Logger::WARN)
28
- @request_id = 0
29
- end
30
-
31
- # List available tools
32
- # @return [Array<MCPClient::Tool>]
33
- def list_tools
34
- request_json = jsonrpc_request('tools/list', {})
35
- result = send_request(request_json)
36
- (result['tools'] || []).map { |td| MCPClient::Tool.from_json(td) }
37
- rescue MCPClient::Errors::MCPError
38
- raise
39
- rescue StandardError => e
40
- raise MCPClient::Errors::ToolCallError, "Error listing tools: #{e.message}"
41
- end
42
-
43
- # Call a tool with given parameters
44
- # @param tool_name [String]
45
- # @param parameters [Hash]
46
- # @return [Object] result of invocation
47
- def call_tool(tool_name, parameters)
48
- request_json = jsonrpc_request('tools/call', { 'name' => tool_name, 'arguments' => parameters })
49
- send_request(request_json)
50
- rescue MCPClient::Errors::MCPError
51
- raise
52
- rescue StandardError => e
53
- raise MCPClient::Errors::ToolCallError, "Error calling tool '#{tool_name}': #{e.message}"
54
- end
55
-
56
- # Streaming is not supported over simple HTTP transport; fallback to single response
57
- # @param tool_name [String]
58
- # @param parameters [Hash]
59
- # @return [Enumerator]
60
- def call_tool_streaming(tool_name, parameters)
61
- Enumerator.new do |yielder|
62
- yielder << call_tool(tool_name, parameters)
63
- end
64
- end
65
-
66
- private
67
-
68
- def jsonrpc_request(method, params)
69
- @request_id += 1
70
- {
71
- 'jsonrpc' => '2.0',
72
- 'id' => @request_id,
73
- 'method' => method,
74
- 'params' => params
75
- }
76
- end
77
-
78
- def send_request(request)
79
- attempts = 0
80
- begin
81
- attempts += 1
82
- uri = URI.parse(base_url)
83
- http = Net::HTTP.new(uri.host, uri.port)
84
- if uri.scheme == 'https'
85
- http.use_ssl = true
86
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
87
- end
88
- http.open_timeout = 10
89
- http.read_timeout = read_timeout
90
-
91
- @logger.debug("Sending HTTP JSONRPC request: #{request.to_json}")
92
- response = http.post(uri.path, request.to_json, default_headers)
93
- @logger.debug("Received HTTP response: #{response.code} #{response.body}")
94
-
95
- unless response.is_a?(Net::HTTPSuccess)
96
- raise MCPClient::Errors::ServerError, "Server returned error: #{response.code} #{response.message}"
97
- end
98
-
99
- data = JSON.parse(response.body)
100
- raise MCPClient::Errors::ServerError, data['error']['message'] if data['error']
101
-
102
- data['result']
103
- rescue MCPClient::Errors::ServerError, MCPClient::Errors::TransportError, IOError, Timeout::Error => e
104
- raise unless attempts <= max_retries
105
-
106
- delay = retry_backoff * (2**(attempts - 1))
107
- @logger.debug("Retry attempt #{attempts} after error: #{e.message}, sleeping #{delay}s")
108
- sleep(delay)
109
- retry
110
- rescue JSON::ParserError => e
111
- raise MCPClient::Errors::TransportError, "Invalid JSON response: #{e.message}"
112
- end
113
- end
114
-
115
- def default_headers
116
- h = headers.dup
117
- h['Content-Type'] = 'application/json'
118
- h
119
- end
120
- end
121
- end