@@ -3,6 +3,7 @@ package mcp
33import (
44 "context"
55 "errors"
6+ "fmt"
67 "testing"
78
89 "github.com/containers/kubernetes-mcp-server/internal/test"
@@ -59,7 +60,7 @@ func (s *ElicitationSuite) registerElicitingToolset(handler api.ToolHandlerFunc)
5960
6061func (s * ElicitationSuite ) TestElicitationAccepted () {
6162 s .registerElicitingToolset (func (params api.ToolHandlerParams ) (* api.ToolCallResult , error ) {
62- result , err := params .Elicit (params .Context , "Please confirm" , nil )
63+ result , err := params .Elicit (params .Context , & api. ElicitParams { Message : "Please confirm" } )
6364 if err != nil {
6465 return nil , err
6566 }
@@ -90,7 +91,7 @@ func (s *ElicitationSuite) TestElicitationAccepted() {
9091
9192func (s * ElicitationSuite ) TestElicitationDeclined () {
9293 s .registerElicitingToolset (func (params api.ToolHandlerParams ) (* api.ToolCallResult , error ) {
93- result , err := params .Elicit (params .Context , "Please confirm" , nil )
94+ result , err := params .Elicit (params .Context , & api. ElicitParams { Message : "Please confirm" } )
9495 if err != nil {
9596 return nil , err
9697 }
@@ -118,7 +119,7 @@ func (s *ElicitationSuite) TestElicitationDeclined() {
118119
119120func (s * ElicitationSuite ) TestElicitationWithUnsupportedClient () {
120121 s .registerElicitingToolset (func (params api.ToolHandlerParams ) (* api.ToolCallResult , error ) {
121- _ , err := params .Elicit (params .Context , "Please confirm" , nil )
122+ _ , err := params .Elicit (params .Context , & api. ElicitParams { Message : "Please confirm" } )
122123 if err != nil {
123124 if errors .Is (err , ErrElicitationNotSupported ) {
124125 return api .NewToolCallResult ("fallback-result" , nil ), nil
@@ -144,6 +145,121 @@ func (s *ElicitationSuite) TestElicitationWithUnsupportedClient() {
144145 })
145146}
146147
148+ func (s * ElicitationSuite ) TestElicitationURLAccepted () {
149+ s .registerElicitingToolset (func (params api.ToolHandlerParams ) (* api.ToolCallResult , error ) {
150+ result , err := params .Elicit (params .Context , & api.ElicitParams {
151+ Message : "Please complete the form" ,
152+ URL : "https://example.com/form" ,
153+ })
154+ if err != nil {
155+ return nil , err
156+ }
157+ return api .NewToolCallResult ("action=" + result .Action , nil ), nil
158+ })
159+
160+ s .InitMcpClient (
161+ test .WithElicitationHandler (
162+ func (_ context.Context , _ * mcp.ElicitRequest ) (* mcp.ElicitResult , error ) {
163+ return & mcp.ElicitResult {Action : "accept" }, nil
164+ },
165+ ),
166+ test .WithClientCapabilities (& mcp.ClientCapabilities {
167+ Elicitation : & mcp.ElicitationCapabilities {
168+ URL : & mcp.URLElicitationCapabilities {},
169+ },
170+ }),
171+ )
172+
173+ toolResult , err := s .CallTool ("elicit_test_tool" , map [string ]any {})
174+
175+ s .Run ("returns accepted action for URL elicitation" , func () {
176+ s .NoError (err )
177+ s .Require ().NotNil (toolResult )
178+ s .False (toolResult .IsError )
179+ s .Require ().Len (toolResult .Content , 1 )
180+ textContent , ok := toolResult .Content [0 ].(* mcp.TextContent )
181+ s .Require ().True (ok )
182+ s .Equal ("action=accept" , textContent .Text )
183+ })
184+ }
185+
186+ func (s * ElicitationSuite ) TestElicitationURLWithElicitationID () {
187+ s .registerElicitingToolset (func (params api.ToolHandlerParams ) (* api.ToolCallResult , error ) {
188+ result , err := params .Elicit (params .Context , & api.ElicitParams {
189+ Message : "Please complete the form" ,
190+ URL : "https://example.com/form" ,
191+ ElicitationID : "elicit-123" ,
192+ })
193+ if err != nil {
194+ return nil , err
195+ }
196+ return api .NewToolCallResult ("action=" + result .Action , nil ), nil
197+ })
198+
199+ s .InitMcpClient (
200+ test .WithElicitationHandler (
201+ func (_ context.Context , req * mcp.ElicitRequest ) (* mcp.ElicitResult , error ) {
202+ if req .Params .ElicitationID != "elicit-123" {
203+ return nil , fmt .Errorf ("expected elicitationID 'elicit-123', got '%s'" , req .Params .ElicitationID )
204+ }
205+ return & mcp.ElicitResult {Action : "accept" }, nil
206+ },
207+ ),
208+ test .WithClientCapabilities (& mcp.ClientCapabilities {
209+ Elicitation : & mcp.ElicitationCapabilities {
210+ URL : & mcp.URLElicitationCapabilities {},
211+ },
212+ }),
213+ )
214+
215+ toolResult , err := s .CallTool ("elicit_test_tool" , map [string ]any {})
216+
217+ s .Run ("forwards elicitationID to the client" , func () {
218+ s .NoError (err )
219+ s .Require ().NotNil (toolResult )
220+ s .False (toolResult .IsError )
221+ s .Require ().Len (toolResult .Content , 1 )
222+ textContent , ok := toolResult .Content [0 ].(* mcp.TextContent )
223+ s .Require ().True (ok )
224+ s .Equal ("action=accept" , textContent .Text )
225+ })
226+ }
227+
228+ func (s * ElicitationSuite ) TestElicitationURLWithUnsupportedClient () {
229+ s .registerElicitingToolset (func (params api.ToolHandlerParams ) (* api.ToolCallResult , error ) {
230+ _ , err := params .Elicit (params .Context , & api.ElicitParams {
231+ Message : "Please complete the form" ,
232+ URL : "https://example.com/form" ,
233+ })
234+ if err != nil {
235+ if errors .Is (err , ErrElicitationNotSupported ) {
236+ return api .NewToolCallResult ("url-fallback-result" , nil ), nil
237+ }
238+ return nil , err
239+ }
240+ return api .NewToolCallResult ("should-not-reach" , nil ), nil
241+ })
242+
243+ // Client supports elicitation but not URL mode (default capabilities = form only)
244+ s .InitMcpClient (test .WithElicitationHandler (
245+ func (_ context.Context , _ * mcp.ElicitRequest ) (* mcp.ElicitResult , error ) {
246+ return & mcp.ElicitResult {Action : "accept" }, nil
247+ },
248+ ))
249+
250+ toolResult , err := s .CallTool ("elicit_test_tool" , map [string ]any {})
251+
252+ s .Run ("tool handles unsupported URL elicitation gracefully" , func () {
253+ s .NoError (err )
254+ s .Require ().NotNil (toolResult )
255+ s .False (toolResult .IsError )
256+ s .Require ().Len (toolResult .Content , 1 )
257+ textContent , ok := toolResult .Content [0 ].(* mcp.TextContent )
258+ s .Require ().True (ok )
259+ s .Equal ("url-fallback-result" , textContent .Text )
260+ })
261+ }
262+
147263// mockElicitToolset is a test toolset that provides tools using the Elicitor interface
148264type mockElicitToolset struct {
149265 tools []api.ServerTool
0 commit comments