diff --git a/lib/mcp/prompt.rb b/lib/mcp/prompt.rb index 9445cf7..128ee47 100644 --- a/lib/mcp/prompt.rb +++ b/lib/mcp/prompt.rb @@ -20,7 +20,7 @@ def to_h name: name_value, title: title_value, description: description_value, - icons: icons&.map(&:to_h), + icons: icons_value&.then { |icons| icons.empty? ? nil : icons.map(&:to_h) }, arguments: arguments_value&.map(&:to_h), _meta: meta_value, }.compact diff --git a/lib/mcp/resource.rb b/lib/mcp/resource.rb index 95b74b0..6f06d36 100644 --- a/lib/mcp/resource.rb +++ b/lib/mcp/resource.rb @@ -19,7 +19,7 @@ def to_h name: name, title: title, description: description, - icons: icons.map(&:to_h), + icons: icons&.then { |icons| icons.empty? ? nil : icons.map(&:to_h) }, mimeType: mime_type, }.compact end diff --git a/lib/mcp/resource_template.rb b/lib/mcp/resource_template.rb index bfb3c54..871600e 100644 --- a/lib/mcp/resource_template.rb +++ b/lib/mcp/resource_template.rb @@ -19,7 +19,7 @@ def to_h name: name, title: title, description: description, - icons: icons.map(&:to_h), + icons: icons&.then { |icons| icons.empty? ? nil : icons.map(&:to_h) }, mimeType: mime_type, }.compact end diff --git a/lib/mcp/server.rb b/lib/mcp/server.rb index 74c014d..e5b4711 100644 --- a/lib/mcp/server.rb +++ b/lib/mcp/server.rb @@ -290,7 +290,7 @@ def default_capabilities def server_info @server_info ||= { description: description, - icons: icons, + icons: icons&.then { |icons| icons.empty? ? nil : icons.map(&:to_h) }, name: name, title: title, version: version, diff --git a/lib/mcp/tool.rb b/lib/mcp/tool.rb index b1d2ad0..6c86ce5 100644 --- a/lib/mcp/tool.rb +++ b/lib/mcp/tool.rb @@ -21,7 +21,7 @@ def to_h name: name_value, title: title_value, description: description_value, - icons: icons&.map(&:to_h), + icons: icons_value&.then { |icons| icons.empty? ? nil : icons.map(&:to_h) }, inputSchema: input_schema_value.to_h, outputSchema: @output_schema_value&.to_h, annotations: annotations_value&.to_h, diff --git a/test/mcp/prompt_test.rb b/test/mcp/prompt_test.rb index 16bb584..a434e06 100644 --- a/test/mcp/prompt_test.rb +++ b/test/mcp/prompt_test.rb @@ -195,5 +195,24 @@ class NoArgumentsPrompt < Prompt assert_equal expected, prompt.to_h end + + test "#to_h does not have `:icons` key when icons is empty" do + prompt = Prompt.define( + name: "prompt_without_icons", + description: "a prompt without icons", + ) + + refute prompt.to_h.key?(:icons) + end + + test "#to_h does not have `:icons` key when icons is nil" do + prompt = Prompt.define( + name: "prompt_without_icons", + description: "a prompt without icons", + icons: nil, + ) + + refute prompt.to_h.key?(:icons) + end end end diff --git a/test/mcp/resource_template_test.rb b/test/mcp/resource_template_test.rb new file mode 100644 index 0000000..6b8a565 --- /dev/null +++ b/test/mcp/resource_template_test.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "test_helper" + +module MCP + class ResourceTemplateTest < ActiveSupport::TestCase + test "#to_h does not have `:icons` key when icons is empty" do + resource_template = ResourceTemplate.new( + uri_template: "file:///{path}", + name: "resource_template_without_icons", + description: "a resource template without icons", + ) + + refute resource_template.to_h.key?(:icons) + end + + test "#to_h does not have `:icons` key when icons is nil" do + resource_template = ResourceTemplate.new( + uri_template: "file:///{path}", + name: "resource_template_without_icons", + description: "a resource template without icons", + icons: nil, + ) + + refute resource_template.to_h.key?(:icons) + end + + test "#to_h includes icons when present" do + resource_template = ResourceTemplate.new( + uri_template: "file:///{path}", + name: "resource_template_with_icons", + description: "a resource template with icons", + icons: [Icon.new(mime_type: "image/png", sizes: ["48x48"], src: "https://example.com", theme: "light")], + ) + expected_icons = [{ mimeType: "image/png", sizes: ["48x48"], src: "https://example.com", theme: "light" }] + + assert_equal expected_icons, resource_template.to_h[:icons] + end + end +end diff --git a/test/mcp/resource_test.rb b/test/mcp/resource_test.rb new file mode 100644 index 0000000..9e78012 --- /dev/null +++ b/test/mcp/resource_test.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "test_helper" + +module MCP + class ResourceTest < ActiveSupport::TestCase + test "#to_h does not have `:icons` key when icons is empty" do + resource = Resource.new( + uri: "file:///test.txt", + name: "resource_without_icons", + description: "a resource without icons", + ) + + refute resource.to_h.key?(:icons) + end + + test "#to_h does not have `:icons` key when icons is nil" do + resource = Resource.new( + uri: "file:///test.txt", + name: "resource_without_icons", + description: "a resource without icons", + icons: nil, + ) + + refute resource.to_h.key?(:icons) + end + + test "#to_h includes icons when present" do + resource = Resource.new( + uri: "file:///test.txt", + name: "resource_with_icons", + description: "a resource with icons", + icons: [Icon.new(mime_type: "image/png", sizes: ["48x48"], src: "https://example.com", theme: "light")], + ) + expected_icons = [{ mimeType: "image/png", sizes: ["48x48"], src: "https://example.com", theme: "light" }] + + assert_equal expected_icons, resource.to_h[:icons] + end + end +end diff --git a/test/mcp/server_test.rb b/test/mcp/server_test.rb index b9ef6e5..0f54cae 100644 --- a/test/mcp/server_test.rb +++ b/test/mcp/server_test.rb @@ -895,6 +895,46 @@ class Example < Tool refute response[:result][:serverInfo].key?(:website_url) end + test "server response does not include icons when icons is empty" do + server = Server.new(name: "test_server") + request = { + jsonrpc: "2.0", + method: "initialize", + id: 1, + } + response = server.handle(request) + + refute response[:result][:serverInfo].key?(:icons) + end + + test "server response does not include icons when icons is nil" do + server = Server.new(name: "test_server", icons: nil) + request = { + jsonrpc: "2.0", + method: "initialize", + id: 1, + } + response = server.handle(request) + + refute response[:result][:serverInfo].key?(:icons) + end + + test "server response includes icons when icons is present" do + server = Server.new( + name: "test_server", + icons: [Icon.new(mime_type: "image/png", sizes: ["48x48"], src: "https://example.com", theme: "light")], + ) + request = { + jsonrpc: "2.0", + method: "initialize", + id: 1, + } + response = server.handle(request) + expected_icons = [{ mimeType: "image/png", sizes: ["48x48"], src: "https://example.com", theme: "light" }] + + assert_equal expected_icons, response[:result][:serverInfo][:icons] + end + test "server uses default version when not configured" do server = Server.new(name: "test_server") request = { diff --git a/test/mcp/tool_test.rb b/test/mcp/tool_test.rb index 3d8369c..ede3fbf 100644 --- a/test/mcp/tool_test.rb +++ b/test/mcp/tool_test.rb @@ -53,6 +53,25 @@ def call(message:, server_context: nil) refute tool.to_h.key?(:title) end + test "#to_h does not have `:icons` key when icons is empty" do + tool = Tool.define( + name: "tool_without_icons", + description: "a tool without icons", + ) + + refute tool.to_h.key?(:icons) + end + + test "#to_h does not have `:icons` key when icons is nil" do + tool = Tool.define( + name: "tool_without_icons", + description: "a tool without icons", + icons: nil, + ) + + refute tool.to_h.key?(:icons) + end + test "#to_h includes annotations when present" do tool = TestTool expected_annotations = {