mcp: validation only for accept action (#766)
Fix: #758 - validate schema only for accept action - add unit test
This commit is contained in:
parent
fe6d3cf74a
commit
b29ab52878
3 changed files with 73 additions and 1 deletions
|
|
@ -590,7 +590,7 @@ func (c *Client) elicit(ctx context.Context, req *ElicitRequest) (*ElicitResult,
|
|||
return nil, err
|
||||
}
|
||||
// Validate elicitation result content against requested schema.
|
||||
if schema != nil && res.Content != nil {
|
||||
if res.Action == "accept" && schema != nil && res.Content != nil {
|
||||
resolved, err := schema.Resolve(nil)
|
||||
if err != nil {
|
||||
return nil, &jsonrpc.Error{Code: jsonrpc.CodeInvalidParams, Message: fmt.Sprintf("failed to resolve requested schema: %v", err)}
|
||||
|
|
|
|||
|
|
@ -201,3 +201,71 @@ func TestElicitationCompleteNotification(t *testing.T) {
|
|||
t.Fatal("timed out waiting for elicitation complete notification")
|
||||
}
|
||||
}
|
||||
|
||||
func TestElicitationNoValidationWithoutAccept(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
schema := &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"test": {Type: "string"},
|
||||
},
|
||||
Required: []string{"test"},
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
action string
|
||||
content map[string]any
|
||||
wantAction string
|
||||
}{
|
||||
{
|
||||
name: "cancel action",
|
||||
action: "cancel",
|
||||
content: nil, // Empty content should be ignored
|
||||
wantAction: "cancel",
|
||||
},
|
||||
{
|
||||
name: "decline action",
|
||||
action: "decline",
|
||||
content: map[string]any{}, // Empty content should be ignored
|
||||
wantAction: "decline",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ct, st := NewInMemoryTransports()
|
||||
s := NewServer(testImpl, nil)
|
||||
ss, err := s.Connect(ctx, st, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ss.Close()
|
||||
|
||||
c := NewClient(testImpl, &ClientOptions{
|
||||
ElicitationHandler: func(context.Context, *ElicitRequest) (*ElicitResult, error) {
|
||||
return &ElicitResult{Action: tc.action, Content: tc.content}, nil
|
||||
},
|
||||
})
|
||||
cs, err := c.Connect(ctx, ct, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer cs.Close()
|
||||
|
||||
res, err := ss.Elicit(ctx, &ElicitParams{
|
||||
Message: "Test bug",
|
||||
RequestedSchema: schema,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Elicit failed: %v", err)
|
||||
}
|
||||
|
||||
if res.Action != tc.wantAction {
|
||||
t.Errorf("Expected action %q, got %q", tc.wantAction, res.Action)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1218,6 +1218,10 @@ func (ss *ServerSession) Elicit(ctx context.Context, params *ElicitParams) (*Eli
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if res.Action != "accept" {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
if params.RequestedSchema == nil {
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue