skybridge 0.0.0-dev.df0cfdd → 0.0.0-dev.df1e961

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 (233) hide show
  1. package/README.md +7 -7
  2. package/dist/cli/build-helpers.d.ts +1 -1
  3. package/dist/cli/build-helpers.js +4 -4
  4. package/dist/cli/build-helpers.js.map +1 -1
  5. package/dist/cli/build-helpers.test.js +2 -2
  6. package/dist/cli/build-helpers.test.js.map +1 -1
  7. package/dist/cli/build-steps.js +1 -1
  8. package/dist/cli/build-steps.js.map +1 -1
  9. package/dist/cli/detect-port.js +0 -1
  10. package/dist/cli/detect-port.js.map +1 -1
  11. package/dist/cli/use-execute-steps.d.ts +1 -1
  12. package/dist/cli/use-nodemon.js +11 -3
  13. package/dist/cli/use-nodemon.js.map +1 -1
  14. package/dist/cli/use-typescript-check.js +1 -1
  15. package/dist/cli/use-typescript-check.js.map +1 -1
  16. package/dist/commands/dev.js +1 -1
  17. package/dist/commands/dev.js.map +1 -1
  18. package/dist/commands/start.js +2 -2
  19. package/dist/commands/start.js.map +1 -1
  20. package/dist/server/app.d.ts +194 -0
  21. package/dist/server/app.js +266 -0
  22. package/dist/server/app.js.map +1 -0
  23. package/dist/server/app.test.js +97 -0
  24. package/dist/server/app.test.js.map +1 -0
  25. package/dist/server/auth/discovery.d.ts +2 -1
  26. package/dist/server/auth/discovery.js +2 -2
  27. package/dist/server/auth/discovery.js.map +1 -1
  28. package/dist/server/auth/index.d.ts +21 -17
  29. package/dist/server/auth/index.js.map +1 -1
  30. package/dist/server/auth/providers/auth0.d.ts +2 -2
  31. package/dist/server/auth/providers/auth0.js +13 -8
  32. package/dist/server/auth/providers/auth0.js.map +1 -1
  33. package/dist/server/auth/providers/auth0.test.js +1 -1
  34. package/dist/server/auth/providers/auth0.test.js.map +1 -1
  35. package/dist/server/auth/providers/authplane.d.ts +2 -2
  36. package/dist/server/auth/providers/authplane.js.map +1 -1
  37. package/dist/server/auth/providers/authplane.test.js +10 -7
  38. package/dist/server/auth/providers/authplane.test.js.map +1 -1
  39. package/dist/server/auth/providers/clerk.d.ts +2 -2
  40. package/dist/server/auth/providers/clerk.js.map +1 -1
  41. package/dist/server/auth/providers/clerk.test.js +1 -1
  42. package/dist/server/auth/providers/clerk.test.js.map +1 -1
  43. package/dist/server/auth/providers/custom.d.ts +4 -4
  44. package/dist/server/auth/providers/custom.js +5 -2
  45. package/dist/server/auth/providers/custom.js.map +1 -1
  46. package/dist/server/auth/providers/custom.test.js +13 -10
  47. package/dist/server/auth/providers/custom.test.js.map +1 -1
  48. package/dist/server/auth/providers/descope.d.ts +2 -2
  49. package/dist/server/auth/providers/descope.js.map +1 -1
  50. package/dist/server/auth/providers/descope.test.js +3 -3
  51. package/dist/server/auth/providers/descope.test.js.map +1 -1
  52. package/dist/server/auth/providers/stytch.d.ts +2 -2
  53. package/dist/server/auth/providers/stytch.js.map +1 -1
  54. package/dist/server/auth/providers/workos.d.ts +2 -2
  55. package/dist/server/auth/providers/workos.js.map +1 -1
  56. package/dist/server/auth/setup.d.ts +1 -1
  57. package/dist/server/auth/setup.js +3 -4
  58. package/dist/server/auth/setup.js.map +1 -1
  59. package/dist/server/auth/setup.test.js +83 -77
  60. package/dist/server/auth/setup.test.js.map +1 -1
  61. package/dist/server/auth/verify.js +2 -2
  62. package/dist/server/auth/verify.js.map +1 -1
  63. package/dist/server/auth-extra.test-d.js +97 -49
  64. package/dist/server/auth-extra.test-d.js.map +1 -1
  65. package/dist/server/auth.d.ts +7 -8
  66. package/dist/server/auth.js +4 -5
  67. package/dist/server/auth.js.map +1 -1
  68. package/dist/server/build-manifest.test.js +7 -6
  69. package/dist/server/build-manifest.test.js.map +1 -1
  70. package/dist/server/content-helpers.d.ts +1 -1
  71. package/dist/server/content-helpers.js.map +1 -1
  72. package/dist/server/express.d.ts +23 -3
  73. package/dist/server/express.js +38 -32
  74. package/dist/server/express.js.map +1 -1
  75. package/dist/server/express.test.js +220 -103
  76. package/dist/server/express.test.js.map +1 -1
  77. package/dist/server/file-ref.d.ts +1 -1
  78. package/dist/server/file-ref.js +1 -1
  79. package/dist/server/file-ref.js.map +1 -1
  80. package/dist/server/index.d.ts +6 -3
  81. package/dist/server/index.js +3 -1
  82. package/dist/server/index.js.map +1 -1
  83. package/dist/server/mcp-errors.test.js +41 -0
  84. package/dist/server/mcp-errors.test.js.map +1 -0
  85. package/dist/server/middleware.d.ts +6 -6
  86. package/dist/server/middleware.js.map +1 -1
  87. package/dist/server/middleware.test-d.js +1 -1
  88. package/dist/server/middleware.test-d.js.map +1 -1
  89. package/dist/server/middleware.test.js +222 -150
  90. package/dist/server/middleware.test.js.map +1 -1
  91. package/dist/server/register-tool.test.d.ts +1 -0
  92. package/dist/server/register-tool.test.js +27 -0
  93. package/dist/server/register-tool.test.js.map +1 -0
  94. package/dist/server/server.d.ts +74 -122
  95. package/dist/server/server.js +101 -302
  96. package/dist/server/server.js.map +1 -1
  97. package/dist/server/skills-integration.test.js +19 -12
  98. package/dist/server/skills-integration.test.js.map +1 -1
  99. package/dist/server/skills.d.ts +3 -5
  100. package/dist/server/skills.js +17 -24
  101. package/dist/server/skills.js.map +1 -1
  102. package/dist/server/skills.test.js +8 -12
  103. package/dist/server/skills.test.js.map +1 -1
  104. package/dist/server/templateHelper.d.ts +0 -3
  105. package/dist/server/templateHelper.js.map +1 -1
  106. package/dist/server/templates.generated.js +4 -8
  107. package/dist/server/templates.generated.js.map +1 -1
  108. package/dist/server/tool-extra.test.d.ts +1 -0
  109. package/dist/server/tool-extra.test.js +88 -0
  110. package/dist/server/tool-extra.test.js.map +1 -0
  111. package/dist/server/view-resource-resolution.test.js +18 -13
  112. package/dist/server/view-resource-resolution.test.js.map +1 -1
  113. package/dist/test/utils.d.ts +9 -11
  114. package/dist/test/utils.js +220 -201
  115. package/dist/test/utils.js.map +1 -1
  116. package/dist/test/view.test.js +25 -37
  117. package/dist/test/view.test.js.map +1 -1
  118. package/dist/views/index.d.ts +10 -0
  119. package/dist/views/index.js +3 -0
  120. package/dist/views/index.js.map +1 -0
  121. package/dist/views/scan-views.d.ts +16 -0
  122. package/dist/views/scan-views.js +88 -0
  123. package/dist/views/scan-views.js.map +1 -0
  124. package/dist/views/scan-views.test.d.ts +1 -0
  125. package/dist/views/scan-views.test.js +99 -0
  126. package/dist/views/scan-views.test.js.map +1 -0
  127. package/dist/views/validate-view.d.ts +1 -0
  128. package/dist/views/validate-view.js +9 -0
  129. package/dist/views/validate-view.js.map +1 -0
  130. package/dist/views/validate-view.test.d.ts +1 -0
  131. package/dist/views/validate-view.test.js +24 -0
  132. package/dist/views/validate-view.test.js.map +1 -0
  133. package/dist/web/bridges/adaptor.test.js +1 -1
  134. package/dist/web/bridges/adaptor.test.js.map +1 -1
  135. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +1 -1
  136. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +1 -1
  137. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  138. package/dist/web/bridges/get-adaptor.test.js +2 -2
  139. package/dist/web/bridges/get-adaptor.test.js.map +1 -1
  140. package/dist/web/bridges/mcp-app/bridge.js +1 -1
  141. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  142. package/dist/web/bridges/mcp-app/bridge.test.js +2 -2
  143. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -1
  144. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +1 -1
  145. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +1 -1
  146. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  147. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -1
  148. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  149. package/dist/web/bridges/mcp-app/view-tools.test.js +1 -1
  150. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -1
  151. package/dist/web/bridges/types.d.ts +17 -12
  152. package/dist/web/bridges/types.js.map +1 -1
  153. package/dist/web/create-store.test.js +2 -2
  154. package/dist/web/create-store.test.js.map +1 -1
  155. package/dist/web/data-llm.test.js +2 -2
  156. package/dist/web/data-llm.test.js.map +1 -1
  157. package/dist/web/generate-helpers.d.ts +22 -18
  158. package/dist/web/generate-helpers.js +19 -15
  159. package/dist/web/generate-helpers.js.map +1 -1
  160. package/dist/web/generate-helpers.test-d.js +3 -3
  161. package/dist/web/generate-helpers.test-d.js.map +1 -1
  162. package/dist/web/generate-helpers.test.js +2 -2
  163. package/dist/web/generate-helpers.test.js.map +1 -1
  164. package/dist/web/hooks/index.d.ts +2 -2
  165. package/dist/web/hooks/index.js +2 -2
  166. package/dist/web/hooks/index.js.map +1 -1
  167. package/dist/web/hooks/use-call-tool.test.js +2 -2
  168. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  169. package/dist/web/hooks/use-display-mode.d.ts +1 -1
  170. package/dist/web/hooks/use-display-mode.js +1 -1
  171. package/dist/web/hooks/use-display-mode.js.map +1 -1
  172. package/dist/web/hooks/use-display-mode.test.js +1 -1
  173. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  174. package/dist/web/hooks/use-download.d.ts +1 -3
  175. package/dist/web/hooks/use-download.js +1 -2
  176. package/dist/web/hooks/use-download.js.map +1 -1
  177. package/dist/web/hooks/use-download.test.js +7 -7
  178. package/dist/web/hooks/use-download.test.js.map +1 -1
  179. package/dist/web/hooks/use-files.test.js +1 -1
  180. package/dist/web/hooks/use-files.test.js.map +1 -1
  181. package/dist/web/hooks/{use-host-info.d.ts → use-host.d.ts} +2 -2
  182. package/dist/web/hooks/{use-host-info.js → use-host.js} +3 -3
  183. package/dist/web/hooks/use-host.js.map +1 -0
  184. package/dist/web/hooks/use-host.test.d.ts +1 -0
  185. package/dist/web/hooks/{use-host-info.test.js → use-host.test.js} +7 -7
  186. package/dist/web/hooks/use-host.test.js.map +1 -0
  187. package/dist/web/hooks/use-open-external.test.js +2 -2
  188. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  189. package/dist/web/hooks/use-register-view-tool.d.ts +2 -3
  190. package/dist/web/hooks/use-register-view-tool.js.map +1 -1
  191. package/dist/web/hooks/use-request-close.test.js +1 -1
  192. package/dist/web/hooks/use-request-close.test.js.map +1 -1
  193. package/dist/web/hooks/use-request-modal.test.js +1 -1
  194. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  195. package/dist/web/hooks/use-request-size.d.ts +1 -1
  196. package/dist/web/hooks/use-request-size.js +1 -1
  197. package/dist/web/hooks/use-request-size.js.map +1 -1
  198. package/dist/web/hooks/use-request-size.test.js +1 -1
  199. package/dist/web/hooks/use-request-size.test.js.map +1 -1
  200. package/dist/web/hooks/use-set-open-in-app-url.test.js +2 -8
  201. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  202. package/dist/web/hooks/use-tool-info.d.ts +1 -20
  203. package/dist/web/hooks/use-tool-info.js +0 -1
  204. package/dist/web/hooks/use-tool-info.js.map +1 -1
  205. package/dist/web/hooks/use-tool-info.test-d.js +0 -5
  206. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  207. package/dist/web/hooks/use-tool-info.test.js +2 -7
  208. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  209. package/dist/web/hooks/use-user.d.ts +3 -2
  210. package/dist/web/hooks/use-user.js +4 -3
  211. package/dist/web/hooks/use-user.js.map +1 -1
  212. package/dist/web/hooks/use-user.test.js +5 -3
  213. package/dist/web/hooks/use-user.test.js.map +1 -1
  214. package/dist/web/hooks/use-view-state.test.js +2 -2
  215. package/dist/web/hooks/use-view-state.test.js.map +1 -1
  216. package/dist/web/hooks/use-viewport.d.ts +20 -0
  217. package/dist/web/hooks/use-viewport.js +21 -0
  218. package/dist/web/hooks/use-viewport.js.map +1 -0
  219. package/dist/web/hooks/use-viewport.test.d.ts +1 -0
  220. package/dist/web/hooks/{use-layout.test.js → use-viewport.test.js} +12 -32
  221. package/dist/web/hooks/use-viewport.test.js.map +1 -0
  222. package/dist/web/mount-view.d.ts +3 -2
  223. package/dist/web/mount-view.js +5 -8
  224. package/dist/web/mount-view.js.map +1 -1
  225. package/package.json +15 -8
  226. package/dist/web/hooks/use-host-info.js.map +0 -1
  227. package/dist/web/hooks/use-host-info.test.js.map +0 -1
  228. package/dist/web/hooks/use-layout.d.ts +0 -24
  229. package/dist/web/hooks/use-layout.js +0 -25
  230. package/dist/web/hooks/use-layout.js.map +0 -1
  231. package/dist/web/hooks/use-layout.test.js.map +0 -1
  232. /package/dist/{web/hooks/use-host-info.test.d.ts → server/app.test.d.ts} +0 -0
  233. /package/dist/{web/hooks/use-layout.test.d.ts → server/mcp-errors.test.d.ts} +0 -0
