diff --git a/lib/mcp.rb b/lib/mcp.rb index 84ccce4..6e8f144 100644 --- a/lib/mcp.rb +++ b/lib/mcp.rb @@ -19,6 +19,7 @@ require_relative "mcp/tool" require_relative "mcp/tool/input_schema" require_relative "mcp/tool/response" +require_relative "mcp/tool/error_response" require_relative "mcp/tool/annotations" require_relative "mcp/transport" require_relative "mcp/version" diff --git a/lib/mcp/tool/error_response.rb b/lib/mcp/tool/error_response.rb new file mode 100644 index 0000000..fbf5022 --- /dev/null +++ b/lib/mcp/tool/error_response.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module MCP + class Tool + class ErrorResponse + def initialize(content) = super(content, error: true) + end + end +end diff --git a/lib/mcp/tool/response.rb b/lib/mcp/tool/response.rb index abf6ff4..32e6e82 100644 --- a/lib/mcp/tool/response.rb +++ b/lib/mcp/tool/response.rb @@ -3,16 +3,18 @@ module MCP class Tool class Response - attr_reader :content, :is_error + attr_reader :content, :error - def initialize(content, is_error = false) + def initialize(content, error: false) @content = content - @is_error = is_error + @error = error end def to_h - { content:, isError: is_error }.compact + { content:, isError: error? }.compact end + + alias_method :error?, :error end end end diff --git a/test/mcp/tool/error_response.rb b/test/mcp/tool/error_response.rb new file mode 100644 index 0000000..33181e3 --- /dev/null +++ b/test/mcp/tool/error_response.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require "test_helper" + +module MCP + class Tool + class ErrorResponseTest < ActiveSupport::TestCase + test "#initialize with content" do + content = [{ + type: "text", + text: "Unauthorized", + }] + response = ErrorResponse.new(content) + + assert_equal content, response.content + assert response.error? + end + + test "#to_h" do + content = [{ + type: "text", + text: "Unauthorized", + }] + response = ErrorResponse.new(content) + actual = response.to_h + + assert_equal [:content, :isError].sort, actual.keys.sort + assert_equal content, actual[:content] + assert actual[:isError] + end + + test "#error?" do + response = ErrorResponse.new(nil) + assert response.error? + end + end + end +end diff --git a/test/mcp/tool/response_test.rb b/test/mcp/tool/response_test.rb new file mode 100644 index 0000000..e68f93b --- /dev/null +++ b/test/mcp/tool/response_test.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require "test_helper" + +module MCP + class Tool + class ResponseTest < ActiveSupport::TestCase + test "#initialize with content and error flag" do + content = [{ + type: "text", + text: "Unauthorized", + }] + response = Response.new(content, error: true) + + assert_equal content, response.content + assert response.error? + + response = Response.new(content, error: false) + assert_equal content, response.content + refute response.error? + + response = Response.new(content) + assert_equal content, response.content + refute response.error? + end + + test "#to_h" do + content = [{ + type: "text", + text: "Unauthorized", + }] + response = Response.new(content) + actual = response.to_h + + assert_equal [:content, :isError].sort, actual.keys.sort + assert_equal content, actual[:content] + refute actual[:isError] + + response = Response.new(content, error: true) + actual = response.to_h + assert_equal [:content, :isError].sort, actual.keys.sort + assert_equal content, actual[:content] + assert actual[:isError] + end + + test "#error?" do + response = Response.new(nil, error: true) + assert response.error? + + response = Response.new(nil, error: false) + refute response.error? + end + end + end +end diff --git a/test/mcp/tool_test.rb b/test/mcp/tool_test.rb index abd3fcb..76c9544 100644 --- a/test/mcp/tool_test.rb +++ b/test/mcp/tool_test.rb @@ -45,7 +45,7 @@ def call(message:, server_context: nil) tool = TestTool response = tool.call(message: "test") assert_equal response.content, [{ type: "text", content: "OK" }] - assert_equal response.is_error, false + refute response.error? end test "allows declarative definition of tools as classes" do @@ -250,7 +250,7 @@ def call(message:, server_context: nil) tool = TypedTestTool response = tool.call(message: "test") assert_equal response.content, [{ type: "text", content: "OK" }] - assert_equal response.is_error, false + refute response.error? end class TestToolWithoutServerContext < Tool