@@ -1200,6 +1200,97 @@ func TestFeatureFlagError(t *testing.T) {
12001200 }
12011201}
12021202
1203+ func TestRegisterToolsOutputSchemaFeatureFlag (t * testing.T ) {
1204+ outputSchema := map [string ]any {
1205+ "type" : "object" ,
1206+ "properties" : map [string ]any {
1207+ "id" : map [string ]any {"type" : "string" },
1208+ },
1209+ }
1210+ tools := []ServerTool {
1211+ mockTool ("tool_with_schema" , "toolset1" , true ).WithOutputSchema (outputSchema ),
1212+ }
1213+
1214+ tests := []struct {
1215+ name string
1216+ featureChecker FeatureFlagChecker
1217+ wantOutputSchema bool
1218+ }{
1219+ {
1220+ name : "omits output schema by default" ,
1221+ wantOutputSchema : false ,
1222+ },
1223+ {
1224+ name : "includes output schema when feature is enabled" ,
1225+ featureChecker : func (_ context.Context , flag string ) (bool , error ) {
1226+ return flag == outputSchemasFeatureFlag , nil
1227+ },
1228+ wantOutputSchema : true ,
1229+ },
1230+ }
1231+
1232+ for _ , tt := range tests {
1233+ t .Run (tt .name , func (t * testing.T ) {
1234+ reg := mustBuild (t , NewBuilder ().SetTools (tools ).WithToolsets ([]string {"all" }).WithFeatureChecker (tt .featureChecker ))
1235+
1236+ registeredTools := listRegisteredTools (context .Background (), t , reg )
1237+ require .Len (t , registeredTools , 1 )
1238+
1239+ if tt .wantOutputSchema {
1240+ require .NotNil (t , registeredTools [0 ].OutputSchema )
1241+ requireJSONEqual (t , outputSchema , registeredTools [0 ].OutputSchema )
1242+ } else {
1243+ require .Nil (t , registeredTools [0 ].OutputSchema )
1244+ }
1245+
1246+ require .Nil (t , reg .AllTools ()[0 ].Tool .OutputSchema )
1247+ })
1248+ }
1249+ }
1250+
1251+ func listRegisteredTools (ctx context.Context , t * testing.T , reg * Inventory ) []* mcp.Tool {
1252+ t .Helper ()
1253+
1254+ srv := mcp .NewServer (& mcp.Implementation {Name : "test-server" }, nil )
1255+ reg .RegisterTools (ctx , srv , nil )
1256+
1257+ st , ct := mcp .NewInMemoryTransports ()
1258+ client := mcp .NewClient (& mcp.Implementation {Name : "test-client" }, nil )
1259+
1260+ type connectResult struct {
1261+ session * mcp.ClientSession
1262+ err error
1263+ }
1264+ connectCh := make (chan connectResult , 1 )
1265+ go func () {
1266+ clientSession , err := client .Connect (ctx , ct , nil )
1267+ connectCh <- connectResult {session : clientSession , err : err }
1268+ }()
1269+
1270+ serverSession , err := srv .Connect (ctx , st , nil )
1271+ require .NoError (t , err )
1272+ t .Cleanup (func () { require .NoError (t , serverSession .Close ()) })
1273+
1274+ clientResult := <- connectCh
1275+ require .NoError (t , clientResult .err )
1276+ require .NotNil (t , clientResult .session )
1277+ t .Cleanup (func () { require .NoError (t , clientResult .session .Close ()) })
1278+
1279+ result , err := clientResult .session .ListTools (ctx , nil )
1280+ require .NoError (t , err )
1281+ return result .Tools
1282+ }
1283+
1284+ func requireJSONEqual (t * testing.T , expected , actual any ) {
1285+ t .Helper ()
1286+
1287+ expectedJSON , err := json .Marshal (expected )
1288+ require .NoError (t , err )
1289+ actualJSON , err := json .Marshal (actual )
1290+ require .NoError (t , err )
1291+ require .JSONEq (t , string (expectedJSON ), string (actualJSON ))
1292+ }
1293+
12031294func TestFeatureFlagResources (t * testing.T ) {
12041295 resources := []ServerResourceTemplate {
12051296 mockResource ("always_available" , "toolset1" , "uri1" ),
0 commit comments