@@ -1 +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"]}
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,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AAC3D,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,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,QAAQ,GAAG;YACf,qBAAqB,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE;SAC5D,CAAC;QACF,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAE7B,UAAU,EAAE,CAAC;QACb,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrD,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({ name: \"test\", version: \"0.0.1\" });\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(\"keeps priming every McpServer the app factory builds per request\", () => {\n const manifest = {\n \"src/views/index.tsx\": { file: \"assets/index-CAFEBABE.js\" },\n };\n __setBuildManifest(manifest);\n\n makeServer();\n expect(manifestOf(makeServer())).toEqual(manifest);\n });\n});\n"]}
@@ -1,4 +1,4 @@
1
- import type { AudioContent, EmbeddedResource, ImageContent, ResourceLink, TextContent } from "@modelcontextprotocol/sdk/types.js";
1
+ import type { AudioContent, EmbeddedResource, ImageContent, ResourceLink, TextContent } from "@modelcontextprotocol/server";
2
2
  /**
3
3
  * MCP content annotations applied to any returned block.
4
4
  *
@@ -1 +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"]}
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/server\";\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"]}
@@ -1,11 +1,31 @@
1
1
  import type http from "node:http";
2
+ import { type McpHttpHandler } from "@modelcontextprotocol/server";
2
3
  import express from "express";
3
- import type { McpServer } from "./server.js";
4
- export declare function createApp({ mcpServer, httpServer, errorMiddleware, }: {
5
- mcpServer: McpServer;
4
+ import type { Skybridge } from "./app.js";
5
+ import type { JsonOptions } from "./server.js";
6
+ type SkybridgeApp = Pick<Skybridge, "express" | "createServerInstance" | "ready">;
7
+ /**
8
+ * The `/mcp` fetch handler for a {@link Skybridge} app: a `Request` →
9
+ * `Response` function that builds a fresh MCP server per request.
10
+ *
11
+ * @internal
12
+ */
13
+ export declare function buildMcpHandler(skybridgeApp: SkybridgeApp): McpHttpHandler;
14
+ /**
15
+ * Build the bare Express app a {@link Skybridge} instance owns: the instance
16
+ * plus the built-in `express.json()` body parser, tuned by the `json` config
17
+ * field.
18
+ *
19
+ * @internal
20
+ */
21
+ export declare function createBaseApp(json?: JsonOptions): express.Express;
22
+ export declare function createApp({ app: skybridgeApp, httpServer, mcpHandler, errorMiddleware, }: {
23
+ app: SkybridgeApp;
6
24
  httpServer: http.Server;
25
+ mcpHandler?: McpHttpHandler;
7
26
  errorMiddleware?: {
8
27
  path?: string;
9
28
  handlers: express.ErrorRequestHandler[];
10
29
  }[];
11
30
  }): Promise<express.Express>;
