skybridge 0.0.0-dev.b9f65be → 0.0.0-dev.b9f85b3

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 (369) hide show
  1. package/README.md +3 -0
  2. package/dist/cli/build-helpers.d.ts +7 -1
  3. package/dist/cli/build-helpers.js +58 -6
  4. package/dist/cli/build-helpers.js.map +1 -1
  5. package/dist/cli/build-helpers.test.js +89 -1
  6. package/dist/cli/build-helpers.test.js.map +1 -1
  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 +8 -20
  14. package/dist/cli/detect-port.js.map +1 -1
  15. package/dist/cli/header.d.ts +1 -1
  16. package/dist/cli/resolve-skybridge-config.d.ts +5 -0
  17. package/dist/cli/{resolve-views-dir.js → resolve-skybridge-config.js} +4 -3
  18. package/dist/cli/resolve-skybridge-config.js.map +1 -0
  19. package/dist/cli/run-plain.d.ts +18 -0
  20. package/dist/cli/run-plain.js +89 -0
  21. package/dist/cli/run-plain.js.map +1 -0
  22. package/dist/cli/use-execute-steps.d.ts +1 -1
  23. package/dist/cli/use-nodemon.d.ts +14 -0
  24. package/dist/cli/use-nodemon.js +81 -62
  25. package/dist/cli/use-nodemon.js.map +1 -1
  26. package/dist/cli/use-typescript-check.d.ts +8 -2
  27. package/dist/cli/use-typescript-check.js +70 -67
  28. package/dist/cli/use-typescript-check.js.map +1 -1
  29. package/dist/commands/build.d.ts +0 -3
  30. package/dist/commands/build.js +5 -56
  31. package/dist/commands/build.js.map +1 -1
  32. package/dist/commands/dev.d.ts +1 -0
  33. package/dist/commands/dev.js +35 -3
  34. package/dist/commands/dev.js.map +1 -1
  35. package/dist/commands/start.js +7 -1
  36. package/dist/commands/start.js.map +1 -1
  37. package/dist/context-warnings.d.ts +5 -0
  38. package/dist/context-warnings.js +31 -0
  39. package/dist/context-warnings.js.map +1 -0
  40. package/dist/context-warnings.test.js +28 -0
  41. package/dist/context-warnings.test.js.map +1 -0
  42. package/dist/server/app.d.ts +175 -0
  43. package/dist/server/app.js +275 -0
  44. package/dist/server/app.js.map +1 -0
  45. package/dist/server/auth/discovery.d.ts +33 -0
  46. package/dist/server/auth/discovery.js +56 -0
  47. package/dist/server/auth/discovery.js.map +1 -0
  48. package/dist/server/auth/discovery.test.js +93 -0
  49. package/dist/server/auth/discovery.test.js.map +1 -0
  50. package/dist/server/auth/index.d.ts +30 -0
  51. package/dist/server/auth/index.js +2 -0
  52. package/dist/server/auth/index.js.map +1 -0
  53. package/dist/server/auth/providers/auth0.d.ts +40 -0
  54. package/dist/server/auth/providers/auth0.js +31 -0
  55. package/dist/server/auth/providers/auth0.js.map +1 -0
  56. package/dist/server/auth/providers/auth0.test.js +50 -0
  57. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  58. package/dist/server/auth/providers/authplane.d.ts +49 -0
  59. package/dist/server/auth/providers/authplane.js +57 -0
  60. package/dist/server/auth/providers/authplane.js.map +1 -0
  61. package/dist/server/auth/providers/authplane.test.d.ts +1 -0
  62. package/dist/server/auth/providers/authplane.test.js +140 -0
  63. package/dist/server/auth/providers/authplane.test.js.map +1 -0
  64. package/dist/server/auth/providers/clerk.d.ts +51 -0
  65. package/dist/server/auth/providers/clerk.js +19 -0
  66. package/dist/server/auth/providers/clerk.js.map +1 -0
  67. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  68. package/dist/server/auth/providers/clerk.test.js +30 -0
  69. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  70. package/dist/server/auth/providers/custom.d.ts +40 -0
  71. package/dist/server/auth/providers/custom.js +56 -0
  72. package/dist/server/auth/providers/custom.js.map +1 -0
  73. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  74. package/dist/server/auth/providers/custom.test.js +158 -0
  75. package/dist/server/auth/providers/custom.test.js.map +1 -0
  76. package/dist/server/auth/providers/descope.d.ts +44 -0
  77. package/dist/server/auth/providers/descope.js +44 -0
  78. package/dist/server/auth/providers/descope.js.map +1 -0
  79. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  80. package/dist/server/auth/providers/descope.test.js +62 -0
  81. package/dist/server/auth/providers/descope.test.js.map +1 -0
  82. package/dist/server/auth/providers/shared.d.ts +2 -0
  83. package/dist/server/auth/providers/shared.js +6 -0
  84. package/dist/server/auth/providers/shared.js.map +1 -0
  85. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  86. package/dist/server/auth/providers/shared.test.js +10 -0
  87. package/dist/server/auth/providers/shared.test.js.map +1 -0
  88. package/dist/server/auth/providers/stytch.d.ts +25 -0
  89. package/dist/server/auth/providers/stytch.js +16 -0
  90. package/dist/server/auth/providers/stytch.js.map +1 -0
  91. package/dist/server/auth/providers/verify-spy.d.ts +12 -0
  92. package/dist/server/auth/providers/verify-spy.js +21 -0
  93. package/dist/server/auth/providers/verify-spy.js.map +1 -0
  94. package/dist/server/auth/providers/workos.d.ts +33 -0
  95. package/dist/server/auth/providers/workos.js +15 -0
  96. package/dist/server/auth/providers/workos.js.map +1 -0
  97. package/dist/server/auth/security-schemes.d.ts +23 -0
  98. package/dist/server/auth/security-schemes.js +64 -0
  99. package/dist/server/auth/security-schemes.js.map +1 -0
  100. package/dist/server/auth/security-schemes.test.d.ts +1 -0
  101. package/dist/server/auth/security-schemes.test.js +99 -0
  102. package/dist/server/auth/security-schemes.test.js.map +1 -0
  103. package/dist/server/auth/setup.d.ts +6 -0
  104. package/dist/server/auth/setup.js +91 -0
  105. package/dist/server/auth/setup.js.map +1 -0
  106. package/dist/server/auth/setup.test.d.ts +1 -0
  107. package/dist/server/auth/setup.test.js +512 -0
  108. package/dist/server/auth/setup.test.js.map +1 -0
  109. package/dist/server/auth/verify.d.ts +46 -0
  110. package/dist/server/auth/verify.js +62 -0
  111. package/dist/server/auth/verify.js.map +1 -0
  112. package/dist/server/auth/verify.test.d.ts +1 -0
  113. package/dist/server/auth/verify.test.js +149 -0
  114. package/dist/server/auth/verify.test.js.map +1 -0
  115. package/dist/server/auth-extra.test-d.js +71 -0
  116. package/dist/server/auth-extra.test-d.js.map +1 -0
  117. package/dist/server/auth.d.ts +42 -5
  118. package/dist/server/auth.js +3 -4
  119. package/dist/server/auth.js.map +1 -1
  120. package/dist/server/build-manifest.test.d.ts +1 -0
  121. package/dist/server/build-manifest.test.js +28 -0
  122. package/dist/server/build-manifest.test.js.map +1 -0
  123. package/dist/server/content-helpers.d.ts +1 -1
  124. package/dist/server/content-helpers.js.map +1 -1
  125. package/dist/server/express.d.ts +23 -3
  126. package/dist/server/express.js +37 -32
  127. package/dist/server/express.js.map +1 -1
  128. package/dist/server/express.test.js +154 -95
  129. package/dist/server/express.test.js.map +1 -1
  130. package/dist/server/factory-loader.test.d.ts +1 -0
  131. package/dist/server/factory-loader.test.js +81 -0
  132. package/dist/server/factory-loader.test.js.map +1 -0
  133. package/dist/server/file-ref.d.ts +1 -1
  134. package/dist/server/file-ref.js +1 -1
  135. package/dist/server/file-ref.js.map +1 -1
  136. package/dist/server/host.d.ts +2 -0
  137. package/dist/server/host.js +11 -0
  138. package/dist/server/host.js.map +1 -0
  139. package/dist/server/host.test.d.ts +1 -0
  140. package/dist/server/host.test.js +13 -0
  141. package/dist/server/host.test.js.map +1 -0
  142. package/dist/server/index.d.ts +16 -3
  143. package/dist/server/index.js +13 -2
  144. package/dist/server/index.js.map +1 -1
  145. package/dist/server/mcp-errors.test.d.ts +1 -0
  146. package/dist/server/mcp-errors.test.js +37 -0
  147. package/dist/server/mcp-errors.test.js.map +1 -0
  148. package/dist/server/middleware.d.ts +35 -10
  149. package/dist/server/middleware.js +33 -0
  150. package/dist/server/middleware.js.map +1 -1
  151. package/dist/server/middleware.test-d.js +1 -1
  152. package/dist/server/middleware.test-d.js.map +1 -1
  153. package/dist/server/middleware.test.js +190 -131
  154. package/dist/server/middleware.test.js.map +1 -1
  155. package/dist/server/register-tool.test.d.ts +1 -0
  156. package/dist/server/register-tool.test.js +23 -0
  157. package/dist/server/register-tool.test.js.map +1 -0
  158. package/dist/server/requestOrigin.d.ts +7 -0
  159. package/dist/server/requestOrigin.js +25 -0
  160. package/dist/server/requestOrigin.js.map +1 -0
  161. package/dist/server/server.d.ts +167 -122
  162. package/dist/server/server.js +346 -330
  163. package/dist/server/server.js.map +1 -1
  164. package/dist/server/skills-integration.test.d.ts +1 -0
  165. package/dist/server/skills-integration.test.js +79 -0
  166. package/dist/server/skills-integration.test.js.map +1 -0
  167. package/dist/server/skills.d.ts +27 -0
  168. package/dist/server/skills.js +188 -0
  169. package/dist/server/skills.js.map +1 -0
  170. package/dist/server/skills.test.d.ts +1 -0
  171. package/dist/server/skills.test.js +243 -0
  172. package/dist/server/skills.test.js.map +1 -0
  173. package/dist/server/templateHelper.d.ts +0 -3
  174. package/dist/server/templateHelper.js.map +1 -1
  175. package/dist/server/templates.generated.js +4 -8
  176. package/dist/server/templates.generated.js.map +1 -1
  177. package/dist/server/tool-extra.test.d.ts +1 -0
  178. package/dist/server/tool-extra.test.js +72 -0
  179. package/dist/server/tool-extra.test.js.map +1 -0
  180. package/dist/server/view-name.test-d.d.ts +1 -0
  181. package/dist/server/view-name.test-d.js +8 -0
  182. package/dist/server/view-name.test-d.js.map +1 -0
  183. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  184. package/dist/server/view-resource-resolution.test.js +172 -0
  185. package/dist/server/view-resource-resolution.test.js.map +1 -0
  186. package/dist/server/viewsDevServer.js +4 -1
  187. package/dist/server/viewsDevServer.js.map +1 -1
  188. package/dist/test/utils.d.ts +9 -11
  189. package/dist/test/utils.js +18 -13
  190. package/dist/test/utils.js.map +1 -1
  191. package/dist/test/view.test.js +88 -120
  192. package/dist/test/view.test.js.map +1 -1
  193. package/dist/views/index.d.ts +10 -0
  194. package/dist/views/index.js +3 -0
  195. package/dist/views/index.js.map +1 -0
  196. package/dist/{web/plugin → views}/scan-views.js +1 -1
  197. package/dist/views/scan-views.js.map +1 -0
  198. package/dist/views/scan-views.test.d.ts +1 -0
  199. package/dist/views/scan-views.test.js.map +1 -0
  200. package/dist/views/validate-view.d.ts +1 -0
  201. package/dist/{web/plugin → views}/validate-view.js +2 -2
  202. package/dist/views/validate-view.js.map +1 -0
  203. package/dist/views/validate-view.test.d.ts +1 -0
  204. package/dist/views/validate-view.test.js.map +1 -0
  205. package/dist/web/bridges/adaptor.d.ts +51 -0
  206. package/dist/web/bridges/adaptor.js +327 -0
  207. package/dist/web/bridges/adaptor.js.map +1 -0
  208. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  209. package/dist/web/bridges/adaptor.test.js +225 -0
  210. package/dist/web/bridges/adaptor.test.js.map +1 -0
  211. package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -2
  212. package/dist/web/bridges/apps-sdk/bridge.js +15 -4
  213. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  214. package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
  215. package/dist/web/bridges/apps-sdk/index.js +0 -1
  216. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  217. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +1 -1
  218. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +1 -1
  219. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  220. package/dist/web/bridges/get-adaptor.d.ts +4 -4
  221. package/dist/web/bridges/get-adaptor.js +6 -11
  222. package/dist/web/bridges/get-adaptor.js.map +1 -1
  223. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  224. package/dist/web/bridges/get-adaptor.test.js +32 -0
  225. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  226. package/dist/web/bridges/mcp-app/bridge.d.ts +15 -3
  227. package/dist/web/bridges/mcp-app/bridge.js +73 -8
  228. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  229. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  230. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  231. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  232. package/dist/web/bridges/mcp-app/index.d.ts +0 -1
  233. package/dist/web/bridges/mcp-app/index.js +0 -1
  234. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  235. package/dist/web/bridges/mcp-app/types.d.ts +2 -0
  236. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  237. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +1 -1
  238. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +1 -1
  239. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  240. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -1
  241. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  242. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  243. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  244. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  245. package/dist/web/bridges/types.d.ts +55 -7
  246. package/dist/web/bridges/types.js +14 -1
  247. package/dist/web/bridges/types.js.map +1 -1
  248. package/dist/web/bridges/types.test.d.ts +1 -0
  249. package/dist/web/bridges/types.test.js +19 -0
  250. package/dist/web/bridges/types.test.js.map +1 -0
  251. package/dist/web/components/modal-provider.d.ts +1 -1
  252. package/dist/web/components/modal-provider.js +4 -3
  253. package/dist/web/components/modal-provider.js.map +1 -1
  254. package/dist/web/create-store.test.js +10 -7
  255. package/dist/web/create-store.test.js.map +1 -1
  256. package/dist/web/data-llm.d.ts +1 -1
  257. package/dist/web/data-llm.test.js +20 -7
  258. package/dist/web/data-llm.test.js.map +1 -1
  259. package/dist/web/generate-helpers.d.ts +13 -12
  260. package/dist/web/generate-helpers.js +10 -9
  261. package/dist/web/generate-helpers.js.map +1 -1
  262. package/dist/web/generate-helpers.test-d.js +7 -5
  263. package/dist/web/generate-helpers.test-d.js.map +1 -1
  264. package/dist/web/generate-helpers.test.js +2 -2
  265. package/dist/web/generate-helpers.test.js.map +1 -1
  266. package/dist/web/hooks/index.d.ts +3 -1
  267. package/dist/web/hooks/index.js +3 -1
  268. package/dist/web/hooks/index.js.map +1 -1
  269. package/dist/web/hooks/test/utils.d.ts +2 -1
  270. package/dist/web/hooks/test/utils.js +1 -1
  271. package/dist/web/hooks/test/utils.js.map +1 -1
  272. package/dist/web/hooks/use-call-tool.test.js +39 -25
  273. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  274. package/dist/web/hooks/use-display-mode.d.ts +1 -1
  275. package/dist/web/hooks/use-display-mode.js +1 -1
  276. package/dist/web/hooks/use-display-mode.js.map +1 -1
  277. package/dist/web/hooks/use-display-mode.test.js +57 -21
  278. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  279. package/dist/web/hooks/use-download.d.ts +1 -3
  280. package/dist/web/hooks/use-download.js +1 -2
  281. package/dist/web/hooks/use-download.js.map +1 -1
  282. package/dist/web/hooks/use-download.test.js +18 -10
  283. package/dist/web/hooks/use-download.test.js.map +1 -1
  284. package/dist/web/hooks/use-files.test.js +11 -3
  285. package/dist/web/hooks/use-files.test.js.map +1 -1
  286. package/dist/web/hooks/use-host.d.ts +22 -0
  287. package/dist/web/hooks/use-host.js +30 -0
  288. package/dist/web/hooks/use-host.js.map +1 -0
  289. package/dist/web/hooks/use-host.test.d.ts +1 -0
  290. package/dist/web/hooks/use-host.test.js +59 -0
  291. package/dist/web/hooks/use-host.test.js.map +1 -0
  292. package/dist/web/hooks/use-open-external.test.js +15 -5
  293. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  294. package/dist/web/hooks/use-register-view-tool.d.ts +37 -0
  295. package/dist/web/hooks/use-register-view-tool.js +50 -0
  296. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  297. package/dist/web/hooks/use-request-close.test.js +35 -40
  298. package/dist/web/hooks/use-request-close.test.js.map +1 -1
  299. package/dist/web/hooks/use-request-modal.test.js +11 -1
  300. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  301. package/dist/web/hooks/use-request-size.d.ts +1 -1
  302. package/dist/web/hooks/use-request-size.js +1 -1
  303. package/dist/web/hooks/use-request-size.js.map +1 -1
  304. package/dist/web/hooks/use-request-size.test.js +35 -53
  305. package/dist/web/hooks/use-request-size.test.js.map +1 -1
  306. package/dist/web/hooks/use-set-open-in-app-url.test.js +26 -12
  307. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  308. package/dist/web/hooks/use-tool-info.d.ts +18 -19
  309. package/dist/web/hooks/use-tool-info.js +4 -8
  310. package/dist/web/hooks/use-tool-info.js.map +1 -1
  311. package/dist/web/hooks/use-tool-info.test-d.js +11 -34
  312. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  313. package/dist/web/hooks/use-tool-info.test.js +42 -37
  314. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  315. package/dist/web/hooks/use-user.d.ts +3 -2
  316. package/dist/web/hooks/use-user.js +4 -3
  317. package/dist/web/hooks/use-user.js.map +1 -1
  318. package/dist/web/hooks/use-user.test.js +85 -37
  319. package/dist/web/hooks/use-user.test.js.map +1 -1
  320. package/dist/web/hooks/use-view-state.js +19 -9
  321. package/dist/web/hooks/use-view-state.js.map +1 -1
  322. package/dist/web/hooks/use-view-state.test.js +39 -4
  323. package/dist/web/hooks/use-view-state.test.js.map +1 -1
  324. package/dist/web/hooks/use-viewport.d.ts +20 -0
  325. package/dist/web/hooks/use-viewport.js +21 -0
  326. package/dist/web/hooks/use-viewport.js.map +1 -0
  327. package/dist/web/hooks/use-viewport.test.d.ts +1 -0
  328. package/dist/web/hooks/use-viewport.test.js +109 -0
  329. package/dist/web/hooks/use-viewport.test.js.map +1 -0
  330. package/dist/web/mount-view.d.ts +3 -2
  331. package/dist/web/mount-view.js +5 -8
  332. package/dist/web/mount-view.js.map +1 -1
  333. package/package.json +33 -27
  334. package/dist/cli/resolve-views-dir.d.ts +0 -1
  335. package/dist/cli/resolve-views-dir.js.map +0 -1
  336. package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -28
  337. package/dist/web/bridges/apps-sdk/adaptor.js +0 -113
  338. package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
  339. package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -52
  340. package/dist/web/bridges/mcp-app/adaptor.js +0 -280
  341. package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
  342. package/dist/web/hooks/use-layout.d.ts +0 -24
  343. package/dist/web/hooks/use-layout.js +0 -25
  344. package/dist/web/hooks/use-layout.js.map +0 -1
  345. package/dist/web/hooks/use-layout.test.js +0 -96
  346. package/dist/web/hooks/use-layout.test.js.map +0 -1
  347. package/dist/web/plugin/data-llm.test.js +0 -81
  348. package/dist/web/plugin/data-llm.test.js.map +0 -1
  349. package/dist/web/plugin/plugin.d.ts +0 -33
  350. package/dist/web/plugin/plugin.js +0 -189
  351. package/dist/web/plugin/plugin.js.map +0 -1
  352. package/dist/web/plugin/scan-views.js.map +0 -1
  353. package/dist/web/plugin/scan-views.test.js.map +0 -1
  354. package/dist/web/plugin/transform-data-llm.d.ts +0 -12
  355. package/dist/web/plugin/transform-data-llm.js +0 -96
  356. package/dist/web/plugin/transform-data-llm.js.map +0 -1
  357. package/dist/web/plugin/transform-data-llm.test.js +0 -81
  358. package/dist/web/plugin/transform-data-llm.test.js.map +0 -1
  359. package/dist/web/plugin/validate-view.d.ts +0 -1
  360. package/dist/web/plugin/validate-view.js.map +0 -1
  361. package/dist/web/plugin/validate-view.test.js.map +0 -1
  362. /package/dist/{web/hooks/use-layout.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  363. /package/dist/{web/plugin/data-llm.test.d.ts → context-warnings.test.d.ts} +0 -0
  364. /package/dist/{web/plugin/transform-data-llm.test.d.ts → server/auth/discovery.test.d.ts} +0 -0
  365. /package/dist/{web/plugin/validate-view.test.d.ts → server/auth/providers/auth0.test.d.ts} +0 -0
  366. /package/dist/{web/plugin/scan-views.test.d.ts → server/auth-extra.test-d.d.ts} +0 -0
  367. /package/dist/{web/plugin → views}/scan-views.d.ts +0 -0
  368. /package/dist/{web/plugin → views}/scan-views.test.js +0 -0
  369. /package/dist/{web/plugin → views}/validate-view.test.js +0 -0
@@ -1,7 +1,36 @@
1
1
  import path from "node:path";
2
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
2
+ import { toNodeHandler } from "@modelcontextprotocol/node";
3
+ import { createMcpHandler, UnsupportedProtocolVersionError, } from "@modelcontextprotocol/server";
3
4
  import cors from "cors";
4
5
  import express from "express";
6
+ /**
7
+ * The `/mcp` fetch handler for a {@link Skybridge} app: a `Request` →
8
+ * `Response` function that builds a fresh MCP server per request.
9
+ *
10
+ * @internal
11
+ */
12
+ export function buildMcpHandler(skybridgeApp) {
13
+ return createMcpHandler(() => skybridgeApp.createServerInstance(), {
14
+ onerror: (error) => {
15
+ if (error instanceof UnsupportedProtocolVersionError) {
16
+ return;
17
+ }
18
+ console.error("Error handling MCP request:", error);
19
+ },
20
+ });
21
+ }
22
+ /**
23
+ * Build the bare Express app a {@link Skybridge} instance owns: the instance
24
+ * plus the built-in `express.json()` body parser, tuned by the `json` config
25
+ * field.
26
+ *
27
+ * @internal
28
+ */
29
+ export function createBaseApp(json) {
30
+ const app = express();
31
+ app.use(express.json(json));
32
+ return app;
33
+ }
5
34
  function parseControlPort(raw) {
6
35
  if (raw === undefined) {
7
36
  return null;
@@ -32,8 +61,8 @@ function defaultErrorHandler(err, _req, res, _next) {
32
61
  });
33
62
  }
34
63
  }
