diff --git a/README.md b/README.md index 8dad241..0cbd174 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,16 @@ void main() async { server.tool( "calculate", description: 'Perform basic arithmetic operations', - inputSchemaProperties: { - 'operation': { - 'type': 'string', - 'enum': ['add', 'subtract', 'multiply', 'divide'], + inputSchema: { + 'properties': { + 'operation': { + 'type': 'string', + 'enum': ['add', 'subtract', 'multiply', 'divide'], + }, + 'a': {'type': 'number'}, + 'b': {'type': 'number'}, }, - 'a': {'type': 'number'}, - 'b': {'type': 'number'}, + 'required': ['operation', 'a', 'b'], }, callback: ({args, extra}) async { final operation = args!['operation']; diff --git a/lib/src/server/mcp.dart b/lib/src/server/mcp.dart index 8dd2157..a59fd40 100644 --- a/lib/src/server/mcp.dart +++ b/lib/src/server/mcp.dart @@ -82,17 +82,17 @@ class ResourceTemplateRegistration { class _RegisteredTool { final String? description; - final Map? inputSchemaProperties; + final Map? inputSchema; final ToolCallback callback; const _RegisteredTool({ this.description, - this.inputSchemaProperties, + this.inputSchema, required this.callback, }); Tool toTool(String name) { - final schema = ToolInputSchema(properties: inputSchemaProperties); + final schema = ToolInputSchema.fromJson(inputSchema ?? {}); return Tool(name: name, description: description, inputSchema: schema); } } @@ -561,7 +561,7 @@ class McpServer { void tool( String name, { String? description, - Map? inputSchemaProperties, + Map? inputSchema, required ToolCallback callback, }) { if (_registeredTools.containsKey(name)) { @@ -569,7 +569,7 @@ class McpServer { } _registeredTools[name] = _RegisteredTool( description: description, - inputSchemaProperties: inputSchemaProperties, + inputSchema: inputSchema, callback: callback, ); _ensureToolHandlersInitialized(); diff --git a/lib/src/types.dart b/lib/src/types.dart index 952d445..f2dd2d3 100644 --- a/lib/src/types.dart +++ b/lib/src/types.dart @@ -1756,26 +1756,36 @@ class JsonRpcPromptListChangedNotification extends JsonRpcNotification { /// Describes the input schema for a tool, based on JSON Schema. class ToolInputSchema { - /// Must be "object". - final String type = "object"; + /// Must be "object" at the top level. + final String type; /// JSON Schema properties definition. - final Map? properties; + final ToolInputSchema? properties; + + /// Optional list of required properties. + final List? required; - /// Additional JSON Schema properties (e.g., required). + /// Additional JSON Schema properties. final Map additionalProperties; const ToolInputSchema({ + required this.type, this.properties, + this.required, this.additionalProperties = const {}, }); factory ToolInputSchema.fromJson(Map json) { final rest = Map.from(json) ..remove('type') - ..remove('properties'); + ..remove('properties') + ..remove('required'); return ToolInputSchema( - properties: json['properties'] as Map?, + type: json['type'] ?? "object", + properties: json['properties'] != null + ? ToolInputSchema.fromJson(json['properties']) + : null, + required: (json['required'] as List?)?.cast(), additionalProperties: rest, ); } @@ -1783,6 +1793,7 @@ class ToolInputSchema { Map toJson() => { 'type': type, if (properties != null) 'properties': properties, + if (required != null) 'required': required, ...additionalProperties, }; }