31
+ export {};
@@ -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,9 @@ 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
+ await skybridgeApp.ready();
66
+ const app = skybridgeApp.express;
37
67
  // Read `process.env.NODE_ENV` inline: wrangler/esbuild only substitute the literal expression,
38
68
  // so a local const would defeat dead-code elimination of the dev-only imports below.
39
69
  if (process.env.NODE_ENV !== "production") {
@@ -55,43 +85,19 @@ export async function createApp({ mcpServer, httpServer, errorMiddleware = [], }
55
85
  app.use("/assets", cors());
56
86
  app.use("/assets", express.static(assetsPath));
57
87
  }
58
- app.use("/mcp", mcpMiddleware(mcpServer));
88
+ app.use("/mcp", mcpMiddleware(mcpHandler ?? buildMcpHandler(skybridgeApp)));
59
89
  applyMiddlewares(app, errorMiddleware);
60
90
  app.use("/mcp", defaultErrorHandler);
61
91
  return app;
62
92
  }
63
- const mcpMiddleware = (server) => {
93
+ const mcpMiddleware = (mcpHandler) => {
94
+ const handler = toNodeHandler(mcpHandler);
64
95
  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
96
  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
97
  // Express strips the mount path from req.url (e.g. "/mcp" becomes "/").
92
- // Restore it so the SDK builds the correct requestInfo.url.
98
+ // Restore it so the SDK builds the correct request URL.
93
99
  req.url = req.originalUrl;
94
- await transport.handleRequest(req, res, req.body);
100
+ await handler(req, res, req.body);
95
101
  }
96
102
  catch (error) {
97
103
  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<\n Skybridge,\n \"express\" | \"createServerInstance\" | \"ready\"\n>;\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 await skybridgeApp.ready();\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"]}