@@ -16,10 +16,81 @@ public struct Tool: Hashable, Codable, Sendable {
16
16
/// The tool input schema
17
17
public let inputSchema : Value ?
18
18
19
- public init ( name: String , description: String , inputSchema: Value ? = nil ) {
19
+ /// Annotations that provide display-facing and operational information for a Tool.
20
+ ///
21
+ /// - Note: All properties in `ToolAnnotations` are **hints**.
22
+ /// They are not guaranteed to provide a faithful description of
23
+ /// tool behavior (including descriptive properties like `title`).
24
+ ///
25
+ /// Clients should never make tool use decisions based on `ToolAnnotations`
26
+ /// received from untrusted servers.
27
+ public struct Annotations : Hashable , Codable , Sendable , ExpressibleByNilLiteral {
28
+ /// A human-readable title for the tool
29
+ public var title : String ?
30
+
31
+ /// If true, the tool may perform destructive updates to its environment.
32
+ /// If false, the tool performs only additive updates.
33
+ /// (This property is meaningful only when `readOnlyHint == false`)
34
+ ///
35
+ /// When unspecified, the implicit default is `true`.
36
+ public var destructiveHint : Bool ?
37
+
38
+ /// If true, calling the tool repeatedly with the same arguments
39
+ /// will have no additional effect on its environment.
40
+ /// (This property is meaningful only when `readOnlyHint == false`)
41
+ ///
42
+ /// When unspecified, the implicit default is `false`.
43
+ public var idempotentHint : Bool ?
44
+
45
+ /// If true, this tool may interact with an "open world" of external
46
+ /// entities. If false, the tool's domain of interaction is closed.
47
+ /// For example, the world of a web search tool is open, whereas that
48
+ /// of a memory tool is not.
49
+ ///
50
+ /// When unspecified, the implicit default is `true`.
51
+ public var openWorldHint : Bool ?
52
+
53
+ /// If true, the tool does not modify its environment.
54
+ ///
55
+ /// When unspecified, the implicit default is `false`.
56
+ public var readOnlyHint : Bool ?
57
+
58
+ /// Returns true if all properties are nil
59
+ public var isEmpty : Bool {
60
+ title == nil && readOnlyHint == nil && destructiveHint == nil && idempotentHint == nil
61
+ && openWorldHint == nil
62
+ }
63
+
64
+ public init (
65
+ title: String ? = nil ,
66
+ readOnlyHint: Bool ? = nil ,
67
+ destructiveHint: Bool ? = nil ,
68
+ idempotentHint: Bool ? = nil ,
69
+ openWorldHint: Bool ? = nil
70
+ ) {
71
+ self . title = title
72
+ self . readOnlyHint = readOnlyHint
73
+ self . destructiveHint = destructiveHint
74
+ self . idempotentHint = idempotentHint
75
+ self . openWorldHint = openWorldHint
76
+ }
77
+
78
+ public init ( nilLiteral: ( ) ) { }
79
+ }
80
+
81
+ /// Optional annotations that provide display-facing and operational information
82
+ public let annotations : Annotations
83
+
84
+ public init (
85
+ name: String ,
86
+ description: String ,
87
+ inputSchema: Value ? = nil ,
88
+ annotations: Annotations = nil
89
+ ) {
20
90
self . name = name
21
91
self . description = description
22
92
self . inputSchema = inputSchema
93
+ self . annotations = annotations
23
94
}
24
95
25
96
/// Content types that can be returned by a tool
@@ -92,13 +163,16 @@ public struct Tool: Hashable, Codable, Sendable {
92
163
case name
93
164
case description
94
165
case inputSchema
166
+ case annotations
95
167
}
96
168
97
169
public init ( from decoder: Decoder ) throws {
98
170
let container = try decoder. container ( keyedBy: CodingKeys . self)
99
171
name = try container. decode ( String . self, forKey: . name)
100
172
description = try container. decode ( String . self, forKey: . description)
101
173
inputSchema = try container. decodeIfPresent ( Value . self, forKey: . inputSchema)
174
+ annotations =
175
+ try container. decodeIfPresent ( Tool . Annotations. self, forKey: . annotations) ?? . init( )
102
176
}
103
177
104
178
public func encode( to encoder: Encoder ) throws {
@@ -108,6 +182,9 @@ public struct Tool: Hashable, Codable, Sendable {
108
182
if let schema = inputSchema {
109
183
try container. encode ( schema, forKey: . inputSchema)
110
184
}
185
+ if !annotations. isEmpty {
186
+ try container. encode ( annotations, forKey: . annotations)
187
+ }
111
188
}
112
189
}
113
190
@@ -120,7 +197,7 @@ public enum ListTools: Method {
120
197
121
198
public struct Parameters : NotRequired , Hashable , Codable , Sendable {
122
199
public let cursor : String ?
123
-
200
+
124
201
public init ( ) {
125
202
self . cursor = nil
126
203
}
0 commit comments