@@ -54,34 +54,35 @@ func (t *manualGreeter) greet(_ context.Context, req *mcp.CallToolRequest) (*mcp
5454 // Handle the parsing and validation of input and output.
5555 //
5656 // Note that errors here are treated as tool errors, not protocol errors.
57+
58+ // First, unmarshal to a map[string]any and validate.
59+ if err := unmarshalAndValidate (req .Params .Arguments , t .inputSchema ); err != nil {
60+ return errf ("invalid input: %v" , err ), nil
61+ }
62+
63+ // Now unmarshal again to input.
5764 var input Input
5865 if err := json .Unmarshal (req .Params .Arguments , & input ); err != nil {
5966 return errf ("failed to unmarshal arguments: %v" , err ), nil
6067 }
61- if err := validateStruct (input , t .inputSchema ); err != nil {
62- return errf ("invalid input: %v" , err ), nil
63- }
6468 output := Output {Greeting : "Hi " + input .Name }
65- if err := validateStruct (output , t .outputSchema ); err != nil {
66- return errf ("tool produced invalid output: %v" , err ), nil
67- }
6869 outputJSON , err := json .Marshal (output )
6970 if err != nil {
7071 return errf ("output failed to marshal: %v" , err ), nil
7172 }
73+ //
74+ if err := unmarshalAndValidate (outputJSON , t .outputSchema ); err != nil {
75+ return errf ("invalid output: %v" , err ), nil
76+ }
77+
7278 return & mcp.CallToolResult {
7379 Content : []mcp.Content {& mcp.TextContent {Text : string (outputJSON )}},
7480 StructuredContent : output ,
7581 }, nil
7682}
7783
78- // validateStruct validates x against schema by first changing the struct to
79- // a map[string]any, then validating that.
80- func validateStruct (x any , res * jsonschema.Resolved ) error {
81- data , err := json .Marshal (x )
82- if err != nil {
83- return err
84- }
84+ // unmarshalAndValidate unmarshals data to a map[string]any, then validates that against res.
85+ func unmarshalAndValidate (data []byte , res * jsonschema.Resolved ) error {
8586 var m map [string ]any
8687 if err := json .Unmarshal (data , & m ); err != nil {
8788 return err
0 commit comments