skybridge 0.0.0-dev.ccf1ae1 → 0.0.0-dev.cd1bd15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/LICENSE +21 -0
  2. package/bin/run.js +5 -0
  3. package/dist/{src/server → server}/index.d.ts +0 -1
  4. package/dist/{src/server → server}/index.js +0 -1
  5. package/dist/server/index.js.map +1 -0
  6. package/dist/server/inferUtilityTypes.js.map +1 -0
  7. package/dist/{src/server → server}/server.d.ts +28 -1
  8. package/dist/server/server.js +130 -0
  9. package/dist/server/server.js.map +1 -0
  10. package/dist/server/templateHelper.js.map +1 -0
  11. package/dist/server/templates/development.hbs +66 -0
  12. package/dist/{src/server → server}/widgetsDevServer.d.ts +2 -2
  13. package/dist/{src/server → server}/widgetsDevServer.js +11 -3
  14. package/dist/server/widgetsDevServer.js.map +1 -0
  15. package/dist/test/utils.js.map +1 -0
  16. package/dist/{src/test → test}/widget.test.js +116 -12
  17. package/dist/test/widget.test.js.map +1 -0
  18. package/dist/{src/web → web}/bridges/adaptors/apps-sdk-adaptor.d.ts +1 -0
  19. package/dist/{src/web → web}/bridges/adaptors/apps-sdk-adaptor.js +3 -0
  20. package/dist/web/bridges/adaptors/apps-sdk-adaptor.js.map +1 -0
  21. package/dist/{src/web → web}/bridges/adaptors/mcp-app-adaptor.d.ts +1 -0
  22. package/dist/{src/web → web}/bridges/adaptors/mcp-app-adaptor.js +8 -1
  23. package/dist/web/bridges/adaptors/mcp-app-adaptor.js.map +1 -0
  24. package/dist/web/bridges/apps-sdk-bridge.js.map +1 -0
  25. package/dist/web/bridges/hooks/use-adaptor.js.map +1 -0
  26. package/dist/web/bridges/hooks/use-apps-sdk-bridge.js.map +1 -0
  27. package/dist/web/bridges/hooks/use-bridge.js.map +1 -0
  28. package/dist/web/bridges/hooks/use-mcp-app-bridge.js.map +1 -0
  29. package/dist/{src/web → web}/bridges/hooks/use-mcp-app-bridge.test.js +21 -0
  30. package/dist/web/bridges/hooks/use-mcp-app-bridge.test.js.map +1 -0
  31. package/dist/web/bridges/index.js.map +1 -0
  32. package/dist/{src/web → web}/bridges/mcp-app-bridge.d.ts +8 -0
  33. package/dist/{src/web → web}/bridges/mcp-app-bridge.js +55 -0
  34. package/dist/web/bridges/mcp-app-bridge.js.map +1 -0
  35. package/dist/{src/web → web}/bridges/types.d.ts +2 -1
  36. package/dist/{src/web → web}/bridges/types.js.map +1 -1
  37. package/dist/web/create-store.js.map +1 -0
  38. package/dist/web/create-store.test.js.map +1 -0
  39. package/dist/web/data-llm.js.map +1 -0
  40. package/dist/web/data-llm.test.js.map +1 -0
  41. package/dist/web/generate-helpers.js.map +1 -0
  42. package/dist/web/generate-helpers.test-d.js.map +1 -0
  43. package/dist/web/generate-helpers.test.js.map +1 -0
  44. package/dist/web/helpers/state.js.map +1 -0
  45. package/dist/web/helpers/state.test.js.map +1 -0
  46. package/dist/web/hooks/index.js.map +1 -0
  47. package/dist/web/hooks/test/utils.js.map +1 -0
  48. package/dist/{src/web → web}/hooks/use-call-tool.d.ts +1 -1
  49. package/dist/web/hooks/use-call-tool.js.map +1 -0
  50. package/dist/{src/web → web}/hooks/use-call-tool.test-d.js +1 -1
  51. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
  52. package/dist/{src/web → web}/hooks/use-call-tool.test.js +3 -4
  53. package/dist/web/hooks/use-call-tool.test.js.map +1 -0
  54. package/dist/web/hooks/use-display-mode.js.map +1 -0
  55. package/dist/web/hooks/use-display-mode.test.js.map +1 -0
  56. package/dist/web/hooks/use-files.js.map +1 -0
  57. package/dist/web/hooks/use-files.test.js.map +1 -0
  58. package/dist/web/hooks/use-layout.js.map +1 -0
  59. package/dist/web/hooks/use-layout.test.js.map +1 -0
  60. package/dist/web/hooks/use-open-external.js +8 -0
  61. package/dist/web/hooks/use-open-external.js.map +1 -0
  62. package/dist/web/hooks/use-open-external.test.js +50 -0
  63. package/dist/web/hooks/use-open-external.test.js.map +1 -0
  64. package/dist/web/hooks/use-openai-global.js.map +1 -0
  65. package/dist/web/hooks/use-request-modal.js.map +1 -0
  66. package/dist/web/hooks/use-request-modal.test.js.map +1 -0
  67. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
  68. package/dist/web/hooks/use-tool-info.js.map +1 -0
  69. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
  70. package/dist/web/hooks/use-tool-info.test.js.map +1 -0
  71. package/dist/web/hooks/use-user.js.map +1 -0
  72. package/dist/web/hooks/use-user.test.js.map +1 -0
  73. package/dist/web/hooks/use-widget-state.js.map +1 -0
  74. package/dist/web/hooks/use-widget-state.test.js.map +1 -0
  75. package/dist/web/index.js.map +1 -0
  76. package/dist/web/mount-widget.js.map +1 -0
  77. package/dist/web/plugin/data-llm.test.js.map +1 -0
  78. package/dist/web/plugin/plugin.js.map +1 -0
  79. package/dist/web/plugin/transform-data-llm.js.map +1 -0
  80. package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
  81. package/dist/web/proxy.js.map +1 -0
  82. package/dist/{src/web → web}/types.d.ts +1 -1
  83. package/dist/web/types.js.map +1 -0
  84. package/package.json +42 -30
  85. package/dist/src/server/devtoolsStaticServer.d.ts +0 -15
  86. package/dist/src/server/devtoolsStaticServer.js +0 -38
  87. package/dist/src/server/devtoolsStaticServer.js.map +0 -1
  88. package/dist/src/server/index.js.map +0 -1
  89. package/dist/src/server/inferUtilityTypes.js.map +0 -1
  90. package/dist/src/server/server.js +0 -82
  91. package/dist/src/server/server.js.map +0 -1
  92. package/dist/src/server/templateHelper.js.map +0 -1
  93. package/dist/src/server/templates/development.hbs +0 -13
  94. package/dist/src/server/widgetsDevServer.js.map +0 -1
  95. package/dist/src/test/utils.js.map +0 -1
  96. package/dist/src/test/widget.test.js.map +0 -1
  97. package/dist/src/web/bridges/adaptors/apps-sdk-adaptor.js.map +0 -1
  98. package/dist/src/web/bridges/adaptors/mcp-app-adaptor.js.map +0 -1
  99. package/dist/src/web/bridges/apps-sdk-bridge.js.map +0 -1
  100. package/dist/src/web/bridges/hooks/use-adaptor.js.map +0 -1
  101. package/dist/src/web/bridges/hooks/use-apps-sdk-bridge.js.map +0 -1
  102. package/dist/src/web/bridges/hooks/use-bridge.js.map +0 -1
  103. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.js.map +0 -1
  104. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.test.js.map +0 -1
  105. package/dist/src/web/bridges/index.js.map +0 -1
  106. package/dist/src/web/bridges/mcp-app-bridge.js.map +0 -1
  107. package/dist/src/web/create-store.js.map +0 -1
  108. package/dist/src/web/create-store.test.js.map +0 -1
  109. package/dist/src/web/data-llm.js.map +0 -1
  110. package/dist/src/web/data-llm.test.js.map +0 -1
  111. package/dist/src/web/generate-helpers.js.map +0 -1
  112. package/dist/src/web/generate-helpers.test-d.js.map +0 -1
  113. package/dist/src/web/generate-helpers.test.js.map +0 -1
  114. package/dist/src/web/helpers/state.js.map +0 -1
  115. package/dist/src/web/helpers/state.test.js.map +0 -1
  116. package/dist/src/web/hooks/index.js.map +0 -1
  117. package/dist/src/web/hooks/test/utils.js.map +0 -1
  118. package/dist/src/web/hooks/use-call-tool.js.map +0 -1
  119. package/dist/src/web/hooks/use-call-tool.test-d.js.map +0 -1
  120. package/dist/src/web/hooks/use-call-tool.test.js.map +0 -1
  121. package/dist/src/web/hooks/use-display-mode.js.map +0 -1
  122. package/dist/src/web/hooks/use-display-mode.test.js.map +0 -1
  123. package/dist/src/web/hooks/use-files.js.map +0 -1
  124. package/dist/src/web/hooks/use-files.test.js.map +0 -1
  125. package/dist/src/web/hooks/use-layout.js.map +0 -1
  126. package/dist/src/web/hooks/use-layout.test.js.map +0 -1
  127. package/dist/src/web/hooks/use-open-external.js +0 -6
  128. package/dist/src/web/hooks/use-open-external.js.map +0 -1
  129. package/dist/src/web/hooks/use-open-external.test.js +0 -24
  130. package/dist/src/web/hooks/use-open-external.test.js.map +0 -1
  131. package/dist/src/web/hooks/use-openai-global.js.map +0 -1
  132. package/dist/src/web/hooks/use-request-modal.js.map +0 -1
  133. package/dist/src/web/hooks/use-request-modal.test.js.map +0 -1
  134. package/dist/src/web/hooks/use-send-follow-up-message.js.map +0 -1
  135. package/dist/src/web/hooks/use-tool-info.js.map +0 -1
  136. package/dist/src/web/hooks/use-tool-info.test-d.js.map +0 -1
  137. package/dist/src/web/hooks/use-tool-info.test.js.map +0 -1
  138. package/dist/src/web/hooks/use-user.js.map +0 -1
  139. package/dist/src/web/hooks/use-user.test.js.map +0 -1
  140. package/dist/src/web/hooks/use-widget-state.js.map +0 -1
  141. package/dist/src/web/hooks/use-widget-state.test.js.map +0 -1
  142. package/dist/src/web/index.js.map +0 -1
  143. package/dist/src/web/mount-widget.js.map +0 -1
  144. package/dist/src/web/plugin/data-llm.test.js.map +0 -1
  145. package/dist/src/web/plugin/plugin.js.map +0 -1
  146. package/dist/src/web/plugin/transform-data-llm.js.map +0 -1
  147. package/dist/src/web/plugin/transform-data-llm.test.js.map +0 -1
  148. package/dist/src/web/proxy.js.map +0 -1
  149. package/dist/src/web/types.js.map +0 -1
  150. package/dist/vitest.config.d.ts +0 -2
  151. package/dist/vitest.config.js +0 -8
  152. package/dist/vitest.config.js.map +0 -1
  153. /package/dist/{src/server → server}/inferUtilityTypes.d.ts +0 -0
  154. /package/dist/{src/server → server}/inferUtilityTypes.js +0 -0
  155. /package/dist/{src/server → server}/templateHelper.d.ts +0 -0
  156. /package/dist/{src/server → server}/templateHelper.js +0 -0
  157. /package/dist/{src/server → server}/templates/production.hbs +0 -0
  158. /package/dist/{src/test → test}/utils.d.ts +0 -0
  159. /package/dist/{src/test → test}/utils.js +0 -0
  160. /package/dist/{src/test → test}/widget.test.d.ts +0 -0
  161. /package/dist/{src/web → web}/bridges/apps-sdk-bridge.d.ts +0 -0
  162. /package/dist/{src/web → web}/bridges/apps-sdk-bridge.js +0 -0
  163. /package/dist/{src/web → web}/bridges/hooks/use-adaptor.d.ts +0 -0
  164. /package/dist/{src/web → web}/bridges/hooks/use-adaptor.js +0 -0
  165. /package/dist/{src/web → web}/bridges/hooks/use-apps-sdk-bridge.d.ts +0 -0
  166. /package/dist/{src/web → web}/bridges/hooks/use-apps-sdk-bridge.js +0 -0
  167. /package/dist/{src/web → web}/bridges/hooks/use-bridge.d.ts +0 -0
  168. /package/dist/{src/web → web}/bridges/hooks/use-bridge.js +0 -0
  169. /package/dist/{src/web → web}/bridges/hooks/use-mcp-app-bridge.d.ts +0 -0
  170. /package/dist/{src/web → web}/bridges/hooks/use-mcp-app-bridge.js +0 -0
  171. /package/dist/{src/web → web}/bridges/hooks/use-mcp-app-bridge.test.d.ts +0 -0
  172. /package/dist/{src/web → web}/bridges/index.d.ts +0 -0
  173. /package/dist/{src/web → web}/bridges/index.js +0 -0
  174. /package/dist/{src/web → web}/bridges/types.js +0 -0
  175. /package/dist/{src/web → web}/create-store.d.ts +0 -0
  176. /package/dist/{src/web → web}/create-store.js +0 -0
  177. /package/dist/{src/web → web}/create-store.test.d.ts +0 -0
  178. /package/dist/{src/web → web}/create-store.test.js +0 -0
  179. /package/dist/{src/web → web}/data-llm.d.ts +0 -0
  180. /package/dist/{src/web → web}/data-llm.js +0 -0
  181. /package/dist/{src/web → web}/data-llm.test.d.ts +0 -0
  182. /package/dist/{src/web → web}/data-llm.test.js +0 -0
  183. /package/dist/{src/web → web}/generate-helpers.d.ts +0 -0
  184. /package/dist/{src/web → web}/generate-helpers.js +0 -0
  185. /package/dist/{src/web → web}/generate-helpers.test-d.d.ts +0 -0
  186. /package/dist/{src/web → web}/generate-helpers.test-d.js +0 -0
  187. /package/dist/{src/web → web}/generate-helpers.test.d.ts +0 -0
  188. /package/dist/{src/web → web}/generate-helpers.test.js +0 -0
  189. /package/dist/{src/web → web}/helpers/state.d.ts +0 -0
  190. /package/dist/{src/web → web}/helpers/state.js +0 -0
  191. /package/dist/{src/web → web}/helpers/state.test.d.ts +0 -0
  192. /package/dist/{src/web → web}/helpers/state.test.js +0 -0
  193. /package/dist/{src/web → web}/hooks/index.d.ts +0 -0
  194. /package/dist/{src/web → web}/hooks/index.js +0 -0
  195. /package/dist/{src/web → web}/hooks/test/utils.d.ts +0 -0
  196. /package/dist/{src/web → web}/hooks/test/utils.js +0 -0
  197. /package/dist/{src/web → web}/hooks/use-call-tool.js +0 -0
  198. /package/dist/{src/web → web}/hooks/use-call-tool.test-d.d.ts +0 -0
  199. /package/dist/{src/web → web}/hooks/use-call-tool.test.d.ts +0 -0
  200. /package/dist/{src/web → web}/hooks/use-display-mode.d.ts +0 -0
  201. /package/dist/{src/web → web}/hooks/use-display-mode.js +0 -0
  202. /package/dist/{src/web → web}/hooks/use-display-mode.test.d.ts +0 -0
  203. /package/dist/{src/web → web}/hooks/use-display-mode.test.js +0 -0
  204. /package/dist/{src/web → web}/hooks/use-files.d.ts +0 -0
  205. /package/dist/{src/web → web}/hooks/use-files.js +0 -0
  206. /package/dist/{src/web → web}/hooks/use-files.test.d.ts +0 -0
  207. /package/dist/{src/web → web}/hooks/use-files.test.js +0 -0
  208. /package/dist/{src/web → web}/hooks/use-layout.d.ts +0 -0
  209. /package/dist/{src/web → web}/hooks/use-layout.js +0 -0
  210. /package/dist/{src/web → web}/hooks/use-layout.test.d.ts +0 -0
  211. /package/dist/{src/web → web}/hooks/use-layout.test.js +0 -0
  212. /package/dist/{src/web → web}/hooks/use-open-external.d.ts +0 -0
  213. /package/dist/{src/web → web}/hooks/use-open-external.test.d.ts +0 -0
  214. /package/dist/{src/web → web}/hooks/use-openai-global.d.ts +0 -0
  215. /package/dist/{src/web → web}/hooks/use-openai-global.js +0 -0
  216. /package/dist/{src/web → web}/hooks/use-request-modal.d.ts +0 -0
  217. /package/dist/{src/web → web}/hooks/use-request-modal.js +0 -0
  218. /package/dist/{src/web → web}/hooks/use-request-modal.test.d.ts +0 -0
  219. /package/dist/{src/web → web}/hooks/use-request-modal.test.js +0 -0
  220. /package/dist/{src/web → web}/hooks/use-send-follow-up-message.d.ts +0 -0
  221. /package/dist/{src/web → web}/hooks/use-send-follow-up-message.js +0 -0
  222. /package/dist/{src/web → web}/hooks/use-tool-info.d.ts +0 -0
  223. /package/dist/{src/web → web}/hooks/use-tool-info.js +0 -0
  224. /package/dist/{src/web → web}/hooks/use-tool-info.test-d.d.ts +0 -0
  225. /package/dist/{src/web → web}/hooks/use-tool-info.test-d.js +0 -0
  226. /package/dist/{src/web → web}/hooks/use-tool-info.test.d.ts +0 -0
  227. /package/dist/{src/web → web}/hooks/use-tool-info.test.js +0 -0
  228. /package/dist/{src/web → web}/hooks/use-user.d.ts +0 -0
  229. /package/dist/{src/web → web}/hooks/use-user.js +0 -0
  230. /package/dist/{src/web → web}/hooks/use-user.test.d.ts +0 -0
  231. /package/dist/{src/web → web}/hooks/use-user.test.js +0 -0
  232. /package/dist/{src/web → web}/hooks/use-widget-state.d.ts +0 -0
  233. /package/dist/{src/web → web}/hooks/use-widget-state.js +0 -0
  234. /package/dist/{src/web → web}/hooks/use-widget-state.test.d.ts +0 -0
  235. /package/dist/{src/web → web}/hooks/use-widget-state.test.js +0 -0
  236. /package/dist/{src/web → web}/index.d.ts +0 -0
  237. /package/dist/{src/web → web}/index.js +0 -0
  238. /package/dist/{src/web → web}/mount-widget.d.ts +0 -0
  239. /package/dist/{src/web → web}/mount-widget.js +0 -0
  240. /package/dist/{src/web → web}/plugin/data-llm.test.d.ts +0 -0
  241. /package/dist/{src/web → web}/plugin/data-llm.test.js +0 -0
  242. /package/dist/{src/web → web}/plugin/plugin.d.ts +0 -0
  243. /package/dist/{src/web → web}/plugin/plugin.js +0 -0
  244. /package/dist/{src/web → web}/plugin/transform-data-llm.d.ts +0 -0
  245. /package/dist/{src/web → web}/plugin/transform-data-llm.js +0 -0
  246. /package/dist/{src/web → web}/plugin/transform-data-llm.test.d.ts +0 -0
  247. /package/dist/{src/web → web}/plugin/transform-data-llm.test.js +0 -0
  248. /package/dist/{src/web → web}/proxy.d.ts +0 -0
  249. /package/dist/{src/web → web}/proxy.js +0 -0
  250. /package/dist/{src/web → web}/types.js +0 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Alpic
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/bin/run.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execute } from "@oclif/core";
4
+
5
+ await execute({ dir: import.meta.url });
@@ -1,4 +1,3 @@
1
- export { devtoolsStaticServer } from "./devtoolsStaticServer.js";
2
1
  export type { AnyToolRegistry, InferTools, ToolInput, ToolNames, ToolOutput, ToolResponseMetadata, } from "./inferUtilityTypes.js";
