mcp: support url mode elicitation (#646)

Add initial support for URL mode elicitation, by introducing the new
types, as well as both server and client-side validation.

A follow-up CL will add support for ErrURLElicitationRequired.

For #623
This commit is contained in:
Robert Findley 2025-11-23 12:58:28 -05:00 • committed by GitHub
commit 21fb03dd1a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -10,6 +10,7 @@ import (
"encoding/base64"
"encoding/gob"
"encoding/json"
"errors"
"fmt"
"iter"
"log/slog"
@ -1018,6 +1019,36 @@ func (ss *ServerSession) Elicit(ctx context.Context, params *ElicitParams) (*Eli
if err := ss.checkInitialized(methodElicit); err != nil {
return nil, err
}
if params == nil {
return nil, fmt.Errorf("%w: params cannot be nil", jsonrpc2.ErrInvalidParams)
}
if params.Mode == "" {
params2 := *params
if params.URL != "" || params.ElicitationID != "" {
params2.Mode = "url"
} else {
params2.Mode = "form"
}
params = &params2
}
if iparams := ss.InitializeParams(); iparams == nil || iparams.Capabilities == nil || iparams.Capabilities.Elicitation == nil {
return nil, fmt.Errorf("client does not support elicitation")
}
caps := ss.InitializeParams().Capabilities.Elicitation
switch params.Mode {
case "form":
if caps.Form == nil && caps.URL != nil {
// Note: if both 'Form' and 'URL' are nil, we assume the client supports
// form elicitation for backward compatibility.
return nil, errors.New(`client does not support "form" elicitation`)
}
case "url":
if caps.URL == nil {
return nil, errors.New(`client does not support "url" elicitation`)
}
}
res, err := handleSend[*ElicitResult](ctx, methodElicit, newServerRequest(ss, orZero[Params](params)))
if err != nil {