35
- export async function createApp({ mcpServer, httpServer, errorMiddleware = [], }) {
36
- const app = mcpServer.express;
64
+ export async function createApp({ app: skybridgeApp, httpServer, mcpHandler, errorMiddleware = [], }) {
65
+ const app = skybridgeApp.express;
37
66
  // Read `process.env.NODE_ENV` inline: wrangler/esbuild only substitute the literal expression,
38
67
  // so a local const would defeat dead-code elimination of the dev-only imports below.
39
68
  if (process.env.NODE_ENV !== "production") {
@@ -55,43 +84,19 @@ export async function createApp({ mcpServer, httpServer, errorMiddleware = [], }
55
84
  app.use("/assets", cors());
56
85
  app.use("/assets", express.static(assetsPath));
57
86
  }
58
- app.use("/mcp", mcpMiddleware(mcpServer));
87
+ app.use("/mcp", mcpMiddleware(mcpHandler ?? buildMcpHandler(skybridgeApp)));
59
88
  applyMiddlewares(app, errorMiddleware);
60
89
  app.use("/mcp", defaultErrorHandler);
61
90
  return app;
62
91
  }
63
- const mcpMiddleware = (server) => {
92
+ const mcpMiddleware = (mcpHandler) => {
93
+ const handler = toNodeHandler(mcpHandler);
64
94
  return async (req, res, next) => {
65
- if (req.method !== "POST") {
66
- res.writeHead(405).end(JSON.stringify({
67
- jsonrpc: "2.0",
68
- error: {
69
- code: -32000,
70
- message: "Method not allowed.",
71
- },
72
- id: null,
73
- }));
74
- return;
75
- }
76
95
  try {
77
- const transport = new StreamableHTTPServerTransport({
78
- sessionIdGenerator: undefined,
79
- // Respond with a single JSON body instead of SSE. Skybridge's stateless
80
- // transport never streams server-initiated messages, so SSE adds no
81
- // capability — and on workerd specifically, `cloudflare:node`'s http
82
- // bridge silently drops chunked writes that happen after the request
83
- // handler awaits, which manifests as a 200 with empty body for any
84
- // async tools/call.
85
- enableJsonResponse: true,
86
- });
87
- res.on("close", () => {
88
- transport.close();
89
- });
90
- await server.connectStatelessTransport(transport);
91
96
  // Express strips the mount path from req.url (e.g. "/mcp" becomes "/").
92
- // Restore it so the SDK builds the correct requestInfo.url.
97
+ // Restore it so the SDK builds the correct request URL.
93
98
  req.url = req.originalUrl;
94
- await transport.handleRequest(req, res, req.body);
99
+ await handler(req, res, req.body);
95
100
  }
96
101
  catch (error) {
97
102
  next(error);
@@ -1 +1 @@
1
- {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/server/express.ts"],"names":[],"mappings":"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","sourcesContent":["import type http from \"node:http\";\nimport path from \"node:path\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport cors from \"cors\";\nimport express from \"express\";\nimport type { McpServer } from \"./server.js\";\n\nfunction parseControlPort(raw: string | undefined): number | null {\n if (raw === undefined) {\n return null;\n }\n const n = Number.parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0 || n >= 65536) {\n return null;\n }\n return n;\n}\n\nfunction applyMiddlewares(\n app: express.Express,\n middlewares: Array<{\n path?: string;\n handlers: express.ErrorRequestHandler[];\n }>,\n): void {\n for (const middleware of middlewares) {\n if (middleware.path) {\n app.use(middleware.path, ...middleware.handlers);\n } else {\n app.use(...middleware.handlers);\n }\n }\n}\n\nfunction defaultErrorHandler(\n err: unknown,\n _req: express.Request,\n res: express.Response,\n _next: express.NextFunction,\n) {\n console.error(\"Error handling MCP request:\", err);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Internal server error\" },\n id: null,\n });\n }\n}\n\nexport async function createApp({\n mcpServer,\n httpServer,\n errorMiddleware = [],\n}: {\n mcpServer: McpServer;\n httpServer: http.Server;\n errorMiddleware?: {\n path?: string;\n handlers: express.ErrorRequestHandler[];\n }[];\n}): Promise<express.Express> {\n const app = mcpServer.express;\n\n // Read `process.env.NODE_ENV` inline: wrangler/esbuild only substitute the literal expression,\n // so a local const would defeat dead-code elimination of the dev-only imports below.\n if (process.env.NODE_ENV !== \"production\") {\n const { devtoolsStaticServer } = await import(\"@skybridge/devtools\");\n app.use(await devtoolsStaticServer());\n const { viewsDevServer } = await import(\"./viewsDevServer.js\");\n app.use(await viewsDevServer(httpServer));\n\n const controlPort = parseControlPort(process.env.__TUNNEL_CONTROL_PORT);\n if (controlPort !== null) {\n const { createTunnelProxyRouter } = await import(\n \"./tunnel-proxy-router.js\"\n );\n app.use(createTunnelProxyRouter(controlPort));\n } else if (process.env.__TUNNEL_CONTROL_PORT !== undefined) {\n console.warn(\n `Ignoring invalid __TUNNEL_CONTROL_PORT=${process.env.__TUNNEL_CONTROL_PORT}`,\n );\n }\n } else {\n const assetsPath = path.join(process.cwd(), \"dist\", \"assets\");\n\n app.use(\"/assets\", cors());\n app.use(\"/assets\", express.static(assetsPath));\n }\n\n app.use(\"/mcp\", mcpMiddleware(mcpServer));\n\n applyMiddlewares(app, errorMiddleware);\n\n app.use(\"/mcp\", defaultErrorHandler);\n\n return app;\n}\n\nconst mcpMiddleware = (server: McpServer): express.RequestHandler => {\n return async (\n req: express.Request,\n res: express.Response,\n next: express.NextFunction,\n ) => {\n if (req.method !== \"POST\") {\n res.writeHead(405).end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Method not allowed.\",\n },\n id: null,\n }),\n );\n return;\n }\n\n try {\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n // Respond with a single JSON body instead of SSE. Skybridge's stateless\n // transport never streams server-initiated messages, so SSE adds no\n // capability — and on workerd specifically, `cloudflare:node`'s http\n // bridge silently drops chunked writes that happen after the request\n // handler awaits, which manifests as a 200 with empty body for any\n // async tools/call.\n enableJsonResponse: true,\n });\n\n res.on(\"close\", () => {\n transport.close();\n });\n\n await server.connectStatelessTransport(transport);\n // Express strips the mount path from req.url (e.g. \"/mcp\" becomes \"/\").\n // Restore it so the SDK builds the correct requestInfo.url.\n req.url = req.originalUrl;\n await transport.handleRequest(req, res, req.body);\n } catch (error) {\n next(error);\n }\n };\n};\n"]}
1
+ {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/server/express.ts"],"names":[],"mappings":"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","sourcesContent":["import type http from \"node:http\";\nimport path from \"node:path\";\nimport { toNodeHandler } from \"@modelcontextprotocol/node\";\nimport {\n createMcpHandler,\n type McpHttpHandler,\n UnsupportedProtocolVersionError,\n} from \"@modelcontextprotocol/server\";\nimport cors from \"cors\";\nimport express from \"express\";\nimport type { Skybridge } from \"./app.js\";\nimport type { JsonOptions } from \"./server.js\";\n\ntype SkybridgeApp = Pick<Skybridge, \"express\" | \"createServerInstance\">;\n\n/**\n * The `/mcp` fetch handler for a {@link Skybridge} app: a `Request` →\n * `Response` function that builds a fresh MCP server per request.\n *\n * @internal\n */\nexport function buildMcpHandler(skybridgeApp: SkybridgeApp): McpHttpHandler {\n return createMcpHandler(() => skybridgeApp.createServerInstance(), {\n onerror: (error) => {\n if (error instanceof UnsupportedProtocolVersionError) {\n return;\n }\n console.error(\"Error handling MCP request:\", error);\n },\n });\n}\n\n/**\n * Build the bare Express app a {@link Skybridge} instance owns: the instance\n * plus the built-in `express.json()` body parser, tuned by the `json` config\n * field.\n *\n * @internal\n */\nexport function createBaseApp(json?: JsonOptions): express.Express {\n const app = express();\n app.use(express.json(json));\n return app;\n}\n\nfunction parseControlPort(raw: string | undefined): number | null {\n if (raw === undefined) {\n return null;\n }\n const n = Number.parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0 || n >= 65536) {\n return null;\n }\n return n;\n}\n\nfunction applyMiddlewares(\n app: express.Express,\n middlewares: Array<{\n path?: string;\n handlers: express.ErrorRequestHandler[];\n }>,\n): void {\n for (const middleware of middlewares) {\n if (middleware.path) {\n app.use(middleware.path, ...middleware.handlers);\n } else {\n app.use(...middleware.handlers);\n }\n }\n}\n\nfunction defaultErrorHandler(\n err: unknown,\n _req: express.Request,\n res: express.Response,\n _next: express.NextFunction,\n) {\n console.error(\"Error handling MCP request:\", err);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Internal server error\" },\n id: null,\n });\n }\n}\n\nexport async function createApp({\n app: skybridgeApp,\n httpServer,\n mcpHandler,\n errorMiddleware = [],\n}: {\n app: SkybridgeApp;\n httpServer: http.Server;\n mcpHandler?: McpHttpHandler;\n errorMiddleware?: {\n path?: string;\n handlers: express.ErrorRequestHandler[];\n }[];\n}): Promise<express.Express> {\n const app = skybridgeApp.express;\n\n // Read `process.env.NODE_ENV` inline: wrangler/esbuild only substitute the literal expression,\n // so a local const would defeat dead-code elimination of the dev-only imports below.\n if (process.env.NODE_ENV !== \"production\") {\n const { devtoolsStaticServer } = await import(\"@skybridge/devtools\");\n app.use(await devtoolsStaticServer());\n const { viewsDevServer } = await import(\"./viewsDevServer.js\");\n app.use(await viewsDevServer(httpServer));\n\n const controlPort = parseControlPort(process.env.__TUNNEL_CONTROL_PORT);\n if (controlPort !== null) {\n const { createTunnelProxyRouter } = await import(\n \"./tunnel-proxy-router.js\"\n );\n app.use(createTunnelProxyRouter(controlPort));\n } else if (process.env.__TUNNEL_CONTROL_PORT !== undefined) {\n console.warn(\n `Ignoring invalid __TUNNEL_CONTROL_PORT=${process.env.__TUNNEL_CONTROL_PORT}`,\n );\n }\n } else {\n const assetsPath = path.join(process.cwd(), \"dist\", \"assets\");\n\n app.use(\"/assets\", cors());\n app.use(\"/assets\", express.static(assetsPath));\n }\n\n app.use(\"/mcp\", mcpMiddleware(mcpHandler ?? buildMcpHandler(skybridgeApp)));\n\n applyMiddlewares(app, errorMiddleware);\n\n app.use(\"/mcp\", defaultErrorHandler);\n\n return app;\n}\n\nconst mcpMiddleware = (mcpHandler: McpHttpHandler): express.RequestHandler => {\n const handler = toNodeHandler(mcpHandler);\n\n return async (\n req: express.Request,\n res: express.Response,\n next: express.NextFunction,\n ) => {\n try {\n // Express strips the mount path from req.url (e.g. \"/mcp\" becomes \"/\").\n // Restore it so the SDK builds the correct request URL.\n req.url = req.originalUrl;\n await handler(req, res, req.body);\n } catch (error) {\n next(error);\n }\n };\n};\n"]}
@@ -1,6 +1,7 @@
1
1
  import http from "node:http";
2
+ import { Client, StreamableHTTPClientTransport, } from "@modelcontextprotocol/client";
2
3
  import { afterEach, describe, expect, it, vi } from "vitest";
3
- import { McpServer } from "./server.js";
4
+ import { Skybridge } from "./app.js";
4
5
  vi.mock("@skybridge/devtools", () => ({
5
6
  devtoolsStaticServer: () => ((_req, _res, next) => next()),
6
7
  }));
@@ -25,22 +26,22 @@ async function postMcp(port) {
25
26
  async function postApi(port) {
26
27
  return fetch(`http://localhost:${port}/api/test`, { method: "POST" });
27
28
  }
28
- describe("McpServer.express", () => {
29
+ describe("Skybridge.express", () => {
29
30
  it("exposes a ready Express app immediately after construction", () => {
30
- const server = new McpServer({ name: "t", version: "0.0.0" });
31
- expect(server.express).toBeDefined();
32
- expect(typeof server.express.use).toBe("function");
33
- expect(typeof server.express.get).toBe("function");
31
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
32
+ expect(app.express).toBeDefined();
33
+ expect(typeof app.express.use).toBe("function");
34
+ expect(typeof app.express.get).toBe("function");
34
35
  });
35
- it("server.express.get registers a route reachable alongside /mcp", async () => {
36
+ it("app.express.get registers a route reachable alongside /mcp", async () => {
36
37
  const { createApp } = await import("./express.js");
37
- const server = new McpServer({ name: "t", version: "0.0.0" });
38
- server.express.get("/health", (_req, res) => {
38
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
39
+ app.express.get("/health", (_req, res) => {
39
40
  res.json({ status: "ok" });
40
41
  });
41
42
  const httpServer = http.createServer();
42
- await createApp({ mcpServer: server, httpServer });
43
- const { port, server: listening } = await listen(server.express);
43
+ await createApp({ app, httpServer });
44
+ const { port, server: listening } = await listen(app.express);
44
45
  openServer = listening;
45
46
  const health = await fetch(`http://localhost:${port}/health`);
46
47
  expect(health.status).toBe(200);
@@ -49,12 +50,12 @@ describe("McpServer.express", () => {
49
50
  const mcp = await postMcp(port);
50
51
  expect(mcp.status).not.toBe(404);
51
52
  });
52
- it("server.use and server.express.use produce the same registration order", async () => {
53
+ it("app.use and app.express.use produce the same registration order", async () => {
53
54
  const { createApp } = await import("./express.js");
54
55
  const callsA = [];
55
56
  const callsB = [];
56
- const buildServer = () => new McpServer({ name: "t", version: "0.0.0" });
57
- const sA = buildServer();
57
+ const buildApp = () => new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
58
+ const sA = buildApp();
58
59
  sA.use((_req, _res, next) => {
59
60
  callsA.push("first");
60
61
  next();
@@ -63,7 +64,7 @@ describe("McpServer.express", () => {
63
64
  callsA.push("second");
64
65
  next();
65
66
  });
66
- const sB = buildServer();
67
+ const sB = buildApp();
67
68
  sB.express.use((_req, _res, next) => {
68
69
  callsB.push("first");
69
70
  next();
@@ -75,7 +76,7 @@ describe("McpServer.express", () => {
75
76
  for (const s of [sA, sB]) {
76
77
  s.express.get("/probe", (_req, res) => res.json({ ok: true }));
77
78
  const httpServer = http.createServer();
78
- await createApp({ mcpServer: s, httpServer });
79
+ await createApp({ app: s, httpServer });
79
80
  const { port, server: listening } = await listen(s.express);
80
81
  openServer = listening;
81
82
  await fetch(`http://localhost:${port}/probe`);
@@ -86,26 +87,28 @@ describe("McpServer.express", () => {
86
87
  });
87
88
  it("useOnError still wraps thrown /mcp errors after the route is mounted", async () => {
88
89
  const { createApp } = await import("./express.js");
89
- const server = new McpServer({ name: "t", version: "0.0.0" });
90
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
90
91
  // Register the error handler BEFORE createApp — useOnError should still
91
92
  // apply it after /mcp, so /mcp errors hit it.
92
93
  const seen = [];
93
- server.useOnError((_err, _req, res, _next) => {
94
+ app.useOnError((_err, _req, res, _next) => {
94
95
  seen.push("useOnError");
95
96
  res.status(503).json({ from: "useOnError" });
96
97
  });
97
98
  // Force the /mcp handler to throw so the error pipeline runs.
98
- vi.spyOn(server, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
99
+ app.use("/mcp", () => {
100
+ throw new Error("boom");
101
+ });
99
102
  const httpServer = http.createServer();
100
103
  await createApp({
101
- mcpServer: server,
104
+ app,
102
105
  httpServer,
103
- // Mirror what run() does: forward the McpServer's useOnError handlers
106
+ // Mirror what run() does: forward the app's useOnError handlers
104
107
  // to createApp so they get applied after /mcp.
105
108
  // biome-ignore lint/complexity/useLiteralKeys: test mirrors run() internals to verify useOnError ordering
106
- errorMiddleware: server["customErrorMiddleware"],
109
+ errorMiddleware: app["errorMiddleware"],
107
110
  });
108
- const { port, server: listening } = await listen(server.express);
111
+ const { port, server: listening } = await listen(app.express);
109
112
  openServer = listening;
110
113
  const res = await postMcp(port);
111
114
  expect(seen).toEqual(["useOnError"]);
@@ -113,6 +116,37 @@ describe("McpServer.express", () => {
113
116
  expect(await res.json()).toEqual({ from: "useOnError" });
114
117
  });
115
118
  });
119
+ describe("Skybridge JSON body parser options", () => {
120
+ const largeBody = JSON.stringify({ data: "x".repeat(200 * 1024) });
121
+ async function postEcho(port, body) {
122
+ return fetch(`http://localhost:${port}/echo`, {
123
+ method: "POST",
124
+ headers: { "Content-Type": "application/json" },
125
+ body,
126
+ });
127
+ }
128
+ it("forwards json options to express.json", async () => {
129
+ const app = new Skybridge({ name: "t", version: "0.0.0", json: { limit: "10mb" } }, (server) => server);
130
+ app.express.post("/echo", (req, res) => {
131
+ res.json({ received: req.body.data.length });
132
+ });
133
+ const { port, server: listening } = await listen(app.express);
134
+ openServer = listening;
135
+ const res = await postEcho(port, largeBody);
136
+ expect(res.status).toBe(200);
137
+ expect(await res.json()).toEqual({ received: 200 * 1024 });
138
+ });
139
+ it("keeps the default 100kb limit when no options are passed", async () => {
140
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
141
+ app.express.post("/echo", (_req, res) => {
142
+ res.json({ ok: true });
143
+ });
144
+ const { port, server: listening } = await listen(app.express);
145
+ openServer = listening;
146
+ const res = await postEcho(port, largeBody);
147
+ expect(res.status).toBe(413);
148
+ });
149
+ });
116
150
  describe("createApp", () => {
117
151
  it("runs global custom middleware before the /mcp handler", async () => {
118
152
  const { createApp } = await import("./express.js");
@@ -121,11 +155,11 @@ describe("createApp", () => {
121
155
  calls.push("custom");
122
156
  next();
123
157
  };
124
- const server = new McpServer({ name: "t", version: "0.0.0" });
125
- server.use(mw);
158
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
159
+ app.use(mw);
126
160
  const httpServer = http.createServer();
127
- const app = await createApp({ mcpServer: server, httpServer });
128
- const { port, server: httpListening } = await listen(app);
161
+ const expressApp = await createApp({ app, httpServer });
162
+ const { port, server: httpListening } = await listen(expressApp);
129
163
  openServer = httpListening;
130
164
  await postMcp(port);
131
165
  expect(calls).toEqual(["custom"]);
@@ -137,11 +171,11 @@ describe("createApp", () => {
137
171
  calls.push("auth");
138
172
  next();
139
173
  };
140
- const server = new McpServer({ name: "t", version: "0.0.0" });
141
- server.use("/mcp", mw);
174
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
175
+ app.use("/mcp", mw);
142
176
  const httpServer = http.createServer();
143
- const app = await createApp({ mcpServer: server, httpServer });
144
- const { port, server: httpListening } = await listen(app);
177
+ const expressApp = await createApp({ app, httpServer });
178
+ const { port, server: httpListening } = await listen(expressApp);
145
179
  openServer = httpListening;
146
180
  await postMcp(port);
147
181
  expect(calls).toEqual(["auth"]);
@@ -153,11 +187,11 @@ describe("createApp", () => {
153
187
  calls.push("reject");
154
188
  res.status(401).json({ error: "Unauthorized" });
155
189
  };
156
- const server = new McpServer({ name: "t", version: "0.0.0" });
157
- server.use("/mcp", reject);
190
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
191
+ app.use("/mcp", reject);
158
192
  const httpServer = http.createServer();
159
- const app = await createApp({ mcpServer: server, httpServer });
160
- const { port, server: httpListening } = await listen(app);
193
+ const expressApp = await createApp({ app, httpServer });
194
+ const { port, server: httpListening } = await listen(expressApp);
161
195
  openServer = httpListening;
162
196
  const res = await postMcp(port);
163
197
  expect(calls).toEqual(["reject"]);
@@ -175,12 +209,12 @@ describe("createApp", () => {
175
209
  calls.push("B");
176
210
  next();
177
211
  };
178
- const server = new McpServer({ name: "t", version: "0.0.0" });
179
- server.use(mwA);
180
- server.use(mwB);
212
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
213
+ app.use(mwA);
214
+ app.use(mwB);
181
215
  const httpServer = http.createServer();
182
- const app = await createApp({ mcpServer: server, httpServer });
183
- const { port, server: httpListening } = await listen(app);
216
+ const expressApp = await createApp({ app, httpServer });
217
+ const { port, server: httpListening } = await listen(expressApp);
184
218
  openServer = httpListening;
185
219
  await postMcp(port);
186
220
  expect(calls).toEqual(["A", "B"]);
@@ -192,11 +226,11 @@ describe("createApp", () => {
192
226
  calls.push("api");
193
227
  next();
194
228
  };
195
- const server = new McpServer({ name: "t", version: "0.0.0" });
196
- server.use("/api", apiMw);
229
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
230
+ app.use("/api", apiMw);
197
231
  const httpServer = http.createServer();
198
- const app = await createApp({ mcpServer: server, httpServer });
199
- const { port, server: httpListening } = await listen(app);
232
+ const expressApp = await createApp({ app, httpServer });
233
+ const { port, server: httpListening } = await listen(expressApp);
200
234
  openServer = httpListening;
201
235
  // Hit /mcp — the /api middleware should NOT fire
202
236
  await postMcp(port);
@@ -209,11 +243,11 @@ describe("createApp", () => {
209
243
  router.get("/health", (_req, res) => {
210
244
  res.json({ status: "ok" });
211
245
  });
212
- const server = new McpServer({ name: "t", version: "0.0.0" });
213
- server.use(router);
246
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
247
+ app.use(router);
214
248
  const httpServer = http.createServer();
215
- const app = await createApp({ mcpServer: server, httpServer });
216
- const { port, server: httpListening } = await listen(app);
249
+ const expressApp = await createApp({ app, httpServer });
250
+ const { port, server: httpListening } = await listen(expressApp);
217
251
  openServer = httpListening;
218
252
  const res = await fetch(`http://localhost:${port}/health`);
219
253
  expect(res.status).toBe(200);
@@ -226,11 +260,11 @@ describe("createApp", () => {
226
260
  router.get("/data", (_req, res) => {
227
261
  res.json({ value: 42 });
228
262
  });
229
- const server = new McpServer({ name: "t", version: "0.0.0" });
230
- server.use("/api", router);
263
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
264
+ app.use("/api", router);
231
265
  const httpServer = http.createServer();
232
- const app = await createApp({ mcpServer: server, httpServer });
233
- const { port, server: httpListening } = await listen(app);
266
+ const expressApp = await createApp({ app, httpServer });
267
+ const { port, server: httpListening } = await listen(expressApp);
234
268
  openServer = httpListening;
235
269
  const res = await fetch(`http://localhost:${port}/api/data`);
236
270
  expect(res.status).toBe(200);
@@ -241,11 +275,11 @@ describe("createApp", () => {
241
275
  const throwing = () => {
242
276
  throw new Error("boom");
243
277
  };
244
- const server = new McpServer({ name: "t", version: "0.0.0" });
245
- server.use("/explode", throwing);
278
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
279
+ app.use("/explode", throwing);
246
280
  const httpServer = http.createServer();
247
- const app = await createApp({ mcpServer: server, httpServer });
248
- const { port, server: httpListening } = await listen(app);
281
+ const expressApp = await createApp({ app, httpServer });
282
+ const { port, server: httpListening } = await listen(expressApp);
249
283
  openServer = httpListening;
250
284
  const res = await fetch(`http://localhost:${port}/explode`);
251
285
  expect(res.status).toBe(500);
@@ -256,14 +290,15 @@ describe("createApp", () => {
256
290
  it("returns 500 JSON-RPC error when the MCP handler throws and no error middleware is registered", async () => {
257
291
  const { createApp } = await import("./express.js");
258
292
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
259
- const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
260
- // Force the express-level error path: make connectStatelessTransport
261
- // reject so the request handler hits its try/catch and calls next(error),
262
- // which lands in the default /mcp error handler.
263
- vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
293
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
294
+ // Force the express-level error path: make a /mcp middleware throw so the
295
+ // error pipeline runs and lands in the default /mcp error handler.
296
+ app.use("/mcp", () => {
297
+ throw new Error("boom");
298
+ });
264
299
  const httpServer = http.createServer();
265
- const app = await createApp({ mcpServer, httpServer });
266
- const { port, server: httpListening } = await listen(app);
300
+ const expressApp = await createApp({ app, httpServer });
301
+ const { port, server: httpListening } = await listen(expressApp);
267
302
  openServer = httpListening;
268
303
  const res = await postMcp(port);
269
304
  expect(res.status).toBe(500);
@@ -282,15 +317,17 @@ describe("createApp", () => {
282
317
  calls.push("error-handler");
283
318
  res.status(503).json({ custom: true });
284
319
  };
285
- const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
286
- vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
320
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
321
+ app.use("/mcp", () => {
322
+ throw new Error("boom");
323
+ });
287
324
  const httpServer = http.createServer();
288
- const app = await createApp({
289
- mcpServer,
325
+ const expressApp = await createApp({
326
+ app,
290
327
  httpServer,
291
328
  errorMiddleware: [{ handlers: [errorHandler] }],
292
329
  });
293
- const { port, server: httpListening } = await listen(app);
330
+ const { port, server: httpListening } = await listen(expressApp);
294
331
  openServer = httpListening;
295
332
  const res = await postMcp(port);
296
333
  expect(calls).toEqual(["error-handler"]);
@@ -307,16 +344,18 @@ describe("createApp", () => {
307
344
  const throwingApiRoute = (_req, _res, next) => {
308
345
  next(new Error("api error"));
309
346
  };
310
- const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
311
- vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
312
- mcpServer.use("/api/test", throwingApiRoute);
347
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
348
+ app.use("/mcp", () => {
349
+ throw new Error("boom");
350
+ });
351
+ app.use("/api/test", throwingApiRoute);
313
352
  const httpServer = http.createServer();
314
- const app = await createApp({
315
- mcpServer,
353
+ const expressApp = await createApp({
354
+ app,
316
355
  httpServer,
317
356
  errorMiddleware: [{ path: "/mcp", handlers: [mcpErrorHandler] }],
318
357
  });
319
- const { port, server: httpListening } = await listen(app);
358
+ const { port, server: httpListening } = await listen(expressApp);
320
359
  openServer = httpListening;
321
360
  const mcpRes = await postMcp(port);
322
361
  expect(calls).toEqual(["mcp-error-handler"]);
@@ -330,20 +369,16 @@ describe("createApp", () => {
330
369
  });
331
370
  it("handles concurrent /mcp requests without 'Already connected to a transport'", async () => {
332
371
  const { createApp } = await import("./express.js");
333
- const mcpServer = new McpServer({
334
- name: "concurrent-test",
335
- version: "0.0.0",
336
- });
337
372
  // Slow tool: keeps the underlying transport bound long enough to overlap
338
373
  // with concurrent requests, exposing the shared-McpServer race.
339
- mcpServer.registerTool({ name: "slow", description: "slow" }, async () => {
374
+ const app = new Skybridge({ name: "concurrent-test", version: "0.0.0" }, (server) => server.registerTool({ name: "slow", description: "slow" }, async () => {
340
375
  await new Promise((r) => setTimeout(r, 50));
341
376
  return { content: [{ type: "text", text: "done" }] };
342
- });
377
+ }));
343
378
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
344
379
  const httpServer = http.createServer();
345
- const app = await createApp({ mcpServer, httpServer });
346
- const { port, server } = await listen(app);
380
+ const expressApp = await createApp({ app, httpServer });
381
+ const { port, server } = await listen(expressApp);
347
382
  openServer = server;
348
383
  const callBody = (id) => JSON.stringify({
349
384
  jsonrpc: "2.0",
@@ -366,19 +401,19 @@ describe("createApp", () => {
366
401
  });
367
402
  });
368
403
  describe("createApp Vercel mode", () => {
369
- it("server.run() returns the Express app without binding a port when VERCEL=1", async () => {
404
+ it("app.run() returns the Express app without binding a port when VERCEL=1", async () => {
370
405
  const prevVercel = process.env.VERCEL;
371
406
  const prevEnv = process.env.NODE_ENV;
372
407
  process.env.VERCEL = "1";
373
408
  process.env.NODE_ENV = "production";
374
409
  try {
375
410
  vi.resetModules();
376
- const { McpServer: Reloaded } = await import("./server.js");
377
- const server = new Reloaded({ name: "t", version: "0.0.0" });
378
- const result = await server.run();
411
+ const { Skybridge: Reloaded } = await import("./app.js");
412
+ const app = new Reloaded({ name: "t", version: "0.0.0" }, (server) => server);
413
+ const result = await app.run();
379
414
  expect(typeof result).toBe("function");
380
- expect(result).toBe(server.express);
381
- const { port, server: listening } = await listen(server.express);
415
+ expect(result).toBe(app.express);
416
+ const { port, server: listening } = await listen(app.express);
382
417
  openServer = listening;
383
418
  const res = await postMcp(port);
384
419
  expect(res.status).not.toBe(404);
@@ -413,10 +448,10 @@ describe("createApp tunnel routes", () => {
413
448
  process.env.__TUNNEL_CONTROL_PORT = String(controlPort);
414
449
  try {
415
450
  const { createApp } = await import("./express.js");
416
- const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
451
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server);
417
452
  const httpServer = http.createServer();
418
- const app = await createApp({ mcpServer, httpServer });
419
- const { port, server } = await listen(app);
453
+ const expressApp = await createApp({ app, httpServer });
454
+ const { port, server } = await listen(expressApp);
420
455
  openServer = server;
421
456
  const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
422
457
  method: "POST",
@@ -440,11 +475,11 @@ describe("createApp tunnel routes", () => {
440
475
  try {
441
476
  vi.resetModules();
442
477
  const { createApp } = await import("./express.js");
443
- const { McpServer: ReloadedMcpServer } = await import("./server.js");
444
- const mcpServer = new ReloadedMcpServer({ name: "t", version: "0.0.0" });
478
+ const { Skybridge: ReloadedSkybridge } = await import("./app.js");
479
+ const app = new ReloadedSkybridge({ name: "t", version: "0.0.0" }, (server) => server);
445
480
  const httpServer = http.createServer();
446
- const app = await createApp({ mcpServer, httpServer });
447
- const { port, server } = await listen(app);
481
+ const expressApp = await createApp({ app, httpServer });
482
+ const { port, server } = await listen(expressApp);
448
483
  openServer = server;
449
484
  const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
450
485
  method: "POST",
@@ -457,4 +492,28 @@ describe("createApp tunnel routes", () => {
457
492
  }
458
493
  });
459
494
  });
495
+ describe("createApp mount path", () => {
496
+ it("serves /mcp with the mount path intact on the request URL", async () => {
497
+ const { createApp } = await import("./express.js");
498
+ const app = new Skybridge({ name: "t", version: "0.0.0" }, (server) => server.registerTool({
499
+ name: "echo-url",
500
+ description: "Echoes the request URL.",
501
+ inputSchema: {},
502
+ }, (_args, extra) => ({
503
+ content: [{ type: "text", text: extra.http?.req?.url ?? "" }],
504
+ })));
505
+ const httpServer = http.createServer();
506
+ const expressApp = await createApp({ app, httpServer });
507
+ const { port, server } = await listen(expressApp);
508
+ openServer = server;
509
+ const client = new Client({ name: "test-client", version: "0.0.0" });
510
+ await client.connect(new StreamableHTTPClientTransport(new URL(`http://localhost:${port}/mcp`)));
511
+ const result = (await client.callTool({
512
+ name: "echo-url",
513
+ arguments: {},
514
+ }));
515
+ await client.close();
516
+ expect(new URL(result.content[0]?.text ?? "").pathname).toBe("/mcp");
517
+ });
518
+ });
460
519
  //# sourceMappingURL=express.test.js.map