Skip to content

Commit b94a938

Browse files
Merge pull request #54 from julianojulio/make_server_context_optional_and_sorbet_friendly
Make `server_context` optional for Tools and Prompts
2 parents db98dbc + 5d0c5b7 commit b94a938

File tree

6 files changed

+477
-24
lines changed

6 files changed

+477
-24
lines changed

lib/mcp/prompt.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class << self
99
attr_reader :description_value
1010
attr_reader :arguments_value
1111

12-
def template(args, server_context:)
12+
def template(args, server_context: nil)
1313
raise NotImplementedError, "Subclasses must implement template"
1414
end
1515

@@ -57,7 +57,7 @@ def define(name: nil, description: nil, arguments: [], &block)
5757
prompt_name name
5858
description description
5959
arguments arguments
60-
define_singleton_method(:template) do |args, server_context:|
60+
define_singleton_method(:template) do |args, server_context: nil|
6161
instance_exec(args, server_context:, &block)
6262
end
6363
end

lib/mcp/server.rb

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,7 @@ def call_tool(request)
243243
end
244244

245245
begin
246-
call_params = tool_call_parameters(tool)
247-
248-
if call_params.include?(:server_context)
249-
tool.call(**arguments.transform_keys(&:to_sym), server_context:).to_h
250-
else
251-
tool.call(**arguments.transform_keys(&:to_sym)).to_h
252-
end
246+
call_tool_with_args(tool, arguments)
253247
rescue => e
254248
raise RequestHandlerError.new("Internal error calling tool #{tool_name}", request, original_error: e)
255249
end
@@ -272,7 +266,7 @@ def get_prompt(request)
272266
prompt_args = request[:arguments]
273267
prompt.validate_arguments!(prompt_args)
274268

275-
prompt.template(prompt_args, server_context:).to_h
269+
call_prompt_template_with_args(prompt, prompt_args)
276270
end
277271

278272
def list_resources(request)
@@ -299,22 +293,29 @@ def index_resources_by_uri(resources)
299293
end
300294
end
301295

302-
def tool_call_parameters(tool)
303-
method_def = tool_call_method_def(tool)
304-
method_def.parameters.flatten
296+
def accepts_server_context?(method_object)
297+
parameters = method_object.parameters
298+
accepts_server_context = parameters.any? { |_type, name| name == :server_context }
299+
has_kwargs = parameters.any? { |type, _| type == :keyrest }
300+
301+
accepts_server_context || has_kwargs
305302
end
306303

307-
def tool_call_method_def(tool)
308-
method = tool.method(:call)
304+
def call_tool_with_args(tool, arguments)
305+
args = arguments.transform_keys(&:to_sym)
309306

310-
if defined?(T::Utils) && T::Utils.respond_to?(:signature_for_method)
311-
sorbet_typed_method_definition = T::Utils.signature_for_method(method)&.method
307+
if accepts_server_context?(tool.method(:call))
308+
tool.call(**args, server_context: server_context).to_h
309+
else
310+
tool.call(**args).to_h
311+
end
312+
end
312313

313-
# Return the Sorbet typed method definition if it exists, otherwise fallback to original method
314-
# definition if Sorbet is defined but not used by this tool.
315-
sorbet_typed_method_definition || method
314+
def call_prompt_template_with_args(prompt, args)
315+
if accepts_server_context?(prompt.method(:template))
316+
prompt.template(args, server_context: server_context).to_h
316317
else
317-
method
318+
prompt.template(args).to_h
318319
end
319320
end
320321
end

lib/mcp/tool.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class << self
99
attr_reader :input_schema_value
1010
attr_reader :annotations_value
1111

12-
def call(*args, server_context:)
12+
def call(*args, server_context: nil)
1313
raise NotImplementedError, "Subclasses must implement call"
1414
end
1515

0 commit comments

Comments
 (0)