@@ -52,6 +52,131 @@ describe("registerAppTool", () => {
5252 ) . toBe ( "ui://test/widget.html" ) ;
5353 expect ( capturedHandler ) . toBe ( handler ) ;
5454 } ) ;
55+
56+ describe ( "backward compatibility" , ( ) => {
57+ it ( "should set legacy key when _meta.ui.resourceUri is provided" , ( ) => {
58+ let capturedConfig : Record < string , unknown > | undefined ;
59+
60+ const mockServer = {
61+ registerTool : mock (
62+ ( _name : string , config : Record < string , unknown > , _handler : unknown ) => {
63+ capturedConfig = config ;
64+ } ,
65+ ) ,
66+ } ;
67+
68+ registerAppTool (
69+ mockServer as unknown as Pick < McpServer , "registerTool" > ,
70+ "my-tool" ,
71+ {
72+ _meta : {
73+ ui : { resourceUri : "ui://test/widget.html" } ,
74+ } ,
75+ } ,
76+ async ( ) => ( { content : [ { type : "text" as const , text : "ok" } ] } ) ,
77+ ) ;
78+
79+ const meta = capturedConfig ?. _meta as Record < string , unknown > ;
80+ // New format should be preserved
81+ expect ( ( meta . ui as { resourceUri : string } ) . resourceUri ) . toBe (
82+ "ui://test/widget.html" ,
83+ ) ;
84+ // Legacy key should also be set
85+ expect ( meta [ RESOURCE_URI_META_KEY ] ) . toBe ( "ui://test/widget.html" ) ;
86+ } ) ;
87+
88+ it ( "should set _meta.ui.resourceUri when legacy key is provided" , ( ) => {
89+ let capturedConfig : Record < string , unknown > | undefined ;
90+
91+ const mockServer = {
92+ registerTool : mock (
93+ ( _name : string , config : Record < string , unknown > , _handler : unknown ) => {
94+ capturedConfig = config ;
95+ } ,
96+ ) ,
97+ } ;
98+
99+ registerAppTool (
100+ mockServer as unknown as Pick < McpServer , "registerTool" > ,
101+ "my-tool" ,
102+ {
103+ _meta : {
104+ [ RESOURCE_URI_META_KEY ] : "ui://test/widget.html" ,
105+ } ,
106+ } ,
107+ async ( ) => ( { content : [ { type : "text" as const , text : "ok" } ] } ) ,
108+ ) ;
109+
110+ const meta = capturedConfig ?. _meta as Record < string , unknown > ;
111+ // Legacy key should be preserved
112+ expect ( meta [ RESOURCE_URI_META_KEY ] ) . toBe ( "ui://test/widget.html" ) ;
113+ // New format should also be set
114+ expect ( ( meta . ui as { resourceUri : string } ) . resourceUri ) . toBe (
115+ "ui://test/widget.html" ,
116+ ) ;
117+ } ) ;
118+
119+ it ( "should preserve visibility when converting from legacy format" , ( ) => {
120+ let capturedConfig : Record < string , unknown > | undefined ;
121+
122+ const mockServer = {
123+ registerTool : mock (
124+ ( _name : string , config : Record < string , unknown > , _handler : unknown ) => {
125+ capturedConfig = config ;
126+ } ,
127+ ) ,
128+ } ;
129+
130+ registerAppTool (
131+ mockServer as unknown as Pick < McpServer , "registerTool" > ,
132+ "my-tool" ,
133+ {
134+ _meta : {
135+ ui : { visibility : [ "app" ] } ,
136+ [ RESOURCE_URI_META_KEY ] : "ui://test/widget.html" ,
137+ } ,
138+ } as any ,
139+ async ( ) => ( { content : [ { type : "text" as const , text : "ok" } ] } ) ,
140+ ) ;
141+
142+ const meta = capturedConfig ?. _meta as Record < string , unknown > ;
143+ const ui = meta . ui as { resourceUri : string ; visibility : string [ ] } ;
144+ // Should have merged resourceUri into existing ui object
145+ expect ( ui . resourceUri ) . toBe ( "ui://test/widget.html" ) ;
146+ expect ( ui . visibility ) . toEqual ( [ "app" ] ) ;
147+ } ) ;
148+
149+ it ( "should not overwrite if both formats are already set" , ( ) => {
150+ let capturedConfig : Record < string , unknown > | undefined ;
151+
152+ const mockServer = {
153+ registerTool : mock (
154+ ( _name : string , config : Record < string , unknown > , _handler : unknown ) => {
155+ capturedConfig = config ;
156+ } ,
157+ ) ,
158+ } ;
159+
160+ registerAppTool (
161+ mockServer as unknown as Pick < McpServer , "registerTool" > ,
162+ "my-tool" ,
163+ {
164+ _meta : {
165+ ui : { resourceUri : "ui://new/widget.html" } ,
166+ [ RESOURCE_URI_META_KEY ] : "ui://old/widget.html" ,
167+ } ,
168+ } as any ,
169+ async ( ) => ( { content : [ { type : "text" as const , text : "ok" } ] } ) ,
170+ ) ;
171+
172+ const meta = capturedConfig ?. _meta as Record < string , unknown > ;
173+ // Both should remain unchanged
174+ expect ( ( meta . ui as { resourceUri : string } ) . resourceUri ) . toBe (
175+ "ui://new/widget.html" ,
176+ ) ;
177+ expect ( meta [ RESOURCE_URI_META_KEY ] ) . toBe ( "ui://old/widget.html" ) ;
178+ } ) ;
179+ } ) ;
55180} ) ;
56181
57182describe ( "registerAppResource" , ( ) => {
0 commit comments