@@ -21,7 +21,6 @@ import (
2121 "time"
2222
2323 "github.com/google/go-cmp/cmp"
24- "github.com/google/go-cmp/cmp/cmpopts"
2524 "github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2"
2625 "github.com/modelcontextprotocol/go-sdk/jsonschema"
2726)
@@ -30,6 +29,9 @@ type hiParams struct {
3029 Name string
3130}
3231
32+ // TODO(jba): after schemas are stateless (WIP), this can be a variable.
33+ func greetTool () * Tool { return & Tool {Name : "greet" , Description : "say hi" } }
34+
3335func sayHi (ctx context.Context , ss * ServerSession , params * CallToolParamsFor [hiParams ]) (* CallToolResultFor [any ], error ) {
3436 if err := ss .Ping (ctx , nil ); err != nil {
3537 return nil , fmt .Errorf ("ping failed: %v" , err )
@@ -63,7 +65,14 @@ func TestEndToEnd(t *testing.T) {
6365 },
6466 }
6567 s := NewServer ("testServer" , "v1.0.0" , sopts )
66- add (tools , s .AddTools , "greet" , "fail" )
68+ AddTool (s , & Tool {
69+ Name : "greet" ,
70+ Description : "say hi" ,
71+ }, sayHi )
72+ s .AddTool (& Tool {Name : "fail" , InputSchema : & jsonschema.Schema {}},
73+ func (context.Context , * ServerSession , * CallToolParamsFor [map [string ]any ]) (* CallToolResult , error ) {
74+ return nil , errTestFailure
75+ })
6776 add (prompts , s .AddPrompts , "code_review" , "fail" )
6877 add (resources , s .AddResources , "info.txt" , "fail.txt" )
6978
@@ -161,32 +170,7 @@ func TestEndToEnd(t *testing.T) {
161170 })
162171
163172 t .Run ("tools" , func (t * testing.T ) {
164- res , err := cs .ListTools (ctx , nil )
165- if err != nil {
166- t .Errorf ("tools/list failed: %v" , err )
167- }
168- wantTools := []* Tool {
169- {
170- Name : "fail" ,
171- InputSchema : nil ,
172- },
173- {
174- Name : "greet" ,
175- Description : "say hi" ,
176- InputSchema : & jsonschema.Schema {
177- Type : "object" ,
178- Required : []string {"Name" },
179- Properties : map [string ]* jsonschema.Schema {
180- "Name" : {Type : "string" },
181- },
182- AdditionalProperties : falseSchema (),
183- },
184- },
185- }
186- if diff := cmp .Diff (wantTools , res .Tools , cmpopts .IgnoreUnexported (jsonschema.Schema {})); diff != "" {
187- t .Fatalf ("tools/list mismatch (-want +got):\n %s" , diff )
188- }
189-
173+ // ListTools is tested in client_list_test.go.
190174 gotHi , err := cs .CallTool (ctx , & CallToolParams {
191175 Name : "greet" ,
192176 Arguments : map [string ]any {"name" : "user" },
@@ -222,7 +206,7 @@ func TestEndToEnd(t *testing.T) {
222206 t .Errorf ("tools/call 'fail' mismatch (-want +got):\n %s" , diff )
223207 }
224208
225- s .AddTools ( & ServerTool { Tool : & Tool {Name : "T" }, Handler : nopHandler } )
209+ s .AddTool ( & Tool {Name : "T" , InputSchema : & jsonschema. Schema {}}, nopHandler )
226210 waitForNotification (t , "tools" )
227211 s .RemoveTools ("T" )
228212 waitForNotification (t , "tools" )
@@ -434,16 +418,6 @@ func TestEndToEnd(t *testing.T) {
434418var (
435419 errTestFailure = errors .New ("mcp failure" )
436420
437- tools = map [string ]* ServerTool {
438- "greet" : NewServerTool ("greet" , "say hi" , sayHi ),
439- "fail" : {
440- Tool : & Tool {Name : "fail" },
441- Handler : func (context.Context , * ServerSession , * CallToolParamsFor [map [string ]any ]) (* CallToolResult , error ) {
442- return nil , errTestFailure
443- },
444- },
445- }
446-
447421 prompts = map [string ]* ServerPrompt {
448422 "code_review" : {
449423 Prompt : & Prompt {
@@ -540,21 +514,21 @@ func errorCode(err error) int64 {
540514 return - 1
541515}
542516
543- // basicConnection returns a new basic client-server connection configured with
544- // the provided tools .
517+ // basicConnection returns a new basic client-server connection, with the server
518+ // configured via the provided function .
545519//
546520// The caller should cancel either the client connection or server connection
547521// when the connections are no longer needed.
548- func basicConnection (t * testing.T , tools ... * ServerTool ) (* ServerSession , * ClientSession ) {
522+ func basicConnection (t * testing.T , config func ( * Server ) ) (* ServerSession , * ClientSession ) {
549523 t .Helper ()
550524
551525 ctx := context .Background ()
552526 ct , st := NewInMemoryTransports ()
553527
554528 s := NewServer ("testServer" , "v1.0.0" , nil )
555-
556- // The 'greet' tool says hi.
557- s . AddTools ( tools ... )
529+ if config != nil {
530+ config ( s )
531+ }
558532 ss , err := s .Connect (ctx , st )
559533 if err != nil {
560534 t .Fatal (err )
@@ -569,7 +543,9 @@ func basicConnection(t *testing.T, tools ...*ServerTool) (*ServerSession, *Clien
569543}
570544
571545func TestServerClosing (t * testing.T ) {
572- cc , cs := basicConnection (t , NewServerTool ("greet" , "say hi" , sayHi ))
546+ cc , cs := basicConnection (t , func (s * Server ) {
547+ AddTool (s , greetTool (), sayHi )
548+ })
573549 defer cs .Close ()
574550
575551 ctx := context .Background ()
@@ -651,11 +627,9 @@ func TestCancellation(t *testing.T) {
651627 }
652628 return nil , nil
653629 }
654- st := & ServerTool {
655- Tool : & Tool {Name : "slow" },
656- Handler : slowRequest ,
657- }
658- _ , cs := basicConnection (t , st )
630+ _ , cs := basicConnection (t , func (s * Server ) {
631+ s .AddTool (& Tool {Name : "slow" }, slowRequest )
632+ })
659633 defer cs .Close ()
660634
661635 ctx , cancel := context .WithCancel (context .Background ())
@@ -852,7 +826,7 @@ func TestKeepAlive(t *testing.T) {
852826 KeepAlive : 100 * time .Millisecond ,
853827 }
854828 s := NewServer ("testServer" , "v1.0.0" , serverOpts )
855- s . AddTools ( NewServerTool ( "greet" , "say hi" , sayHi ) )
829+ AddTool ( s , greetTool () , sayHi )
856830
857831 ss , err := s .Connect (ctx , st )
858832 if err != nil {
@@ -897,7 +871,7 @@ func TestKeepAliveFailure(t *testing.T) {
897871
898872 // Server without keepalive (to test one-sided keepalive)
899873 s := NewServer ("testServer" , "v1.0.0" , nil )
900- s . AddTools ( NewServerTool ( "greet" , "say hi" , sayHi ) )
874+ AddTool ( s , greetTool () , sayHi )
901875 ss , err := s .Connect (ctx , st )
902876 if err != nil {
903877 t .Fatal (err )
0 commit comments