3
2
  export type { McpServerTypes, ToolDef, WidgetHostType } from "./server.js";
4
3
  export { McpServer } from "./server.js";
@@ -1,4 +1,3 @@
1
- export { devtoolsStaticServer } from "./devtoolsStaticServer.js";
2
1
  export { McpServer } from "./server.js";
3
2
  export { widgetsDevServer } from "./widgetsDevServer.js";
4
3
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inferUtilityTypes.js","sourceRoot":"","sources":["../../src/server/inferUtilityTypes.ts"],"names":[],"mappings":""}
@@ -1,3 +1,4 @@
1
+ import type { McpUiResourceMeta } from "@modelcontextprotocol/ext-apps";
1
2
  import { McpServer as McpServerBase, type RegisteredTool } from "@modelcontextprotocol/sdk/server/mcp.js";
2
3
  import type { AnySchema, SchemaOutput, ZodRawShapeCompat } from "@modelcontextprotocol/sdk/server/zod-compat.js";
3
4
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
@@ -7,8 +8,34 @@ export type ToolDef<TInput = unknown, TOutput = unknown, TResponseMetadata = unk
7
8
  output: TOutput;
8
9
  responseMetadata: TResponseMetadata;
9
10
  };
11
+ /**
12
+ * Extended MCP Apps CSP with upcoming fields from ext-apps PR #158
13
+ * and Skybridge-specific fields for OpenAI compatibility
14
+ * @see https://github.com/modelcontextprotocol/ext-apps/pull/158
15
+ */
16
+ type ExtendedMcpUiResourceCsp = McpUiResourceMeta["csp"] & {
17
+ /** Origins allowed for nested iframe embeds */
18
+ frameDomains?: string[];
19
+ /** Origins permitted for the <base> tag URI directive */
20
+ baseUriDomains?: string[];
21
+ /**
22
+ * Origins that can receive openExternal redirects without safe-link modal (OpenAI-specific)
23
+ * @see https://developers.openai.com/apps-sdk/reference#component-resource-_meta-fields
24
+ */
25
+ redirectDomains?: string[];
26
+ };
27
+ /** Extended MCP Apps resource metadata with upcoming CSP fields */
28
+ type ExtendedMcpUiResourceMeta = Omit<McpUiResourceMeta, "csp"> & {
29
+ csp?: ExtendedMcpUiResourceCsp;
30
+ };
31
+ /** User-provided resource configuration with optional CSP override */
32
+ export type WidgetResourceMeta = {
33
+ ui?: ExtendedMcpUiResourceMeta;
34
+ } & Resource["_meta"];
10
35
  export type WidgetHostType = "apps-sdk" | "mcp-app";
