@@ -1287,6 +1287,40 @@ describe("App <-> AppBridge integration", () => {
12871287 expect ( result . tools . map ( ( t ) => t . name ) ) . toContain ( "tool3" ) ;
12881288 } ) ;
12891289
1290+ it ( "emits core MCP Tool fields (title, outputSchema only when provided)" , async ( ) => {
1291+ const appCapabilities = { tools : { listChanged : true } } ;
1292+ app = new App ( testAppInfo , appCapabilities , { autoResize : false } ) ;
1293+
1294+ app . registerTool (
1295+ "with-output" ,
1296+ {
1297+ title : "With Output" ,
1298+ description : "has structured output" ,
1299+ outputSchema : z . object ( { ok : z . boolean ( ) } ) ,
1300+ } ,
1301+ async ( ) => ( {
1302+ content : [ ] ,
1303+ structuredContent : { ok : true } ,
1304+ } ) ,
1305+ ) ;
1306+ app . registerTool (
1307+ "no-output" ,
1308+ { description : "no structured output" } ,
1309+ async ( ) => ( { content : [ ] } ) ,
1310+ ) ;
1311+
1312+ await app . connect ( appTransport ) ;
1313+ const result = await bridge . listTools ( { } ) ;
1314+ const byName = Object . fromEntries ( result . tools . map ( ( t ) => [ t . name , t ] ) ) ;
1315+
1316+ expect ( byName [ "with-output" ] . title ) . toBe ( "With Output" ) ;
1317+ expect ( byName [ "with-output" ] . inputSchema ) . toBeDefined ( ) ;
1318+ expect ( byName [ "with-output" ] . outputSchema ) . toBeDefined ( ) ;
1319+ // outputSchema is optional in core MCP — omitted when not declared
1320+ expect ( byName [ "no-output" ] ) . not . toHaveProperty ( "outputSchema" ) ;
1321+ expect ( byName [ "no-output" ] . inputSchema ) . toBeDefined ( ) ;
1322+ } ) ;
1323+
12901324 it ( "returns empty list when no tools registered" , async ( ) => {
12911325 const appCapabilities = { tools : { listChanged : true } } ;
12921326 app = new App ( testAppInfo , appCapabilities , { autoResize : false } ) ;
0 commit comments