mcp-sdk.rb 0.1.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +63 -0
- data/lib/mcp/client.rb +108 -0
- data/lib/mcp/convert.rb +29 -0
- data/lib/mcp/sse_client.rb +90 -0
- data/lib/mcp/stdio_client.rb +112 -0
- data/lib/mcp/types.rb +37 -0
- data/lib/mcp.rb +9 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 11e337fa046c8b12a083f96718f78b050af34cbfdcd3df7599c6240625123039
|
4
|
+
data.tar.gz: 492711d7e4b5796548f669d593eff579dc906ea3eeabdf29839c25187e2d0b32
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9f51739d8bf36abc3f9fcf356d7fc679f434590eb90c7abb2aa1a955d5a9e99b1c802beb5bc09bbb3c31e0078fa547a420042e3b3f34c0491e3d38a6fe49178f
|
7
|
+
data.tar.gz: cd9a155aa772476ffaa2c7cf3aa8ae509dd824292483e5133168df86bbdf5ef7522e88c8bd38e7df9b711d71c48e881d0cb031a1db55cd0eab10e7fa651d44d1
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# MCP SDK for Ruby
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/mcp-sdk.rb)
|
4
|
+
|
5
|
+
A Ruby implementation of the Model Context Protocol (MCP) for connecting to MCP servers.
|
6
|
+
|
7
|
+
## Features
|
8
|
+
|
9
|
+
- Supports both SSE (Server-Sent Events) and Stdio-based MCP servers
|
10
|
+
- Type-safe client interfaces
|
11
|
+
- Easy integration with Ruby applications
|
12
|
+
- Comprehensive error handling
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Add this line to your application's Gemfile:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
gem 'mcp-sdk.rb'
|
20
|
+
```
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
```bash
|
25
|
+
$ bundle install
|
26
|
+
```
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
```bash
|
31
|
+
$ gem install mcp-sdk.rb
|
32
|
+
```
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
### Connecting to an SSE-based MCP server
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
require 'mcp-sdk.rb'
|
40
|
+
client = MCP::SSEClient.new('http://example.com/sse?key=api_key')
|
41
|
+
client.start
|
42
|
+
mcp_server_json = client.list_tools
|
43
|
+
puts JSON.pretty_generate(convertFormat(mcp_server_json))
|
44
|
+
```
|
45
|
+
|
46
|
+
### Connecting to a Stdio-based MCP server
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
require 'mcp-sdk.rb'
|
50
|
+
|
51
|
+
client = MCP::StdioClient.new('nodejs path/to/server_executable.js')
|
52
|
+
client.start
|
53
|
+
mcp_server_json = client.list_tools
|
54
|
+
puts JSON.pretty_generate(convertFormat(mcp_server_json))
|
55
|
+
```
|
56
|
+
|
57
|
+
## Contributing
|
58
|
+
|
59
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/zhuangbiaowei/mcp-sdk.rb.
|
60
|
+
|
61
|
+
## License
|
62
|
+
|
63
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/lib/mcp/client.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
require "json"
|
2
|
+
require "childprocess"
|
3
|
+
require "timeout"
|
4
|
+
|
5
|
+
module MCP
|
6
|
+
class Error < StandardError; end
|
7
|
+
|
8
|
+
class Client
|
9
|
+
def initialize(server_cmd)
|
10
|
+
cmd, server_path = server_cmd.split(" ")
|
11
|
+
@server = ChildProcess.build(cmd, server_path)
|
12
|
+
@stdout, @stdout_writer = IO.pipe
|
13
|
+
@stderr, @stderr_writer = IO.pipe
|
14
|
+
@server.io.stdout = @stdout_writer
|
15
|
+
@server.io.stderr = @stderr_writer
|
16
|
+
@server.duplex = true
|
17
|
+
@request_id = 0
|
18
|
+
@pending_requests = {}
|
19
|
+
@response_queue = Queue.new
|
20
|
+
@running = false
|
21
|
+
end
|
22
|
+
|
23
|
+
def start
|
24
|
+
@server.start
|
25
|
+
sleep 0.5 # Wait for server startup
|
26
|
+
@running = true
|
27
|
+
setup_io_handlers
|
28
|
+
end
|
29
|
+
|
30
|
+
def stop
|
31
|
+
@running = false
|
32
|
+
@stdout_writer.close
|
33
|
+
@stderr_writer.close
|
34
|
+
@reader.join if @reader
|
35
|
+
@server.stop
|
36
|
+
@stdout.close
|
37
|
+
@stderr.close
|
38
|
+
end
|
39
|
+
|
40
|
+
def list_tools()
|
41
|
+
request_id = next_id
|
42
|
+
request = ListToolsRequest.new(request_id: request_id).to_json
|
43
|
+
write_request(request)
|
44
|
+
read_response(request_id)
|
45
|
+
end
|
46
|
+
|
47
|
+
def call_method(params)
|
48
|
+
request_id = next_id
|
49
|
+
request = CallMethodRequest.new(
|
50
|
+
request_id: request_id,
|
51
|
+
params: params,
|
52
|
+
).to_json
|
53
|
+
write_request(request)
|
54
|
+
read_response(request_id)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def next_id
|
60
|
+
@request_id += 1
|
61
|
+
end
|
62
|
+
|
63
|
+
def write_request(request)
|
64
|
+
@server.io.stdin.puts request
|
65
|
+
end
|
66
|
+
|
67
|
+
def setup_io_handlers
|
68
|
+
@reader = Thread.new do
|
69
|
+
while @running
|
70
|
+
begin
|
71
|
+
if line = @stdout.gets
|
72
|
+
handle_response(line)
|
73
|
+
end
|
74
|
+
rescue IOError => e
|
75
|
+
break unless @running
|
76
|
+
raise e
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def handle_response(line)
|
83
|
+
response = JSON.parse(line)
|
84
|
+
@pending_requests[response["id"]] = response
|
85
|
+
rescue JSON::ParserError
|
86
|
+
raise Error, "Invalid JSON response: #{line}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def read_response(request_id, timeout = 10)
|
90
|
+
Timeout.timeout(timeout) do
|
91
|
+
while !@pending_requests.key?(request_id)
|
92
|
+
sleep 0.1
|
93
|
+
end
|
94
|
+
response = @pending_requests.delete(request_id)
|
95
|
+
process_response(response)
|
96
|
+
end
|
97
|
+
rescue Timeout::Error
|
98
|
+
raise Error, "Timeout waiting for response"
|
99
|
+
end
|
100
|
+
|
101
|
+
def process_response(response)
|
102
|
+
if response["error"]
|
103
|
+
raise Error.new(response["error"]["message"])
|
104
|
+
end
|
105
|
+
response["result"]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/mcp/convert.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
def convertFormat(mcp_server_json)
|
2
|
+
toolCalling_json = {}
|
3
|
+
toolCalling_json["tools"] ||= []
|
4
|
+
mcp_server_json["tools"].each do |tool|
|
5
|
+
function = {}
|
6
|
+
function["name"] = tool["name"]
|
7
|
+
function["description"] = tool["description"]
|
8
|
+
function["parameters"] = {}
|
9
|
+
function["parameters"]["type"] = "object"
|
10
|
+
function["parameters"]["required"] = tool["inputSchema"]["required"] || []
|
11
|
+
tool["inputSchema"]["properties"].each do |prop_name, prop_def|
|
12
|
+
param_def = {
|
13
|
+
type: prop_def["type"],
|
14
|
+
description: prop_def["description"],
|
15
|
+
}
|
16
|
+
|
17
|
+
if prop_def["enum"]
|
18
|
+
param_def["enum"] = prop_def["enum"]
|
19
|
+
end
|
20
|
+
function["parameters"]["properties"] ||= {}
|
21
|
+
function["parameters"]["properties"][prop_name] = param_def
|
22
|
+
end
|
23
|
+
toolCalling_json["tools"] << {
|
24
|
+
"type": "function",
|
25
|
+
"function": function,
|
26
|
+
}
|
27
|
+
end
|
28
|
+
toolCalling_json
|
29
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require "uri"
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module MCP
|
6
|
+
class SSEClient < StdioClient
|
7
|
+
def initialize(url, opt = {})
|
8
|
+
@request_id = 0
|
9
|
+
@pending_requests = {}
|
10
|
+
@response_queue = Queue.new
|
11
|
+
@running = false
|
12
|
+
@endpoint = nil
|
13
|
+
@temp_chunk = nil
|
14
|
+
uri = URI(url)
|
15
|
+
@conn = Faraday.new(url: uri.origin) do |f|
|
16
|
+
f.adapter :net_http
|
17
|
+
f.options.timeout = 30 # read timeout
|
18
|
+
f.options.open_timeout = 10 # connection timeout
|
19
|
+
end
|
20
|
+
@thread = Thread.new do
|
21
|
+
loop do
|
22
|
+
begin
|
23
|
+
@conn.get do |req|
|
24
|
+
req.url uri.request_uri
|
25
|
+
req.headers["Accept"] = "text/event-stream; charset=utf-8"
|
26
|
+
req.headers["Accept-Encoding"] = "identity"
|
27
|
+
req.headers["Content-Type"] = "application/json"
|
28
|
+
|
29
|
+
req.options.on_data = proc do |chunk, overall_received_bytes|
|
30
|
+
if @temp_chunk == nil
|
31
|
+
@temp_chunk = chunk
|
32
|
+
else
|
33
|
+
@temp_chunk += chunk
|
34
|
+
end
|
35
|
+
event_type = @temp_chunk.split("\n")[0].split(":")[1].strip
|
36
|
+
data = @temp_chunk.split("\n")[1][5..-1].strip
|
37
|
+
if event_type == "endpoint"
|
38
|
+
@endpoint = data
|
39
|
+
@temp_chunk = nil
|
40
|
+
else
|
41
|
+
if verify_json(data) && event_type == "message"
|
42
|
+
handle_response(data)
|
43
|
+
@temp_chunk = nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
rescue Faraday::Error => e
|
49
|
+
#puts "SSE connection error: #{e.message}"
|
50
|
+
sleep 1
|
51
|
+
rescue => e
|
52
|
+
#puts "Unexpected error in SSE thread: #{e.message}"
|
53
|
+
sleep 1
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def verify_json(str)
|
60
|
+
JSON.parse(str)
|
61
|
+
true
|
62
|
+
rescue JSON::ParserError
|
63
|
+
false
|
64
|
+
end
|
65
|
+
|
66
|
+
def write_request(message)
|
67
|
+
while (@endpoint == nil)
|
68
|
+
sleep(0.2)
|
69
|
+
end
|
70
|
+
if @endpoint
|
71
|
+
@conn.post(@endpoint, message, { "content-type" => "application/json" })
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def start
|
76
|
+
request_id = next_id
|
77
|
+
write_request({
|
78
|
+
jsonrpc: "2.0",
|
79
|
+
id: request_id,
|
80
|
+
method: "initialize",
|
81
|
+
params: {
|
82
|
+
protocolVersion: "2025-04-28",
|
83
|
+
clientInfo: { name: "mcp-ruby-client", version: "0.0.1" },
|
84
|
+
},
|
85
|
+
}.to_json)
|
86
|
+
read_response(request_id)
|
87
|
+
write_request({ jsonrpc: "2.0", method: "notifications/initialized" }.to_json)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require "json"
|
2
|
+
require "childprocess"
|
3
|
+
require "timeout"
|
4
|
+
|
5
|
+
module MCP
|
6
|
+
class Error < StandardError; end
|
7
|
+
|
8
|
+
class StdioClient
|
9
|
+
def initialize(server_cmd)
|
10
|
+
cmds = server_cmd.split(" ")
|
11
|
+
@server = ChildProcess.build(*cmds)
|
12
|
+
@stdout, @stdout_writer = IO.pipe
|
13
|
+
@stderr, @stderr_writer = IO.pipe
|
14
|
+
@server.io.stdout = @stdout_writer
|
15
|
+
@server.io.stderr = @stderr_writer
|
16
|
+
@server.duplex = true
|
17
|
+
@request_id = 0
|
18
|
+
@pending_requests = {}
|
19
|
+
@response_queue = Queue.new
|
20
|
+
@running = false
|
21
|
+
end
|
22
|
+
|
23
|
+
def start
|
24
|
+
@server.start
|
25
|
+
sleep 0.5 # Wait for server startup
|
26
|
+
@running = true
|
27
|
+
setup_io_handlers
|
28
|
+
end
|
29
|
+
|
30
|
+
def stop
|
31
|
+
@running = false
|
32
|
+
@stdout_writer.close
|
33
|
+
@stderr_writer.close
|
34
|
+
@reader.join if @reader
|
35
|
+
@server.stop
|
36
|
+
@stdout.close
|
37
|
+
@stderr.close
|
38
|
+
end
|
39
|
+
|
40
|
+
def list_tools()
|
41
|
+
request_id = next_id
|
42
|
+
request = ListToolsRequest.new(request_id: request_id).to_json
|
43
|
+
write_request(request)
|
44
|
+
read_response(request_id)
|
45
|
+
end
|
46
|
+
|
47
|
+
def call_method(params)
|
48
|
+
request_id = next_id
|
49
|
+
request = CallMethodRequest.new(
|
50
|
+
request_id: request_id,
|
51
|
+
params: params,
|
52
|
+
).to_json
|
53
|
+
write_request(request)
|
54
|
+
read_response(request_id)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def next_id
|
60
|
+
@request_id += 1
|
61
|
+
end
|
62
|
+
|
63
|
+
def write_request(request)
|
64
|
+
begin
|
65
|
+
@server.io.stdin.puts request
|
66
|
+
rescue Errno::EPIPE => e
|
67
|
+
raise Error, "Server connection broken: #{e.message}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def setup_io_handlers
|
72
|
+
@reader = Thread.new do
|
73
|
+
while @running
|
74
|
+
begin
|
75
|
+
if line = @stdout.gets
|
76
|
+
handle_response(line)
|
77
|
+
end
|
78
|
+
rescue IOError => e
|
79
|
+
break unless @running
|
80
|
+
raise e
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def handle_response(line)
|
87
|
+
response = JSON.parse(line)
|
88
|
+
@pending_requests[response["id"]] = response
|
89
|
+
rescue JSON::ParserError
|
90
|
+
raise Error, "Invalid JSON response: #{line}"
|
91
|
+
end
|
92
|
+
|
93
|
+
def read_response(request_id, timeout = 10)
|
94
|
+
Timeout.timeout(timeout) do
|
95
|
+
while !@pending_requests.key?(request_id)
|
96
|
+
sleep 0.1
|
97
|
+
end
|
98
|
+
response = @pending_requests.delete(request_id)
|
99
|
+
process_response(response)
|
100
|
+
end
|
101
|
+
rescue Timeout::Error
|
102
|
+
raise Error, "Timeout waiting for response"
|
103
|
+
end
|
104
|
+
|
105
|
+
def process_response(response)
|
106
|
+
if response["error"]
|
107
|
+
raise Error.new(response["error"]["message"])
|
108
|
+
end
|
109
|
+
response["result"]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/lib/mcp/types.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module MCP
|
2
|
+
class Request
|
3
|
+
def initialize(jsonrpc: nil, request_id: nil, method: nil, params: {})
|
4
|
+
@jsonrpc = jsonrpc
|
5
|
+
@id = request_id
|
6
|
+
@method = method
|
7
|
+
@params = params
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_json
|
11
|
+
{
|
12
|
+
"jsonrpc": @jsonrpc,
|
13
|
+
"id": @id,
|
14
|
+
"method": @method,
|
15
|
+
"params": @params,
|
16
|
+
}.to_json
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class JSONRPCRequest < Request
|
21
|
+
def initialize(request_id: nil, method: nil, params: {})
|
22
|
+
super(jsonrpc: "2.0", request_id: request_id, method: method, params: params)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class ListToolsRequest < JSONRPCRequest
|
27
|
+
def initialize(request_id: 0)
|
28
|
+
super(request_id: request_id, method: "tools/list")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class CallMethodRequest < JSONRPCRequest
|
33
|
+
def initialize(request_id: 0, params:)
|
34
|
+
super(request_id: request_id, method: "tools/call", params: params)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/mcp.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require File.expand_path("../mcp/types", __FILE__)
|
2
|
+
require File.expand_path("../mcp/client", __FILE__)
|
3
|
+
require File.expand_path("../mcp/stdio_client", __FILE__)
|
4
|
+
require File.expand_path("../mcp/sse_client", __FILE__)
|
5
|
+
require File.expand_path("../mcp/convert", __FILE__)
|
6
|
+
|
7
|
+
module MCP
|
8
|
+
LATEST_PROTOCOL_VERSION = "2024-11-05".freeze
|
9
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mcp-sdk.rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Zhuang Biaowei
|
8
|
+
bindir: bin
|
9
|
+
cert_chain: []
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: json
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 2.7.1
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 2.7.1
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: faraday
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.0.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 2.0.0
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: bundler
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2.0'
|
47
|
+
type: :development
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: rake
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '13.0'
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '13.0'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rspec
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.0'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '3.0'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rubocop
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.0'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '1.0'
|
96
|
+
description: A Ruby SDK for the MCP (Multi-Channel Protocol) implementation
|
97
|
+
email:
|
98
|
+
- zbw@kaiyuanshe.org
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- LICENSE
|
104
|
+
- README.md
|
105
|
+
- lib/mcp.rb
|
106
|
+
- lib/mcp/client.rb
|
107
|
+
- lib/mcp/convert.rb
|
108
|
+
- lib/mcp/sse_client.rb
|
109
|
+
- lib/mcp/stdio_client.rb
|
110
|
+
- lib/mcp/types.rb
|
111
|
+
homepage: https://github.com/zhuangbiaowei/mcp-sdk.rb
|
112
|
+
licenses:
|
113
|
+
- MIT
|
114
|
+
metadata: {}
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 3.0.0
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubygems_version: 3.6.8
|
130
|
+
specification_version: 4
|
131
|
+
summary: MCP SDK for Ruby
|
132
|
+
test_files: []
|