11
- type McpServerOriginalResourceConfig = Omit<Resource, "uri" | "name" | "mimeType">;
36
+ type McpServerOriginalResourceConfig = Omit<Resource, "uri" | "name" | "mimeType" | "_meta"> & {
37
+ _meta?: WidgetResourceMeta;
38
+ };
12
39
  type McpServerOriginalToolConfig = Omit<Parameters<typeof McpServerBase.prototype.registerTool<ZodRawShapeCompat, ZodRawShapeCompat>>[1], "inputSchema" | "outputSchema">;
13
40
  type Simplify<T> = {
14
41
  [K in keyof T]: T[K];
@@ -0,0 +1,130 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { McpServer as McpServerBase, } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { toMerged } from "es-toolkit";
5
+ import { templateHelper } from "./templateHelper.js";
6
+ export class McpServer extends McpServerBase {
7
+ registerWidget(name, resourceConfig, toolConfig, toolCallback) {
8
+ const userMeta = resourceConfig._meta;
9
+ const appsSdkResourceConfig = {
10
+ hostType: "apps-sdk",
11
+ uri: `ui://widgets/apps-sdk/${name}.html`,
12
+ mimeType: "text/html+skybridge",
13
+ buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
14
+ const userUi = userMeta?.ui;
15
+ const userCsp = userUi?.csp;
16
+ const defaults = {
17
+ "openai/widgetCSP": {
18
+ resource_domains: resourceDomains,
19
+ connect_domains: connectDomains,
20
+ },
21
+ "openai/widgetDomain": domain,
22
+ "openai/widgetDescription": toolConfig.description,
23
+ };
24
+ const fromUi = {
25
+ "openai/widgetCSP": {
26
+ resource_domains: userCsp?.resourceDomains,
27
+ connect_domains: userCsp?.connectDomains,
28
+ frame_domains: userCsp?.frameDomains,
29
+ redirect_domains: userCsp?.redirectDomains,
30
+ },
31
+ "openai/widgetDomain": userUi?.domain,
32
+ "openai/widgetPrefersBorder": userUi?.prefersBorder,
33
+ };
34
+ const directOpenaiKeys = Object.fromEntries(Object.entries(userMeta ?? {}).filter(([key]) => key.startsWith("openai/")));
35
+ return toMerged(toMerged(defaults, fromUi), directOpenaiKeys);
36
+ },
37
+ };
38
+ const extAppsResourceConfig = {
39
+ hostType: "mcp-app",
40
+ uri: `ui://widgets/ext-apps/${name}.html`,
41
+ mimeType: "text/html;profile=mcp-app",
42
+ buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
43
+ const defaults = {
44
+ ui: {
45
+ csp: {
46
+ resourceDomains,
47
+ connectDomains,
48
+ },
49
+ domain,
50
+ },
51
+ };
52
+ return toMerged(defaults, { ui: userMeta?.ui });
53
+ },
54
+ };
55
+ [appsSdkResourceConfig, extAppsResourceConfig].forEach((widgetConfig) => {
56
+ this.registerWidgetResource({
57
+ name,
58
+ widgetConfig,
59
+ resourceConfig,
60
+ });
61
+ });
62
+ const toolMeta = {
63
+ ...toolConfig._meta,
64
+ "openai/outputTemplate": appsSdkResourceConfig.uri,
65
+ ui: {
66
+ resourceUri: extAppsResourceConfig.uri,
67
+ },
68
+ };
69
+ this.registerTool(name, {
70
+ ...toolConfig,
71
+ _meta: toolMeta,
72
+ }, toolCallback);
73
+ return this;
74
+ }
75
+ registerTool(name, config, cb) {
76
+ super.registerTool(name, config, cb);
77
+ return this;
78
+ }
79
+ registerWidgetResource({ name, widgetConfig, resourceConfig, }) {
80
+ const { hostType, uri: widgetUri, mimeType, buildContentMeta, } = widgetConfig;
81
+ this.registerResource(name, widgetUri, { ...resourceConfig, _meta: resourceConfig._meta }, async (uri, extra) => {
82
+ const isProduction = process.env.NODE_ENV === "production";
83
+ const serverUrl = isProduction
84
+ ? `https://${extra?.requestInfo?.headers?.["x-forwarded-host"] ?? extra?.requestInfo?.headers?.host}`
85
+ : "http://localhost:3000";
86
+ const wsServerUrl = serverUrl.replace(/^http/, "ws");
87
+ const html = isProduction
88
+ ? templateHelper.renderProduction({
89
+ hostType,
90
+ serverUrl,
91
+ widgetFile: this.lookupDistFileWithIndexFallback(`src/widgets/${name}`),
92
+ styleFile: this.lookupDistFile("style.css"),
93
+ })
94
+ : templateHelper.renderDevelopment({
95
+ hostType,
96
+ serverUrl,
97
+ widgetName: name,
98
+ });
99
+ const connectDomains = [serverUrl, wsServerUrl];
100
+ if (!isProduction) {
101
+ const VITE_HMR_WEBSOCKET_DEFAULT_URL = "ws://localhost:24678";
102
+ connectDomains.push(VITE_HMR_WEBSOCKET_DEFAULT_URL);
103
+ }
104
+ const contentMeta = buildContentMeta({
105
+ resourceDomains: [serverUrl],
106
+ connectDomains,
107
+ domain: serverUrl,
108
+ });
109
+ return {
110
+ contents: [
111
+ { uri: uri.href, mimeType, text: html, _meta: contentMeta },
112
+ ],
113
+ };
114
+ });
115
+ }
116
+ lookupDistFile(key) {
117
+ const manifest = this.readManifest();
118
+ return manifest[key]?.file;
119
+ }
120
+ lookupDistFileWithIndexFallback(basePath) {
121
+ const manifest = this.readManifest();
122
+ const flatFileKey = `${basePath}.tsx`;
123
+ const indexFileKey = `${basePath}/index.tsx`;
124
+ return manifest[flatFileKey]?.file ?? manifest[indexFileKey]?.file;
125
+ }
126
+ readManifest() {
127
+ return JSON.parse(readFileSync(path.join(process.cwd(), "dist", "assets", ".vite", "manifest.json"), "utf-8"));
128
+ }
129
+ }
130
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateHelper.js","sourceRoot":"","sources":["../../src/server/templateHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,UAAU,MAAM,YAAY,CAAC;AAGpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,cAAc;IACV,aAAa,GAAG,IAAI,GAAG,EAAsC,CAAC;IAE9D,YAAY,CAAC,YAAoB;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACpD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,YAAY,MAAM,CAAC,CAAC;QACzE,MAAM,cAAc,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEpD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,gBAAgB,CAAC,IAKhB;QACC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACjD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,iBAAiB,CAAC,IAIjB;QACC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAClD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}
@@ -0,0 +1,66 @@
1
+ <base href="{{serverUrl}}" />
2
+ <script type="module">window.skybridge = { hostType: "{{hostType}}" };</script>
3
+ <script type="module">
4
+ import { injectIntoGlobalHook } from "{{serverUrl}}/assets/@react-refresh";
5
+ injectIntoGlobalHook(window); window.$RefreshReg$ = () => {};
6
+ window.$RefreshSig$ = () => (type) => type;
7
+ window.__vite_plugin_react_preamble_installed__ = true;
8
+ </script>
9
+ <script type="module" src="{{serverUrl}}/@vite/client"></script>
10
+ <script type="module">
11
+ // Checks for browser support and shows error if local network access is denied
12
+ (async () => {
13
+ if (!navigator.permissions?.query) {
14
+ return;
15
+ }
16
+
17
+ // Skip for non-http(s) protocols (file://, custom protocols in Electron, etc.)
18
+ const protocol = window.location.protocol;
19
+ const isNonHttpProtocol = protocol !== 'http:' && protocol !== 'https:'
20
+ if (isNonHttpProtocol) {
21
+ return;
22
+ }
23
+
24
+ const host = window.location.hostname;
25
+ const isLoopback = host === 'localhost'
26
+ || /^127\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.test(host)
27
+ || host === '::1';
28
+ if (isLoopback) {
29
+ return;
30
+ }
31
+
32
+ try {
33
+ const status = await navigator.permissions.query({ name: "local-network-access" });
34
+ if (status.state === "denied") {
35
+ const errorDiv = document.createElement("div");
36
+ errorDiv.style.cssText = "background: #fef2f2; border: 2px solid #ef4444; border-radius: 8px; padding: 16px; text-align: center; z-index: 10000; font-family: system-ui, sans-serif;";
37
+
38
+ const errorTitle = document.createElement("div");
39
+ errorTitle.style.cssText = "color: #ef4444; font-size: 18px; font-weight: 600; margin-bottom: 8px;";
40
+ errorTitle.textContent = "Error: Local network access permission is denied.";
41
+
42
+ const errorMessage = document.createElement("div");
43
+ errorMessage.style.cssText = "color: #ef4444; font-size: 14px;";
44
+ errorMessage.textContent = "Local network access is required for your widget to connect to the local dev server. Please enable it in your browser settings. ";
45
+
46
+ const link = document.createElement("a");
47
+ link.href = "https://developer.chrome.com/blog/local-network-access";
48
+ link.target = "_blank";
49
+ link.rel = "noopener noreferrer";
50
+ link.style.cssText = "color: #ef4444; text-decoration: underline;";
51
+ link.textContent = "Learn more";
52
+ errorMessage.appendChild(link);
53
+
54
+ errorDiv.appendChild(errorTitle);
55
+ errorDiv.appendChild(errorMessage);
56
+ document.body.appendChild(errorDiv);
57
+ }
58
+ } catch (e) {
59
+ // Permission API doesn't support local-network-access, ignore silently
60
+ }
61
+ })();
62
+ </script>
63
+ <div id="root"></div>
64
+ <script type="module" id="dev-widget-entry">
65
+ import('{{serverUrl}}/src/widgets/{{widgetName}}');
66
+ </script>
@@ -1,4 +1,4 @@
1
- import { type RequestHandler } from "express";
1
+ import { type Router } from "express";
2
2
  /**
3
3
  * Install Vite dev server
4
4
  * This router MUST be installed at the application root, like so:
@@ -9,4 +9,4 @@ import { type RequestHandler } from "express";
9
9
  * app.use(await widgetsRouter());
10
10
  * }
11
11
  */
