mcp: fix bugs handling pointer types (#344)

Some bad merging in #338 led to a bad bug in the handling of structured
output for pointer output types. Add a conformance test and fix the bug.
This commit is contained in:
Robert Findley 2025-08-21 14:43:22 -04:00 • committed by GitHub
commit d8e18b34cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 46 additions and 4 deletions

View file

@ -8,6 +8,7 @@ package mcp
import (
"bytes"
"context"
"encoding/json"
"errors"
"flag"
@ -96,6 +97,18 @@ func TestServerConformance(t *testing.T) {
}
}
type input struct {
In string `jsonschema:"the input"`
}
type output struct {
Out string `jsonschema:"the output"`
}
func structuredTool(ctx context.Context, req *CallToolRequest, args *input) (*CallToolResult, *output, error) {
return nil, &output{"Ack " + args.In}, nil
}
// runServerTest runs the server conformance test.
// It must be executed in a synctest bubble.
func runServerTest(t *testing.T, test *conformanceTest) {
@ -109,6 +122,8 @@ func runServerTest(t *testing.T, test *conformanceTest) {
Name: "greet",
Description: "say hi",
}, sayHi)
case "structured":
AddTool(s, &Tool{Name: "structured"}, structuredTool)
default:
t.Fatalf("unknown tool %q", tn)
}

View file

@ -206,7 +206,7 @@ func toolForErr[In, Out any](t *Tool, h ToolHandlerFor[In, Out]) (*Tool, ToolHan
)
if reflect.TypeFor[Out]() != reflect.TypeFor[any]() {
var err error
elemZero, err = setSchema[Out](&t.OutputSchema, &outputResolved)
elemZero, err = setSchema[Out](&tt.OutputSchema, &outputResolved)
if err != nil {
return nil, nil, fmt.Errorf("output schema: %v", err)
}
@ -258,9 +258,6 @@ func toolForErr[In, Out any](t *Tool, h ToolHandlerFor[In, Out]) (*Tool, ToolHan
res.StructuredContent = elemZero
}
}
if tt.OutputSchema != nil && elemZero != nil {
res.StructuredContent = elemZero
}
return res, nil
}

View file

@ -8,6 +8,7 @@ Fixed bugs:
-- tools --
greet
structured
-- client --
{
@ -63,6 +64,35 @@ greet
"additionalProperties": false
},
"name": "greet"
},
{
"inputSchema": {
"type": "object",
"required": [
"In"
],
"properties": {
"In": {
"type": "string",
"description": "the input"
}
},
"additionalProperties": false
},
"name": "structured",
"outputSchema": {
"type": "object",
"required": [
"Out"
],
"properties": {
"Out": {
"type": "string",
"description": "the output"
}
},
"additionalProperties": false
}
}
]
}