skybridge 0.0.0-dev.c6d614a → 0.0.0-dev.c6ddc9f
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.
- package/README.md +126 -124
- package/dist/cli/build-helpers.d.ts +11 -0
- package/dist/cli/build-helpers.js +107 -0
- package/dist/cli/build-helpers.js.map +1 -0
- package/dist/cli/build-helpers.test.js +132 -0
- package/dist/cli/build-helpers.test.js.map +1 -0
- package/dist/cli/build-steps.d.ts +2 -0
- package/dist/cli/build-steps.js +73 -0
- package/dist/cli/build-steps.js.map +1 -0
- package/dist/cli/build-steps.test.js +52 -0
- package/dist/cli/build-steps.test.js.map +1 -0
- package/dist/cli/detect-port.d.ts +2 -2
- package/dist/cli/detect-port.js +9 -20
- package/dist/cli/detect-port.js.map +1 -1
- package/dist/cli/header.d.ts +1 -1
- package/dist/cli/header.js.map +1 -1
- package/dist/cli/resolve-skybridge-config.d.ts +5 -0
- package/dist/cli/resolve-skybridge-config.js +18 -0
- package/dist/cli/resolve-skybridge-config.js.map +1 -0
- package/dist/cli/run-command.js.map +1 -1
- package/dist/cli/run-plain.d.ts +18 -0
- package/dist/cli/run-plain.js +89 -0
- package/dist/cli/run-plain.js.map +1 -0
- package/dist/cli/telemetry.js.map +1 -1
- package/dist/cli/tunnel-control-server.d.ts +9 -0
- package/dist/cli/tunnel-control-server.js +31 -0
- package/dist/cli/tunnel-control-server.js.map +1 -0
- package/dist/cli/tunnel-control-server.test.js +39 -0
- package/dist/cli/tunnel-control-server.test.js.map +1 -0
- package/dist/cli/tunnel-handler.d.ts +3 -0
- package/dist/cli/tunnel-handler.js +48 -0
- package/dist/cli/tunnel-handler.js.map +1 -0
- package/dist/cli/tunnel-handler.test.js +105 -0
- package/dist/cli/tunnel-handler.test.js.map +1 -0
- package/dist/cli/tunnel.d.ts +57 -0
- package/dist/cli/tunnel.js +154 -0
- package/dist/cli/tunnel.js.map +1 -0
- package/dist/cli/tunnel.test.js +190 -0
- package/dist/cli/tunnel.test.js.map +1 -0
- package/dist/cli/types.js.map +1 -1
- package/dist/cli/use-execute-steps.d.ts +1 -1
- package/dist/cli/use-execute-steps.js.map +1 -1
- package/dist/cli/use-messages.js.map +1 -1
- package/dist/cli/use-nodemon.d.ts +14 -0
- package/dist/cli/use-nodemon.js +72 -52
- package/dist/cli/use-nodemon.js.map +1 -1
- package/dist/cli/use-open-browser.d.ts +1 -0
- package/dist/cli/use-open-browser.js +44 -0
- package/dist/cli/use-open-browser.js.map +1 -0
- package/dist/cli/use-tunnel.d.ts +1 -1
- package/dist/cli/use-tunnel.js +102 -68
- package/dist/cli/use-tunnel.js.map +1 -1
- package/dist/cli/use-typescript-check.d.ts +9 -2
- package/dist/cli/use-typescript-check.js +89 -51
- package/dist/cli/use-typescript-check.js.map +1 -1
- package/dist/commands/build.d.ts +0 -3
- package/dist/commands/build.js +3 -18
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/create.d.ts +9 -0
- package/dist/commands/create.js +30 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dev.d.ts +2 -0
- package/dist/commands/dev.js +81 -2
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/start.js +8 -7
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/telemetry/disable.js.map +1 -1
- package/dist/commands/telemetry/enable.js.map +1 -1
- package/dist/commands/telemetry/status.js.map +1 -1
- package/dist/context-warnings.d.ts +5 -0
- package/dist/context-warnings.js +31 -0
- package/dist/context-warnings.js.map +1 -0
- package/dist/context-warnings.test.js +28 -0
- package/dist/context-warnings.test.js.map +1 -0
- package/dist/server/asset-base-url-transform-plugin.d.ts +1 -0
- package/dist/server/asset-base-url-transform-plugin.js +17 -2
- package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
- package/dist/server/asset-base-url-transform-plugin.test.js +80 -1
- package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
- package/dist/server/auth/discovery.d.ts +33 -0
- package/dist/server/auth/discovery.js +56 -0
- package/dist/server/auth/discovery.js.map +1 -0
- package/dist/server/auth/discovery.test.d.ts +1 -0
- package/dist/server/auth/discovery.test.js +93 -0
- package/dist/server/auth/discovery.test.js.map +1 -0
- package/dist/server/auth/index.d.ts +30 -0
- package/dist/server/auth/index.js +2 -0
- package/dist/server/auth/index.js.map +1 -0
- package/dist/server/auth/providers/auth0.d.ts +40 -0
- package/dist/server/auth/providers/auth0.js +31 -0
- package/dist/server/auth/providers/auth0.js.map +1 -0
- package/dist/server/auth/providers/auth0.test.d.ts +1 -0
- package/dist/server/auth/providers/auth0.test.js +50 -0
- package/dist/server/auth/providers/auth0.test.js.map +1 -0
- package/dist/server/auth/providers/authplane.d.ts +49 -0
- package/dist/server/auth/providers/authplane.js +57 -0
- package/dist/server/auth/providers/authplane.js.map +1 -0
- package/dist/server/auth/providers/authplane.test.d.ts +1 -0
- package/dist/server/auth/providers/authplane.test.js +140 -0
- package/dist/server/auth/providers/authplane.test.js.map +1 -0
- package/dist/server/auth/providers/clerk.d.ts +51 -0
- package/dist/server/auth/providers/clerk.js +19 -0
- package/dist/server/auth/providers/clerk.js.map +1 -0
- package/dist/server/auth/providers/clerk.test.d.ts +1 -0
- package/dist/server/auth/providers/clerk.test.js +30 -0
- package/dist/server/auth/providers/clerk.test.js.map +1 -0
- package/dist/server/auth/providers/custom.d.ts +40 -0
- package/dist/server/auth/providers/custom.js +56 -0
- package/dist/server/auth/providers/custom.js.map +1 -0
- package/dist/server/auth/providers/custom.test.d.ts +1 -0
- package/dist/server/auth/providers/custom.test.js +158 -0
- package/dist/server/auth/providers/custom.test.js.map +1 -0
- package/dist/server/auth/providers/descope.d.ts +44 -0
- package/dist/server/auth/providers/descope.js +44 -0
- package/dist/server/auth/providers/descope.js.map +1 -0
- package/dist/server/auth/providers/descope.test.d.ts +1 -0
- package/dist/server/auth/providers/descope.test.js +62 -0
- package/dist/server/auth/providers/descope.test.js.map +1 -0
- package/dist/server/auth/providers/shared.d.ts +2 -0
- package/dist/server/auth/providers/shared.js +6 -0
- package/dist/server/auth/providers/shared.js.map +1 -0
- package/dist/server/auth/providers/shared.test.d.ts +1 -0
- package/dist/server/auth/providers/shared.test.js +10 -0
- package/dist/server/auth/providers/shared.test.js.map +1 -0
- package/dist/server/auth/providers/stytch.d.ts +25 -0
- package/dist/server/auth/providers/stytch.js +16 -0
- package/dist/server/auth/providers/stytch.js.map +1 -0
- package/dist/server/auth/providers/verify-spy.d.ts +12 -0
- package/dist/server/auth/providers/verify-spy.js +21 -0
- package/dist/server/auth/providers/verify-spy.js.map +1 -0
- package/dist/server/auth/providers/workos.d.ts +33 -0
- package/dist/server/auth/providers/workos.js +15 -0
- package/dist/server/auth/providers/workos.js.map +1 -0
- package/dist/server/auth/security-schemes.d.ts +23 -0
- package/dist/server/auth/security-schemes.js +64 -0
- package/dist/server/auth/security-schemes.js.map +1 -0
- package/dist/server/auth/security-schemes.test.d.ts +1 -0
- package/dist/server/auth/security-schemes.test.js +99 -0
- package/dist/server/auth/security-schemes.test.js.map +1 -0
- package/dist/server/auth/setup.d.ts +6 -0
- package/dist/server/auth/setup.js +91 -0
- package/dist/server/auth/setup.js.map +1 -0
- package/dist/server/auth/setup.test.d.ts +1 -0
- package/dist/server/auth/setup.test.js +498 -0
- package/dist/server/auth/setup.test.js.map +1 -0
- package/dist/server/auth/verify.d.ts +46 -0
- package/dist/server/auth/verify.js +62 -0
- package/dist/server/auth/verify.js.map +1 -0
- package/dist/server/auth/verify.test.d.ts +1 -0
- package/dist/server/auth/verify.test.js +149 -0
- package/dist/server/auth/verify.test.js.map +1 -0
- package/dist/server/auth-extra.test-d.d.ts +1 -0
- package/dist/server/auth-extra.test-d.js +71 -0
- package/dist/server/auth-extra.test-d.js.map +1 -0
- package/dist/server/auth.d.ts +57 -0
- package/dist/server/auth.js +27 -0
- package/dist/server/auth.js.map +1 -0
- package/dist/server/build-manifest.test.d.ts +1 -0
- package/dist/server/build-manifest.test.js +27 -0
- package/dist/server/build-manifest.test.js.map +1 -0
- package/dist/server/content-helpers.d.ts +67 -0
- package/dist/server/content-helpers.js +79 -0
- package/dist/server/content-helpers.js.map +1 -0
- package/dist/server/content-helpers.test.d.ts +1 -0
- package/dist/server/content-helpers.test.js +70 -0
- package/dist/server/content-helpers.test.js.map +1 -0
- package/dist/server/express.d.ts +1 -5
- package/dist/server/express.js +35 -30
- package/dist/server/express.js.map +1 -1
- package/dist/server/express.test.js +345 -71
- package/dist/server/express.test.js.map +1 -1
- package/dist/server/file-ref.d.ts +28 -0
- package/dist/server/file-ref.js +27 -0
- package/dist/server/file-ref.js.map +1 -0
- package/dist/server/host.d.ts +2 -0
- package/dist/server/host.js +11 -0
- package/dist/server/host.js.map +1 -0
- package/dist/server/host.test.d.ts +1 -0
- package/dist/server/host.test.js +13 -0
- package/dist/server/host.test.js.map +1 -0
- package/dist/server/index.d.ts +18 -3
- package/dist/server/index.js +15 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/inferUtilityTypes.d.ts +6 -6
- package/dist/server/inferUtilityTypes.js.map +1 -1
- package/dist/server/mcp-errors.test.d.ts +1 -0
- package/dist/server/mcp-errors.test.js +37 -0
- package/dist/server/mcp-errors.test.js.map +1 -0
- package/dist/server/metric.js.map +1 -1
- package/dist/server/middleware.d.ts +51 -13
- package/dist/server/middleware.js +33 -0
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/middleware.test-d.js +1 -1
- package/dist/server/middleware.test-d.js.map +1 -1
- package/dist/server/middleware.test.js +50 -12
- package/dist/server/middleware.test.js.map +1 -1
- package/dist/server/register-tool.test.d.ts +1 -0
- package/dist/server/register-tool.test.js +25 -0
- package/dist/server/register-tool.test.js.map +1 -0
- package/dist/server/requestOrigin.d.ts +7 -0
- package/dist/server/requestOrigin.js +25 -0
- package/dist/server/requestOrigin.js.map +1 -0
- package/dist/server/server.d.ts +427 -83
- package/dist/server/server.js +655 -181
- package/dist/server/server.js.map +1 -1
- package/dist/server/skills-integration.test.d.ts +1 -0
- package/dist/server/skills-integration.test.js +79 -0
- package/dist/server/skills-integration.test.js.map +1 -0
- package/dist/server/skills.d.ts +27 -0
- package/dist/server/skills.js +188 -0
- package/dist/server/skills.js.map +1 -0
- package/dist/server/skills.test.d.ts +1 -0
- package/dist/server/skills.test.js +243 -0
- package/dist/server/skills.test.js.map +1 -0
- package/dist/server/templateHelper.d.ts +5 -7
- package/dist/server/templateHelper.js +3 -22
- package/dist/server/templateHelper.js.map +1 -1
- package/dist/server/templates.generated.d.ts +4 -0
- package/dist/server/templates.generated.js +47 -0
- package/dist/server/templates.generated.js.map +1 -0
- package/dist/server/tool-extra.test.d.ts +1 -0
- package/dist/server/tool-extra.test.js +72 -0
- package/dist/server/tool-extra.test.js.map +1 -0
- package/dist/server/tunnel-proxy-router.d.ts +7 -0
- package/dist/server/tunnel-proxy-router.js +110 -0
- package/dist/server/tunnel-proxy-router.js.map +1 -0
- package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
- package/dist/server/tunnel-proxy-router.test.js +229 -0
- package/dist/server/tunnel-proxy-router.test.js.map +1 -0
- package/dist/server/view-name.test-d.d.ts +1 -0
- package/dist/server/view-name.test-d.js +8 -0
- package/dist/server/view-name.test-d.js.map +1 -0
- package/dist/server/view-resource-resolution.test.d.ts +6 -0
- package/dist/server/view-resource-resolution.test.js +169 -0
- package/dist/server/view-resource-resolution.test.js.map +1 -0
- package/dist/server/viewsDevServer.d.ts +14 -0
- package/dist/server/viewsDevServer.js +48 -0
- package/dist/server/viewsDevServer.js.map +1 -0
- package/dist/standard-schema.d.ts +3 -0
- package/dist/standard-schema.js +2 -0
- package/dist/standard-schema.js.map +1 -0
- package/dist/test/utils.d.ts +13 -28
- package/dist/test/utils.js +46 -38
- package/dist/test/utils.js.map +1 -1
- package/dist/test/view.test.d.ts +1 -0
- package/dist/test/view.test.js +536 -0
- package/dist/test/view.test.js.map +1 -0
- package/dist/version.js +1 -3
- package/dist/version.js.map +1 -1
- package/dist/views/index.d.ts +3 -0
- package/dist/views/index.js +3 -0
- package/dist/views/index.js.map +1 -0
- package/dist/views/scan-views.d.ts +16 -0
- package/dist/views/scan-views.js +88 -0
- package/dist/views/scan-views.js.map +1 -0
- package/dist/views/scan-views.test.d.ts +1 -0
- package/dist/views/scan-views.test.js +99 -0
- package/dist/views/scan-views.test.js.map +1 -0
- package/dist/views/validate-view.d.ts +1 -0
- package/dist/views/validate-view.js +9 -0
- package/dist/views/validate-view.js.map +1 -0
- package/dist/views/validate-view.test.d.ts +1 -0
- package/dist/views/validate-view.test.js +24 -0
- package/dist/views/validate-view.test.js.map +1 -0
- package/dist/web/bridges/adaptor.d.ts +51 -0
- package/dist/web/bridges/adaptor.js +327 -0
- package/dist/web/bridges/adaptor.js.map +1 -0
- package/dist/web/bridges/adaptor.test.d.ts +1 -0
- package/dist/web/bridges/adaptor.test.js +225 -0
- package/dist/web/bridges/adaptor.test.js.map +1 -0
- package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -1
- package/dist/web/bridges/apps-sdk/bridge.js +15 -3
- package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
- package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
- package/dist/web/bridges/apps-sdk/index.js +0 -1
- package/dist/web/bridges/apps-sdk/index.js.map +1 -1
- package/dist/web/bridges/apps-sdk/types.d.ts +8 -1
- package/dist/web/bridges/apps-sdk/types.js.map +1 -1
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +11 -0
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +11 -0
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
- package/dist/web/bridges/get-adaptor.d.ts +7 -0
- package/dist/web/bridges/get-adaptor.js +9 -7
- package/dist/web/bridges/get-adaptor.js.map +1 -1
- package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
- package/dist/web/bridges/get-adaptor.test.js +32 -0
- package/dist/web/bridges/get-adaptor.test.js.map +1 -0
- package/dist/web/bridges/index.js.map +1 -1
- package/dist/web/bridges/mcp-app/bridge.d.ts +15 -2
- package/dist/web/bridges/mcp-app/bridge.js +73 -7
- package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
- package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
- package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
- package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
- package/dist/web/bridges/mcp-app/index.d.ts +0 -1
- package/dist/web/bridges/mcp-app/index.js +0 -1
- package/dist/web/bridges/mcp-app/index.js.map +1 -1
- package/dist/web/bridges/mcp-app/types.d.ts +2 -0
- package/dist/web/bridges/mcp-app/types.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +12 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js +12 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
- package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
- package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
- package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
- package/dist/web/bridges/types.d.ts +123 -10
- package/dist/web/bridges/types.js +14 -1
- package/dist/web/bridges/types.js.map +1 -1
- package/dist/web/bridges/types.test.d.ts +1 -0
- package/dist/web/bridges/types.test.js +19 -0
- package/dist/web/bridges/types.test.js.map +1 -0
- package/dist/web/bridges/use-host-context.d.ts +5 -0
- package/dist/web/bridges/use-host-context.js +5 -0
- package/dist/web/bridges/use-host-context.js.map +1 -1
- package/dist/web/components/modal-provider.d.ts +1 -1
- package/dist/web/components/modal-provider.js +4 -3
- package/dist/web/components/modal-provider.js.map +1 -1
- package/dist/web/create-store.d.ts +26 -0
- package/dist/web/create-store.js +35 -9
- package/dist/web/create-store.js.map +1 -1
- package/dist/web/create-store.test.js +23 -22
- package/dist/web/create-store.test.js.map +1 -1
- package/dist/web/data-llm.d.ts +35 -2
- package/dist/web/data-llm.js +31 -3
- package/dist/web/data-llm.js.map +1 -1
- package/dist/web/data-llm.test.js +41 -28
- package/dist/web/data-llm.test.js.map +1 -1
- package/dist/web/generate-helpers.d.ts +22 -18
- package/dist/web/generate-helpers.js +22 -18
- package/dist/web/generate-helpers.js.map +1 -1
- package/dist/web/generate-helpers.test-d.js +30 -28
- package/dist/web/generate-helpers.test-d.js.map +1 -1
- package/dist/web/generate-helpers.test.js.map +1 -1
- package/dist/web/helpers/state.d.ts +2 -2
- package/dist/web/helpers/state.js +11 -11
- package/dist/web/helpers/state.js.map +1 -1
- package/dist/web/helpers/state.test.js +9 -9
- package/dist/web/helpers/state.test.js.map +1 -1
- package/dist/web/hooks/index.d.ts +7 -2
- package/dist/web/hooks/index.js +7 -2
- package/dist/web/hooks/index.js.map +1 -1
- package/dist/web/hooks/test/utils.d.ts +7 -2
- package/dist/web/hooks/test/utils.js +14 -3
- package/dist/web/hooks/test/utils.js.map +1 -1
- package/dist/web/hooks/use-call-tool.d.ts +45 -0
- package/dist/web/hooks/use-call-tool.js +28 -0
- package/dist/web/hooks/use-call-tool.js.map +1 -1
- package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
- package/dist/web/hooks/use-call-tool.test.js +64 -29
- package/dist/web/hooks/use-call-tool.test.js.map +1 -1
- package/dist/web/hooks/use-display-mode.d.ts +20 -0
- package/dist/web/hooks/use-display-mode.js +20 -0
- package/dist/web/hooks/use-display-mode.js.map +1 -1
- package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
- package/dist/web/hooks/use-display-mode.test.js +57 -21
- package/dist/web/hooks/use-display-mode.test.js.map +1 -1
- package/dist/web/hooks/use-download.d.ts +3 -0
- package/dist/web/hooks/use-download.js +7 -0
- package/dist/web/hooks/use-download.js.map +1 -0
- package/dist/web/hooks/use-download.test.d.ts +1 -0
- package/dist/web/hooks/use-download.test.js +103 -0
- package/dist/web/hooks/use-download.test.js.map +1 -0
- package/dist/web/hooks/use-files.d.ts +32 -0
- package/dist/web/hooks/use-files.js +32 -0
- package/dist/web/hooks/use-files.js.map +1 -1
- package/dist/web/hooks/use-files.test.js +11 -3
- package/dist/web/hooks/use-files.test.js.map +1 -1
- package/dist/web/hooks/use-host.d.ts +22 -0
- package/dist/web/hooks/use-host.js +30 -0
- package/dist/web/hooks/use-host.js.map +1 -0
- package/dist/web/hooks/use-host.test.d.ts +1 -0
- package/dist/web/hooks/use-host.test.js +59 -0
- package/dist/web/hooks/use-host.test.js.map +1 -0
- package/dist/web/hooks/use-open-external.d.ts +17 -0
- package/dist/web/hooks/use-open-external.js +16 -0
- package/dist/web/hooks/use-open-external.js.map +1 -1
- package/dist/web/hooks/use-open-external.test.js +14 -4
- package/dist/web/hooks/use-open-external.test.js.map +1 -1
- package/dist/web/hooks/use-register-view-tool.d.ts +37 -0
- package/dist/web/hooks/use-register-view-tool.js +50 -0
- package/dist/web/hooks/use-register-view-tool.js.map +1 -0
- package/dist/web/hooks/use-request-close.d.ts +16 -0
- package/dist/web/hooks/use-request-close.js +21 -0
- package/dist/web/hooks/use-request-close.js.map +1 -0
- package/dist/web/hooks/use-request-close.test.d.ts +1 -0
- package/dist/web/hooks/use-request-close.test.js +47 -0
- package/dist/web/hooks/use-request-close.test.js.map +1 -0
- package/dist/web/hooks/use-request-modal.d.ts +16 -1
- package/dist/web/hooks/use-request-modal.js +19 -4
- package/dist/web/hooks/use-request-modal.js.map +1 -1
- package/dist/web/hooks/use-request-modal.test.js +12 -2
- package/dist/web/hooks/use-request-modal.test.js.map +1 -1
- package/dist/web/hooks/use-request-size.d.ts +20 -0
- package/dist/web/hooks/use-request-size.js +24 -0
- package/dist/web/hooks/use-request-size.js.map +1 -0
- package/dist/web/hooks/use-request-size.test.d.ts +1 -0
- package/dist/web/hooks/use-request-size.test.js +47 -0
- package/dist/web/hooks/use-request-size.test.js.map +1 -0
- package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -1
- package/dist/web/hooks/use-send-follow-up-message.js +19 -2
- package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
- package/dist/web/hooks/use-set-open-in-app-url.d.ts +17 -0
- package/dist/web/hooks/use-set-open-in-app-url.js +17 -0
- package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
- package/dist/web/hooks/use-set-open-in-app-url.test.js +29 -9
- package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
- package/dist/web/hooks/use-tool-info.d.ts +46 -14
- package/dist/web/hooks/use-tool-info.js +29 -7
- package/dist/web/hooks/use-tool-info.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test-d.js +11 -34
- package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test.js +41 -36
- package/dist/web/hooks/use-tool-info.test.js.map +1 -1
- package/dist/web/hooks/use-user.d.ts +5 -2
- package/dist/web/hooks/use-user.js +6 -3
- package/dist/web/hooks/use-user.js.map +1 -1
- package/dist/web/hooks/use-user.test.js +84 -36
- package/dist/web/hooks/use-user.test.js.map +1 -1
- package/dist/web/hooks/use-view-state.d.ts +25 -0
- package/dist/web/hooks/use-view-state.js +42 -0
- package/dist/web/hooks/use-view-state.js.map +1 -0
- package/dist/web/hooks/use-view-state.test.d.ts +1 -0
- package/dist/web/hooks/{use-widget-state.test.js → use-view-state.test.js} +55 -20
- package/dist/web/hooks/use-view-state.test.js.map +1 -0
- package/dist/web/hooks/use-viewport.d.ts +20 -0
- package/dist/web/hooks/use-viewport.js +21 -0
- package/dist/web/hooks/use-viewport.js.map +1 -0
- package/dist/web/hooks/use-viewport.test.d.ts +1 -0
- package/dist/web/hooks/use-viewport.test.js +109 -0
- package/dist/web/hooks/use-viewport.test.js.map +1 -0
- package/dist/web/index.d.ts +2 -2
- package/dist/web/index.js +1 -2
- package/dist/web/index.js.map +1 -1
- package/dist/web/mount-view.d.ts +21 -0
- package/dist/web/{mount-widget.js → mount-view.js} +22 -2
- package/dist/web/mount-view.js.map +1 -0
- package/dist/web/proxy.js.map +1 -1
- package/dist/web/types.d.ts +4 -0
- package/dist/web/types.js.map +1 -1
- package/package.json +45 -26
- package/tsconfig.base.json +2 -0
- package/dist/server/templates/development.hbs +0 -12
- package/dist/server/templates/production.hbs +0 -6
- package/dist/server/widgetsDevServer.d.ts +0 -13
- package/dist/server/widgetsDevServer.js +0 -52
- package/dist/server/widgetsDevServer.js.map +0 -1
- package/dist/test/widget.test.js +0 -334
- package/dist/test/widget.test.js.map +0 -1
- package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -24
- package/dist/web/bridges/apps-sdk/adaptor.js +0 -87
- package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
- package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -48
- package/dist/web/bridges/mcp-app/adaptor.js +0 -268
- package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
- package/dist/web/hooks/use-layout.d.ts +0 -22
- package/dist/web/hooks/use-layout.js +0 -23
- package/dist/web/hooks/use-layout.js.map +0 -1
- package/dist/web/hooks/use-layout.test.js +0 -96
- package/dist/web/hooks/use-layout.test.js.map +0 -1
- package/dist/web/hooks/use-widget-state.d.ts +0 -4
- package/dist/web/hooks/use-widget-state.js +0 -32
- package/dist/web/hooks/use-widget-state.js.map +0 -1
- package/dist/web/hooks/use-widget-state.test.js.map +0 -1
- package/dist/web/mount-widget.d.ts +0 -1
- package/dist/web/mount-widget.js.map +0 -1
- package/dist/web/plugin/data-llm.test.js +0 -81
- package/dist/web/plugin/data-llm.test.js.map +0 -1
- package/dist/web/plugin/plugin.d.ts +0 -2
- package/dist/web/plugin/plugin.js +0 -54
- package/dist/web/plugin/plugin.js.map +0 -1
- package/dist/web/plugin/transform-data-llm.d.ts +0 -12
- package/dist/web/plugin/transform-data-llm.js +0 -96
- package/dist/web/plugin/transform-data-llm.js.map +0 -1
- package/dist/web/plugin/transform-data-llm.test.js +0 -81
- package/dist/web/plugin/transform-data-llm.test.js.map +0 -1
- package/dist/web/plugin/validate-widget.d.ts +0 -5
- package/dist/web/plugin/validate-widget.js +0 -27
- package/dist/web/plugin/validate-widget.js.map +0 -1
- package/dist/web/plugin/validate-widget.test.js +0 -42
- package/dist/web/plugin/validate-widget.test.js.map +0 -1
- /package/dist/{test/widget.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
- /package/dist/{web/hooks/use-layout.test.d.ts → cli/build-steps.test.d.ts} +0 -0
- /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
- /package/dist/{web/plugin/data-llm.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
- /package/dist/{web/plugin/transform-data-llm.test.d.ts → cli/tunnel.test.d.ts} +0 -0
- /package/dist/{web/plugin/validate-widget.test.d.ts → context-warnings.test.d.ts} +0 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import http from "node:http";
|
|
2
|
+
import { Client, StreamableHTTPClientTransport, } from "@modelcontextprotocol/client";
|
|
2
3
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { McpServer } from "./server.js";
|
|
3
5
|
vi.mock("@skybridge/devtools", () => ({
|
|
4
6
|
devtoolsStaticServer: () => ((_req, _res, next) => next()),
|
|
5
7
|
}));
|
|
6
|
-
vi.mock("./
|
|
7
|
-
|
|
8
|
+
vi.mock("./viewsDevServer.js", () => ({
|
|
9
|
+
viewsDevServer: (_httpServer) => ((_req, _res, next) => next()),
|
|
8
10
|
}));
|
|
9
|
-
const fakeServer = {};
|
|
10
11
|
async function listen(app) {
|
|
11
12
|
const server = http.createServer(app);
|
|
12
13
|
await new Promise((resolve) => server.listen(0, resolve));
|
|
@@ -25,6 +26,127 @@ async function postMcp(port) {
|
|
|
25
26
|
async function postApi(port) {
|
|
26
27
|
return fetch(`http://localhost:${port}/api/test`, { method: "POST" });
|
|
27
28
|
}
|
|
29
|
+
describe("McpServer.express", () => {
|
|
30
|
+
it("exposes a ready Express app immediately after construction", () => {
|
|
31
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
32
|
+
expect(server.express).toBeDefined();
|
|
33
|
+
expect(typeof server.express.use).toBe("function");
|
|
34
|
+
expect(typeof server.express.get).toBe("function");
|
|
35
|
+
});
|
|
36
|
+
it("server.express.get registers a route reachable alongside /mcp", async () => {
|
|
37
|
+
const { createApp } = await import("./express.js");
|
|
38
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
39
|
+
server.express.get("/health", (_req, res) => {
|
|
40
|
+
res.json({ status: "ok" });
|
|
41
|
+
});
|
|
42
|
+
const httpServer = http.createServer();
|
|
43
|
+
await createApp({ mcpServer: server, httpServer });
|
|
44
|
+
const { port, server: listening } = await listen(server.express);
|
|
45
|
+
openServer = listening;
|
|
46
|
+
const health = await fetch(`http://localhost:${port}/health`);
|
|
47
|
+
expect(health.status).toBe(200);
|
|
48
|
+
expect(await health.json()).toEqual({ status: "ok" });
|
|
49
|
+
// /mcp still works (POST returns 200/4xx, not 404)
|
|
50
|
+
const mcp = await postMcp(port);
|
|
51
|
+
expect(mcp.status).not.toBe(404);
|
|
52
|
+
});
|
|
53
|
+
it("server.use and server.express.use produce the same registration order", async () => {
|
|
54
|
+
const { createApp } = await import("./express.js");
|
|
55
|
+
const callsA = [];
|
|
56
|
+
const callsB = [];
|
|
57
|
+
const buildServer = () => new McpServer({ name: "t", version: "0.0.0" });
|
|
58
|
+
const sA = buildServer();
|
|
59
|
+
sA.use((_req, _res, next) => {
|
|
60
|
+
callsA.push("first");
|
|
61
|
+
next();
|
|
62
|
+
});
|
|
63
|
+
sA.express.use((_req, _res, next) => {
|
|
64
|
+
callsA.push("second");
|
|
65
|
+
next();
|
|
66
|
+
});
|
|
67
|
+
const sB = buildServer();
|
|
68
|
+
sB.express.use((_req, _res, next) => {
|
|
69
|
+
callsB.push("first");
|
|
70
|
+
next();
|
|
71
|
+
});
|
|
72
|
+
sB.use((_req, _res, next) => {
|
|
73
|
+
callsB.push("second");
|
|
74
|
+
next();
|
|
75
|
+
});
|
|
76
|
+
for (const s of [sA, sB]) {
|
|
77
|
+
s.express.get("/probe", (_req, res) => res.json({ ok: true }));
|
|
78
|
+
const httpServer = http.createServer();
|
|
79
|
+
await createApp({ mcpServer: s, httpServer });
|
|
80
|
+
const { port, server: listening } = await listen(s.express);
|
|
81
|
+
openServer = listening;
|
|
82
|
+
await fetch(`http://localhost:${port}/probe`);
|
|
83
|
+
listening.close();
|
|
84
|
+
}
|
|
85
|
+
expect(callsA).toEqual(["first", "second"]);
|
|
86
|
+
expect(callsB).toEqual(["first", "second"]);
|
|
87
|
+
});
|
|
88
|
+
it("useOnError still wraps thrown /mcp errors after the route is mounted", async () => {
|
|
89
|
+
const { createApp } = await import("./express.js");
|
|
90
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
91
|
+
// Register the error handler BEFORE createApp — useOnError should still
|
|
92
|
+
// apply it after /mcp, so /mcp errors hit it.
|
|
93
|
+
const seen = [];
|
|
94
|
+
server.useOnError((_err, _req, res, _next) => {
|
|
95
|
+
seen.push("useOnError");
|
|
96
|
+
res.status(503).json({ from: "useOnError" });
|
|
97
|
+
});
|
|
98
|
+
// Force the /mcp handler to throw so the error pipeline runs.
|
|
99
|
+
server.use("/mcp", () => {
|
|
100
|
+
throw new Error("boom");
|
|
101
|
+
});
|
|
102
|
+
const httpServer = http.createServer();
|
|
103
|
+
await createApp({
|
|
104
|
+
mcpServer: server,
|
|
105
|
+
httpServer,
|
|
106
|
+
// Mirror what run() does: forward the McpServer's useOnError handlers
|
|
107
|
+
// to createApp so they get applied after /mcp.
|
|
108
|
+
// biome-ignore lint/complexity/useLiteralKeys: test mirrors run() internals to verify useOnError ordering
|
|
109
|
+
errorMiddleware: server["customErrorMiddleware"],
|
|
110
|
+
});
|
|
111
|
+
const { port, server: listening } = await listen(server.express);
|
|
112
|
+
openServer = listening;
|
|
113
|
+
const res = await postMcp(port);
|
|
114
|
+
expect(seen).toEqual(["useOnError"]);
|
|
115
|
+
expect(res.status).toBe(503);
|
|
116
|
+
expect(await res.json()).toEqual({ from: "useOnError" });
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe("McpServer 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 server = new McpServer({ name: "t", version: "0.0.0" }, {}, { json: { limit: "10mb" } });
|
|
130
|
+
server.express.post("/echo", (req, res) => {
|
|
131
|
+
res.json({ received: req.body.data.length });
|
|
132
|
+
});
|
|
133
|
+
const { port, server: listening } = await listen(server.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 server = new McpServer({ name: "t", version: "0.0.0" });
|
|
141
|
+
server.express.post("/echo", (_req, res) => {
|
|
142
|
+
res.json({ ok: true });
|
|
143
|
+
});
|
|
144
|
+
const { port, server: listening } = await listen(server.express);
|
|
145
|
+
openServer = listening;
|
|
146
|
+
const res = await postEcho(port, largeBody);
|
|
147
|
+
expect(res.status).toBe(413);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
28
150
|
describe("createApp", () => {
|
|
29
151
|
it("runs global custom middleware before the /mcp handler", async () => {
|
|
30
152
|
const { createApp } = await import("./express.js");
|
|
@@ -33,14 +155,12 @@ describe("createApp", () => {
|
|
|
33
155
|
calls.push("custom");
|
|
34
156
|
next();
|
|
35
157
|
};
|
|
158
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
159
|
+
server.use(mw);
|
|
36
160
|
const httpServer = http.createServer();
|
|
37
|
-
const app = await createApp({
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
customMiddleware: [{ handlers: [mw] }],
|
|
41
|
-
});
|
|
42
|
-
const { port, server } = await listen(app);
|
|
43
|
-
openServer = server;
|
|
161
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
162
|
+
const { port, server: httpListening } = await listen(app);
|
|
163
|
+
openServer = httpListening;
|
|
44
164
|
await postMcp(port);
|
|
45
165
|
expect(calls).toEqual(["custom"]);
|
|
46
166
|
});
|
|
@@ -51,14 +171,12 @@ describe("createApp", () => {
|
|
|
51
171
|
calls.push("auth");
|
|
52
172
|
next();
|
|
53
173
|
};
|
|
174
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
175
|
+
server.use("/mcp", mw);
|
|
54
176
|
const httpServer = http.createServer();
|
|
55
|
-
const app = await createApp({
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
customMiddleware: [{ path: "/mcp", handlers: [mw] }],
|
|
59
|
-
});
|
|
60
|
-
const { port, server } = await listen(app);
|
|
61
|
-
openServer = server;
|
|
177
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
178
|
+
const { port, server: httpListening } = await listen(app);
|
|
179
|
+
openServer = httpListening;
|
|
62
180
|
await postMcp(port);
|
|
63
181
|
expect(calls).toEqual(["auth"]);
|
|
64
182
|
});
|
|
@@ -69,14 +187,12 @@ describe("createApp", () => {
|
|
|
69
187
|
calls.push("reject");
|
|
70
188
|
res.status(401).json({ error: "Unauthorized" });
|
|
71
189
|
};
|
|
190
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
191
|
+
server.use("/mcp", reject);
|
|
72
192
|
const httpServer = http.createServer();
|
|
73
|
-
const app = await createApp({
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
customMiddleware: [{ path: "/mcp", handlers: [reject] }],
|
|
77
|
-
});
|
|
78
|
-
const { port, server } = await listen(app);
|
|
79
|
-
openServer = server;
|
|
193
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
194
|
+
const { port, server: httpListening } = await listen(app);
|
|
195
|
+
openServer = httpListening;
|
|
80
196
|
const res = await postMcp(port);
|
|
81
197
|
expect(calls).toEqual(["reject"]);
|
|
82
198
|
expect(res.status).toBe(401);
|
|
@@ -93,14 +209,13 @@ describe("createApp", () => {
|
|
|
93
209
|
calls.push("B");
|
|
94
210
|
next();
|
|
95
211
|
};
|
|
212
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
213
|
+
server.use(mwA);
|
|
214
|
+
server.use(mwB);
|
|
96
215
|
const httpServer = http.createServer();
|
|
97
|
-
const app = await createApp({
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
customMiddleware: [{ handlers: [mwA] }, { handlers: [mwB] }],
|
|
101
|
-
});
|
|
102
|
-
const { port, server } = await listen(app);
|
|
103
|
-
openServer = server;
|
|
216
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
217
|
+
const { port, server: httpListening } = await listen(app);
|
|
218
|
+
openServer = httpListening;
|
|
104
219
|
await postMcp(port);
|
|
105
220
|
expect(calls).toEqual(["A", "B"]);
|
|
106
221
|
});
|
|
@@ -111,14 +226,12 @@ describe("createApp", () => {
|
|
|
111
226
|
calls.push("api");
|
|
112
227
|
next();
|
|
113
228
|
};
|
|
229
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
230
|
+
server.use("/api", apiMw);
|
|
114
231
|
const httpServer = http.createServer();
|
|
115
|
-
const app = await createApp({
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
customMiddleware: [{ path: "/api", handlers: [apiMw] }],
|
|
119
|
-
});
|
|
120
|
-
const { port, server } = await listen(app);
|
|
121
|
-
openServer = server;
|
|
232
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
233
|
+
const { port, server: httpListening } = await listen(app);
|
|
234
|
+
openServer = httpListening;
|
|
122
235
|
// Hit /mcp — the /api middleware should NOT fire
|
|
123
236
|
await postMcp(port);
|
|
124
237
|
expect(calls).toEqual([]);
|
|
@@ -130,14 +243,12 @@ describe("createApp", () => {
|
|
|
130
243
|
router.get("/health", (_req, res) => {
|
|
131
244
|
res.json({ status: "ok" });
|
|
132
245
|
});
|
|
246
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
247
|
+
server.use(router);
|
|
133
248
|
const httpServer = http.createServer();
|
|
134
|
-
const app = await createApp({
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
customMiddleware: [{ handlers: [router] }],
|
|
138
|
-
});
|
|
139
|
-
const { port, server } = await listen(app);
|
|
140
|
-
openServer = server;
|
|
249
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
250
|
+
const { port, server: httpListening } = await listen(app);
|
|
251
|
+
openServer = httpListening;
|
|
141
252
|
const res = await fetch(`http://localhost:${port}/health`);
|
|
142
253
|
expect(res.status).toBe(200);
|
|
143
254
|
expect(await res.json()).toEqual({ status: "ok" });
|
|
@@ -149,16 +260,12 @@ describe("createApp", () => {
|
|
|
149
260
|
router.get("/data", (_req, res) => {
|
|
150
261
|
res.json({ value: 42 });
|
|
151
262
|
});
|
|
263
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
264
|
+
server.use("/api", router);
|
|
152
265
|
const httpServer = http.createServer();
|
|
153
|
-
const app = await createApp({
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
customMiddleware: [
|
|
157
|
-
{ path: "/api", handlers: [router] },
|
|
158
|
-
],
|
|
159
|
-
});
|
|
160
|
-
const { port, server } = await listen(app);
|
|
161
|
-
openServer = server;
|
|
266
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
267
|
+
const { port, server: httpListening } = await listen(app);
|
|
268
|
+
openServer = httpListening;
|
|
162
269
|
const res = await fetch(`http://localhost:${port}/api/data`);
|
|
163
270
|
expect(res.status).toBe(200);
|
|
164
271
|
expect(await res.json()).toEqual({ value: 42 });
|
|
@@ -168,14 +275,12 @@ describe("createApp", () => {
|
|
|
168
275
|
const throwing = () => {
|
|
169
276
|
throw new Error("boom");
|
|
170
277
|
};
|
|
278
|
+
const server = new McpServer({ name: "t", version: "0.0.0" });
|
|
279
|
+
server.use("/explode", throwing);
|
|
171
280
|
const httpServer = http.createServer();
|
|
172
|
-
const app = await createApp({
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
customMiddleware: [{ path: "/explode", handlers: [throwing] }],
|
|
176
|
-
});
|
|
177
|
-
const { port, server } = await listen(app);
|
|
178
|
-
openServer = server;
|
|
281
|
+
const app = await createApp({ mcpServer: server, httpServer });
|
|
282
|
+
const { port, server: httpListening } = await listen(app);
|
|
283
|
+
openServer = httpListening;
|
|
179
284
|
const res = await fetch(`http://localhost:${port}/explode`);
|
|
180
285
|
expect(res.status).toBe(500);
|
|
181
286
|
// Server process did not crash — it still accepts connections
|
|
@@ -185,10 +290,16 @@ describe("createApp", () => {
|
|
|
185
290
|
it("returns 500 JSON-RPC error when the MCP handler throws and no error middleware is registered", async () => {
|
|
186
291
|
const { createApp } = await import("./express.js");
|
|
187
292
|
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
|
|
293
|
+
const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
|
|
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
|
+
mcpServer.use("/mcp", () => {
|
|
297
|
+
throw new Error("boom");
|
|
298
|
+
});
|
|
188
299
|
const httpServer = http.createServer();
|
|
189
|
-
const app = await createApp({ mcpServer
|
|
190
|
-
const { port, server } = await listen(app);
|
|
191
|
-
openServer =
|
|
300
|
+
const app = await createApp({ mcpServer, httpServer });
|
|
301
|
+
const { port, server: httpListening } = await listen(app);
|
|
302
|
+
openServer = httpListening;
|
|
192
303
|
const res = await postMcp(port);
|
|
193
304
|
expect(res.status).toBe(500);
|
|
194
305
|
expect(await res.json()).toEqual({
|
|
@@ -206,14 +317,18 @@ describe("createApp", () => {
|
|
|
206
317
|
calls.push("error-handler");
|
|
207
318
|
res.status(503).json({ custom: true });
|
|
208
319
|
};
|
|
320
|
+
const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
|
|
321
|
+
mcpServer.use("/mcp", () => {
|
|
322
|
+
throw new Error("boom");
|
|
323
|
+
});
|
|
209
324
|
const httpServer = http.createServer();
|
|
210
325
|
const app = await createApp({
|
|
211
|
-
mcpServer
|
|
326
|
+
mcpServer,
|
|
212
327
|
httpServer,
|
|
213
328
|
errorMiddleware: [{ handlers: [errorHandler] }],
|
|
214
329
|
});
|
|
215
|
-
const { port, server } = await listen(app);
|
|
216
|
-
openServer =
|
|
330
|
+
const { port, server: httpListening } = await listen(app);
|
|
331
|
+
openServer = httpListening;
|
|
217
332
|
const res = await postMcp(port);
|
|
218
333
|
expect(calls).toEqual(["error-handler"]);
|
|
219
334
|
expect(res.status).toBe(503);
|
|
@@ -229,15 +344,19 @@ describe("createApp", () => {
|
|
|
229
344
|
const throwingApiRoute = (_req, _res, next) => {
|
|
230
345
|
next(new Error("api error"));
|
|
231
346
|
};
|
|
347
|
+
const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
|
|
348
|
+
mcpServer.use("/mcp", () => {
|
|
349
|
+
throw new Error("boom");
|
|
350
|
+
});
|
|
351
|
+
mcpServer.use("/api/test", throwingApiRoute);
|
|
232
352
|
const httpServer = http.createServer();
|
|
233
353
|
const app = await createApp({
|
|
234
|
-
mcpServer
|
|
354
|
+
mcpServer,
|
|
235
355
|
httpServer,
|
|
236
|
-
customMiddleware: [{ path: "/api/test", handlers: [throwingApiRoute] }],
|
|
237
356
|
errorMiddleware: [{ path: "/mcp", handlers: [mcpErrorHandler] }],
|
|
238
357
|
});
|
|
239
|
-
const { port, server } = await listen(app);
|
|
240
|
-
openServer =
|
|
358
|
+
const { port, server: httpListening } = await listen(app);
|
|
359
|
+
openServer = httpListening;
|
|
241
360
|
const mcpRes = await postMcp(port);
|
|
242
361
|
expect(calls).toEqual(["mcp-error-handler"]);
|
|
243
362
|
expect(mcpRes.status).toBe(503);
|
|
@@ -248,5 +367,160 @@ describe("createApp", () => {
|
|
|
248
367
|
expect(apiRes.status).toBe(500);
|
|
249
368
|
consoleSpy.mockRestore();
|
|
250
369
|
});
|
|
370
|
+
it("handles concurrent /mcp requests without 'Already connected to a transport'", async () => {
|
|
371
|
+
const { createApp } = await import("./express.js");
|
|
372
|
+
const mcpServer = new McpServer({
|
|
373
|
+
name: "concurrent-test",
|
|
374
|
+
version: "0.0.0",
|
|
375
|
+
});
|
|
376
|
+
// Slow tool: keeps the underlying transport bound long enough to overlap
|
|
377
|
+
// with concurrent requests, exposing the shared-McpServer race.
|
|
378
|
+
mcpServer.registerTool({ name: "slow", description: "slow" }, async () => {
|
|
379
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
380
|
+
return { content: [{ type: "text", text: "done" }] };
|
|
381
|
+
});
|
|
382
|
+
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
|
|
383
|
+
const httpServer = http.createServer();
|
|
384
|
+
const app = await createApp({ mcpServer, httpServer });
|
|
385
|
+
const { port, server } = await listen(app);
|
|
386
|
+
openServer = server;
|
|
387
|
+
const callBody = (id) => JSON.stringify({
|
|
388
|
+
jsonrpc: "2.0",
|
|
389
|
+
method: "tools/call",
|
|
390
|
+
id,
|
|
391
|
+
params: { name: "slow", arguments: {} },
|
|
392
|
+
});
|
|
393
|
+
const N = 10;
|
|
394
|
+
const responses = await Promise.all(Array.from({ length: N }, (_, i) => fetch(`http://localhost:${port}/mcp`, {
|
|
395
|
+
method: "POST",
|
|
396
|
+
headers: {
|
|
397
|
+
"Content-Type": "application/json",
|
|
398
|
+
Accept: "application/json, text/event-stream",
|
|
399
|
+
},
|
|
400
|
+
body: callBody(i + 1),
|
|
401
|
+
})));
|
|
402
|
+
expect(responses.map((r) => r.status)).toEqual(Array(N).fill(200));
|
|
403
|
+
expect(consoleSpy).not.toHaveBeenCalledWith("Error handling MCP request:", expect.any(Error));
|
|
404
|
+
consoleSpy.mockRestore();
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
describe("createApp Vercel mode", () => {
|
|
408
|
+
it("server.run() returns the Express app without binding a port when VERCEL=1", async () => {
|
|
409
|
+
const prevVercel = process.env.VERCEL;
|
|
410
|
+
const prevEnv = process.env.NODE_ENV;
|
|
411
|
+
process.env.VERCEL = "1";
|
|
412
|
+
process.env.NODE_ENV = "production";
|
|
413
|
+
try {
|
|
414
|
+
vi.resetModules();
|
|
415
|
+
const { McpServer: Reloaded } = await import("./server.js");
|
|
416
|
+
const server = new Reloaded({ name: "t", version: "0.0.0" });
|
|
417
|
+
const result = await server.run();
|
|
418
|
+
expect(typeof result).toBe("function");
|
|
419
|
+
expect(result).toBe(server.express);
|
|
420
|
+
const { port, server: listening } = await listen(server.express);
|
|
421
|
+
openServer = listening;
|
|
422
|
+
const res = await postMcp(port);
|
|
423
|
+
expect(res.status).not.toBe(404);
|
|
424
|
+
}
|
|
425
|
+
finally {
|
|
426
|
+
if (prevVercel === undefined) {
|
|
427
|
+
delete process.env.VERCEL;
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
process.env.VERCEL = prevVercel;
|
|
431
|
+
}
|
|
432
|
+
process.env.NODE_ENV = prevEnv;
|
|
433
|
+
vi.resetModules();
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
describe("createApp tunnel routes", () => {
|
|
438
|
+
it("proxies POST /__skybridge/tunnel to the cli control server in dev mode", async () => {
|
|
439
|
+
// Stand up a fake control listener that returns a known JSON body.
|
|
440
|
+
const control = http.createServer((_req, res) => {
|
|
441
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
442
|
+
res.end('{"status":"idle"}');
|
|
443
|
+
});
|
|
444
|
+
await new Promise((resolve) => control.listen(0, "127.0.0.1", resolve));
|
|
445
|
+
const controlAddr = control.address();
|
|
446
|
+
if (typeof controlAddr === "string" || controlAddr === null) {
|
|
447
|
+
control.close();
|
|
448
|
+
throw new Error("control server has no address");
|
|
449
|
+
}
|
|
450
|
+
const controlPort = controlAddr.port;
|
|
451
|
+
const prev = process.env.__TUNNEL_CONTROL_PORT;
|
|
452
|
+
process.env.__TUNNEL_CONTROL_PORT = String(controlPort);
|
|
453
|
+
try {
|
|
454
|
+
const { createApp } = await import("./express.js");
|
|
455
|
+
const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
|
|
456
|
+
const httpServer = http.createServer();
|
|
457
|
+
const app = await createApp({ mcpServer, httpServer });
|
|
458
|
+
const { port, server } = await listen(app);
|
|
459
|
+
openServer = server;
|
|
460
|
+
const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
|
|
461
|
+
method: "POST",
|
|
462
|
+
});
|
|
463
|
+
expect(res.status).toBe(200);
|
|
464
|
+
expect(await res.json()).toEqual({ status: "idle" });
|
|
465
|
+
}
|
|
466
|
+
finally {
|
|
467
|
+
if (prev === undefined) {
|
|
468
|
+
delete process.env.__TUNNEL_CONTROL_PORT;
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
process.env.__TUNNEL_CONTROL_PORT = prev;
|
|
472
|
+
}
|
|
473
|
+
await new Promise((resolve) => control.close(() => resolve()));
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
it("does not expose /__skybridge/tunnel in production mode", async () => {
|
|
477
|
+
const prevEnv = process.env.NODE_ENV;
|
|
478
|
+
process.env.NODE_ENV = "production";
|
|
479
|
+
try {
|
|
480
|
+
vi.resetModules();
|
|
481
|
+
const { createApp } = await import("./express.js");
|
|
482
|
+
const { McpServer: ReloadedMcpServer } = await import("./server.js");
|
|
483
|
+
const mcpServer = new ReloadedMcpServer({ name: "t", version: "0.0.0" });
|
|
484
|
+
const httpServer = http.createServer();
|
|
485
|
+
const app = await createApp({ mcpServer, httpServer });
|
|
486
|
+
const { port, server } = await listen(app);
|
|
487
|
+
openServer = server;
|
|
488
|
+
const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
|
|
489
|
+
method: "POST",
|
|
490
|
+
});
|
|
491
|
+
expect(res.status).toBe(404);
|
|
492
|
+
}
|
|
493
|
+
finally {
|
|
494
|
+
process.env.NODE_ENV = prevEnv;
|
|
495
|
+
vi.resetModules();
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
describe("createApp mount path", () => {
|
|
500
|
+
it("serves /mcp with the mount path intact on the request URL", async () => {
|
|
501
|
+
const { createApp } = await import("./express.js");
|
|
502
|
+
const mcpServer = new McpServer({
|
|
503
|
+
name: "t",
|
|
504
|
+
version: "0.0.0",
|
|
505
|
+
}).registerTool({
|
|
506
|
+
name: "echo-url",
|
|
507
|
+
description: "Echoes the request URL.",
|
|
508
|
+
inputSchema: {},
|
|
509
|
+
}, (_args, extra) => ({
|
|
510
|
+
content: [{ type: "text", text: extra.http?.req?.url ?? "" }],
|
|
511
|
+
}));
|
|
512
|
+
const httpServer = http.createServer();
|
|
513
|
+
const app = await createApp({ mcpServer, httpServer });
|
|
514
|
+
const { port, server } = await listen(app);
|
|
515
|
+
openServer = server;
|
|
516
|
+
const client = new Client({ name: "test-client", version: "0.0.0" });
|
|
517
|
+
await client.connect(new StreamableHTTPClientTransport(new URL(`http://localhost:${port}/mcp`)));
|
|
518
|
+
const result = (await client.callTool({
|
|
519
|
+
name: "echo-url",
|
|
520
|
+
arguments: {},
|
|
521
|
+
}));
|
|
522
|
+
await client.close();
|
|
523
|
+
expect(new URL(result.content[0]?.text ?? "").pathname).toBe("/mcp");
|
|
524
|
+
});
|
|
251
525
|
});
|
|
252
526
|
//# sourceMappingURL=express.test.js.map
|