12
- export declare const widgetsDevServer: () => Promise<RequestHandler>;
12
+ export declare const widgetsDevServer: () => Promise<Router>;
@@ -1,3 +1,4 @@
1
+ import { existsSync } from "node:fs";
1
2
  import path from "node:path";
2
3
  import cors from "cors";
3
4
  import express, {} from "express";
@@ -14,10 +15,17 @@ import express, {} from "express";
14
15
  export const widgetsDevServer = async () => {
15
16
  const router = express.Router();
16
17
  const { createServer, searchForWorkspaceRoot, loadConfigFromFile } = await import("vite");
17
- const workspaceRoot = searchForWorkspaceRoot(process.cwd());
18
- const webAppRoot = path.join(workspaceRoot, "web");
18
+ // Since 0.16.0, the template is a single package that does not rely on workspace.
19
+ // It means that, when starting the server, the working dir is the template root
20
+ // hence we don't need to walk up the tree to find the workspace, which does not exist anymore.
21
+ let webAppRoot = path.join(process.cwd(), "web");
22
+ // fallback to the old behavior for backward compatibility
23
+ const hasWebAppRoot = existsSync(webAppRoot);
24
+ if (!hasWebAppRoot) {
25
+ const workspaceRoot = searchForWorkspaceRoot(process.cwd());
26
+ webAppRoot = path.join(workspaceRoot, "web");
27
+ }
19
28
  const configResult = await loadConfigFromFile({ command: "serve", mode: "development" }, path.join(webAppRoot, "vite.config.ts"), webAppRoot);
20
- // biome-ignore lint/correctness/noUnusedVariables: Remove build-specific options that don't apply to dev server
21
29
  const { build, preview, ...devConfig } = configResult?.config || {};
22
30
  const vite = await createServer({
23
31
  ...devConfig,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgetsDevServer.js","sourceRoot":"","sources":["../../src/server/widgetsDevServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAO,EAAE,EAAe,MAAM,SAAS,CAAC;AAC/C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAAqB,EAAE;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,MAAM,EAAE,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,GAChE,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvB,kFAAkF;IAClF,gFAAgF;IAChF,+FAA+F;IAC/F,IAAI,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;IAEjD,0DAA0D;IAC1D,MAAM,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,aAAa,GAAG,sBAAsB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5D,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAC3C,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EACzC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,EACvC,UAAU,CACX,CAAC;IAEF,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,GAAG,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;IAEpE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC;QAC9B,GAAG,SAAS;QACZ,UAAU,EAAE,KAAK,EAAE,kFAAkF;QACrG,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE;YACN,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;SACrB;QACD,IAAI,EAAE,UAAU;QAChB,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,CAAC;SACvC;KACF,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD;;GAEG;AACH,MAAM,UAAU,mBAAmB;IAKjC,mCAAmC;IACnC,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,OAAO;KACjB,EACD,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;IAEF,6CAA6C;IAC7C,MAAM,oBAAoB,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAClE,MAAM,gBAAgB,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAE1D,OAAO;QACL,MAAM;QACN,oBAAoB;QACpB,gBAAgB;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;SAC7D,cAAc,CACb,eAAe,EACf,EAAE,EACF;QACE,WAAW,EAAE,oBAAoB;QACjC,WAAW,EAAE;YACX,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;YACvB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACpC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SAChC;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,CAAC,KAAK,CACd,CAAC,CAAC,MAAM,CAAC;gBACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;gBACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;gBAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;aAClB,CAAC,CACH;YACD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;SACvB;KACF,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;QACxB,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,WAAW,EAAE,EAAE,CAAC;YAClE,iBAAiB,EAAE;gBACjB,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;gBACjD,UAAU,EAAE,CAAC;aACd;SACF,CAAC;IACJ,CAAC,CACF;SACA,cAAc,CACb,kBAAkB,EAClB,EAAE,EACF;QACE,WAAW,EAAE,kBAAkB;QAC/B,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;SACnB;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;YACvB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SAC5B;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,MAAM,EAAE,EAAE,CAAC;YAC1D,iBAAiB,EAAE;gBACjB,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,cAAc;gBAC3B,MAAM,EAAE,CAAC,YAAY,CAAC;aACvB;SACF,CAAC;IACJ,CAAC,CACF;SACA,cAAc,CACb,iBAAiB,EACjB,EAAE,EACF;QACE,WAAW,EAAE,sBAAsB;QACnC,WAAW,EAAE,EAAE;QACf,YAAY,EAAE,EAAE;KACjB,EACD,KAAK,IAAI,EAAE;QACT,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC;YACpD,iBAAiB,EAAE,EAAE;SACtB,CAAC;IACJ,CAAC,CACF;SACA,cAAc,CACb,wBAAwB,EACxB,EAAE,EACF;QACE,WAAW,EAAE,2CAA2C;QACxD,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;SAClB;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAClB,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC;YACpD,iBAAiB,EAAE;gBACjB,eAAe,EAAE,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;gBACpD,aAAa,EAAE,CAAC;aACjB;SACF,CAAC;IACJ,CAAC,CACF;SACA,YAAY,CACX,iBAAiB,EACjB;QACE,WAAW,EAAE,sBAAsB;QACnC,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;SACvB;QACD,YAAY,EAAE;YACZ,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;YACtB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;SACrB;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE;QAC/B,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,MAAM,EAAE,EAAE,CAAC;YACxD,iBAAiB,EAAE;gBACjB,UAAU,EAAE,IAAI,GAAG,UAAU;gBAC7B,QAAQ,EAAE,KAAK;aAChB;SACF,CAAC;IACJ,CAAC,CACF;SACA,YAAY,CACX,eAAe,EACf;QACE,WAAW,EAAE,yCAAyC;QACtD,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;SACnB;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC;YACpD,iBAAiB,EAAE;gBACjB,WAAW,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,IAAI,EAAE;gBACvD,SAAS,EAAE,YAAY;aACxB;SACF,CAAC;IACJ,CAAC,CACF;SACA,cAAc,CACb,sBAAsB,EACtB,EAAE,EACF;QACE,WAAW,EAAE,uCAAuC;QACpD,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;SACvB;KACF,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;QACvB,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,UAAU,EAAE,EAAE,CAAC;YAC5D,iBAAiB,EAAE;gBACjB,IAAI,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE;aACvC;YACD,KAAK,EAAE;gBACL,SAAS,EAAE,SAAS;gBACpB,SAAS,EAAE,aAAa;gBACxB,MAAM,EAAE,KAAK;aACd;SACF,CAAC;IACJ,CAAC,CACF;SACA,YAAY,CACX,oBAAoB,EACpB;QACE,WAAW,EAAE,qCAAqC;QAClD,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;SAClB;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAClB,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC;YACpD,iBAAiB,EAAE;gBACjB,OAAO,EAAE,CAAC,KAAK,CAAC;aACjB;YACD,KAAK,EAAE;gBACL,aAAa,EAAE,GAAG;gBAClB,MAAM,EAAE,OAAO;aAChB;SACF,CAAC;IACJ,CAAC,CACF;SACA,cAAc,CACb,2BAA2B,EAC3B,EAAE,EACF;QACE,WAAW,EACT,gEAAgE;QAClE,WAAW,EAAE;YACX,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;SAC3B;KACF,EACD,KAAK,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE;QAC1B,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,wBAAwB;YACxB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;gBACnD,iBAAiB,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE;aACrD,CAAC;QACJ,CAAC;QACD,2BAA2B;QAC3B,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC5C,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACrC,KAAK,EAAE;gBACL,WAAW,EAAE,aAAa;gBAC1B,MAAM,EAAE,WAAW;aACpB;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACN,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO,IAAI,SAAS,CAClB,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EACtC,EAAE,CACH,CAAC,cAAc,CACd,eAAe,EACf,EAAE,EACF;QACE,WAAW,EAAE,oBAAoB;QACjC,WAAW,EAAE;YACX,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;SACxB;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;SAC/C;KACF,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;QACxB,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,WAAW,EAAE,EAAE,CAAC;YAClE,iBAAiB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;SAC9C,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC;AAkBD,MAAM,UAAU,yBAAyB;IACvC,OAAO,IAAI,SAAS,CAClB,EAAE,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,EAAE,EAChD,EAAE,CACH,CAAC,cAAc,CAKd,kBAAkB,EAClB,EAAE,EACF;QACE,WAAW,EAAE,oCAAoC;QACjD,WAAW,EAAE;YACX,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;SACf;KACF,EACD,KAAK,EAAE,EAAE,EAAE,EAAE,EAAgC,EAAE;QAC7C,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;YAC/C,iBAAiB,EAAE;gBACjB,QAAQ,EAAE,WAAW;gBACrB,QAAQ,EAAE,EAAE;aACb;YACD,KAAK,EAAE;gBACL,WAAW,EAAE,MAAM;gBACnB,OAAO,EAAE,CAAC;aACX;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO;QACL,WAAW,EAAE;YACX,OAAO,EAAE,EAAE,IAAI,EAAE;SAClB;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAA2B;IACpD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC9B,CAAC"}
@@ -5,15 +5,12 @@ const mockManifest = {
5
5
  "src/widgets/folder-widget/index.tsx": { file: "folder-widget.js" },
6
6
  "style.css": { file: "style.css" },
7
7
  };
8
- vi.mock("node:fs", async () => {
9
- const actual = await vi.importActual("node:fs");
8
+ const actual = vi.hoisted(() => require("node:fs"));
9
+ vi.mock("node:fs", () => {
10
10
  const readFileSyncImpl = (path, ...args) => {
11
11
  if (typeof path === "string" && path.includes("manifest.json")) {
12
12
  return JSON.stringify(mockManifest);
13
13
  }
14
- // Type assertion needed because readFileSync has overloads with different parameter types
15
- // Using @ts-expect-error because the overloads are complex and we're forwarding args
16
- // @ts-expect-error - readFileSync overloads require complex type handling
17
14
  return actual.readFileSync(path, ...args);
18
15
  };
19
16
  const readFileSync = vi.fn(readFileSyncImpl);
@@ -56,11 +53,23 @@ describe("McpServer.registerWidget", () => {
56
53
  uri: "ui://widgets/apps-sdk/my-widget.html",
57
54
  mimeType: "text/html+skybridge",
58
55
  text: expect.stringContaining('<div id="root"></div>'),
56
+ _meta: {
57
+ "openai/widgetCSP": {
58
+ resource_domains: [serverUrl],
59
+ connect_domains: [
60
+ serverUrl,
61
+ "ws://localhost:3000",
62
+ "ws://localhost:24678",
63
+ ],
64
+ },
65
+ "openai/widgetDomain": serverUrl,
66
+ "openai/widgetDescription": "Test tool",
67
+ },
59
68
  },
60
69
  ],
61
70
  });
62
71
  // Check development-specific content
63
- expect(result.contents[0]?.text).toContain(`${serverUrl}/@react-refresh`);
72
+ expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/@react-refresh`);
64
73
  expect(result.contents[0]?.text).toContain(`${serverUrl}/@vite/client`);
65
74
  expect(result.contents[0]?.text).toContain(`${serverUrl}/src/widgets/my-widget`);
66
75
  expect(result.contents[0]?.text).not.toContain(`${serverUrl}/src/widgets/my-widget.tsx`);
@@ -75,8 +84,9 @@ describe("McpServer.registerWidget", () => {
75
84
  const appsSdkResourceCallback = mockRegisterResource.mock
76
85
  .calls[0]?.[3];
77
86
  expect(appsSdkResourceCallback).toBeDefined();
78
- const serverUrl = "https://myapp.com";
79
- const mockExtra = createMockExtra(serverUrl);
87
+ const host = "myapp.com";
88
+ const serverUrl = `https://${host}`;
89
+ const mockExtra = createMockExtra(host);
80
90
  const result = await appsSdkResourceCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), mockExtra);
81
91
  expect(result).toEqual({
82
92
  contents: [
@@ -84,11 +94,19 @@ describe("McpServer.registerWidget", () => {
84
94
  uri: "ui://widgets/apps-sdk/my-widget.html",
85
95
  mimeType: "text/html+skybridge",
86
96
  text: expect.stringContaining('<div id="root"></div>'),
97
+ _meta: {
98
+ "openai/widgetCSP": {
99
+ resource_domains: [serverUrl],
100
+ connect_domains: [serverUrl, `wss://${host}`],
101
+ },
102
+ "openai/widgetDomain": serverUrl,
103
+ "openai/widgetDescription": "Test tool",
104
+ },
87
105
  },
88
106
  ],
89
107
  });
90
108
  // Check production-specific content
91
- expect(result.contents[0]?.text).not.toContain(`${serverUrl}@react-refresh`);
109
+ expect(result.contents[0]?.text).not.toContain(`${serverUrl}/assets/@react-refresh`);
92
110
  expect(result.contents[0]?.text).not.toContain(`${serverUrl}@vite/client`);
93
111
  expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/my-widget.js`);
94
112
  expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/style.css`);
@@ -102,15 +120,19 @@ describe("McpServer.registerWidget", () => {
102
120
  const appsSdkResourceCallback = mockRegisterResource.mock
103
121
  .calls[0]?.[3];
104
122
  expect(appsSdkResourceCallback).toBeDefined();
105
- const serverUrl = "https://myapp.com";
106
- const mockExtra = createMockExtra(serverUrl);
123
+ const host = "myapp.com";
124
+ const serverUrl = `https://${host}`;
125
+ const mockExtra = createMockExtra(host);
107
126
  const result = await appsSdkResourceCallback(new URL("ui://widgets/apps-sdk/folder-widget.html"), mockExtra);
108
127
  // Should resolve to folder-widget.js from the manifest entry "src/widgets/folder-widget/index.tsx"
109
128
  expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/folder-widget.js`);
110
129
  });
111
130
  it("should register resources with correct hostType for both apps-sdk and ext-apps formats", async () => {
112
131
  const mockToolCallback = vi.fn();
113
- const mockRegisterResourceConfig = { description: "Test widget" };
132
+ const mockRegisterResourceConfig = {
133
+ description: "Test widget",
134
+ _meta: { "openai/widgetPrefersBorder": true },
135
+ };
114
136
  const mockToolConfig = { description: "Test tool" };
115
137
  server.registerWidget("my-widget", mockRegisterResourceConfig, mockToolConfig, mockToolCallback);
116
138
  expect(mockRegisterResource).toHaveBeenCalledTimes(2);
@@ -123,6 +145,19 @@ describe("McpServer.registerWidget", () => {
123
145
  uri: "ui://widgets/apps-sdk/my-widget.html",
124
146
  mimeType: "text/html+skybridge",
125
147
  text: expect.stringContaining('<div id="root"></div>'),
148
+ _meta: {
149
+ "openai/widgetCSP": {
150
+ resource_domains: ["http://localhost:3000"],
151
+ connect_domains: [
152
+ "http://localhost:3000",
153
+ "ws://localhost:3000",
154
+ "ws://localhost:24678",
155
+ ],
156
+ },
157
+ "openai/widgetDomain": "http://localhost:3000",
158
+ "openai/widgetDescription": "Test tool",
159
+ "openai/widgetPrefersBorder": true,
160
+ },
126
161
  },
127
162
  ],
128
163
  });
@@ -137,10 +172,79 @@ describe("McpServer.registerWidget", () => {
137
172
  uri: "ui://widgets/ext-apps/my-widget.html",
138
173
  mimeType: "text/html;profile=mcp-app",
139
174
  text: expect.stringContaining('<div id="root"></div>'),
175
+ _meta: {
176
+ ui: {
177
+ csp: {
178
+ resourceDomains: ["http://localhost:3000"],
179
+ connectDomains: [
180
+ "http://localhost:3000",
181
+ "ws://localhost:3000",
182
+ "ws://localhost:24678",
183
+ ],
184
+ },
185
+ domain: "http://localhost:3000",
186
+ },
187
+ },
140
188
  },
141
189
  ],
142
190
  });
143
191
  expect(extAppsResult.contents[0]?.text).toContain('window.skybridge = { hostType: "mcp-app" }');
144
192
  });
193
+ it("should register tool with ui.resourceUri metadata (not deprecated ui/resourceUri)", async () => {
194
+ const mockToolCallback = vi.fn();
195
+ const mockRegisterResourceConfig = { description: "Test widget" };
196
+ const mockToolConfig = { description: "Test tool" };
197
+ server.registerWidget("my-widget", mockRegisterResourceConfig, mockToolConfig, mockToolCallback);
198
+ expect(mockRegisterTool).toHaveBeenCalledTimes(1);
199
+ const toolCallArgs = mockRegisterTool.mock.calls[0];
200
+ const toolConfig = toolCallArgs?.[1];
201
+ expect(toolConfig._meta).toHaveProperty("ui");
202
+ expect(toolConfig._meta?.ui).toEqual({
203
+ resourceUri: "ui://widgets/ext-apps/my-widget.html",
204
+ });
205
+ });
206
+ it("should apply meta overrides in correct priority: defaults < ui.* < direct openai/* keys", async () => {
207
+ const mockToolCallback = vi.fn();
208
+ const mockRegisterResourceConfig = {
209
+ description: "Test widget",
210
+ _meta: {
211
+ // ui.csp overrides (middle priority)
212
+ ui: {
213
+ csp: {
214
+ resourceDomains: ["https://from-ui-csp.com"],
215
+ connectDomains: ["https://from-ui-csp.com"],
216
+ },
217
+ domain: "https://from-ui-domain.com",
218
+ prefersBorder: false,
219
+ },
220
+ // Direct openai/* keys (highest priority) - should override ui.*
221
+ "openai/widgetDomain": "https://direct-override.com",
222
+ "openai/widgetPrefersBorder": true,
223
+ },
224
+ };
225
+ const mockToolConfig = { description: "Test tool" };
226
+ server.registerWidget("override-test", mockRegisterResourceConfig, mockToolConfig, mockToolCallback);
227
+ const appsSdkCallback = mockRegisterResource.mock
228
+ .calls[0]?.[3];
229
+ const result = await appsSdkCallback(new URL("ui://widgets/apps-sdk/override-test.html"), createMockExtra("__not_used__"));
230
+ const meta = result.contents[0]?._meta;
231
+ // CSP arrays are merged by index - user value replaces at index 0, defaults remain at other indices
232
+ expect(meta["openai/widgetCSP"]).toEqual({
233
+ resource_domains: ["https://from-ui-csp.com"],
234
+ connect_domains: [
235
+ "https://from-ui-csp.com",
236
+ "ws://localhost:3000",
237
+ "ws://localhost:24678",
238
+ ],
239
+ frame_domains: undefined,
240
+ redirect_domains: undefined,
241
+ });
242
+ // Domain should be overridden by direct openai/* key (highest priority)
243
+ expect(meta["openai/widgetDomain"]).toBe("https://direct-override.com");
244
+ // PrefersBorder should be overridden by direct openai/* key (highest priority)
245
+ expect(meta["openai/widgetPrefersBorder"]).toBe(true);
246
+ // Description should be from defaults (toolConfig.description)
247
+ expect(meta["openai/widgetDescription"]).toBe("Test tool");
248
+ });
145
249
  });
146
250
  //# sourceMappingURL=widget.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget.test.js","sourceRoot":"","sources":["../../src/test/widget.test.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,MAAM,EACN,EAAE,EAEF,EAAE,GACH,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,YAAY,EACZ,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,MAAM,YAAY,GAAG;IACnB,2BAA2B,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;IACrD,qCAAqC,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE;IACnE,WAAW,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;CACnC,CAAC;AAEF,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;AAEpD,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;IACtB,MAAM,gBAAgB,GAAG,CACvB,IAA+C,EAC/C,GAAG,IAAe,EACsB,EAAE;QAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YAC/D,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAEjC,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC,CAAC;IACF,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAA+B,CAAC;IAE3E,OAAO;QACL,YAAY;QACZ,OAAO,EAAE;YACP,YAAY;SACb;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,IAAI,MAAiB,CAAC;IACtB,IAAI,oBAAiE,CAAC;IACtE,IAAI,gBAAyD,CAAC;IAE9D,UAAU,CAAC,GAAG,EAAE;QACd,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,gBAAgB,EAAE;YACjD,mBAAmB,EAAE,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,YAAY,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,UAAU,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC;QAExC,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,0BAA0B,GAAG,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;QAClE,MAAM,cAAc,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;QAEpD,MAAM,CAAC,cAAc,CACnB,WAAW,EACX,0BAA0B,EAC1B,cAAc,EACd,gBAAgB,CACjB,CAAC;QAEF,qCAAqC;QACrC,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAI;aACtD,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAKb,CAAC;QACH,MAAM,CAAC,uBAAuB,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9C,MAAM,SAAS,GAAG,uBAAuB,CAAC;QAC1C,MAAM,SAAS,GAAG,eAAe,CAC/B,cAAc,CACsD,CAAC;QACvE,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,IAAI,GAAG,CAAC,sCAAsC,CAAC,EAC/C,SAAS,CACV,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,sCAAsC;oBAC3C,QAAQ,EAAE,qBAAqB;oBAC/B,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,CAAC;oBACtD,KAAK,EAAE;wBACL,kBAAkB,EAAE;4BAClB,gBAAgB,EAAE,CAAC,SAAS,CAAC;4BAC7B,eAAe,EAAE;gCACf,SAAS;gCACT,qBAAqB;gCACrB,sBAAsB;6BACvB;yBACF;wBACD,qBAAqB,EAAE,SAAS;wBAChC,0BAA0B,EAAE,WAAW;qBACxC;iBACF;aACF;SACF,CAAC,CAAC;QAEH,qCAAqC;QACrC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CACxC,GAAG,SAAS,wBAAwB,CACrC,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,GAAG,SAAS,eAAe,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CACxC,GAAG,SAAS,wBAAwB,CACrC,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAC5C,GAAG,SAAS,4BAA4B,CACzC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,UAAU,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;QAEvC,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,0BAA0B,GAAG,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;QAClE,MAAM,cAAc,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;QAEpD,MAAM,CAAC,cAAc,CACnB,WAAW,EACX,0BAA0B,EAC1B,cAAc,EACd,gBAAgB,CACjB,CAAC;QAEF,qCAAqC;QACrC,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAI;aACtD,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAKb,CAAC;QACH,MAAM,CAAC,uBAAuB,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9C,MAAM,IAAI,GAAG,WAAW,CAAC;QACzB,MAAM,SAAS,GAAG,WAAW,IAAI,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAGrC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,IAAI,GAAG,CAAC,sCAAsC,CAAC,EAC/C,SAAS,CACV,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,sCAAsC;oBAC3C,QAAQ,EAAE,qBAAqB;oBAC/B,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,CAAC;oBACtD,KAAK,EAAE;wBACL,kBAAkB,EAAE;4BAClB,gBAAgB,EAAE,CAAC,SAAS,CAAC;4BAC7B,eAAe,EAAE,CAAC,SAAS,EAAE,SAAS,IAAI,EAAE,CAAC;yBAC9C;wBACD,qBAAqB,EAAE,SAAS;wBAChC,0BAA0B,EAAE,WAAW;qBACxC;iBACF;aACF;SACF,CAAC,CAAC;QAEH,oCAAoC;QACpC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAC5C,GAAG,SAAS,wBAAwB,CACrC,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,SAAS,cAAc,CAAC,CAAC;QAC3E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CACxC,GAAG,SAAS,sBAAsB,CACnC,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,GAAG,SAAS,mBAAmB,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,UAAU,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;QAEvC,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,0BAA0B,GAAG,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;QACpE,MAAM,cAAc,GAAG,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;QAEtD,MAAM,CAAC,cAAc,CACnB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,gBAAgB,CACjB,CAAC;QAEF,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAI;aACtD,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAKb,CAAC;QACH,MAAM,CAAC,uBAAuB,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9C,MAAM,IAAI,GAAG,WAAW,CAAC;QACzB,MAAM,SAAS,GAAG,WAAW,IAAI,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAGrC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,IAAI,GAAG,CAAC,0CAA0C,CAAC,EACnD,SAAS,CACV,CAAC;QAEF,mGAAmG;QACnG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CACxC,GAAG,SAAS,0BAA0B,CACvC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wFAAwF,EAAE,KAAK,IAAI,EAAE;QACtG,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,0BAA0B,GAAG;YACjC,WAAW,EAAE,aAAa;YAC1B,KAAK,EAAE,EAAE,4BAA4B,EAAE,IAAI,EAAE;SAC9C,CAAC;QACF,MAAM,cAAc,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;QAEpD,MAAM,CAAC,cAAc,CACnB,WAAW,EACX,0BAA0B,EAC1B,cAAc,EACd,gBAAgB,CACjB,CAAC;QAEF,MAAM,CAAC,oBAAoB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAEtD,MAAM,eAAe,GAAG,oBAAoB,CAAC,IAAI;aAC9C,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAKb,CAAC;QACH,MAAM,aAAa,GAAG,MAAM,eAAe,CACzC,IAAI,GAAG,CAAC,sCAAsC,CAAC,EAC/C,eAAe,CAAC,cAAc,CAG7B,CACF,CAAC;QAEF,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC;YAC5B,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,sCAAsC;oBAC3C,QAAQ,EAAE,qBAAqB;oBAC/B,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,CAAC;oBACtD,KAAK,EAAE;wBACL,kBAAkB,EAAE;4BAClB,gBAAgB,EAAE,CAAC,uBAAuB,CAAC;4BAC3C,eAAe,EAAE;gCACf,uBAAuB;gCACvB,qBAAqB;gCACrB,sBAAsB;6BACvB;yBACF;wBACD,qBAAqB,EAAE,uBAAuB;wBAC9C,0BAA0B,EAAE,WAAW;wBACvC,4BAA4B,EAAE,IAAI;qBACnC;iBACF;aACF;SACF,CAAC,CAAC;QACH,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAC/C,6CAA6C,CAC9C,CAAC;QAEF,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAI;aACtD,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAUb,CAAC;QACH,MAAM,CAAC,uBAAuB,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9C,MAAM,aAAa,GAAG,MAAM,uBAAuB,CACjD,IAAI,GAAG,CAAC,sCAAsC,CAAC,EAC/C,eAAe,CAAC,cAAc,CAG7B,CACF,CAAC;QAEF,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC;YAC5B,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,sCAAsC;oBAC3C,QAAQ,EAAE,2BAA2B;oBACrC,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,CAAC;oBACtD,KAAK,EAAE;wBACL,EAAE,EAAE;4BACF,GAAG,EAAE;gCACH,eAAe,EAAE,CAAC,uBAAuB,CAAC;gCAC1C,cAAc,EAAE;oCACd,uBAAuB;oCACvB,qBAAqB;oCACrB,sBAAsB;iCACvB;6BACF;4BACD,MAAM,EAAE,uBAAuB;yBAChC;qBACF;iBACF;aACF;SACF,CAAC,CAAC;QACH,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAC/C,4CAA4C,CAC7C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;QACjG,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,0BAA0B,GAAG,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;QAClE,MAAM,cAAc,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;QAEpD,MAAM,CAAC,cAAc,CACnB,WAAW,EACX,0BAA0B,EAC1B,cAAc,EACd,gBAAgB,CACjB,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAElD,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC,CAAC,CAAwC,CAAC;QAE5E,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC;YACnC,WAAW,EAAE,sCAAsC;SACpD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yFAAyF,EAAE,KAAK,IAAI,EAAE;QACvG,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,0BAA0B,GAAG;YACjC,WAAW,EAAE,aAAa;YAC1B,KAAK,EAAE;gBACL,qCAAqC;gBACrC,EAAE,EAAE;oBACF,GAAG,EAAE;wBACH,eAAe,EAAE,CAAC,yBAAyB,CAAC;wBAC5C,cAAc,EAAE,CAAC,yBAAyB,CAAC;qBAC5C;oBACD,MAAM,EAAE,4BAA4B;oBACpC,aAAa,EAAE,KAAK;iBACrB;gBACD,iEAAiE;gBACjE,qBAAqB,EAAE,6BAA6B;gBACpD,4BAA4B,EAAE,IAAI;aACnC;SACF,CAAC;QACF,MAAM,cAAc,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;QAEpD,MAAM,CAAC,cAAc,CACnB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,gBAAgB,CACjB,CAAC;QAEF,MAAM,eAAe,GAAG,oBAAoB,CAAC,IAAI;aAC9C,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAUb,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,eAAe,CAClC,IAAI,GAAG,CAAC,0CAA0C,CAAC,EACnD,eAAe,CAAC,cAAc,CAG7B,CACF,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAgC,CAAC;QAElE,oGAAoG;QACpG,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC;YACvC,gBAAgB,EAAE,CAAC,yBAAyB,CAAC;YAC7C,eAAe,EAAE;gBACf,yBAAyB;gBACzB,qBAAqB;gBACrB,sBAAsB;aACvB;YACD,aAAa,EAAE,SAAS;YACxB,gBAAgB,EAAE,SAAS;SAC5B,CAAC,CAAC;QAEH,wEAAwE;QACxE,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAExE,+EAA+E;QAC/E,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtD,+DAA+D;QAC/D,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -9,4 +9,5 @@ export declare class AppsSdkAdaptor implements Adaptor {
9
9
  mode: DisplayMode;
10
10
  }>;
11
11
  sendFollowUpMessage: (prompt: string) => Promise<void>;
12
+ openExternal(href: string): void;
12
13
  }
@@ -26,5 +26,8 @@ export class AppsSdkAdaptor {
26
26
  sendFollowUpMessage = (prompt) => {
27
27
  return window.openai.sendFollowUpMessage({ prompt });
28
28
  };
29
+ openExternal(href) {
30
+ window.openai.openExternal({ href });
31
+ }
29
32
  }
30
33
  //# sourceMappingURL=apps-sdk-adaptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-sdk-adaptor.js","sourceRoot":"","sources":["../../../../src/web/bridges/adaptors/apps-sdk-adaptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAStD,MAAM,OAAO,cAAc;IACjB,MAAM,CAAC,QAAQ,GAA0B,IAAI,CAAC;IAE/C,MAAM,CAAC,WAAW;QACvB,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC7B,cAAc,CAAC,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;QACjD,CAAC;QACD,OAAO,cAAc,CAAC,QAAQ,CAAC;IACjC,CAAC;IAEM,MAAM,CAAC,aAAa;QACzB,cAAc,CAAC,QAAQ,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,gBAAgB,CACrB,GAAM;QAEN,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;QAC3C,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;YAChC,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC;SAC3C,CAAC;IACJ,CAAC;IAEM,QAAQ,GAAG,KAAK,EAIrB,IAAY,EACZ,IAAc,EACS,EAAE;QACzB,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAyB,IAAI,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC,CAAC;IAEK,kBAAkB,GAAG,CAC1B,IAAiB,EACe,EAAE;QAClC,OAAO,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC;IAEK,mBAAmB,GAAG,CAAC,MAAc,EAAiB,EAAE;QAC7D,OAAO,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC;IAEK,YAAY,CAAC,IAAY;QAC9B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC"}
@@ -10,6 +10,7 @@ export declare class McpAppAdaptor implements Adaptor {
10
10
  callTool: <ToolArgs extends Record<string, unknown> | null = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs) => Promise<ToolResponse>;
11
11
  requestDisplayMode: (mode: DisplayMode) => Promise<McpUiRequestDisplayModeResult>;
12
12
  sendFollowUpMessage: (prompt: string) => Promise<void>;
13
+ openExternal(href: string): void;
13
14
  private initializeStores;
14
15
  private createExternalStore;
15
16
  }
@@ -36,7 +36,7 @@ export class McpAppAdaptor {
36
36
  structuredContent: response.structuredContent ?? {},
37
37
  isError: response.isError ?? false,
38
38
  result,
39
- meta: response._meta ?? {},
39
+ _meta: response._meta ?? {},
40
40
  };
41
41
  };
42
42
  requestDisplayMode = (mode) => {
@@ -64,6 +64,13 @@ export class McpAppAdaptor {
64
64
  },
65
65
  });
66
66
  };
67
+ openExternal(href) {
68
+ const bridge = McpAppBridge.getInstance();
69
+ bridge.request({
70
+ method: "ui/open-link",
71
+ params: { url: href },
72
+ });
73
+ }
67
74
  initializeStores() {
68
75
  return {
69
76
  theme: this.createExternalStore(["theme"], ({ theme }) => theme ?? "light"),