Skip to content

Commit da471a2

Browse files
authored
Merge pull request #118 from koic/add_default_value_to_tool_annotation
Set default values for `ToolAnnotations` hints
2 parents e51c692 + cae3054 commit da471a2

File tree

4 files changed

+33
-30
lines changed

4 files changed

+33
-30
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,10 @@ e.g. around authentication state.
421421

422422
Tools can include annotations that provide additional metadata about their behavior. The following annotations are supported:
423423

424-
- `destructive_hint`: Indicates if the tool performs destructive operations
425-
- `idempotent_hint`: Indicates if the tool's operations are idempotent
426-
- `open_world_hint`: Indicates if the tool operates in an open world context
427-
- `read_only_hint`: Indicates if the tool only reads data (doesn't modify state)
424+
- `destructive_hint`: Indicates if the tool performs destructive operations. Defaults to true
425+
- `idempotent_hint`: Indicates if the tool's operations are idempotent. Defaults to false
426+
- `open_world_hint`: Indicates if the tool operates in an open world context. Defaults to true
427+
- `read_only_hint`: Indicates if the tool only reads data (doesn't modify state). Defaults to false
428428
- `title`: A human-readable title for the tool
429429

430430
Annotations can be set either through the class definition using the `annotations` class method or when defining a tool using the `define` method.

lib/mcp/tool/annotations.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
module MCP
44
class Tool
55
class Annotations
6-
attr_reader :title, :read_only_hint, :destructive_hint, :idempotent_hint, :open_world_hint
6+
attr_reader :destructive_hint, :idempotent_hint, :open_world_hint, :read_only_hint, :title
77

8-
def initialize(title: nil, read_only_hint: nil, destructive_hint: nil, idempotent_hint: nil, open_world_hint: nil)
8+
def initialize(destructive_hint: true, idempotent_hint: false, open_world_hint: true, read_only_hint: false, title: nil)
99
@title = title
1010
@read_only_hint = read_only_hint
1111
@destructive_hint = destructive_hint
@@ -15,11 +15,11 @@ def initialize(title: nil, read_only_hint: nil, destructive_hint: nil, idempoten
1515

1616
def to_h
1717
{
18-
title:,
19-
readOnlyHint: read_only_hint,
2018
destructiveHint: destructive_hint,
2119
idempotentHint: idempotent_hint,
2220
openWorldHint: open_world_hint,
21+
readOnlyHint: read_only_hint,
22+
title:,
2323
}.compact
2424
end
2525
end

test/mcp/tool/annotations_test.rb

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,31 @@ class Tool
77
class AnnotationsTest < ActiveSupport::TestCase
88
test "Tool::Annotations initializes with all properties" do
99
annotations = Tool::Annotations.new(
10-
title: "Test Tool",
11-
read_only_hint: true,
1210
destructive_hint: false,
1311
idempotent_hint: true,
1412
open_world_hint: false,
13+
read_only_hint: true,
14+
title: "Test Tool",
1515
)
1616

17-
assert_equal "Test Tool", annotations.title
18-
assert annotations.read_only_hint
1917
refute annotations.destructive_hint
2018
assert annotations.idempotent_hint
2119
refute annotations.open_world_hint
20+
assert annotations.read_only_hint
21+
assert_equal "Test Tool", annotations.title
2222
end
2323

2424
test "Tool::Annotations initializes with partial properties" do
2525
annotations = Tool::Annotations.new(
26-
title: "Test Tool",
2726
read_only_hint: true,
27+
title: "Test Tool",
2828
)
2929

30-
assert_equal "Test Tool", annotations.title
30+
assert annotations.destructive_hint
31+
refute annotations.idempotent_hint
32+
assert annotations.open_world_hint
3133
assert annotations.read_only_hint
32-
assert_nil annotations.destructive_hint
33-
assert_nil annotations.idempotent_hint
34-
assert_nil annotations.open_world_hint
34+
assert_equal "Test Tool", annotations.title
3535
end
3636

3737
test "Tool::Annotations#to_h omits nil values" do
@@ -41,34 +41,37 @@ class AnnotationsTest < ActiveSupport::TestCase
4141
)
4242

4343
expected = {
44-
title: "Test Tool",
44+
destructiveHint: true,
45+
idempotentHint: false,
46+
openWorldHint: true,
4547
readOnlyHint: true,
48+
title: "Test Tool",
4649
}
4750
assert_equal expected, annotations.to_h
4851
end
4952

5053
test "Tool::Annotations#to_h handles all properties" do
5154
annotations = Tool::Annotations.new(
52-
title: "Test Tool",
53-
read_only_hint: true,
5455
destructive_hint: false,
5556
idempotent_hint: true,
5657
open_world_hint: false,
58+
read_only_hint: true,
59+
title: "Test Tool",
5760
)
5861

5962
expected = {
60-
title: "Test Tool",
61-
readOnlyHint: true,
6263
destructiveHint: false,
6364
idempotentHint: true,
6465
openWorldHint: false,
66+
readOnlyHint: true,
67+
title: "Test Tool",
6568
}
6669
assert_equal expected, annotations.to_h
6770
end
6871

69-
test "Tool::Annotations#to_h returns empty hash when all values are nil" do
72+
test "Tool::Annotations#to_h returns hash with default hint values" do
7073
annotations = Tool::Annotations.new
71-
assert_empty annotations.to_h
74+
assert_equal({ destructiveHint: true, idempotentHint: false, openWorldHint: true, readOnlyHint: false }, annotations.to_h)
7275
end
7376
end
7477
end

test/mcp/tool_test.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ class TestTool < Tool
1010
description "a test tool for testing"
1111
input_schema({ properties: { message: { type: "string" } }, required: ["message"] })
1212
annotations(
13-
title: "Test Tool",
14-
read_only_hint: true,
1513
destructive_hint: false,
1614
idempotent_hint: true,
1715
open_world_hint: false,
16+
read_only_hint: true,
17+
title: "Test Tool",
1818
)
1919

2020
class << self
@@ -36,11 +36,11 @@ def call(message:, server_context: nil)
3636
test "#to_h includes annotations when present" do
3737
tool = TestTool
3838
expected_annotations = {
39-
title: "Test Tool",
40-
readOnlyHint: true,
4139
destructiveHint: false,
4240
idempotentHint: true,
4341
openWorldHint: false,
42+
readOnlyHint: true,
43+
title: "Test Tool",
4444
}
4545
assert_equal expected_annotations, tool.to_h[:annotations]
4646
end
@@ -142,15 +142,15 @@ class InputSchemaTool < Tool
142142
assert_equal "Mock Tool", tool.title
143143
assert_equal "a mock tool for testing", tool.description
144144
assert_equal tool.input_schema, Tool::InputSchema.new
145-
assert_equal({ readOnlyHint: true, title: "Mock Tool" }, tool.annotations_value.to_h)
145+
assert_equal({ destructiveHint: true, idempotentHint: false, openWorldHint: true, readOnlyHint: true, title: "Mock Tool" }, tool.annotations_value.to_h)
146146
end
147147

148148
test "Tool class method annotations can be set and retrieved" do
149149
class AnnotationsTestTool < Tool
150150
tool_name "annotations_test"
151151
annotations(
152-
title: "Annotations Test",
153152
read_only_hint: true,
153+
title: "Annotations Test",
154154
)
155155
end
156156

0 commit comments

Comments
 (0)