ruby-sdk
ruby-sdk copied to clipboard
"Internal error calling tool" following readme example
Describe the bug
class ApplicationController < ActionController::API
def mcp2
server = MCP::Server.new(
name: "rails-mcp",
version: "1.0.0",
tools: [SecretNumber]
)
render(json: server.handle_json(request.body.read))
end
end
class SecretNumber < MCP::Tool
class << self
def call(message:, server_context:)
MCP::Tool::Response.new([{
type: "text",
text: "1337",
}])
end
end
end
MCP.configure do |config|
config.exception_reporter = ->(exception, server_context) {
Rails.logger.error "MCP exception: #{exception.class} - #{exception.message}"
Rails.logger.error "Backtrace: #{exception.backtrace.join("\n")}"
}
end
I can connect to the MCP from calude code, when it tries to call the tool:
Server:
MCP exception: MCP::Server::RequestHandlerError - Internal error calling tool secret_number
Backtrace: /usr/local/bundle/gems/mcp-0.4.0/lib/mcp/server.rb:291:in 'MCP::Server#call_tool'
/usr/local/bundle/gems/mcp-0.4.0/lib/mcp/server.rb:215:in 'Method#call'
Client:
> give me a secret number
⏺ I'll use the secret number tool to get you a secret number.
⎿ Error: MCP error -32603: Internal error
⏺ I tried to use the mcp__test__secret_number tool, but it returned an internal error. This appears to be a test MCP server tool that may not be properly configured or
running.
v0.4.0
The underlying exception:
MCP exception: ArgumentError - wrong number of arguments (given 1, expected 2)
Backtrace: /app/app/controllers/application_controller.rb:29:in 'block in mcp2'
/usr/local/bundle/bundler/gems/ruby-sdk-da7603eb4d67/lib/mcp/server.rb:345:in 'MCP::Server#call_tool_with_args'
/usr/local/bundle/bundler/gems/ruby-sdk-da7603eb4d67/lib/mcp/server.rb:288:in 'MCP::Server#call_tool'
/usr/local/bundle/bundler/gems/ruby-sdk-da7603eb4d67/lib/mcp/server.rb:215:in 'Method#call'
Apparently this is incorrect:
define_tool() { |args, server_context| }
Instead:
define_tool() { |**args| }
Yeah, As an example, the block arguments needed to be written as |args, server_context:|. I opened #187 to fix this.
Thanks @koic. The class definition example doesn't work either..
Fails:
def self.call(message:, server_context:)
MCP::Tool::Response.new([{
type: "text",
text: "1337",
}])
end
def self.call(message, server_context:)
MCP::Tool::Response.new([{
type: "text",
text: "1337",
}])
end
Works:
def self.call(**args)
MCP::Tool::Response.new([{
type: "text",
text: "1337",
}])
end
Nevermind, looks like self.call is passed the inputs defined in input_schema plus server_context.