From a85fa028f71756abcb1d53ea6896e361d402e3bc Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 31 Jan 2026 15:15:19 +0900 Subject: [PATCH] Extract `MCP::Annotations` into a dedicated file This PR moves `MCP::Annotations` from lib/mcp.rb to lib/mcp/annotations.rb for better organization, following the pattern used for other classes such as `Tool::Annotations`. This PR also adds the missing `last_modified` attribute to `MCP::Annotations`: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-11-25/schema.ts#L1701-L1736 It also adds a `to_h` method for serialization and includes comprehensive test coverage. NOTE: This code is unused within the ruby-sdk repository, but it is kept for compatibility, as it may be used by users. --- lib/mcp.rb | 10 +----- lib/mcp/annotations.rb | 21 +++++++++++++ test/mcp/annotations_test.rb | 59 ++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 lib/mcp/annotations.rb create mode 100644 test/mcp/annotations_test.rb diff --git a/lib/mcp.rb b/lib/mcp.rb index c918f77..ac1f217 100644 --- a/lib/mcp.rb +++ b/lib/mcp.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require_relative "json_rpc_handler" +require_relative "mcp/annotations" require_relative "mcp/configuration" require_relative "mcp/content" require_relative "mcp/icon" @@ -39,13 +40,4 @@ def configuration @configuration ||= Configuration.new end end - - class Annotations - attr_reader :audience, :priority - - def initialize(audience: nil, priority: nil) - @audience = audience - @priority = priority - end - end end diff --git a/lib/mcp/annotations.rb b/lib/mcp/annotations.rb new file mode 100644 index 0000000..9674c73 --- /dev/null +++ b/lib/mcp/annotations.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module MCP + class Annotations + attr_reader :audience, :priority, :last_modified + + def initialize(audience: nil, priority: nil, last_modified: nil) + @audience = audience + @priority = priority + @last_modified = last_modified + end + + def to_h + { + audience: audience, + priority: priority, + lastModified: last_modified, + }.compact + end + end +end diff --git a/test/mcp/annotations_test.rb b/test/mcp/annotations_test.rb new file mode 100644 index 0000000..4253cd5 --- /dev/null +++ b/test/mcp/annotations_test.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require "test_helper" + +module MCP + class AnnotationsTest < ActiveSupport::TestCase + def test_initialization + annotations = Annotations.new(audience: ["developers"], priority: 0.8) + + assert_equal(["developers"], annotations.audience) + assert_equal(0.8, annotations.priority) + assert_nil(annotations.last_modified) + + assert_equal({ audience: ["developers"], priority: 0.8 }, annotations.to_h) + end + + def test_initialization_with_all_attributes + timestamp = Time.utc(2025, 1, 12, 15, 0, 58).iso8601 + annotations = Annotations.new(audience: ["developers"], priority: 0.8, last_modified: timestamp) + + assert_equal(["developers"], annotations.audience) + assert_equal(0.8, annotations.priority) + assert_equal(timestamp, annotations.last_modified) + + assert_equal({ audience: ["developers"], priority: 0.8, lastModified: timestamp }, annotations.to_h) + end + + def test_initialization_by_default + annotations = Annotations.new + + assert_nil(annotations.audience) + assert_nil(annotations.priority) + assert_nil(annotations.last_modified) + + assert_empty(annotations.to_h) + end + + def test_initialization_with_partial_attributes + annotations = Annotations.new(audience: ["developers"]) + + assert_equal(["developers"], annotations.audience) + assert_nil(annotations.priority) + assert_nil(annotations.last_modified) + + assert_equal({ audience: ["developers"] }, annotations.to_h) + end + + def test_initialization_with_last_modified_only + timestamp = Time.utc(2025, 1, 12, 15, 0, 58).iso8601 + annotations = Annotations.new(last_modified: timestamp) + + assert_nil(annotations.audience) + assert_nil(annotations.priority) + assert_equal(timestamp, annotations.last_modified) + + assert_equal({ lastModified: timestamp }, annotations.to_h) + end + end +end