skybridge 0.0.0-dev.8027fea → 0.0.0-dev.8054fa4

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 (468) hide show
  1. package/README.md +125 -116
  2. package/dist/cli/build-helpers.d.ts +11 -0
  3. package/dist/cli/build-helpers.js +107 -0
  4. package/dist/cli/build-helpers.js.map +1 -0
  5. package/dist/cli/build-helpers.test.js +130 -0
  6. package/dist/cli/build-helpers.test.js.map +1 -0
  7. package/dist/cli/build-steps.d.ts +2 -0
  8. package/dist/cli/build-steps.js +73 -0
  9. package/dist/cli/build-steps.js.map +1 -0
  10. package/dist/cli/build-steps.test.js +52 -0
  11. package/dist/cli/build-steps.test.js.map +1 -0
  12. package/dist/cli/detect-port.d.ts +2 -2
  13. package/dist/cli/detect-port.js +9 -20
  14. package/dist/cli/detect-port.js.map +1 -1
  15. package/dist/cli/header.d.ts +1 -1
  16. package/dist/cli/header.js +1 -1
  17. package/dist/cli/header.js.map +1 -1
  18. package/dist/cli/resolve-skybridge-config.d.ts +5 -0
  19. package/dist/cli/resolve-skybridge-config.js +18 -0
  20. package/dist/cli/resolve-skybridge-config.js.map +1 -0
  21. package/dist/cli/run-command.js.map +1 -1
  22. package/dist/cli/run-plain.d.ts +18 -0
  23. package/dist/cli/run-plain.js +89 -0
  24. package/dist/cli/run-plain.js.map +1 -0
  25. package/dist/cli/telemetry.js.map +1 -1
  26. package/dist/cli/tunnel-control-server.d.ts +9 -0
  27. package/dist/cli/tunnel-control-server.js +31 -0
  28. package/dist/cli/tunnel-control-server.js.map +1 -0
  29. package/dist/cli/tunnel-control-server.test.js +39 -0
  30. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  31. package/dist/cli/tunnel-handler.d.ts +3 -0
  32. package/dist/cli/tunnel-handler.js +48 -0
  33. package/dist/cli/tunnel-handler.js.map +1 -0
  34. package/dist/cli/tunnel-handler.test.d.ts +1 -0
  35. package/dist/cli/tunnel-handler.test.js +105 -0
  36. package/dist/cli/tunnel-handler.test.js.map +1 -0
  37. package/dist/cli/tunnel.d.ts +57 -0
  38. package/dist/cli/tunnel.js +154 -0
  39. package/dist/cli/tunnel.js.map +1 -0
  40. package/dist/cli/tunnel.test.d.ts +1 -0
  41. package/dist/cli/tunnel.test.js +190 -0
  42. package/dist/cli/tunnel.test.js.map +1 -0
  43. package/dist/cli/types.d.ts +5 -0
  44. package/dist/cli/types.js +2 -0
  45. package/dist/cli/types.js.map +1 -0
  46. package/dist/cli/use-execute-steps.js.map +1 -1
  47. package/dist/cli/use-messages.d.ts +3 -0
  48. package/dist/cli/use-messages.js +11 -0
  49. package/dist/cli/use-messages.js.map +1 -0
  50. package/dist/cli/use-nodemon.d.ts +16 -6
  51. package/dist/cli/use-nodemon.js +74 -59
  52. package/dist/cli/use-nodemon.js.map +1 -1
  53. package/dist/cli/use-open-browser.d.ts +1 -0
  54. package/dist/cli/use-open-browser.js +44 -0
  55. package/dist/cli/use-open-browser.js.map +1 -0
  56. package/dist/cli/use-tunnel.d.ts +14 -0
  57. package/dist/cli/use-tunnel.js +131 -0
  58. package/dist/cli/use-tunnel.js.map +1 -0
  59. package/dist/cli/use-typescript-check.d.ts +9 -2
  60. package/dist/cli/use-typescript-check.js +89 -51
  61. package/dist/cli/use-typescript-check.js.map +1 -1
  62. package/dist/commands/build.d.ts +0 -3
  63. package/dist/commands/build.js +3 -18
  64. package/dist/commands/build.js.map +1 -1
  65. package/dist/commands/create.d.ts +9 -0
  66. package/dist/commands/create.js +30 -0
  67. package/dist/commands/create.js.map +1 -0
  68. package/dist/commands/dev.d.ts +4 -1
  69. package/dist/commands/dev.js +94 -8
  70. package/dist/commands/dev.js.map +1 -1
  71. package/dist/commands/start.js +13 -10
  72. package/dist/commands/start.js.map +1 -1
  73. package/dist/commands/telemetry/disable.js.map +1 -1
  74. package/dist/commands/telemetry/enable.js.map +1 -1
  75. package/dist/commands/telemetry/status.js.map +1 -1
  76. package/dist/server/asset-base-url-transform-plugin.d.ts +6 -6
  77. package/dist/server/asset-base-url-transform-plugin.js +25 -11
  78. package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
  79. package/dist/server/asset-base-url-transform-plugin.test.js +92 -14
  80. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
  81. package/dist/server/auth/discovery.d.ts +32 -0
  82. package/dist/server/auth/discovery.js +56 -0
  83. package/dist/server/auth/discovery.js.map +1 -0
  84. package/dist/server/auth/discovery.test.d.ts +1 -0
  85. package/dist/server/auth/discovery.test.js +93 -0
  86. package/dist/server/auth/discovery.test.js.map +1 -0
  87. package/dist/server/auth/index.d.ts +18 -0
  88. package/dist/server/auth/index.js +2 -0
  89. package/dist/server/auth/index.js.map +1 -0
  90. package/dist/server/auth/providers/auth0.d.ts +18 -0
  91. package/dist/server/auth/providers/auth0.js +31 -0
  92. package/dist/server/auth/providers/auth0.js.map +1 -0
  93. package/dist/server/auth/providers/auth0.test.d.ts +1 -0
  94. package/dist/server/auth/providers/auth0.test.js +48 -0
  95. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  96. package/dist/server/auth/providers/authplane.d.ts +47 -0
  97. package/dist/server/auth/providers/authplane.js +57 -0
  98. package/dist/server/auth/providers/authplane.js.map +1 -0
  99. package/dist/server/auth/providers/authplane.test.d.ts +1 -0
  100. package/dist/server/auth/providers/authplane.test.js +138 -0
  101. package/dist/server/auth/providers/authplane.test.js.map +1 -0
  102. package/dist/server/auth/providers/clerk.d.ts +14 -0
  103. package/dist/server/auth/providers/clerk.js +16 -0
  104. package/dist/server/auth/providers/clerk.js.map +1 -0
  105. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  106. package/dist/server/auth/providers/clerk.test.js +28 -0
  107. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  108. package/dist/server/auth/providers/custom.d.ts +32 -0
  109. package/dist/server/auth/providers/custom.js +49 -0
  110. package/dist/server/auth/providers/custom.js.map +1 -0
  111. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  112. package/dist/server/auth/providers/custom.test.js +156 -0
  113. package/dist/server/auth/providers/custom.test.js.map +1 -0
  114. package/dist/server/auth/providers/descope.d.ts +15 -0
  115. package/dist/server/auth/providers/descope.js +44 -0
  116. package/dist/server/auth/providers/descope.js.map +1 -0
  117. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  118. package/dist/server/auth/providers/descope.test.js +60 -0
  119. package/dist/server/auth/providers/descope.test.js.map +1 -0
  120. package/dist/server/auth/providers/shared.d.ts +2 -0
  121. package/dist/server/auth/providers/shared.js +6 -0
  122. package/dist/server/auth/providers/shared.js.map +1 -0
  123. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  124. package/dist/server/auth/providers/shared.test.js +10 -0
  125. package/dist/server/auth/providers/shared.test.js.map +1 -0
  126. package/dist/server/auth/providers/stytch.d.ts +12 -0
  127. package/dist/server/auth/providers/stytch.js +13 -0
  128. package/dist/server/auth/providers/stytch.js.map +1 -0
  129. package/dist/server/auth/providers/workos.d.ts +11 -0
  130. package/dist/server/auth/providers/workos.js +12 -0
  131. package/dist/server/auth/providers/workos.js.map +1 -0
  132. package/dist/server/auth/security-schemes.d.ts +23 -0
  133. package/dist/server/auth/security-schemes.js +64 -0
  134. package/dist/server/auth/security-schemes.js.map +1 -0
  135. package/dist/server/auth/security-schemes.test.d.ts +1 -0
  136. package/dist/server/auth/security-schemes.test.js +99 -0
  137. package/dist/server/auth/security-schemes.test.js.map +1 -0
  138. package/dist/server/auth/setup.d.ts +6 -0
  139. package/dist/server/auth/setup.js +92 -0
  140. package/dist/server/auth/setup.js.map +1 -0
  141. package/dist/server/auth/setup.test.d.ts +1 -0
  142. package/dist/server/auth/setup.test.js +474 -0
  143. package/dist/server/auth/setup.test.js.map +1 -0
  144. package/dist/server/auth/verify.d.ts +12 -0
  145. package/dist/server/auth/verify.js +38 -0
  146. package/dist/server/auth/verify.js.map +1 -0
  147. package/dist/server/auth/verify.test.d.ts +1 -0
  148. package/dist/server/auth/verify.test.js +100 -0
  149. package/dist/server/auth/verify.test.js.map +1 -0
  150. package/dist/server/auth-extra.test-d.d.ts +1 -0
  151. package/dist/server/auth-extra.test-d.js +34 -0
  152. package/dist/server/auth-extra.test-d.js.map +1 -0
  153. package/dist/server/auth.d.ts +43 -0
  154. package/dist/server/auth.js +28 -0
  155. package/dist/server/auth.js.map +1 -0
  156. package/dist/server/build-manifest.test.d.ts +1 -0
  157. package/dist/server/build-manifest.test.js +27 -0
  158. package/dist/server/build-manifest.test.js.map +1 -0
  159. package/dist/server/content-helpers.d.ts +67 -0
  160. package/dist/server/content-helpers.js +79 -0
  161. package/dist/server/content-helpers.js.map +1 -0
  162. package/dist/server/content-helpers.test.d.ts +1 -0
  163. package/dist/server/content-helpers.test.js +70 -0
  164. package/dist/server/content-helpers.test.js.map +1 -0
  165. package/dist/server/express.d.ts +7 -5
  166. package/dist/server/express.js +53 -26
  167. package/dist/server/express.js.map +1 -1
  168. package/dist/server/express.test.js +442 -25
  169. package/dist/server/express.test.js.map +1 -1
  170. package/dist/server/file-ref.d.ts +28 -0
  171. package/dist/server/file-ref.js +27 -0
  172. package/dist/server/file-ref.js.map +1 -0
  173. package/dist/server/host.d.ts +2 -0
  174. package/dist/server/host.js +11 -0
  175. package/dist/server/host.js.map +1 -0
  176. package/dist/server/host.test.d.ts +1 -0
  177. package/dist/server/host.test.js +13 -0
  178. package/dist/server/host.test.js.map +1 -0
  179. package/dist/server/index.d.ts +16 -2
  180. package/dist/server/index.js +13 -1
  181. package/dist/server/index.js.map +1 -1
  182. package/dist/server/inferUtilityTypes.d.ts +6 -6
  183. package/dist/server/inferUtilityTypes.js.map +1 -1
  184. package/dist/server/metric.d.ts +14 -0
  185. package/dist/server/metric.js +62 -0
  186. package/dist/server/metric.js.map +1 -0
  187. package/dist/server/middleware.d.ts +140 -0
  188. package/dist/server/middleware.js +93 -0
  189. package/dist/server/middleware.js.map +1 -0
  190. package/dist/server/middleware.test-d.d.ts +1 -0
  191. package/dist/server/middleware.test-d.js +75 -0
  192. package/dist/server/middleware.test-d.js.map +1 -0
  193. package/dist/server/middleware.test.d.ts +1 -0
  194. package/dist/server/middleware.test.js +493 -0
  195. package/dist/server/middleware.test.js.map +1 -0
  196. package/dist/server/requestOrigin.d.ts +7 -0
  197. package/dist/server/requestOrigin.js +25 -0
  198. package/dist/server/requestOrigin.js.map +1 -0
  199. package/dist/server/server.d.ts +446 -64
  200. package/dist/server/server.js +696 -148
  201. package/dist/server/server.js.map +1 -1
  202. package/dist/server/skills-integration.test.d.ts +1 -0
  203. package/dist/server/skills-integration.test.js +63 -0
  204. package/dist/server/skills-integration.test.js.map +1 -0
  205. package/dist/server/skills.d.ts +23 -0
  206. package/dist/server/skills.js +178 -0
  207. package/dist/server/skills.js.map +1 -0
  208. package/dist/server/skills.test.d.ts +1 -0
  209. package/dist/server/skills.test.js +210 -0
  210. package/dist/server/skills.test.js.map +1 -0
  211. package/dist/server/templateHelper.d.ts +5 -8
  212. package/dist/server/templateHelper.js +3 -22
  213. package/dist/server/templateHelper.js.map +1 -1
  214. package/dist/server/templates.generated.d.ts +4 -0
  215. package/dist/server/templates.generated.js +47 -0
  216. package/dist/server/templates.generated.js.map +1 -0
  217. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  218. package/dist/server/tunnel-proxy-router.js +110 -0
  219. package/dist/server/tunnel-proxy-router.js.map +1 -0
  220. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  221. package/dist/server/tunnel-proxy-router.test.js +229 -0
  222. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  223. package/dist/server/view-name.test-d.d.ts +1 -0
  224. package/dist/server/view-name.test-d.js +8 -0
  225. package/dist/server/view-name.test-d.js.map +1 -0
  226. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  227. package/dist/server/view-resource-resolution.test.js +171 -0
  228. package/dist/server/view-resource-resolution.test.js.map +1 -0
  229. package/dist/server/viewsDevServer.d.ts +14 -0
  230. package/dist/server/viewsDevServer.js +48 -0
  231. package/dist/server/viewsDevServer.js.map +1 -0
  232. package/dist/test/utils.d.ts +16 -24
  233. package/dist/test/utils.js +42 -37
  234. package/dist/test/utils.js.map +1 -1
  235. package/dist/test/view.test.d.ts +1 -0
  236. package/dist/test/view.test.js +536 -0
  237. package/dist/test/view.test.js.map +1 -0
  238. package/dist/version.d.ts +1 -0
  239. package/dist/version.js +3 -0
  240. package/dist/version.js.map +1 -0
  241. package/dist/web/bridges/adaptor.d.ts +51 -0
  242. package/dist/web/bridges/adaptor.js +341 -0
  243. package/dist/web/bridges/adaptor.js.map +1 -0
  244. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  245. package/dist/web/bridges/adaptor.test.js +224 -0
  246. package/dist/web/bridges/adaptor.test.js.map +1 -0
  247. package/dist/web/bridges/apps-sdk/bridge.d.ts +7 -2
  248. package/dist/web/bridges/apps-sdk/bridge.js +15 -3
  249. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  250. package/dist/web/bridges/apps-sdk/index.d.ts +1 -2
  251. package/dist/web/bridges/apps-sdk/index.js +0 -1
  252. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  253. package/dist/web/bridges/apps-sdk/types.d.ts +22 -9
  254. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  255. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +11 -0
  256. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +11 -0
  257. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  258. package/dist/web/bridges/get-adaptor.d.ts +7 -0
  259. package/dist/web/bridges/get-adaptor.js +9 -7
  260. package/dist/web/bridges/get-adaptor.js.map +1 -1
  261. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  262. package/dist/web/bridges/get-adaptor.test.js +32 -0
  263. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  264. package/dist/web/bridges/index.js.map +1 -1
  265. package/dist/web/bridges/mcp-app/bridge.d.ts +27 -31
  266. package/dist/web/bridges/mcp-app/bridge.js +111 -203
  267. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  268. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  269. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  270. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  271. package/dist/web/bridges/mcp-app/index.d.ts +0 -1
  272. package/dist/web/bridges/mcp-app/index.js +0 -1
  273. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  274. package/dist/web/bridges/mcp-app/types.d.ts +2 -0
  275. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  276. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +17 -3
  277. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +14 -2
  278. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  279. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -41
  280. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  281. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  282. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  283. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  284. package/dist/web/bridges/types.d.ts +123 -11
  285. package/dist/web/bridges/types.js +14 -1
  286. package/dist/web/bridges/types.js.map +1 -1
  287. package/dist/web/bridges/types.test.d.ts +1 -0
  288. package/dist/web/bridges/types.test.js +19 -0
  289. package/dist/web/bridges/types.test.js.map +1 -0
  290. package/dist/web/bridges/use-host-context.d.ts +5 -0
  291. package/dist/web/bridges/use-host-context.js +5 -0
  292. package/dist/web/bridges/use-host-context.js.map +1 -1
  293. package/dist/web/components/modal-provider.d.ts +1 -1
  294. package/dist/web/components/modal-provider.js +5 -6
  295. package/dist/web/components/modal-provider.js.map +1 -1
  296. package/dist/web/create-store.d.ts +26 -0
  297. package/dist/web/create-store.js +43 -3
  298. package/dist/web/create-store.js.map +1 -1
  299. package/dist/web/create-store.test.js +29 -23
  300. package/dist/web/create-store.test.js.map +1 -1
  301. package/dist/web/data-llm.d.ts +35 -2
  302. package/dist/web/data-llm.js +31 -3
  303. package/dist/web/data-llm.js.map +1 -1
  304. package/dist/web/data-llm.test.js +41 -28
  305. package/dist/web/data-llm.test.js.map +1 -1
  306. package/dist/web/generate-helpers.d.ts +22 -18
  307. package/dist/web/generate-helpers.js +22 -18
  308. package/dist/web/generate-helpers.js.map +1 -1
  309. package/dist/web/generate-helpers.test-d.js +30 -28
  310. package/dist/web/generate-helpers.test-d.js.map +1 -1
  311. package/dist/web/generate-helpers.test.js.map +1 -1
  312. package/dist/web/helpers/state.d.ts +2 -2
  313. package/dist/web/helpers/state.js +11 -11
  314. package/dist/web/helpers/state.js.map +1 -1
  315. package/dist/web/helpers/state.test.js +9 -9
  316. package/dist/web/helpers/state.test.js.map +1 -1
  317. package/dist/web/hooks/index.d.ts +6 -1
  318. package/dist/web/hooks/index.js +6 -1
  319. package/dist/web/hooks/index.js.map +1 -1
  320. package/dist/web/hooks/test/utils.d.ts +7 -2
  321. package/dist/web/hooks/test/utils.js +18 -3
  322. package/dist/web/hooks/test/utils.js.map +1 -1
  323. package/dist/web/hooks/use-call-tool.d.ts +45 -0
  324. package/dist/web/hooks/use-call-tool.js +28 -0
  325. package/dist/web/hooks/use-call-tool.js.map +1 -1
  326. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
  327. package/dist/web/hooks/use-call-tool.test.js +62 -27
  328. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  329. package/dist/web/hooks/use-display-mode.d.ts +20 -0
  330. package/dist/web/hooks/use-display-mode.js +20 -0
  331. package/dist/web/hooks/use-display-mode.js.map +1 -1
  332. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
  333. package/dist/web/hooks/use-display-mode.test.js +56 -20
  334. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  335. package/dist/web/hooks/use-download.d.ts +5 -0
  336. package/dist/web/hooks/use-download.js +8 -0
  337. package/dist/web/hooks/use-download.js.map +1 -0
  338. package/dist/web/hooks/use-download.test.d.ts +1 -0
  339. package/dist/web/hooks/use-download.test.js +103 -0
  340. package/dist/web/hooks/use-download.test.js.map +1 -0
  341. package/dist/web/hooks/use-files.d.ts +34 -1
  342. package/dist/web/hooks/use-files.js +33 -0
  343. package/dist/web/hooks/use-files.js.map +1 -1
  344. package/dist/web/hooks/use-files.test.js +30 -2
  345. package/dist/web/hooks/use-files.test.js.map +1 -1
  346. package/dist/web/hooks/use-host-info.d.ts +22 -0
  347. package/dist/web/hooks/use-host-info.js +30 -0
  348. package/dist/web/hooks/use-host-info.js.map +1 -0
  349. package/dist/web/hooks/use-host-info.test.d.ts +1 -0
  350. package/dist/web/hooks/use-host-info.test.js +59 -0
  351. package/dist/web/hooks/use-host-info.test.js.map +1 -0
  352. package/dist/web/hooks/use-layout.d.ts +2 -0
  353. package/dist/web/hooks/use-layout.js +2 -0
  354. package/dist/web/hooks/use-layout.js.map +1 -1
  355. package/dist/web/hooks/use-layout.test.js +62 -29
  356. package/dist/web/hooks/use-layout.test.js.map +1 -1
  357. package/dist/web/hooks/use-open-external.d.ts +17 -0
  358. package/dist/web/hooks/use-open-external.js +16 -0
  359. package/dist/web/hooks/use-open-external.js.map +1 -1
  360. package/dist/web/hooks/use-open-external.test.js +28 -13
  361. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  362. package/dist/web/hooks/use-register-view-tool.d.ts +38 -0
  363. package/dist/web/hooks/use-register-view-tool.js +50 -0
  364. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  365. package/dist/web/hooks/use-request-close.d.ts +16 -0
  366. package/dist/web/hooks/use-request-close.js +21 -0
  367. package/dist/web/hooks/use-request-close.js.map +1 -0
  368. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  369. package/dist/web/hooks/use-request-close.test.js +47 -0
  370. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  371. package/dist/web/hooks/use-request-modal.d.ts +16 -1
  372. package/dist/web/hooks/use-request-modal.js +19 -4
  373. package/dist/web/hooks/use-request-modal.js.map +1 -1
  374. package/dist/web/hooks/use-request-modal.test.js +15 -1
  375. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  376. package/dist/web/hooks/use-request-size.d.ts +20 -0
  377. package/dist/web/hooks/use-request-size.js +24 -0
  378. package/dist/web/hooks/use-request-size.js.map +1 -0
  379. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  380. package/dist/web/hooks/use-request-size.test.js +47 -0
  381. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  382. package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -1
  383. package/dist/web/hooks/use-send-follow-up-message.js +19 -2
  384. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  385. package/dist/web/hooks/use-set-open-in-app-url.d.ts +17 -0
  386. package/dist/web/hooks/use-set-open-in-app-url.js +17 -0
  387. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
  388. package/dist/web/hooks/use-set-open-in-app-url.test.js +28 -8
  389. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  390. package/dist/web/hooks/use-tool-info.d.ts +53 -2
  391. package/dist/web/hooks/use-tool-info.js +30 -7
  392. package/dist/web/hooks/use-tool-info.js.map +1 -1
  393. package/dist/web/hooks/use-tool-info.test-d.js +11 -29
  394. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  395. package/dist/web/hooks/use-tool-info.test.js +43 -33
  396. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  397. package/dist/web/hooks/use-user.d.ts +2 -0
  398. package/dist/web/hooks/use-user.js +20 -2
  399. package/dist/web/hooks/use-user.js.map +1 -1
  400. package/dist/web/hooks/use-user.test.js +101 -27
  401. package/dist/web/hooks/use-user.test.js.map +1 -1
  402. package/dist/web/hooks/use-view-state.d.ts +25 -0
  403. package/dist/web/hooks/use-view-state.js +42 -0
  404. package/dist/web/hooks/use-view-state.js.map +1 -0
  405. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  406. package/dist/web/hooks/use-view-state.test.js +212 -0
  407. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  408. package/dist/web/index.d.ts +1 -2
  409. package/dist/web/index.js +1 -2
  410. package/dist/web/index.js.map +1 -1
  411. package/dist/web/mount-view.d.ts +20 -0
  412. package/dist/web/{mount-widget.js → mount-view.js} +21 -2
  413. package/dist/web/mount-view.js.map +1 -0
  414. package/dist/web/plugin/data-llm.test.js.map +1 -1
  415. package/dist/web/plugin/plugin.d.ts +38 -1
  416. package/dist/web/plugin/plugin.js +160 -25
  417. package/dist/web/plugin/plugin.js.map +1 -1
  418. package/dist/web/plugin/scan-views.d.ts +16 -0
  419. package/dist/web/plugin/scan-views.js +88 -0
  420. package/dist/web/plugin/scan-views.js.map +1 -0
  421. package/dist/web/plugin/scan-views.test.d.ts +1 -0
  422. package/dist/web/plugin/scan-views.test.js +99 -0
  423. package/dist/web/plugin/scan-views.test.js.map +1 -0
  424. package/dist/web/plugin/transform-data-llm.js +1 -1
  425. package/dist/web/plugin/transform-data-llm.js.map +1 -1
  426. package/dist/web/plugin/transform-data-llm.test.js.map +1 -1
  427. package/dist/web/plugin/validate-view.d.ts +1 -0
  428. package/dist/web/plugin/validate-view.js +9 -0
  429. package/dist/web/plugin/validate-view.js.map +1 -0
  430. package/dist/web/plugin/validate-view.test.d.ts +1 -0
  431. package/dist/web/plugin/validate-view.test.js +24 -0
  432. package/dist/web/plugin/validate-view.test.js.map +1 -0
  433. package/dist/web/proxy.js.map +1 -1
  434. package/dist/web/types.d.ts +4 -0
  435. package/dist/web/types.js.map +1 -1
  436. package/package.json +44 -26
  437. package/tsconfig.base.json +5 -0
  438. package/dist/server/const.d.ts +0 -1
  439. package/dist/server/const.js +0 -2
  440. package/dist/server/const.js.map +0 -1
  441. package/dist/server/templates/development.hbs +0 -67
  442. package/dist/server/templates/production.hbs +0 -6
  443. package/dist/server/widgetsDevServer.d.ts +0 -12
  444. package/dist/server/widgetsDevServer.js +0 -63
  445. package/dist/server/widgetsDevServer.js.map +0 -1
  446. package/dist/test/widget.test.js +0 -261
  447. package/dist/test/widget.test.js.map +0 -1
  448. package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -22
  449. package/dist/web/bridges/apps-sdk/adaptor.js +0 -71
  450. package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
  451. package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -36
  452. package/dist/web/bridges/mcp-app/adaptor.js +0 -190
  453. package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
  454. package/dist/web/hooks/use-widget-state.d.ts +0 -4
  455. package/dist/web/hooks/use-widget-state.js +0 -32
  456. package/dist/web/hooks/use-widget-state.js.map +0 -1
  457. package/dist/web/hooks/use-widget-state.test.js +0 -62
  458. package/dist/web/hooks/use-widget-state.test.js.map +0 -1
  459. package/dist/web/mount-widget.d.ts +0 -1
  460. package/dist/web/mount-widget.js.map +0 -1
  461. package/dist/web/plugin/validate-widget.d.ts +0 -5
  462. package/dist/web/plugin/validate-widget.js +0 -27
  463. package/dist/web/plugin/validate-widget.js.map +0 -1
  464. package/dist/web/plugin/validate-widget.test.js +0 -42
  465. package/dist/web/plugin/validate-widget.test.js.map +0 -1
  466. /package/dist/{test/widget.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
  467. /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  468. /package/dist/{web/plugin/validate-widget.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
@@ -0,0 +1,100 @@
1
+ // @vitest-environment node
2
+ import http from "node:http";
3
+ import * as jose from "jose";
4
+ import { afterEach, describe, expect, it } from "vitest";
5
+ import { createJwksVerifier } from "./verify.js";
6
+ const ISSUER = "https://issuer.test";
7
+ const AUDIENCE = "api://default";
8
+ let jwksServer;
9
+ afterEach(() => jwksServer?.close());
10
+ async function startJwks() {
11
+ const { publicKey, privateKey } = await jose.generateKeyPair("RS256");
12
+ const jwk = {
13
+ ...(await jose.exportJWK(publicKey)),
14
+ kid: "test-key",
15
+ alg: "RS256",
16
+ use: "sig",
17
+ };
18
+ const server = http.createServer((_req, res) => {
19
+ res.setHeader("content-type", "application/json");
20
+ res.end(JSON.stringify({ keys: [jwk] }));
21
+ });
22
+ await new Promise((resolve) => server.listen(0, resolve));
23
+ jwksServer = server;
24
+ const port = server.address().port;
25
+ return { privateKey, jwksUri: `http://localhost:${port}/jwks` };
26
+ }
27
+ function sign(key, claims, opts = {}) {
28
+ return new jose.SignJWT(claims)
29
+ .setProtectedHeader({ alg: "RS256", kid: "test-key" })
30
+ .setIssuer(opts.issuer ?? ISSUER)
31
+ .setAudience(opts.audience ?? AUDIENCE)
32
+ .setExpirationTime(opts.expiresAt ?? "1h")
33
+ .sign(key);
34
+ }
35
+ describe("createJwksVerifier", () => {
36
+ it("verifies a valid token and maps claims to AuthInfo", async () => {
37
+ const { privateKey, jwksUri } = await startJwks();
38
+ const verifier = createJwksVerifier({
39
+ issuer: ISSUER,
40
+ audience: AUDIENCE,
41
+ jwksUri,
42
+ });
43
+ const token = await sign(privateKey, {
44
+ client_id: "client-1",
45
+ scope: "openid email",
46
+ sub: "user-1",
47
+ email: "a@b.test",
48
+ });
49
+ const auth = await verifier.verifyAccessToken(token);
50
+ expect(auth.token).toBe(token);
51
+ expect(auth.clientId).toBe("client-1");
52
+ expect(auth.scopes).toEqual(["openid", "email"]);
53
+ expect(auth.extra?.subject).toBe("user-1");
54
+ expect(auth.extra?.email).toBe("a@b.test");
55
+ });
56
+ it("rejects a token with the wrong audience", async () => {
57
+ const { privateKey, jwksUri } = await startJwks();
58
+ const verifier = createJwksVerifier({
59
+ issuer: ISSUER,
60
+ audience: AUDIENCE,
61
+ jwksUri,
62
+ });
63
+ const token = await sign(privateKey, { client_id: "c" }, { audience: "api://other" });
64
+ await expect(verifier.verifyAccessToken(token)).rejects.toThrow(/Token verification failed/);
65
+ });
66
+ it("skips the aud check when no audience is configured (e.g. Clerk)", async () => {
67
+ const { privateKey, jwksUri } = await startJwks();
68
+ const verifier = createJwksVerifier({ issuer: ISSUER, jwksUri });
69
+ // Clerk-shaped access token: no `aud` claim at all.
70
+ const token = await new jose.SignJWT({ client_id: "c", sub: "u" })
71
+ .setProtectedHeader({ alg: "RS256", kid: "test-key" })
72
+ .setIssuer(ISSUER)
73
+ .setExpirationTime("1h")
74
+ .sign(privateKey);
75
+ const auth = await verifier.verifyAccessToken(token);
76
+ expect(auth.clientId).toBe("c");
77
+ expect(auth.extra?.subject).toBe("u");
78
+ });
79
+ it("parses array scope claims and trims extra whitespace", async () => {
80
+ const { privateKey, jwksUri } = await startJwks();
81
+ const verifier = createJwksVerifier({
82
+ issuer: ISSUER,
83
+ audience: AUDIENCE,
84
+ jwksUri,
85
+ });
86
+ const arrayToken = await sign(privateKey, {
87
+ scope: ["openid", "email"],
88
+ });
89
+ expect((await verifier.verifyAccessToken(arrayToken)).scopes).toEqual([
90
+ "openid",
91
+ "email",
92
+ ]);
93
+ const messyToken = await sign(privateKey, { scope: " openid email " });
94
+ expect((await verifier.verifyAccessToken(messyToken)).scopes).toEqual([
95
+ "openid",
96
+ "email",
97
+ ]);
98
+ });
99
+ });
100
+ //# sourceMappingURL=verify.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.test.js","sourceRoot":"","sources":["../../../src/server/auth/verify.test.ts"],"names":[],"mappings":"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","sourcesContent":["// @vitest-environment node\nimport http from \"node:http\";\nimport * as jose from \"jose\";\nimport { afterEach, describe, expect, it } from \"vitest\";\nimport { createJwksVerifier } from \"./verify.js\";\n\nconst ISSUER = \"https://issuer.test\";\nconst AUDIENCE = \"api://default\";\n\nlet jwksServer: http.Server | undefined;\nafterEach(() => jwksServer?.close());\n\nasync function startJwks() {\n const { publicKey, privateKey } = await jose.generateKeyPair(\"RS256\");\n const jwk = {\n ...(await jose.exportJWK(publicKey)),\n kid: \"test-key\",\n alg: \"RS256\",\n use: \"sig\",\n };\n const server = http.createServer((_req, res) => {\n res.setHeader(\"content-type\", \"application/json\");\n res.end(JSON.stringify({ keys: [jwk] }));\n });\n await new Promise<void>((resolve) => server.listen(0, resolve));\n jwksServer = server;\n const port = (server.address() as { port: number }).port;\n return { privateKey, jwksUri: `http://localhost:${port}/jwks` };\n}\n\nfunction sign(\n key: CryptoKey,\n claims: Record<string, unknown>,\n opts: { issuer?: string; audience?: string; expiresAt?: string } = {},\n) {\n return new jose.SignJWT(claims)\n .setProtectedHeader({ alg: \"RS256\", kid: \"test-key\" })\n .setIssuer(opts.issuer ?? ISSUER)\n .setAudience(opts.audience ?? AUDIENCE)\n .setExpirationTime(opts.expiresAt ?? \"1h\")\n .sign(key);\n}\n\ndescribe(\"createJwksVerifier\", () => {\n it(\"verifies a valid token and maps claims to AuthInfo\", async () => {\n const { privateKey, jwksUri } = await startJwks();\n const verifier = createJwksVerifier({\n issuer: ISSUER,\n audience: AUDIENCE,\n jwksUri,\n });\n const token = await sign(privateKey, {\n client_id: \"client-1\",\n scope: \"openid email\",\n sub: \"user-1\",\n email: \"a@b.test\",\n });\n\n const auth = await verifier.verifyAccessToken(token);\n\n expect(auth.token).toBe(token);\n expect(auth.clientId).toBe(\"client-1\");\n expect(auth.scopes).toEqual([\"openid\", \"email\"]);\n expect(auth.extra?.subject).toBe(\"user-1\");\n expect(auth.extra?.email).toBe(\"a@b.test\");\n });\n\n it(\"rejects a token with the wrong audience\", async () => {\n const { privateKey, jwksUri } = await startJwks();\n const verifier = createJwksVerifier({\n issuer: ISSUER,\n audience: AUDIENCE,\n jwksUri,\n });\n const token = await sign(\n privateKey,\n { client_id: \"c\" },\n { audience: \"api://other\" },\n );\n\n await expect(verifier.verifyAccessToken(token)).rejects.toThrow(\n /Token verification failed/,\n );\n });\n\n it(\"skips the aud check when no audience is configured (e.g. Clerk)\", async () => {\n const { privateKey, jwksUri } = await startJwks();\n const verifier = createJwksVerifier({ issuer: ISSUER, jwksUri });\n // Clerk-shaped access token: no `aud` claim at all.\n const token = await new jose.SignJWT({ client_id: \"c\", sub: \"u\" })\n .setProtectedHeader({ alg: \"RS256\", kid: \"test-key\" })\n .setIssuer(ISSUER)\n .setExpirationTime(\"1h\")\n .sign(privateKey);\n\n const auth = await verifier.verifyAccessToken(token);\n expect(auth.clientId).toBe(\"c\");\n expect(auth.extra?.subject).toBe(\"u\");\n });\n\n it(\"parses array scope claims and trims extra whitespace\", async () => {\n const { privateKey, jwksUri } = await startJwks();\n const verifier = createJwksVerifier({\n issuer: ISSUER,\n audience: AUDIENCE,\n jwksUri,\n });\n\n const arrayToken = await sign(privateKey, {\n scope: [\"openid\", \"email\"],\n });\n expect((await verifier.verifyAccessToken(arrayToken)).scopes).toEqual([\n \"openid\",\n \"email\",\n ]);\n\n const messyToken = await sign(privateKey, { scope: \" openid email \" });\n expect((await verifier.verifyAccessToken(messyToken)).scopes).toEqual([\n \"openid\",\n \"email\",\n ]);\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,34 @@
1
+ import { expectTypeOf, test } from "vitest";
2
+ import { z } from "zod";
3
+ const server = null;
4
+ const typed = server.withAuthExtra();
5
+ test("default server keeps the SDK's untyped extra bag", () => {
6
+ server.registerTool({ name: "plain", inputSchema: { q: z.string() } }, (_args, extra) => {
7
+ expectTypeOf(extra.authInfo?.extra).toEqualTypeOf();
8
+ return { content: "ok" };
9
+ });
10
+ });
11
+ test("withAuthExtra types extra.authInfo.extra in tool handlers", () => {
12
+ typed.registerTool({ name: "claims", inputSchema: { q: z.string() } }, (_args, extra) => {
13
+ expectTypeOf(extra.authInfo?.extra?.orgId).toEqualTypeOf();
14
+ expectTypeOf(extra.authInfo?.extra?.subject).toEqualTypeOf();
15
+ // @ts-expect-error unknown claim
16
+ extra.authInfo?.extra?.nope;
17
+ return { content: "ok" };
18
+ });
19
+ });
20
+ test("the declared extra survives registerTool chaining", () => {
21
+ typed
22
+ .registerTool({ name: "a", inputSchema: {} }, () => ({ content: "a" }))
23
+ .registerTool({ name: "b", inputSchema: {} }, (_args, extra) => {
24
+ expectTypeOf(extra.authInfo?.extra?.orgId).toEqualTypeOf();
25
+ return { content: "b" };
26
+ });
27
+ });
28
+ test("withAuthExtra types extra.authInfo.extra in mcp middleware", () => {
29
+ typed.mcpMiddleware("tools/call", (_request, extra, next) => {
30
+ expectTypeOf(extra.authInfo?.extra?.orgId).toEqualTypeOf();
31
+ return next();
32
+ });
33
+ });
34
+ //# sourceMappingURL=auth-extra.test-d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-extra.test-d.js","sourceRoot":"","sources":["../../src/server/auth-extra.test-d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,MAAM,GAAG,IAA4B,CAAC;AAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,EAAU,CAAC;AAE7C,IAAI,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAC5D,MAAM,CAAC,YAAY,CACjB,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EACjD,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACf,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,aAAa,EAE9C,CAAC;QACJ,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2DAA2D,EAAE,GAAG,EAAE;IACrE,KAAK,CAAC,YAAY,CAChB,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAClD,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACf,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,aAAa,EAErD,CAAC;QACJ,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,aAAa,EAEvD,CAAC;QACJ,iCAAiC;QACjC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC;QAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,GAAG,EAAE;IAC7D,KAAK;SACF,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;SACtE,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC7D,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,aAAa,EAErD,CAAC;QACJ,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4DAA4D,EAAE,GAAG,EAAE;IACtE,KAAK,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC1D,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,aAAa,EAErD,CAAC;QACJ,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expectTypeOf, test } from \"vitest\";\nimport { z } from \"zod\";\nimport type { McpServer } from \"./server.js\";\n\ntype Claims = { subject?: string; orgId: string };\n\nconst server = null as unknown as McpServer;\nconst typed = server.withAuthExtra<Claims>();\n\ntest(\"default server keeps the SDK's untyped extra bag\", () => {\n server.registerTool(\n { name: \"plain\", inputSchema: { q: z.string() } },\n (_args, extra) => {\n expectTypeOf(extra.authInfo?.extra).toEqualTypeOf<\n Record<string, unknown> | undefined\n >();\n return { content: \"ok\" };\n },\n );\n});\n\ntest(\"withAuthExtra types extra.authInfo.extra in tool handlers\", () => {\n typed.registerTool(\n { name: \"claims\", inputSchema: { q: z.string() } },\n (_args, extra) => {\n expectTypeOf(extra.authInfo?.extra?.orgId).toEqualTypeOf<\n string | undefined\n >();\n expectTypeOf(extra.authInfo?.extra?.subject).toEqualTypeOf<\n string | undefined\n >();\n // @ts-expect-error unknown claim\n extra.authInfo?.extra?.nope;\n return { content: \"ok\" };\n },\n );\n});\n\ntest(\"the declared extra survives registerTool chaining\", () => {\n typed\n .registerTool({ name: \"a\", inputSchema: {} }, () => ({ content: \"a\" }))\n .registerTool({ name: \"b\", inputSchema: {} }, (_args, extra) => {\n expectTypeOf(extra.authInfo?.extra?.orgId).toEqualTypeOf<\n string | undefined\n >();\n return { content: \"b\" };\n });\n});\n\ntest(\"withAuthExtra types extra.authInfo.extra in mcp middleware\", () => {\n typed.mcpMiddleware(\"tools/call\", (_request, extra, next) => {\n expectTypeOf(extra.authInfo?.extra?.orgId).toEqualTypeOf<\n string | undefined\n >();\n return next();\n });\n});\n"]}
@@ -0,0 +1,43 @@
1
+ import { type BearerAuthMiddlewareOptions } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
2
+ import type { AuthInfo as SdkAuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
3
+ import type { RequestHandler } from "express";
4
+ export { InvalidTokenError } from "@modelcontextprotocol/sdk/server/auth/errors.js";
5
+ export { type BearerAuthMiddlewareOptions, requireBearerAuth, } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
6
+ export { type AuthMetadataOptions, mcpAuthMetadataRouter, } from "@modelcontextprotocol/sdk/server/auth/router.js";
7
+ /**
8
+ * A validated access token, as resolved by a
9
+ * [verifier](https://docs.skybridge.tech/api-reference/verifier) and handed to
10
+ * handlers on `extra.authInfo`.
11
+ *
12
+ * Unparameterized, `extra` stays the SDK's `Record<string, unknown>` bag. Pass
13
+ * the claims your verifier produces to type it, and declare the same shape on
14
+ * the server with {@link McpServer.withAuthExtra} so handlers see it too.
15
+ *
16
+ * @typeParam TExtra - Claims populated in `extra`. Makes `extra` required.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * type Claims = { sub: string; email?: string };
21
+ *
22
+ * async function verifyAccessToken(token: string): Promise<AuthInfo<Claims>> {
23
+ * // ...
24
+ * }
25
+ * ```
26
+ */
27
+ export type AuthInfo<TExtra extends Record<string, unknown> = Record<string, unknown>> = Omit<SdkAuthInfo, "extra"> & {
28
+ extra?: TExtra;
29
+ };
30
+ /**
31
+ * Like `requireBearerAuth`, but lets requests through when no
32
+ * `Authorization` header is present. Used for mixed-auth servers where some
33
+ * tools are public and others require sign-in: each tool enforces its own
34
+ * `securitySchemes` against `extra.authInfo`.
35
+ *
36
+ * Behavior:
37
+ * - No `Authorization` header → `next()` without `req.auth`.
38
+ * - Valid Bearer token → `req.auth` set, same as `requireBearerAuth`.
39
+ * - Invalid / malformed / expired / insufficient-scope → same error response
40
+ * as `requireBearerAuth` (401/403). Sending a bad token is still a client
41
+ * error.
42
+ */
43
+ export declare function optionalBearerAuth(options: BearerAuthMiddlewareOptions): RequestHandler;
@@ -0,0 +1,28 @@
1
+ import { requireBearerAuth, } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
2
+ export { InvalidTokenError } from "@modelcontextprotocol/sdk/server/auth/errors.js";
3
+ export { requireBearerAuth, } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
4
+ export { mcpAuthMetadataRouter, } from "@modelcontextprotocol/sdk/server/auth/router.js";
5
+ /**
6
+ * Like `requireBearerAuth`, but lets requests through when no
7
+ * `Authorization` header is present. Used for mixed-auth servers where some
8
+ * tools are public and others require sign-in: each tool enforces its own
9
+ * `securitySchemes` against `extra.authInfo`.
10
+ *
11
+ * Behavior:
12
+ * - No `Authorization` header → `next()` without `req.auth`.
13
+ * - Valid Bearer token → `req.auth` set, same as `requireBearerAuth`.
14
+ * - Invalid / malformed / expired / insufficient-scope → same error response
15
+ * as `requireBearerAuth` (401/403). Sending a bad token is still a client
16
+ * error.
17
+ */
18
+ export function optionalBearerAuth(options) {
19
+ const required = requireBearerAuth(options);
20
+ return (req, res, next) => {
21
+ if (!req.headers.authorization) {
22
+ next();
23
+ return;
24
+ }
25
+ return required(req, res, next);
26
+ };
27
+ }
28
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/server/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,GAClB,MAAM,gEAAgE,CAAC;AAKxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACpF,OAAO,EAEL,iBAAiB,GAClB,MAAM,gEAAgE,CAAC;AACxE,OAAO,EAEL,qBAAqB,GACtB,MAAM,iDAAiD,CAAC;AAyBzD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAoC;IAEpC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACxB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC/B,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,OAAO,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {\n type BearerAuthMiddlewareOptions,\n requireBearerAuth,\n} from \"@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js\";\nimport type { AuthInfo as SdkAuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\n\nimport type { RequestHandler } from \"express\";\n\nexport { InvalidTokenError } from \"@modelcontextprotocol/sdk/server/auth/errors.js\";\nexport {\n type BearerAuthMiddlewareOptions,\n requireBearerAuth,\n} from \"@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js\";\nexport {\n type AuthMetadataOptions,\n mcpAuthMetadataRouter,\n} from \"@modelcontextprotocol/sdk/server/auth/router.js\";\n/**\n * A validated access token, as resolved by a\n * [verifier](https://docs.skybridge.tech/api-reference/verifier) and handed to\n * handlers on `extra.authInfo`.\n *\n * Unparameterized, `extra` stays the SDK's `Record<string, unknown>` bag. Pass\n * the claims your verifier produces to type it, and declare the same shape on\n * the server with {@link McpServer.withAuthExtra} so handlers see it too.\n *\n * @typeParam TExtra - Claims populated in `extra`. Makes `extra` required.\n *\n * @example\n * ```ts\n * type Claims = { sub: string; email?: string };\n *\n * async function verifyAccessToken(token: string): Promise<AuthInfo<Claims>> {\n * // ...\n * }\n * ```\n */\nexport type AuthInfo<\n TExtra extends Record<string, unknown> = Record<string, unknown>,\n> = Omit<SdkAuthInfo, \"extra\"> & { extra?: TExtra };\n\n/**\n * Like `requireBearerAuth`, but lets requests through when no\n * `Authorization` header is present. Used for mixed-auth servers where some\n * tools are public and others require sign-in: each tool enforces its own\n * `securitySchemes` against `extra.authInfo`.\n *\n * Behavior:\n * - No `Authorization` header → `next()` without `req.auth`.\n * - Valid Bearer token → `req.auth` set, same as `requireBearerAuth`.\n * - Invalid / malformed / expired / insufficient-scope → same error response\n * as `requireBearerAuth` (401/403). Sending a bad token is still a client\n * error.\n */\nexport function optionalBearerAuth(\n options: BearerAuthMiddlewareOptions,\n): RequestHandler {\n const required = requireBearerAuth(options);\n return (req, res, next) => {\n if (!req.headers.authorization) {\n next();\n return;\n }\n return required(req, res, next);\n };\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { __setBuildManifest, McpServer } from "./index.js";
3
+ function manifestOf(server) {
4
+ return server.viteManifest;
5
+ }
6
+ function makeServer() {
7
+ return new McpServer({ name: "test", version: "0.0.1" }, { capabilities: {} });
8
+ }
9
+ describe("__setBuildManifest", () => {
10
+ it("primes the Vite manifest for the next McpServer constructed", () => {
11
+ const manifest = {
12
+ "src/views/index.tsx": { file: "assets/index-DEADBEEF.js" },
13
+ };
14
+ __setBuildManifest(manifest);
15
+ // viteManifest is private; reach into it to lock the contract that the
16
+ // generated `dist/__entry.js` relies on.
17
+ expect(manifestOf(makeServer())).toEqual(manifest);
18
+ });
19
+ it("is consume-once: a second McpServer built without re-priming gets no manifest", () => {
20
+ __setBuildManifest({
21
+ "src/views/index.tsx": { file: "assets/index-CAFEBABE.js" },
22
+ });
23
+ makeServer(); // consumes the primed manifest
24
+ expect(manifestOf(makeServer())).toBeNull();
25
+ });
26
+ });
27
+ //# sourceMappingURL=build-manifest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-manifest.test.js","sourceRoot":"","sources":["../../src/server/build-manifest.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE3D,SAAS,UAAU,CACjB,MAAiB;IAEjB,OACE,MAGD,CAAC,YAAY,CAAC;AACjB,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,IAAI,SAAS,CAClB,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAClC,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,QAAQ,GAAG;YACf,qBAAqB,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE;SAC5D,CAAC;QACF,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAE7B,uEAAuE;QACvE,yCAAyC;QACzC,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,kBAAkB,CAAC;YACjB,qBAAqB,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE;SAC5D,CAAC,CAAC;QAEH,UAAU,EAAE,CAAC,CAAC,+BAA+B;QAC7C,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { __setBuildManifest, McpServer } from \"./index.js\";\n\nfunction manifestOf(\n server: McpServer,\n): Record<string, { file: string }> | null {\n return (\n server as unknown as {\n viteManifest: Record<string, { file: string }> | null;\n }\n ).viteManifest;\n}\n\nfunction makeServer(): McpServer {\n return new McpServer(\n { name: \"test\", version: \"0.0.1\" },\n { capabilities: {} },\n );\n}\n\ndescribe(\"__setBuildManifest\", () => {\n it(\"primes the Vite manifest for the next McpServer constructed\", () => {\n const manifest = {\n \"src/views/index.tsx\": { file: \"assets/index-DEADBEEF.js\" },\n };\n __setBuildManifest(manifest);\n\n // viteManifest is private; reach into it to lock the contract that the\n // generated `dist/__entry.js` relies on.\n expect(manifestOf(makeServer())).toEqual(manifest);\n });\n\n it(\"is consume-once: a second McpServer built without re-priming gets no manifest\", () => {\n __setBuildManifest({\n \"src/views/index.tsx\": { file: \"assets/index-CAFEBABE.js\" },\n });\n\n makeServer(); // consumes the primed manifest\n expect(manifestOf(makeServer())).toBeNull();\n });\n});\n"]}
@@ -0,0 +1,67 @@
1
+ import type { AudioContent, EmbeddedResource, ImageContent, ResourceLink, TextContent } from "@modelcontextprotocol/sdk/types.js";
2
+ /**
3
+ * MCP content annotations applied to any returned block.
4
+ *
5
+ * - `audience` — who is meant to see the content (`"user"`, `"assistant"`, or both).
6
+ * - `priority` — relative importance hint for the host.
7
+ * - `lastModified` — ISO timestamp for when the content was produced.
8
+ */
9
+ type ContentAnnotations = {
10
+ audience?: ("user" | "assistant")[];
11
+ priority?: number;
12
+ lastModified?: string;
13
+ };
14
+ /**
15
+ * Build an MCP text content block.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * return { content: [text("Found 3 results.")] };
20
+ * ```
21
+ */
22
+ export declare function text(value: string, annotations?: ContentAnnotations): TextContent;
23
+ /**
24
+ * Build an MCP image content block.
25
+ *
26
+ * `data` may be a `Uint8Array` (encoded to base64 for you) or a string that is
27
+ * **already base64-encoded**. Passing a raw byte-string will produce invalid
28
+ * content.
29
+ */
30
+ export declare function image(data: string | Uint8Array, mimeType: string, annotations?: ContentAnnotations): ImageContent;
31
+ /**
32
+ * Build an MCP audio content block.
33
+ *
34
+ * `data` may be a `Uint8Array` (encoded to base64 for you) or a string that is
35
+ * **already base64-encoded**.
36
+ */
37
+ export declare function audio(data: string | Uint8Array, mimeType: string, annotations?: ContentAnnotations): AudioContent;
38
+ /**
39
+ * Build an MCP embedded resource — the full content travels inline. Use this
40
+ * when the client needs the bytes themselves rather than a link.
41
+ *
42
+ * Pass either `text` (UTF-8 string) or `blob` (base64-encoded bytes).
43
+ */
44
+ export declare function embeddedResource(resource: {
45
+ uri: string;
46
+ mimeType?: string;
47
+ text: string;
48
+ } | {
49
+ uri: string;
50
+ mimeType?: string;
51
+ blob: string;
52
+ }, annotations?: ContentAnnotations): EmbeddedResource;
53
+ /**
54
+ * Build an MCP resource link — a `type: "resource_link"` block carrying a URI
55
+ * the client can fetch (or subscribe to) on demand. Use a link when the
56
+ * client should retrieve the bytes itself; use {@link embeddedResource} when
57
+ * the content must travel inline with the response.
58
+ */
59
+ export declare function resourceLink(link: {
60
+ uri: string;
61
+ name: string;
62
+ title?: string;
63
+ description?: string;
64
+ mimeType?: string;
65
+ size?: number;
66
+ }, annotations?: ContentAnnotations): ResourceLink;
67
+ export {};
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Returns a base64-encoded string.
3
+ * - `Uint8Array` input is encoded via `Buffer.toString("base64")`.
4
+ * - `string` input is assumed to be **already base64-encoded** and is returned
5
+ * as-is. Passing raw/unencoded string bytes will produce invalid MCP content.
6
+ */
7
+ function toBase64(data) {
8
+ if (typeof data === "string") {
9
+ return data;
10
+ }
11
+ return Buffer.from(data).toString("base64");
12
+ }
13
+ /**
14
+ * Build an MCP text content block.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * return { content: [text("Found 3 results.")] };
19
+ * ```
20
+ */
21
+ export function text(value, annotations) {
22
+ return { type: "text", text: value, ...(annotations && { annotations }) };
23
+ }
24
+ /**
25
+ * Build an MCP image content block.
26
+ *
27
+ * `data` may be a `Uint8Array` (encoded to base64 for you) or a string that is
28
+ * **already base64-encoded**. Passing a raw byte-string will produce invalid
29
+ * content.
30
+ */
31
+ export function image(data, mimeType, annotations) {
32
+ return {
33
+ type: "image",
34
+ data: toBase64(data),
35
+ mimeType,
36
+ ...(annotations && { annotations }),
37
+ };
38
+ }
39
+ /**
40
+ * Build an MCP audio content block.
41
+ *
42
+ * `data` may be a `Uint8Array` (encoded to base64 for you) or a string that is
43
+ * **already base64-encoded**.
44
+ */
45
+ export function audio(data, mimeType, annotations) {
46
+ return {
47
+ type: "audio",
48
+ data: toBase64(data),
49
+ mimeType,
50
+ ...(annotations && { annotations }),
51
+ };
52
+ }
53
+ /**
54
+ * Build an MCP embedded resource — the full content travels inline. Use this
55
+ * when the client needs the bytes themselves rather than a link.
56
+ *
57
+ * Pass either `text` (UTF-8 string) or `blob` (base64-encoded bytes).
58
+ */
59
+ export function embeddedResource(resource, annotations) {
60
+ return {
61
+ type: "resource",
62
+ resource,
63
+ ...(annotations && { annotations }),
64
+ };
65
+ }
66
+ /**
67
+ * Build an MCP resource link — a `type: "resource_link"` block carrying a URI
68
+ * the client can fetch (or subscribe to) on demand. Use a link when the
69
+ * client should retrieve the bytes itself; use {@link embeddedResource} when
70
+ * the content must travel inline with the response.
71
+ */
72
+ export function resourceLink(link, annotations) {
73
+ return {
74
+ type: "resource_link",
75
+ ...link,
76
+ ...(annotations && { annotations }),
77
+ };
78
+ }
79
+ //# sourceMappingURL=content-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-helpers.js","sourceRoot":"","sources":["../../src/server/content-helpers.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,IAAyB;IACzC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAClB,KAAa,EACb,WAAgC;IAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CACnB,IAAyB,EACzB,QAAgB,EAChB,WAAgC;IAEhC,OAAO;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;QACpB,QAAQ;QACR,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC;KACpC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CACnB,IAAyB,EACzB,QAAgB,EAChB,WAAgC;IAEhC,OAAO;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;QACpB,QAAQ;QACR,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC;KACpC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAEoD,EACpD,WAAgC;IAEhC,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,QAAQ;QACR,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC;KACpC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,IAOC,EACD,WAAgC;IAEhC,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,GAAG,IAAI;QACP,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC;KACpC,CAAC;AACJ,CAAC","sourcesContent":["import type {\n AudioContent,\n EmbeddedResource,\n ImageContent,\n ResourceLink,\n TextContent,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\n/**\n * MCP content annotations applied to any returned block.\n *\n * - `audience` — who is meant to see the content (`\"user\"`, `\"assistant\"`, or both).\n * - `priority` — relative importance hint for the host.\n * - `lastModified` — ISO timestamp for when the content was produced.\n */\ntype ContentAnnotations = {\n audience?: (\"user\" | \"assistant\")[];\n priority?: number;\n lastModified?: string;\n};\n\n/**\n * Returns a base64-encoded string.\n * - `Uint8Array` input is encoded via `Buffer.toString(\"base64\")`.\n * - `string` input is assumed to be **already base64-encoded** and is returned\n * as-is. Passing raw/unencoded string bytes will produce invalid MCP content.\n */\nfunction toBase64(data: string | Uint8Array): string {\n if (typeof data === \"string\") {\n return data;\n }\n return Buffer.from(data).toString(\"base64\");\n}\n\n/**\n * Build an MCP text content block.\n *\n * @example\n * ```ts\n * return { content: [text(\"Found 3 results.\")] };\n * ```\n */\nexport function text(\n value: string,\n annotations?: ContentAnnotations,\n): TextContent {\n return { type: \"text\", text: value, ...(annotations && { annotations }) };\n}\n\n/**\n * Build an MCP image content block.\n *\n * `data` may be a `Uint8Array` (encoded to base64 for you) or a string that is\n * **already base64-encoded**. Passing a raw byte-string will produce invalid\n * content.\n */\nexport function image(\n data: string | Uint8Array,\n mimeType: string,\n annotations?: ContentAnnotations,\n): ImageContent {\n return {\n type: \"image\",\n data: toBase64(data),\n mimeType,\n ...(annotations && { annotations }),\n };\n}\n\n/**\n * Build an MCP audio content block.\n *\n * `data` may be a `Uint8Array` (encoded to base64 for you) or a string that is\n * **already base64-encoded**.\n */\nexport function audio(\n data: string | Uint8Array,\n mimeType: string,\n annotations?: ContentAnnotations,\n): AudioContent {\n return {\n type: \"audio\",\n data: toBase64(data),\n mimeType,\n ...(annotations && { annotations }),\n };\n}\n\n/**\n * Build an MCP embedded resource — the full content travels inline. Use this\n * when the client needs the bytes themselves rather than a link.\n *\n * Pass either `text` (UTF-8 string) or `blob` (base64-encoded bytes).\n */\nexport function embeddedResource(\n resource:\n | { uri: string; mimeType?: string; text: string }\n | { uri: string; mimeType?: string; blob: string },\n annotations?: ContentAnnotations,\n): EmbeddedResource {\n return {\n type: \"resource\",\n resource,\n ...(annotations && { annotations }),\n };\n}\n\n/**\n * Build an MCP resource link — a `type: \"resource_link\"` block carrying a URI\n * the client can fetch (or subscribe to) on demand. Use a link when the\n * client should retrieve the bytes itself; use {@link embeddedResource} when\n * the content must travel inline with the response.\n */\nexport function resourceLink(\n link: {\n uri: string;\n name: string;\n title?: string;\n description?: string;\n mimeType?: string;\n size?: number;\n },\n annotations?: ContentAnnotations,\n): ResourceLink {\n return {\n type: \"resource_link\",\n ...link,\n ...(annotations && { annotations }),\n };\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,70 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { audio, embeddedResource, image, resourceLink, text, } from "./content-helpers.js";
3
+ describe("text", () => {
4
+ it("returns a TextContent without annotations when none given", () => {
5
+ expect(text("hello")).toEqual({ type: "text", text: "hello" });
6
+ });
7
+ it("includes annotations when provided", () => {
8
+ expect(text("hi", { priority: 1 })).toEqual({
9
+ type: "text",
10
+ text: "hi",
11
+ annotations: { priority: 1 },
12
+ });
13
+ });
14
+ });
15
+ describe("image", () => {
16
+ it("base64-encodes Uint8Array data", () => {
17
+ const bytes = new Uint8Array([104, 105]);
18
+ expect(image(bytes, "image/png")).toEqual({
19
+ type: "image",
20
+ data: "aGk=",
21
+ mimeType: "image/png",
22
+ });
23
+ });
24
+ it("passes string data through unchanged (caller is responsible for base64)", () => {
25
+ expect(image("YWxyZWFkeS1iNjQ=", "image/png")).toEqual({
26
+ type: "image",
27
+ data: "YWxyZWFkeS1iNjQ=",
28
+ mimeType: "image/png",
29
+ });
30
+ });
31
+ });
32
+ describe("audio", () => {
33
+ it("base64-encodes Uint8Array data", () => {
34
+ const bytes = new Uint8Array([104, 105]);
35
+ expect(audio(bytes, "audio/mpeg")).toMatchObject({
36
+ type: "audio",
37
+ data: "aGk=",
38
+ mimeType: "audio/mpeg",
39
+ });
40
+ });
41
+ });
42
+ describe("embeddedResource", () => {
43
+ it("wraps a text resource with a type tag", () => {
44
+ expect(embeddedResource({
45
+ uri: "file:///a.txt",
46
+ mimeType: "text/plain",
47
+ text: "x",
48
+ })).toEqual({
49
+ type: "resource",
50
+ resource: { uri: "file:///a.txt", mimeType: "text/plain", text: "x" },
51
+ });
52
+ });
53
+ it("wraps a blob resource with a type tag", () => {
54
+ expect(embeddedResource({ uri: "file:///a.bin", blob: "YmFy" })).toEqual({
55
+ type: "resource",
56
+ resource: { uri: "file:///a.bin", blob: "YmFy" },
57
+ });
58
+ });
59
+ });
60
+ describe("resourceLink", () => {
61
+ it("spreads link fields alongside the type tag", () => {
62
+ expect(resourceLink({ uri: "file:///a", name: "a", title: "A" })).toEqual({
63
+ type: "resource_link",
64
+ uri: "file:///a",
65
+ name: "a",
66
+ title: "A",
67
+ });
68
+ });
69
+ });
70
+ //# sourceMappingURL=content-helpers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-helpers.test.js","sourceRoot":"","sources":["../../src/server/content-helpers.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport {\n audio,\n embeddedResource,\n image,\n resourceLink,\n text,\n} from \"./content-helpers.js\";\n\ndescribe(\"text\", () => {\n it(\"returns a TextContent without annotations when none given\", () => {\n expect(text(\"hello\")).toEqual({ type: \"text\", text: \"hello\" });\n });\n\n it(\"includes annotations when provided\", () => {\n expect(text(\"hi\", { priority: 1 })).toEqual({\n type: \"text\",\n text: \"hi\",\n annotations: { priority: 1 },\n });\n });\n});\n\ndescribe(\"image\", () => {\n it(\"base64-encodes Uint8Array data\", () => {\n const bytes = new Uint8Array([104, 105]);\n expect(image(bytes, \"image/png\")).toEqual({\n type: \"image\",\n data: \"aGk=\",\n mimeType: \"image/png\",\n });\n });\n\n it(\"passes string data through unchanged (caller is responsible for base64)\", () => {\n expect(image(\"YWxyZWFkeS1iNjQ=\", \"image/png\")).toEqual({\n type: \"image\",\n data: \"YWxyZWFkeS1iNjQ=\",\n mimeType: \"image/png\",\n });\n });\n});\n\ndescribe(\"audio\", () => {\n it(\"base64-encodes Uint8Array data\", () => {\n const bytes = new Uint8Array([104, 105]);\n expect(audio(bytes, \"audio/mpeg\")).toMatchObject({\n type: \"audio\",\n data: \"aGk=\",\n mimeType: \"audio/mpeg\",\n });\n });\n});\n\ndescribe(\"embeddedResource\", () => {\n it(\"wraps a text resource with a type tag\", () => {\n expect(\n embeddedResource({\n uri: \"file:///a.txt\",\n mimeType: \"text/plain\",\n text: \"x\",\n }),\n ).toEqual({\n type: \"resource\",\n resource: { uri: \"file:///a.txt\", mimeType: \"text/plain\", text: \"x\" },\n });\n });\n\n it(\"wraps a blob resource with a type tag\", () => {\n expect(embeddedResource({ uri: \"file:///a.bin\", blob: \"YmFy\" })).toEqual({\n type: \"resource\",\n resource: { uri: \"file:///a.bin\", blob: \"YmFy\" },\n });\n });\n});\n\ndescribe(\"resourceLink\", () => {\n it(\"spreads link fields alongside the type tag\", () => {\n expect(resourceLink({ uri: \"file:///a\", name: \"a\", title: \"A\" })).toEqual({\n type: \"resource_link\",\n uri: \"file:///a\",\n name: \"a\",\n title: \"A\",\n });\n });\n});\n"]}
@@ -1,9 +1,11 @@
1
+ import type http from "node:http";
1
2
  import express from "express";
2
- import type { McpServer } from "./server";
3
- export declare function createServer({ server, customMiddleware, }: {
4
- server: McpServer;
5
- customMiddleware?: {
3
+ import type { McpServer } from "./server.js";
4
+ export declare function createApp({ mcpServer, httpServer, errorMiddleware, }: {
5
+ mcpServer: McpServer;
6
+ httpServer: http.Server;
7
+ errorMiddleware?: {
6
8
  path?: string;
7
- handlers: express.RequestHandler[];
9
+ handlers: express.ErrorRequestHandler[];
8
10
  }[];
9
11
  }): Promise<express.Express>;