@@ -937,4 +937,39 @@ func TestKeepAliveFailure(t *testing.T) {
937937 t .Errorf ("expected connection to be closed by keepalive, but it wasn't. Last error: %v" , err )
938938}
939939
940+ func TestAddTool_DuplicateNoPanicAndNoDuplicate (t * testing.T ) {
941+ // Adding the same tool pointer twice should not panic and should not
942+ // produce duplicates in the server's tool list.
943+ _ , cs := basicConnection (t , func (s * Server ) {
944+ // Use two distinct Tool instances with the same name but different
945+ // descriptions to ensure the second replaces the first
946+ // This case was written specifically to reproduce a bug where duplicate tools where causing jsonschema errors
947+ t1 := & Tool {Name : "dup" , Description : "first" , InputSchema : & jsonschema.Schema {}}
948+ t2 := & Tool {Name : "dup" , Description : "second" , InputSchema : & jsonschema.Schema {}}
949+ s .AddTool (t1 , nopHandler )
950+ s .AddTool (t2 , nopHandler )
951+ })
952+ defer cs .Close ()
953+
954+ ctx := context .Background ()
955+ res , err := cs .ListTools (ctx , nil )
956+ if err != nil {
957+ t .Fatal (err )
958+ }
959+ var count int
960+ var gotDesc string
961+ for _ , tt := range res .Tools {
962+ if tt .Name == "dup" {
963+ count ++
964+ gotDesc = tt .Description
965+ }
966+ }
967+ if count != 1 {
968+ t .Fatalf ("expected exactly one 'dup' tool, got %d" , count )
969+ }
970+ if gotDesc != "second" {
971+ t .Fatalf ("expected replaced tool to have description %q, got %q" , "second" , gotDesc )
972+ }
973+ }
974+
940975var testImpl = & Implementation {Name : "test" , Version : "v1.0.0" }
0 commit comments