## Motivation and Context The MCP specification defines an optional `size` field on the `Resource` type, added in spec revision 2025-06-18 and retained in 2025-11-25: https://modelcontextprotocol.io/specification/2025-11-25/server/resources > The size of the raw resource content, in bytes (i.e., before base64 > encoding or any tokenization), if known. This can be used by Hosts to > display file sizes and estimate context window usage. `MCP::Resource` was missing this field, so servers had no way to declare a resource's byte size. Without it, hosts cannot show file sizes or estimate context window usage before reading the resource contents. This aligns the Ruby SDK with the spec, matching the TypeScript SDK (modelcontextprotocol/typescript-sdk#1574). ## How Has This Been Tested? Added tests in `test/mcp/resource_test.rb`: - `#to_h` omits `size` when nil - `#to_h` includes `size` when present - `#to_h` includes `size` when zero (distinguishes an unset size from a 0-byte resource) The full unit suite and RuboCop pass locally. ## Breaking Changes None. `size:` is a new optional keyword argument defaulting to `nil`, and it is omitted from `#to_h` output when not set, so existing callers are unaffected.
71 lines
2.2 KiB
Ruby
71 lines
2.2 KiB
Ruby
# 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
|
|
|
|
test "#to_h omits _meta when nil" do
|
|
resource = Resource.new(uri: "file:///test.txt", name: "resource_without_meta")
|
|
|
|
refute resource.to_h.key?(:_meta)
|
|
end
|
|
|
|
test "#to_h includes _meta when present" do
|
|
meta = { "application/vnd.ant.mcp-app" => { "csp" => "default-src 'self'" } }
|
|
resource = Resource.new(uri: "file:///test.txt", name: "resource_with_meta", meta: meta)
|
|
|
|
assert_equal meta, resource.to_h[:_meta]
|
|
end
|
|
|
|
test "#to_h omits size when nil" do
|
|
resource = Resource.new(uri: "file:///test.txt", name: "resource_without_size")
|
|
|
|
refute resource.to_h.key?(:size)
|
|
end
|
|
|
|
test "#to_h includes size when present" do
|
|
resource = Resource.new(uri: "file:///test.txt", name: "resource_with_size", size: 12_345)
|
|
|
|
assert_equal 12_345, resource.to_h[:size]
|
|
end
|
|
|
|
test "#to_h includes size when zero" do
|
|
resource = Resource.new(uri: "file:///empty.txt", name: "empty_resource", size: 0)
|
|
|
|
assert_equal 0, resource.to_h[:size]
|
|
end
|
|
end
|
|
end
|