model-context-protocol-rb 0.3.4 → 0.4.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/CHANGELOG.md +18 -1
- data/README.md +745 -198
- data/lib/model_context_protocol/server/configuration.rb +79 -2
- data/lib/model_context_protocol/server/content.rb +321 -0
- data/lib/model_context_protocol/server/content_helpers.rb +84 -0
- data/lib/model_context_protocol/server/pagination.rb +71 -0
- data/lib/model_context_protocol/server/prompt.rb +106 -14
- data/lib/model_context_protocol/server/registry.rb +94 -18
- data/lib/model_context_protocol/server/resource.rb +95 -25
- data/lib/model_context_protocol/server/resource_template.rb +26 -13
- data/lib/model_context_protocol/server/streamable_http_transport.rb +211 -54
- data/lib/model_context_protocol/server/tool.rb +75 -53
- data/lib/model_context_protocol/server.rb +115 -18
- data/lib/model_context_protocol/version.rb +1 -1
- data/tasks/mcp.rake +28 -2
- data/tasks/templates/dev-http.erb +244 -0
- data/tasks/templates/dev.erb +7 -1
- metadata +6 -2
@@ -37,16 +37,21 @@ module ModelContextProtocol
|
|
37
37
|
|
38
38
|
private
|
39
39
|
|
40
|
-
|
41
|
-
private_constant :
|
40
|
+
SUPPORTED_PROTOCOL_VERSIONS = ["2025-06-18"].freeze
|
41
|
+
private_constant :SUPPORTED_PROTOCOL_VERSIONS
|
42
42
|
|
43
|
-
|
43
|
+
LATEST_PROTOCOL_VERSION = SUPPORTED_PROTOCOL_VERSIONS.first
|
44
|
+
private_constant :LATEST_PROTOCOL_VERSION
|
45
|
+
|
46
|
+
InitializeResponse = Data.define(:protocol_version, :capabilities, :server_info, :instructions) do
|
44
47
|
def serialized
|
45
|
-
{
|
48
|
+
response = {
|
46
49
|
protocolVersion: protocol_version,
|
47
50
|
capabilities: capabilities,
|
48
51
|
serverInfo: server_info
|
49
52
|
}
|
53
|
+
response[:instructions] = instructions if instructions
|
54
|
+
response
|
50
55
|
end
|
51
56
|
end
|
52
57
|
|
@@ -63,14 +68,26 @@ module ModelContextProtocol
|
|
63
68
|
end
|
64
69
|
|
65
70
|
def map_handlers
|
66
|
-
router.map("initialize") do |
|
71
|
+
router.map("initialize") do |message|
|
72
|
+
client_protocol_version = message["params"]&.dig("protocolVersion")
|
73
|
+
|
74
|
+
negotiated_version = if client_protocol_version && SUPPORTED_PROTOCOL_VERSIONS.include?(client_protocol_version)
|
75
|
+
client_protocol_version
|
76
|
+
else
|
77
|
+
LATEST_PROTOCOL_VERSION
|
78
|
+
end
|
79
|
+
|
80
|
+
server_info = {
|
81
|
+
name: configuration.name,
|
82
|
+
version: configuration.version
|
83
|
+
}
|
84
|
+
server_info[:title] = configuration.title if configuration.title
|
85
|
+
|
67
86
|
InitializeResponse[
|
68
|
-
protocol_version:
|
87
|
+
protocol_version: negotiated_version,
|
69
88
|
capabilities: build_capabilities,
|
70
|
-
server_info:
|
71
|
-
|
72
|
-
version: configuration.version
|
73
|
-
}
|
89
|
+
server_info: server_info,
|
90
|
+
instructions: configuration.instructions
|
74
91
|
]
|
75
92
|
end
|
76
93
|
|
@@ -112,8 +129,28 @@ module ModelContextProtocol
|
|
112
129
|
end
|
113
130
|
end
|
114
131
|
|
115
|
-
router.map("resources/list") do
|
116
|
-
|
132
|
+
router.map("resources/list") do |message|
|
133
|
+
params = message["params"] || {}
|
134
|
+
|
135
|
+
if configuration.pagination_enabled? && Server::Pagination.pagination_requested?(params)
|
136
|
+
opts = configuration.pagination_options
|
137
|
+
|
138
|
+
pagination_params = Server::Pagination.extract_pagination_params(
|
139
|
+
params,
|
140
|
+
default_page_size: opts[:default_page_size],
|
141
|
+
max_page_size: opts[:max_page_size]
|
142
|
+
)
|
143
|
+
|
144
|
+
configuration.registry.resources_data(
|
145
|
+
cursor: pagination_params[:cursor],
|
146
|
+
page_size: pagination_params[:page_size],
|
147
|
+
cursor_ttl: opts[:cursor_ttl]
|
148
|
+
)
|
149
|
+
else
|
150
|
+
configuration.registry.resources_data
|
151
|
+
end
|
152
|
+
rescue Server::Pagination::InvalidCursorError => e
|
153
|
+
raise ParameterValidationError, e.message
|
117
154
|
end
|
118
155
|
|
119
156
|
router.map("resources/read") do |message|
|
@@ -123,15 +160,55 @@ module ModelContextProtocol
|
|
123
160
|
raise ModelContextProtocol::Server::ParameterValidationError, "resource not found for #{uri}"
|
124
161
|
end
|
125
162
|
|
126
|
-
resource.call
|
163
|
+
resource.call
|
127
164
|
end
|
128
165
|
|
129
166
|
router.map("resources/templates/list") do |message|
|
130
|
-
|
167
|
+
params = message["params"] || {}
|
168
|
+
|
169
|
+
if configuration.pagination_enabled? && Server::Pagination.pagination_requested?(params)
|
170
|
+
opts = configuration.pagination_options
|
171
|
+
|
172
|
+
pagination_params = Server::Pagination.extract_pagination_params(
|
173
|
+
params,
|
174
|
+
default_page_size: opts[:default_page_size],
|
175
|
+
max_page_size: opts[:max_page_size]
|
176
|
+
)
|
177
|
+
|
178
|
+
configuration.registry.resource_templates_data(
|
179
|
+
cursor: pagination_params[:cursor],
|
180
|
+
page_size: pagination_params[:page_size],
|
181
|
+
cursor_ttl: opts[:cursor_ttl]
|
182
|
+
)
|
183
|
+
else
|
184
|
+
configuration.registry.resource_templates_data
|
185
|
+
end
|
186
|
+
rescue Server::Pagination::InvalidCursorError => e
|
187
|
+
raise ParameterValidationError, e.message
|
131
188
|
end
|
132
189
|
|
133
|
-
router.map("prompts/list") do
|
134
|
-
|
190
|
+
router.map("prompts/list") do |message|
|
191
|
+
params = message["params"] || {}
|
192
|
+
|
193
|
+
if configuration.pagination_enabled? && Server::Pagination.pagination_requested?(params)
|
194
|
+
opts = configuration.pagination_options
|
195
|
+
|
196
|
+
pagination_params = Server::Pagination.extract_pagination_params(
|
197
|
+
params,
|
198
|
+
default_page_size: opts[:default_page_size],
|
199
|
+
max_page_size: opts[:max_page_size]
|
200
|
+
)
|
201
|
+
|
202
|
+
configuration.registry.prompts_data(
|
203
|
+
cursor: pagination_params[:cursor],
|
204
|
+
page_size: pagination_params[:page_size],
|
205
|
+
cursor_ttl: opts[:cursor_ttl]
|
206
|
+
)
|
207
|
+
else
|
208
|
+
configuration.registry.prompts_data
|
209
|
+
end
|
210
|
+
rescue Server::Pagination::InvalidCursorError => e
|
211
|
+
raise ParameterValidationError, e.message
|
135
212
|
end
|
136
213
|
|
137
214
|
router.map("prompts/get") do |message|
|
@@ -143,8 +220,28 @@ module ModelContextProtocol
|
|
143
220
|
.call(symbolized_arguments, configuration.logger, configuration.context)
|
144
221
|
end
|
145
222
|
|
146
|
-
router.map("tools/list") do
|
147
|
-
|
223
|
+
router.map("tools/list") do |message|
|
224
|
+
params = message["params"] || {}
|
225
|
+
|
226
|
+
if configuration.pagination_enabled? && Server::Pagination.pagination_requested?(params)
|
227
|
+
opts = configuration.pagination_options
|
228
|
+
|
229
|
+
pagination_params = Server::Pagination.extract_pagination_params(
|
230
|
+
params,
|
231
|
+
default_page_size: opts[:default_page_size],
|
232
|
+
max_page_size: opts[:max_page_size]
|
233
|
+
)
|
234
|
+
|
235
|
+
configuration.registry.tools_data(
|
236
|
+
cursor: pagination_params[:cursor],
|
237
|
+
page_size: pagination_params[:page_size],
|
238
|
+
cursor_ttl: opts[:cursor_ttl]
|
239
|
+
)
|
240
|
+
else
|
241
|
+
configuration.registry.tools_data
|
242
|
+
end
|
243
|
+
rescue Server::Pagination::InvalidCursorError => e
|
244
|
+
raise ParameterValidationError, e.message
|
148
245
|
end
|
149
246
|
|
150
247
|
router.map("tools/call") do |message|
|
data/tasks/mcp.rake
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require "fileutils"
|
2
2
|
|
3
3
|
namespace :mcp do
|
4
|
-
desc "Generate the development server executable with the correct Ruby path"
|
5
|
-
task :
|
4
|
+
desc "Generate the STDIO development server executable with the correct Ruby path"
|
5
|
+
task :generate_stdio_server do
|
6
6
|
destination_path = "bin/dev"
|
7
7
|
template_path = File.expand_path("templates/dev.erb", __dir__)
|
8
8
|
|
@@ -27,6 +27,32 @@ namespace :mcp do
|
|
27
27
|
puts "Using Ruby path: #{ruby_path}"
|
28
28
|
end
|
29
29
|
|
30
|
+
desc "Generate the streamable HTTP development server executable with the correct Ruby path"
|
31
|
+
task :generate_streamable_http_server do
|
32
|
+
destination_path = "bin/dev-http"
|
33
|
+
template_path = File.expand_path("templates/dev-http.erb", __dir__)
|
34
|
+
|
35
|
+
# Create directory if it doesn't exist
|
36
|
+
FileUtils.mkdir_p(File.dirname(destination_path))
|
37
|
+
|
38
|
+
# Get the Ruby path
|
39
|
+
ruby_path = detect_ruby_path
|
40
|
+
|
41
|
+
# Read and process the template
|
42
|
+
template = File.read(template_path)
|
43
|
+
content = template.gsub("<%= @ruby_path %>", ruby_path)
|
44
|
+
|
45
|
+
# Write the executable
|
46
|
+
File.write(destination_path, content)
|
47
|
+
|
48
|
+
# Set permissions
|
49
|
+
FileUtils.chmod(0o755, destination_path)
|
50
|
+
|
51
|
+
# Show success message
|
52
|
+
puts "\nCreated executable at: #{File.expand_path(destination_path)}"
|
53
|
+
puts "Using Ruby path: #{ruby_path}"
|
54
|
+
end
|
55
|
+
|
30
56
|
def detect_ruby_path
|
31
57
|
# Get Ruby version from project config
|
32
58
|
ruby_version = get_project_ruby_version
|
@@ -0,0 +1,244 @@
|
|
1
|
+
#!/usr/bin/env <%= @ruby_path %>
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "rack"
|
5
|
+
require 'rackup/handler/webrick'
|
6
|
+
require "webrick"
|
7
|
+
require "securerandom"
|
8
|
+
require "redis"
|
9
|
+
require "logger"
|
10
|
+
require "json"
|
11
|
+
require 'stringio'
|
12
|
+
|
13
|
+
require_relative "../lib/model_context_protocol"
|
14
|
+
|
15
|
+
Dir[File.join(__dir__, "../spec/support/**/*.rb")].each { |file| require file }
|
16
|
+
|
17
|
+
logger = Logger.new(STDOUT)
|
18
|
+
logger.level = Logger::INFO
|
19
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
20
|
+
request_id = Thread.current[:request_id] || "----"
|
21
|
+
"[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}] #{severity} [#{request_id}]: #{msg}\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
class MCPHttpApp
|
26
|
+
def initialize(logger)
|
27
|
+
@logger = logger
|
28
|
+
end
|
29
|
+
|
30
|
+
def call(env)
|
31
|
+
request_id = SecureRandom.hex(4)
|
32
|
+
Thread.current[:request_id] = request_id
|
33
|
+
|
34
|
+
request = Rack::Request.new(env)
|
35
|
+
body_content = request.body.read
|
36
|
+
|
37
|
+
case env['REQUEST_METHOD']
|
38
|
+
when 'POST'
|
39
|
+
begin
|
40
|
+
request_json = JSON.parse(body_content)
|
41
|
+
method = request_json['method']
|
42
|
+
id = request_json['id']
|
43
|
+
|
44
|
+
if method&.start_with?('notifications/')
|
45
|
+
@logger.info("→ #{method} [NOTIFICATION]")
|
46
|
+
elsif id.nil?
|
47
|
+
@logger.info("→ #{method} [NOTIFICATION]")
|
48
|
+
else
|
49
|
+
@logger.info("→ #{method} (id: #{id}) [REQUEST]")
|
50
|
+
end
|
51
|
+
@logger.info(" Request: #{body_content}")
|
52
|
+
rescue JSON::ParserError
|
53
|
+
@logger.info("→ POST #{env['PATH_INFO']} [INVALID JSON]")
|
54
|
+
@logger.info(" Request: #{body_content}")
|
55
|
+
end
|
56
|
+
when 'GET'
|
57
|
+
accept_header = env['HTTP_ACCEPT'] || ''
|
58
|
+
if accept_header.include?('text/event-stream')
|
59
|
+
@logger.info("→ GET #{env['PATH_INFO']} [SSE STREAM REQUEST]")
|
60
|
+
else
|
61
|
+
@logger.info("→ GET #{env['PATH_INFO']}")
|
62
|
+
end
|
63
|
+
@logger.info(" Headers: Accept=#{accept_header}") unless accept_header.empty?
|
64
|
+
when 'DELETE'
|
65
|
+
session_id = env['HTTP_MCP_SESSION_ID']
|
66
|
+
if session_id
|
67
|
+
@logger.info("→ DELETE #{env['PATH_INFO']} [SESSION CLEANUP: #{session_id}]")
|
68
|
+
else
|
69
|
+
@logger.info("→ DELETE #{env['PATH_INFO']} [SESSION CLEANUP]")
|
70
|
+
end
|
71
|
+
else
|
72
|
+
@logger.info("→ #{env['REQUEST_METHOD']} #{env['PATH_INFO']}")
|
73
|
+
@logger.info(" Request: #{body_content}") unless body_content.empty?
|
74
|
+
end
|
75
|
+
|
76
|
+
env['rack.input'] = StringIO.new(body_content)
|
77
|
+
request = Rack::Request.new(env)
|
78
|
+
|
79
|
+
unless request.path == "/mcp"
|
80
|
+
return [404, {"Content-Type" => "application/json"}, ['{"error": "Not found"}']]
|
81
|
+
end
|
82
|
+
|
83
|
+
if request.request_method == "OPTIONS"
|
84
|
+
return [200, {
|
85
|
+
"Access-Control-Allow-Origin" => "*",
|
86
|
+
"Access-Control-Allow-Methods" => "GET, POST, DELETE, OPTIONS",
|
87
|
+
"Access-Control-Allow-Headers" => "Content-Type, Accept, Mcp-Session-Id, MCP-Protocol-Version, Origin",
|
88
|
+
"Access-Control-Max-Age" => "86400"
|
89
|
+
}, [""]]
|
90
|
+
end
|
91
|
+
|
92
|
+
begin
|
93
|
+
redis_client = Redis.new(url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0"))
|
94
|
+
@logger.debug("Testing Redis connection...")
|
95
|
+
redis_client.ping
|
96
|
+
@logger.info("Redis connected successfully")
|
97
|
+
end
|
98
|
+
|
99
|
+
transport_config = {
|
100
|
+
type: :streamable_http,
|
101
|
+
env: env,
|
102
|
+
redis_client: redis_client,
|
103
|
+
require_sessions: false, # Optional sessions for easier testing
|
104
|
+
session_ttl: 3600,
|
105
|
+
validate_origin: false, # Disable for testing
|
106
|
+
allowed_origins: ["*"]
|
107
|
+
}
|
108
|
+
|
109
|
+
@logger.debug("Creating MCP server with transport config")
|
110
|
+
server = create_mcp_server(transport_config)
|
111
|
+
|
112
|
+
begin
|
113
|
+
@logger.debug("Starting MCP server")
|
114
|
+
result = server.start
|
115
|
+
|
116
|
+
case result
|
117
|
+
when Hash
|
118
|
+
if result[:stream]
|
119
|
+
@logger.info("← SSE STREAM OPENED [PERSISTENT CONNECTION]")
|
120
|
+
@logger.info(" Connection will remain open for real-time notifications")
|
121
|
+
headers = result[:headers] || {}
|
122
|
+
headers["Access-Control-Allow-Origin"] = "*"
|
123
|
+
headers["Access-Control-Allow-Methods"] = "GET, POST, DELETE, OPTIONS"
|
124
|
+
headers["Access-Control-Allow-Headers"] = "Content-Type, Accept, Mcp-Session-Id, MCP-Protocol-Version, Origin"
|
125
|
+
|
126
|
+
return [200, headers, result[:stream_proc]]
|
127
|
+
elsif result[:json]
|
128
|
+
response_body = result[:json].to_json
|
129
|
+
status = result[:status] || 200
|
130
|
+
|
131
|
+
begin
|
132
|
+
response_json = result[:json]
|
133
|
+
if response_json[:error]
|
134
|
+
@logger.info("← ERROR RESPONSE (code: #{response_json[:error][:code]})")
|
135
|
+
elsif status == 202
|
136
|
+
@logger.info("← NOTIFICATION ACCEPTED [NO RESPONSE REQUIRED]")
|
137
|
+
elsif response_json[:result]
|
138
|
+
method = request_json['method'] rescue 'unknown'
|
139
|
+
@logger.info("← #{method} RESPONSE (id: #{response_json[:id]})")
|
140
|
+
else
|
141
|
+
@logger.info("← RESPONSE (status: #{status})")
|
142
|
+
end
|
143
|
+
@logger.info(" Response: #{response_body}") unless status == 202 && response_body == '{}'
|
144
|
+
rescue
|
145
|
+
@logger.info("← RESPONSE (status: #{status})")
|
146
|
+
@logger.info(" Response: #{response_body}") unless response_body.empty?
|
147
|
+
end
|
148
|
+
|
149
|
+
headers = result[:headers] || {}
|
150
|
+
headers["Content-Type"] = "application/json"
|
151
|
+
headers["Access-Control-Allow-Origin"] = "*"
|
152
|
+
headers["Access-Control-Allow-Methods"] = "GET, POST, DELETE, OPTIONS"
|
153
|
+
headers["Access-Control-Allow-Headers"] = "Content-Type, Accept, Mcp-Session-Id, MCP-Protocol-Version, Origin"
|
154
|
+
|
155
|
+
[result[:status] || 200, headers, [response_body]]
|
156
|
+
else
|
157
|
+
# Fallback
|
158
|
+
@logger.error("← Invalid transport response")
|
159
|
+
[500, {"Content-Type" => "application/json"}, ['{"error": "Invalid transport response"}']]
|
160
|
+
end
|
161
|
+
else
|
162
|
+
@logger.error("← Unexpected response format")
|
163
|
+
[500, {"Content-Type" => "application/json"}, ['{"error": "Unexpected response format"}']]
|
164
|
+
end
|
165
|
+
rescue => e
|
166
|
+
@logger.error("Error handling request: #{e.message}")
|
167
|
+
@logger.debug("Full backtrace:\n#{e.backtrace.join("\n")}")
|
168
|
+
[500, {"Content-Type" => "application/json"}, [%Q({"error": "Internal server error: #{e.message}"})]]
|
169
|
+
ensure
|
170
|
+
Thread.current[:request_id] = nil
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
def create_mcp_server(transport_config)
|
177
|
+
ModelContextProtocol::Server.new do |config|
|
178
|
+
config.name = "MCP Development Server"
|
179
|
+
config.version = "1.0.0"
|
180
|
+
config.logging_enabled = true
|
181
|
+
|
182
|
+
config.pagination = {
|
183
|
+
default_page_size: 2,
|
184
|
+
max_page_size: 3,
|
185
|
+
cursor_ttl: 1800
|
186
|
+
}
|
187
|
+
|
188
|
+
config.set_environment_variable("MCP_ENV", "development")
|
189
|
+
|
190
|
+
config.context = {
|
191
|
+
user_id: "123456",
|
192
|
+
request_id: Thread.current[:request_id]
|
193
|
+
}
|
194
|
+
|
195
|
+
config.transport = transport_config
|
196
|
+
|
197
|
+
config.registry = ModelContextProtocol::Server::Registry.new do
|
198
|
+
prompts list_changed: true do
|
199
|
+
register TestPrompt
|
200
|
+
register TestPromptWithCompletionClass
|
201
|
+
end
|
202
|
+
|
203
|
+
resources list_changed: true, subscribe: true do
|
204
|
+
register TestResource
|
205
|
+
register TestAnnotatedResource
|
206
|
+
register TestBinaryResource
|
207
|
+
end
|
208
|
+
|
209
|
+
resource_templates do
|
210
|
+
register TestResourceTemplate
|
211
|
+
end
|
212
|
+
|
213
|
+
tools list_changed: true do
|
214
|
+
register TestToolWithStructuredContentResponse
|
215
|
+
register TestToolWithTextResponse
|
216
|
+
register TestToolWithImageResponse
|
217
|
+
register TestToolWithMixedContentResponse
|
218
|
+
register TestToolWithResourceResponse
|
219
|
+
register TestToolWithToolErrorResponse
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
logger.info("Starting MCP HTTP Development Server on http://localhost:9292/mcp")
|
227
|
+
|
228
|
+
app = Rack::Builder.new do
|
229
|
+
map '/mcp' do
|
230
|
+
run MCPHttpApp.new(logger)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
server = WEBrick::HTTPServer.new(Port: 9292, Host: '0.0.0.0')
|
235
|
+
server.mount '/', Rackup::Handler::WEBrick, app
|
236
|
+
|
237
|
+
['INT', 'TERM'].each do |signal|
|
238
|
+
Signal.trap(signal) do
|
239
|
+
server.shutdown
|
240
|
+
exit(0)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
server.start
|
data/tasks/templates/dev.erb
CHANGED
@@ -11,6 +11,12 @@ server = ModelContextProtocol::Server.new do |config|
|
|
11
11
|
config.version = "1.0.0"
|
12
12
|
config.logging_enabled = true
|
13
13
|
|
14
|
+
config.pagination = {
|
15
|
+
default_page_size: 10,
|
16
|
+
max_page_size: 20,
|
17
|
+
cursor_ttl: 1800
|
18
|
+
}
|
19
|
+
|
14
20
|
config.set_environment_variable("MCP_ENV", "development")
|
15
21
|
|
16
22
|
config.context = {
|
@@ -25,6 +31,7 @@ server = ModelContextProtocol::Server.new do |config|
|
|
25
31
|
|
26
32
|
resources list_changed: true, subscribe: true do
|
27
33
|
register TestResource
|
34
|
+
register TestAnnotatedResource
|
28
35
|
register TestBinaryResource
|
29
36
|
end
|
30
37
|
|
@@ -37,7 +44,6 @@ server = ModelContextProtocol::Server.new do |config|
|
|
37
44
|
register TestToolWithImageResponse
|
38
45
|
register TestToolWithImageResponseDefaultMimeType
|
39
46
|
register TestToolWithResourceResponse
|
40
|
-
register TestToolWithResourceResponseDefaultMimeType
|
41
47
|
register TestToolWithToolErrorResponse
|
42
48
|
end
|
43
49
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: model-context-protocol-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dick Davis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json-schema
|
@@ -58,7 +58,10 @@ files:
|
|
58
58
|
- lib/model_context_protocol/server.rb
|
59
59
|
- lib/model_context_protocol/server/completion.rb
|
60
60
|
- lib/model_context_protocol/server/configuration.rb
|
61
|
+
- lib/model_context_protocol/server/content.rb
|
62
|
+
- lib/model_context_protocol/server/content_helpers.rb
|
61
63
|
- lib/model_context_protocol/server/mcp_logger.rb
|
64
|
+
- lib/model_context_protocol/server/pagination.rb
|
62
65
|
- lib/model_context_protocol/server/prompt.rb
|
63
66
|
- lib/model_context_protocol/server/registry.rb
|
64
67
|
- lib/model_context_protocol/server/resource.rb
|
@@ -70,6 +73,7 @@ files:
|
|
70
73
|
- lib/model_context_protocol/server/tool.rb
|
71
74
|
- lib/model_context_protocol/version.rb
|
72
75
|
- tasks/mcp.rake
|
76
|
+
- tasks/templates/dev-http.erb
|
73
77
|
- tasks/templates/dev.erb
|
74
78
|
homepage: https://github.com/dickdavis/model-context-protocol-rb
|
75
79
|
licenses:
|