@@ -29,7 +29,13 @@ extension type ListToolsResult.fromMap(Map<String, Object?> _value)
2929 if (meta != null ) '_meta' : meta,
3030 });
3131
32- List <Tool > get tools => (_value['tools' ] as List ).cast <Tool >();
32+ List <Tool > get tools {
33+ final tools = (_value['tools' ] as List ? )? .cast <Tool >();
34+ if (tools == null ) {
35+ throw ArgumentError ('Missing tools field in $ListToolsResult ' );
36+ }
37+ return tools;
38+ }
3339}
3440
3541/// The server's response to a tool call.
@@ -56,7 +62,13 @@ extension type CallToolResult.fromMap(Map<String, Object?> _value)
5662
5763 /// The type of content, either [TextContent] , [ImageContent] ,
5864 /// or [EmbeddedResource] ,
59- List <Content > get content => (_value['content' ] as List ).cast <Content >();
65+ List <Content > get content {
66+ final content = (_value['content' ] as List ? )? .cast <Content >();
67+ if (content == null ) {
68+ throw ArgumentError ('Missing content field in $CallToolResult ' );
69+ }
70+ return content;
71+ }
6072
6173 /// Whether the tool call ended in an error.
6274 ///
@@ -129,14 +141,26 @@ extension type Tool.fromMap(Map<String, Object?> _value) {
129141 as ToolAnnotations ? ;
130142
131143 /// The name of the tool.
132- String get name => _value['name' ] as String ;
144+ String get name {
145+ final name = _value['name' ] as String ? ;
146+ if (name == null ) {
147+ throw ArgumentError ('Missing name field in $Tool ' );
148+ }
149+ return name;
150+ }
133151
134152 /// A human-readable description of the tool.
135153 String ? get description => _value['description' ] as String ? ;
136154
137155 /// A JSON [ObjectSchema] object defining the expected parameters for the
138156 /// tool.
139- ObjectSchema get inputSchema => _value['inputSchema' ] as ObjectSchema ;
157+ ObjectSchema get inputSchema {
158+ final inputSchema = _value['inputSchema' ] as ObjectSchema ? ;
159+ if (inputSchema == null ) {
160+ throw ArgumentError ('Missing inputSchema field in $Tool ' );
161+ }
162+ return inputSchema;
163+ }
140164}
141165
142166/// Additional properties describing a Tool to clients.
@@ -196,6 +220,7 @@ enum JsonType {
196220 num ('number' ),
197221 int ('integer' ),
198222 bool ('boolean' ),
223+ enumeration ('enum' ),
199224 nil ('null' );
200225
201226 const JsonType (this .typeName);
@@ -238,6 +263,9 @@ enum ValidationErrorType {
238263 maxLengthExceeded,
239264 patternMismatch,
240265
266+ // Enum specific
267+ enumValueNotAllowed,
268+
241269 // Number/Integer specific
242270 minimumNotMet,
243271 maximumExceeded,
@@ -334,6 +362,9 @@ extension type Schema.fromMap(Map<String, Object?> _value) {
334362 /// Alias for [ObjectSchema.new] .
335363 static const object = ObjectSchema .new ;
336364
365+ /// Alias for [EnumSchema.new] .
366+ static const enumeration = EnumSchema .new ;
367+
337368 /// Alias for [NullSchema.new] .
338369 static const nil = NullSchema .new ;
339370
@@ -424,6 +455,12 @@ extension SchemaValidation on Schema {
424455 currentPath,
425456 accumulatedFailures,
426457 );
458+ case JsonType .enumeration:
459+ isValid = (this as EnumSchema )._validateEnum (
460+ data,
461+ currentPath,
462+ accumulatedFailures,
463+ );
427464 case JsonType .bool :
428465 if (data is ! bool ) {
429466 isValid = false ;
@@ -1081,6 +1118,66 @@ extension type const StringSchema.fromMap(Map<String, Object?> _value)
10811118 }
10821119}
10831120
1121+ /// A JSON Schema definition for a set of allowed string values.
1122+ extension type EnumSchema .fromMap (Map <String , Object ?> _value)
1123+ implements Schema {
1124+ factory EnumSchema ({
1125+ String ? title,
1126+ String ? description,
1127+ required Iterable <String > values,
1128+ }) => EnumSchema .fromMap ({
1129+ 'type' : JsonType .enumeration.typeName,
1130+ if (title != null ) 'title' : title,
1131+ if (description != null ) 'description' : description,
1132+ 'enum' : values,
1133+ });
1134+
1135+ /// A title for this schema, should be short.
1136+ String ? get title => _value['title' ] as String ? ;
1137+
1138+ /// A description of this schema.
1139+ String ? get description => _value['description' ] as String ? ;
1140+
1141+ /// The allowed enum values.
1142+ Iterable <String > get values {
1143+ final values = (_value['enum' ] as Iterable ? )? .cast <String >();
1144+ if (values == null ) {
1145+ throw ArgumentError ('Missing required property "values"' );
1146+ }
1147+ assert (
1148+ values.toSet ().length == values.length,
1149+ "The 'values' property has duplicate entries." ,
1150+ );
1151+ return values;
1152+ }
1153+
1154+ bool _validateEnum (
1155+ Object ? data,
1156+ List <String > currentPath,
1157+ HashSet <ValidationError > accumulatedFailures,
1158+ ) {
1159+ if (data is ! String ) {
1160+ accumulatedFailures.add (
1161+ ValidationError (ValidationErrorType .typeMismatch, path: currentPath),
1162+ );
1163+ return false ;
1164+ }
1165+ if (! values.contains (data)) {
1166+ accumulatedFailures.add (
1167+ ValidationError (
1168+ ValidationErrorType .enumValueNotAllowed,
1169+ path: currentPath,
1170+ details:
1171+ 'String "$data " is not one of the allowed values: '
1172+ '${values .join (', ' )}' ,
1173+ ),
1174+ );
1175+ return false ;
1176+ }
1177+ return true ;
1178+ }
1179+ }
1180+
10841181/// A JSON Schema definition for a [num] .
10851182extension type NumberSchema .fromMap (Map <String , Object ?> _value)
10861183 implements Schema {
0 commit comments