@frontmcp/sdk 0.4.0 → 0.5.0
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 +30 -18
- package/package.json +20 -5
- package/src/app/app.registry.d.ts +3 -2
- package/src/app/app.registry.js +3 -1
- package/src/app/app.registry.js.map +1 -1
- package/src/app/instances/app.local.instance.js +2 -2
- package/src/app/instances/app.local.instance.js.map +1 -1
- package/src/auth/auth.registry.d.ts +34 -2
- package/src/auth/auth.registry.js +162 -24
- package/src/auth/auth.registry.js.map +1 -1
- package/src/auth/auth.utils.js +8 -9
- package/src/auth/auth.utils.js.map +1 -1
- package/src/auth/authorization/authorization.class.d.ts +125 -0
- package/src/auth/authorization/authorization.class.js +224 -0
- package/src/auth/authorization/authorization.class.js.map +1 -0
- package/src/auth/authorization/authorization.types.d.ts +300 -0
- package/src/auth/authorization/authorization.types.js +79 -0
- package/src/auth/authorization/authorization.types.js.map +1 -0
- package/src/auth/authorization/index.d.ts +5 -0
- package/src/auth/authorization/index.js +19 -0
- package/src/auth/authorization/index.js.map +1 -0
- package/src/auth/authorization/orchestrated.authorization.d.ts +242 -0
- package/src/auth/authorization/orchestrated.authorization.js +306 -0
- package/src/auth/authorization/orchestrated.authorization.js.map +1 -0
- package/src/auth/authorization/public.authorization.d.ts +91 -0
- package/src/auth/authorization/public.authorization.js +132 -0
- package/src/auth/authorization/public.authorization.js.map +1 -0
- package/src/auth/authorization/transparent.authorization.d.ts +130 -0
- package/src/auth/authorization/transparent.authorization.js +147 -0
- package/src/auth/authorization/transparent.authorization.js.map +1 -0
- package/src/auth/consent/consent.types.d.ts +111 -0
- package/src/auth/consent/consent.types.js +119 -0
- package/src/auth/consent/consent.types.js.map +1 -0
- package/src/auth/consent/index.d.ts +1 -0
- package/src/auth/consent/index.js +13 -0
- package/src/auth/consent/index.js.map +1 -0
- package/src/auth/detection/auth-provider-detection.d.ts +84 -0
- package/src/auth/detection/auth-provider-detection.js +230 -0
- package/src/auth/detection/auth-provider-detection.js.map +1 -0
- package/src/auth/detection/index.d.ts +1 -0
- package/src/auth/detection/index.js +15 -0
- package/src/auth/detection/index.js.map +1 -0
- package/src/auth/flows/auth.verify.flow.d.ts +110 -0
- package/src/auth/flows/auth.verify.flow.js +379 -0
- package/src/auth/flows/auth.verify.flow.js.map +1 -0
- package/src/auth/flows/oauth.authorize.flow.d.ts +118 -164
- package/src/auth/flows/oauth.authorize.flow.js +701 -33
- package/src/auth/flows/oauth.authorize.flow.js.map +1 -1
- package/src/auth/flows/oauth.callback.flow.d.ts +117 -0
- package/src/auth/flows/oauth.callback.flow.js +357 -0
- package/src/auth/flows/oauth.callback.flow.js.map +1 -0
- package/src/auth/flows/oauth.register.flow.d.ts +32 -125
- package/src/auth/flows/oauth.token.flow.d.ts +52 -154
- package/src/auth/flows/oauth.token.flow.js +193 -55
- package/src/auth/flows/oauth.token.flow.js.map +1 -1
- package/src/auth/flows/session.verify.flow.d.ts +66 -321
- package/src/auth/flows/session.verify.flow.js +107 -18
- package/src/auth/flows/session.verify.flow.js.map +1 -1
- package/src/auth/flows/well-known.jwks.flow.d.ts +34 -205
- package/src/auth/flows/well-known.jwks.flow.js +15 -8
- package/src/auth/flows/well-known.jwks.flow.js.map +1 -1
- package/src/auth/flows/well-known.oauth-authorization-server.flow.d.ts +48 -223
- package/src/auth/flows/well-known.oauth-authorization-server.flow.js +2 -3
- package/src/auth/flows/well-known.oauth-authorization-server.flow.js.map +1 -1
- package/src/auth/flows/well-known.prm.flow.d.ts +19 -120
- package/src/auth/flows/well-known.prm.flow.js +3 -4
- package/src/auth/flows/well-known.prm.flow.js.map +1 -1
- package/src/auth/instances/instance.local-primary-auth.d.ts +91 -4
- package/src/auth/instances/instance.local-primary-auth.js +236 -6
- package/src/auth/instances/instance.local-primary-auth.js.map +1 -1
- package/src/auth/instances/instance.remote-primary-auth.d.ts +4 -3
- package/src/auth/instances/instance.remote-primary-auth.js +2 -2
- package/src/auth/instances/instance.remote-primary-auth.js.map +1 -1
- package/src/auth/session/authorization-vault.d.ts +611 -0
- package/src/auth/session/authorization-vault.js +817 -0
- package/src/auth/session/authorization-vault.js.map +1 -0
- package/src/auth/session/authorization.store.d.ts +301 -0
- package/src/auth/session/authorization.store.js +323 -0
- package/src/auth/session/authorization.store.js.map +1 -0
- package/src/auth/session/encrypted-authorization-vault.d.ts +181 -0
- package/src/auth/session/encrypted-authorization-vault.js +493 -0
- package/src/auth/session/encrypted-authorization-vault.js.map +1 -0
- package/src/auth/session/index.d.ts +4 -4
- package/src/auth/session/index.js +11 -7
- package/src/auth/session/index.js.map +1 -1
- package/src/auth/session/session.schema.d.ts +1 -1
- package/src/auth/session/session.service.d.ts +1 -1
- package/src/auth/session/transport-session.manager.d.ts +101 -0
- package/src/auth/session/transport-session.manager.js +300 -0
- package/src/auth/session/transport-session.manager.js.map +1 -0
- package/src/auth/session/transport-session.types.d.ts +457 -0
- package/src/auth/session/transport-session.types.js +110 -0
- package/src/auth/session/transport-session.types.js.map +1 -0
- package/src/auth/session/utils/session-id.utils.d.ts +14 -2
- package/src/auth/session/utils/session-id.utils.js +68 -19
- package/src/auth/session/utils/session-id.utils.js.map +1 -1
- package/src/auth/session/vault-encryption.d.ts +189 -0
- package/src/auth/session/vault-encryption.js +263 -0
- package/src/auth/session/vault-encryption.js.map +1 -0
- package/src/auth/ui/base-layout.d.ts +188 -0
- package/src/auth/ui/base-layout.js +292 -0
- package/src/auth/ui/base-layout.js.map +1 -0
- package/src/auth/ui/htmx-templates.d.ts +135 -0
- package/src/auth/ui/htmx-templates.js +433 -0
- package/src/auth/ui/htmx-templates.js.map +1 -0
- package/src/auth/ui/index.d.ts +11 -0
- package/src/auth/ui/index.js +35 -0
- package/src/auth/ui/index.js.map +1 -0
- package/src/auth/utils/audience.validator.d.ts +129 -0
- package/src/auth/utils/audience.validator.js +196 -0
- package/src/auth/utils/audience.validator.js.map +1 -0
- package/src/auth/utils/index.d.ts +2 -0
- package/src/auth/utils/index.js +7 -0
- package/src/auth/utils/index.js.map +1 -0
- package/src/auth/utils/www-authenticate.utils.d.ts +97 -0
- package/src/auth/utils/www-authenticate.utils.js +183 -0
- package/src/auth/utils/www-authenticate.utils.js.map +1 -0
- package/src/common/common.schema.d.ts +2 -16
- package/src/common/constants.d.ts +3 -0
- package/src/common/constants.js +6 -1
- package/src/common/constants.js.map +1 -1
- package/src/common/decorators/decorator-utils.d.ts +131 -0
- package/src/common/decorators/decorator-utils.js +195 -0
- package/src/common/decorators/decorator-utils.js.map +1 -0
- package/src/common/decorators/front-mcp.decorator.js +3 -2
- package/src/common/decorators/front-mcp.decorator.js.map +1 -1
- package/src/common/decorators/hook.decorator.d.ts +58 -2
- package/src/common/decorators/hook.decorator.js +127 -17
- package/src/common/decorators/hook.decorator.js.map +1 -1
- package/src/common/decorators/plugin.decorator.d.ts +1 -1
- package/src/common/decorators/plugin.decorator.js +11 -10
- package/src/common/decorators/plugin.decorator.js.map +1 -1
- package/src/common/decorators/resource.decorator.d.ts +32 -3
- package/src/common/decorators/resource.decorator.js +46 -4
- package/src/common/decorators/resource.decorator.js.map +1 -1
- package/src/common/decorators/tool.decorator.d.ts +54 -5
- package/src/common/decorators/tool.decorator.js.map +1 -1
- package/src/common/dynamic/dynamic.plugin.d.ts +22 -11
- package/src/common/dynamic/dynamic.plugin.js +7 -1
- package/src/common/dynamic/dynamic.plugin.js.map +1 -1
- package/src/common/entries/prompt.entry.d.ts +46 -2
- package/src/common/entries/prompt.entry.js +10 -0
- package/src/common/entries/prompt.entry.js.map +1 -1
- package/src/common/entries/resource.entry.d.ts +69 -6
- package/src/common/entries/resource.entry.js +27 -3
- package/src/common/entries/resource.entry.js.map +1 -1
- package/src/common/entries/scope.entry.d.ts +5 -1
- package/src/common/entries/scope.entry.js +3 -3
- package/src/common/entries/scope.entry.js.map +1 -1
- package/src/common/flow/flow.utils.d.ts +56 -0
- package/src/common/flow/flow.utils.js +96 -0
- package/src/common/flow/flow.utils.js.map +1 -0
- package/src/common/index.d.ts +2 -2
- package/src/common/index.js +2 -2
- package/src/common/index.js.map +1 -1
- package/src/common/interfaces/execution-context.interface.d.ts +59 -0
- package/src/common/interfaces/execution-context.interface.js +81 -0
- package/src/common/interfaces/execution-context.interface.js.map +1 -0
- package/src/common/interfaces/flow.interface.d.ts +1 -1
- package/src/common/interfaces/flow.interface.js.map +1 -1
- package/src/common/interfaces/index.d.ts +1 -0
- package/src/common/interfaces/index.js +1 -0
- package/src/common/interfaces/index.js.map +1 -1
- package/src/common/interfaces/internal/primary-auth-provider.interface.d.ts +17 -2
- package/src/common/interfaces/internal/primary-auth-provider.interface.js +52 -4
- package/src/common/interfaces/internal/primary-auth-provider.interface.js.map +1 -1
- package/src/common/interfaces/internal/registry.interface.d.ts +16 -2
- package/src/common/interfaces/internal/registry.interface.js.map +1 -1
- package/src/common/interfaces/plugin.interface.js.map +1 -1
- package/src/common/interfaces/prompt.interface.d.ts +53 -4
- package/src/common/interfaces/prompt.interface.js +78 -0
- package/src/common/interfaces/prompt.interface.js.map +1 -1
- package/src/common/interfaces/resource.interface.d.ts +47 -17
- package/src/common/interfaces/resource.interface.js +53 -0
- package/src/common/interfaces/resource.interface.js.map +1 -1
- package/src/common/interfaces/tool.interface.d.ts +39 -22
- package/src/common/interfaces/tool.interface.js +61 -34
- package/src/common/interfaces/tool.interface.js.map +1 -1
- package/src/common/metadata/adapter.metadata.d.ts +1 -9
- package/src/common/metadata/app.metadata.d.ts +425 -730
- package/src/common/metadata/auth-provider.metadata.d.ts +2 -12
- package/src/common/metadata/flow.metadata.d.ts +10 -25
- package/src/common/metadata/front-mcp.metadata.d.ts +602 -1023
- package/src/common/metadata/front-mcp.metadata.js +6 -4
- package/src/common/metadata/front-mcp.metadata.js.map +1 -1
- package/src/common/metadata/hook.metadata.d.ts +1 -1
- package/src/common/metadata/hook.metadata.js.map +1 -1
- package/src/common/metadata/index.d.ts +1 -0
- package/src/common/metadata/index.js +1 -0
- package/src/common/metadata/index.js.map +1 -1
- package/src/common/metadata/logger.metadata.d.ts +1 -9
- package/src/common/metadata/plugin.metadata.d.ts +8 -30
- package/src/common/metadata/prompt.metadata.d.ts +4 -161
- package/src/common/metadata/provider.metadata.d.ts +2 -12
- package/src/common/metadata/resource.metadata.d.ts +6 -98
- package/src/common/metadata/resource.metadata.js +15 -6
- package/src/common/metadata/resource.metadata.js.map +1 -1
- package/src/common/metadata/tool-ui.metadata.d.ts +10 -0
- package/src/common/metadata/tool-ui.metadata.js +12 -0
- package/src/common/metadata/tool-ui.metadata.js.map +1 -0
- package/src/common/metadata/tool.metadata.d.ts +78 -199
- package/src/common/metadata/tool.metadata.js +11 -14
- package/src/common/metadata/tool.metadata.js.map +1 -1
- package/src/common/providers/base-config.provider.d.ts +84 -0
- package/src/common/providers/base-config.provider.js +128 -0
- package/src/common/providers/base-config.provider.js.map +1 -0
- package/src/common/records/plugin.record.d.ts +5 -6
- package/src/common/records/plugin.record.js.map +1 -1
- package/src/common/records/prompt.record.js.map +1 -1
- package/src/common/records/resource.record.d.ts +17 -1
- package/src/common/records/resource.record.js +12 -6
- package/src/common/records/resource.record.js.map +1 -1
- package/src/common/records/tool.record.js.map +1 -1
- package/src/common/schemas/annotated-class.schema.d.ts +9 -9
- package/src/common/schemas/annotated-class.schema.js +92 -27
- package/src/common/schemas/annotated-class.schema.js.map +1 -1
- package/src/common/schemas/http-input.schema.d.ts +6 -30
- package/src/common/schemas/http-output.schema.d.ts +326 -1630
- package/src/common/schemas/http-output.schema.js +39 -1
- package/src/common/schemas/http-output.schema.js.map +1 -1
- package/src/common/tokens/front-mcp.tokens.js +4 -1
- package/src/common/tokens/front-mcp.tokens.js.map +1 -1
- package/src/common/tokens/resource.tokens.d.ts +2 -0
- package/src/common/tokens/resource.tokens.js +4 -1
- package/src/common/tokens/resource.tokens.js.map +1 -1
- package/src/common/tokens/tool.tokens.d.ts +2 -0
- package/src/common/tokens/tool.tokens.js +2 -0
- package/src/common/tokens/tool.tokens.js.map +1 -1
- package/src/common/types/auth/jwt.types.d.ts +5 -31
- package/src/common/types/auth/session.types.d.ts +97 -192
- package/src/common/types/auth/session.types.js +24 -11
- package/src/common/types/auth/session.types.js.map +1 -1
- package/src/common/types/options/auth.options.d.ts +1013 -490
- package/src/common/types/options/auth.options.js +554 -36
- package/src/common/types/options/auth.options.js.map +1 -1
- package/src/common/types/options/http.options.d.ts +1 -9
- package/src/common/types/options/logging.options.d.ts +7 -13
- package/src/common/types/options/logging.options.js +4 -0
- package/src/common/types/options/logging.options.js.map +1 -1
- package/src/common/types/options/server-info.options.d.ts +3 -31
- package/src/common/types/options/session.options.d.ts +90 -10
- package/src/common/types/options/session.options.js +26 -3
- package/src/common/types/options/session.options.js.map +1 -1
- package/src/common/utils/decide-request-intent.utils.d.ts +8 -46
- package/src/common/utils/decide-request-intent.utils.js +88 -23
- package/src/common/utils/decide-request-intent.utils.js.map +1 -1
- package/src/completion/flows/complete.flow.d.ts +74 -0
- package/src/completion/flows/complete.flow.js +199 -0
- package/src/completion/flows/complete.flow.js.map +1 -0
- package/src/errors/authorization-required.error.d.ts +189 -0
- package/src/errors/authorization-required.error.js +274 -0
- package/src/errors/authorization-required.error.js.map +1 -0
- package/src/errors/index.d.ts +2 -1
- package/src/errors/index.js +17 -1
- package/src/errors/index.js.map +1 -1
- package/src/errors/mcp.error.d.ts +101 -1
- package/src/errors/mcp.error.js +147 -2
- package/src/errors/mcp.error.js.map +1 -1
- package/src/flows/flow.instance.js +4 -3
- package/src/flows/flow.instance.js.map +1 -1
- package/src/flows/flow.registry.js.map +1 -1
- package/src/flows/flow.stages.js +14 -11
- package/src/flows/flow.stages.js.map +1 -1
- package/src/front-mcp/front-mcp.providers.d.ts +464 -102
- package/src/front-mcp/front-mcp.providers.js +3 -5
- package/src/front-mcp/front-mcp.providers.js.map +1 -1
- package/src/hooks/hook.instance.d.ts +1 -1
- package/src/hooks/hook.instance.js +5 -2
- package/src/hooks/hook.instance.js.map +1 -1
- package/src/hooks/hook.registry.js +7 -5
- package/src/hooks/hook.registry.js.map +1 -1
- package/src/index.d.ts +28 -9
- package/src/index.js +5 -1
- package/src/index.js.map +1 -1
- package/src/logger/instances/instance.logger.js +3 -2
- package/src/logger/instances/instance.logger.js.map +1 -1
- package/src/logger/logger.registry.js +7 -2
- package/src/logger/logger.registry.js.map +1 -1
- package/src/logging/flows/set-level.flow.d.ts +62 -0
- package/src/logging/flows/set-level.flow.js +108 -0
- package/src/logging/flows/set-level.flow.js.map +1 -0
- package/src/mcp-apps/csp.d.ts +111 -0
- package/src/mcp-apps/csp.js +267 -0
- package/src/mcp-apps/csp.js.map +1 -0
- package/src/mcp-apps/index.d.ts +23 -0
- package/src/mcp-apps/index.js +91 -0
- package/src/mcp-apps/index.js.map +1 -0
- package/src/mcp-apps/schemas.d.ts +403 -0
- package/src/mcp-apps/schemas.js +345 -0
- package/src/mcp-apps/schemas.js.map +1 -0
- package/src/mcp-apps/template.d.ts +94 -0
- package/src/mcp-apps/template.js +419 -0
- package/src/mcp-apps/template.js.map +1 -0
- package/src/mcp-apps/types.d.ts +323 -0
- package/src/mcp-apps/types.js +59 -0
- package/src/mcp-apps/types.js.map +1 -0
- package/src/notification/index.d.ts +1 -0
- package/src/notification/index.js +13 -0
- package/src/notification/index.js.map +1 -0
- package/src/notification/notification.service.d.ts +378 -0
- package/src/notification/notification.service.js +727 -0
- package/src/notification/notification.service.js.map +1 -0
- package/src/plugin/plugin.registry.js +12 -9
- package/src/plugin/plugin.registry.js.map +1 -1
- package/src/prompt/flows/get-prompt.flow.d.ts +153 -0
- package/src/prompt/flows/get-prompt.flow.js +214 -0
- package/src/prompt/flows/get-prompt.flow.js.map +1 -0
- package/src/prompt/flows/prompts-list.flow.d.ts +67 -0
- package/src/prompt/flows/prompts-list.flow.js +176 -0
- package/src/prompt/flows/prompts-list.flow.js.map +1 -0
- package/src/prompt/index.d.ts +7 -0
- package/src/prompt/index.js +17 -0
- package/src/prompt/index.js.map +1 -0
- package/src/prompt/prompt.events.d.ts +17 -0
- package/src/prompt/prompt.events.js +25 -0
- package/src/prompt/prompt.events.js.map +1 -0
- package/src/prompt/prompt.instance.d.ts +30 -0
- package/src/prompt/prompt.instance.js +120 -0
- package/src/prompt/prompt.instance.js.map +1 -0
- package/src/prompt/prompt.registry.d.ts +79 -12
- package/src/prompt/prompt.registry.js +360 -15
- package/src/prompt/prompt.registry.js.map +1 -1
- package/src/prompt/prompt.types.d.ts +26 -0
- package/src/prompt/prompt.types.js +11 -0
- package/src/prompt/prompt.types.js.map +1 -0
- package/src/prompt/prompt.utils.d.ts +26 -0
- package/src/prompt/prompt.utils.js +136 -0
- package/src/prompt/prompt.utils.js.map +1 -0
- package/src/provider/provider.registry.d.ts +12 -5
- package/src/provider/provider.registry.js +30 -138
- package/src/provider/provider.registry.js.map +1 -1
- package/src/regsitry/registry.base.d.ts +1 -1
- package/src/regsitry/registry.base.js.map +1 -1
- package/src/resource/flows/read-resource.flow.d.ts +91 -0
- package/src/resource/flows/read-resource.flow.js +270 -0
- package/src/resource/flows/read-resource.flow.js.map +1 -0
- package/src/resource/flows/resource-templates-list.flow.d.ts +64 -0
- package/src/resource/flows/resource-templates-list.flow.js +191 -0
- package/src/resource/flows/resource-templates-list.flow.js.map +1 -0
- package/src/resource/flows/resources-list.flow.d.ts +64 -0
- package/src/resource/flows/resources-list.flow.js +196 -0
- package/src/resource/flows/resources-list.flow.js.map +1 -0
- package/src/resource/flows/subscribe-resource.flow.d.ts +45 -0
- package/src/resource/flows/subscribe-resource.flow.js +123 -0
- package/src/resource/flows/subscribe-resource.flow.js.map +1 -0
- package/src/resource/flows/unsubscribe-resource.flow.d.ts +44 -0
- package/src/resource/flows/unsubscribe-resource.flow.js +107 -0
- package/src/resource/flows/unsubscribe-resource.flow.js.map +1 -0
- package/src/resource/index.d.ts +8 -0
- package/src/resource/index.js +20 -0
- package/src/resource/index.js.map +1 -0
- package/src/resource/resource.events.d.ts +24 -0
- package/src/resource/resource.events.js +17 -0
- package/src/resource/resource.events.js.map +1 -0
- package/src/resource/resource.instance.d.ts +35 -0
- package/src/resource/resource.instance.js +163 -0
- package/src/resource/resource.instance.js.map +1 -0
- package/src/resource/resource.registry.d.ts +106 -12
- package/src/resource/resource.registry.js +449 -13
- package/src/resource/resource.registry.js.map +1 -1
- package/src/resource/resource.types.d.ts +35 -0
- package/src/resource/resource.types.js +11 -0
- package/src/resource/resource.types.js.map +1 -0
- package/src/resource/resource.utils.d.ts +30 -0
- package/src/resource/resource.utils.js +151 -0
- package/src/resource/resource.utils.js.map +1 -0
- package/src/scope/flows/http.request.flow.d.ts +48 -330
- package/src/scope/flows/http.request.flow.js +306 -78
- package/src/scope/flows/http.request.flow.js.map +1 -1
- package/src/scope/scope.instance.d.ts +12 -0
- package/src/scope/scope.instance.js +145 -15
- package/src/scope/scope.instance.js.map +1 -1
- package/src/tool/flows/call-tool.flow.d.ts +64 -1110
- package/src/tool/flows/call-tool.flow.js +303 -15
- package/src/tool/flows/call-tool.flow.js.map +1 -1
- package/src/tool/flows/tools-list.flow.d.ts +32 -473
- package/src/tool/flows/tools-list.flow.js +111 -10
- package/src/tool/flows/tools-list.flow.js.map +1 -1
- package/src/tool/tool.events.d.ts +8 -1
- package/src/tool/tool.events.js.map +1 -1
- package/src/tool/tool.instance.d.ts +3 -1
- package/src/tool/tool.instance.js +17 -3
- package/src/tool/tool.instance.js.map +1 -1
- package/src/tool/tool.registry.d.ts +7 -1
- package/src/tool/tool.registry.js +26 -10
- package/src/tool/tool.registry.js.map +1 -1
- package/src/tool/tool.types.d.ts +4 -4
- package/src/tool/tool.types.js.map +1 -1
- package/src/tool/tool.utils.d.ts +3 -12
- package/src/tool/tool.utils.js +39 -193
- package/src/tool/tool.utils.js.map +1 -1
- package/src/tool/ui/index.d.ts +22 -0
- package/src/tool/ui/index.js +63 -0
- package/src/tool/ui/index.js.map +1 -0
- package/src/tool/ui/platform-adapters.d.ts +10 -0
- package/src/tool/ui/platform-adapters.js +18 -0
- package/src/tool/ui/platform-adapters.js.map +1 -0
- package/src/tool/ui/template-helpers.d.ts +46 -0
- package/src/tool/ui/template-helpers.js +112 -0
- package/src/tool/ui/template-helpers.js.map +1 -0
- package/src/tool/ui/ui-resource-template.d.ts +34 -0
- package/src/tool/ui/ui-resource-template.js +64 -0
- package/src/tool/ui/ui-resource-template.js.map +1 -0
- package/src/tool/ui/ui-resource.handler.d.ts +74 -0
- package/src/tool/ui/ui-resource.handler.js +129 -0
- package/src/tool/ui/ui-resource.handler.js.map +1 -0
- package/src/transport/adapters/transport.local.adapter.d.ts +2 -2
- package/src/transport/adapters/transport.local.adapter.js +28 -7
- package/src/transport/adapters/transport.local.adapter.js.map +1 -1
- package/src/transport/adapters/transport.sse.adapter.d.ts +2 -2
- package/src/transport/adapters/transport.sse.adapter.js +4 -3
- package/src/transport/adapters/transport.sse.adapter.js.map +1 -1
- package/src/transport/adapters/transport.streamable-http.adapter.d.ts +10 -3
- package/src/transport/adapters/transport.streamable-http.adapter.js +54 -8
- package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
- package/src/transport/flows/handle.sse.flow.d.ts +29 -63
- package/src/transport/flows/handle.sse.flow.js +78 -10
- package/src/transport/flows/handle.sse.flow.js.map +1 -1
- package/src/transport/flows/handle.stateless-http.flow.d.ts +29 -0
- package/src/transport/flows/handle.stateless-http.flow.js +102 -0
- package/src/transport/flows/handle.stateless-http.flow.js.map +1 -0
- package/src/transport/flows/handle.streamable-http.flow.d.ts +32 -64
- package/src/transport/flows/handle.streamable-http.flow.js +158 -26
- package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
- package/src/transport/legacy/legacy.sse.tranporter.d.ts +9 -0
- package/src/transport/legacy/legacy.sse.tranporter.js +17 -2
- package/src/transport/legacy/legacy.sse.tranporter.js.map +1 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.js +27 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.js.map +1 -1
- package/src/transport/mcp-handlers/complete-request.handler.d.ts +69 -0
- package/src/transport/mcp-handlers/complete-request.handler.js +11 -0
- package/src/transport/mcp-handlers/complete-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/get-prompt-request.handler.d.ts +87 -0
- package/src/transport/mcp-handlers/get-prompt-request.handler.js +11 -0
- package/src/transport/mcp-handlers/get-prompt-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/index.d.ts +517 -208
- package/src/transport/mcp-handlers/index.js +39 -2
- package/src/transport/mcp-handlers/index.js.map +1 -1
- package/src/transport/mcp-handlers/initialize-request.handler.d.ts +1 -1
- package/src/transport/mcp-handlers/initialize-request.handler.js +73 -7
- package/src/transport/mcp-handlers/initialize-request.handler.js.map +1 -1
- package/src/transport/mcp-handlers/list-prompts-request.handler.d.ts +54 -0
- package/src/transport/mcp-handlers/list-prompts-request.handler.js +11 -0
- package/src/transport/mcp-handlers/list-prompts-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/list-resource-templates-request.handler.d.ts +51 -0
- package/src/transport/mcp-handlers/list-resource-templates-request.handler.js +12 -0
- package/src/transport/mcp-handlers/list-resource-templates-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/list-resources-request.handler.d.ts +51 -0
- package/src/transport/mcp-handlers/list-resources-request.handler.js +12 -0
- package/src/transport/mcp-handlers/list-resources-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +19 -146
- package/src/transport/mcp-handlers/logging-set-level-request.handler.d.ts +46 -0
- package/src/transport/mcp-handlers/logging-set-level-request.handler.js +34 -0
- package/src/transport/mcp-handlers/logging-set-level-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/mcp-handlers.types.d.ts +3 -7
- package/src/transport/mcp-handlers/mcp-handlers.types.js.map +1 -1
- package/src/transport/mcp-handlers/read-resource-request.handler.d.ts +46 -0
- package/src/transport/mcp-handlers/read-resource-request.handler.js +12 -0
- package/src/transport/mcp-handlers/read-resource-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/roots-list-changed-notification.handler.d.ts +11 -0
- package/src/transport/mcp-handlers/roots-list-changed-notification.handler.js +26 -0
- package/src/transport/mcp-handlers/roots-list-changed-notification.handler.js.map +1 -0
- package/src/transport/mcp-handlers/subscribe-request.handler.d.ts +37 -0
- package/src/transport/mcp-handlers/subscribe-request.handler.js +34 -0
- package/src/transport/mcp-handlers/subscribe-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/unsubscribe-request.handler.d.ts +37 -0
- package/src/transport/mcp-handlers/unsubscribe-request.handler.js +34 -0
- package/src/transport/mcp-handlers/unsubscribe-request.handler.js.map +1 -0
- package/src/transport/transport.local.js +7 -2
- package/src/transport/transport.local.js.map +1 -1
- package/src/transport/transport.registry.d.ts +30 -0
- package/src/transport/transport.registry.js +84 -1
- package/src/transport/transport.registry.js.map +1 -1
- package/src/transport/transport.types.d.ts +3 -3
- package/src/transport/transport.types.js.map +1 -1
- package/src/utils/content.utils.d.ts +48 -0
- package/src/utils/content.utils.js +194 -0
- package/src/utils/content.utils.js.map +1 -0
- package/src/utils/index.d.ts +8 -0
- package/src/utils/index.js +55 -0
- package/src/utils/index.js.map +1 -0
- package/src/utils/lineage.utils.d.ts +40 -0
- package/src/utils/lineage.utils.js +82 -0
- package/src/utils/lineage.utils.js.map +1 -0
- package/src/utils/naming.utils.d.ts +46 -0
- package/src/utils/naming.utils.js +136 -0
- package/src/utils/naming.utils.js.map +1 -0
- package/src/utils/types.utils.d.ts +2 -2
- package/src/utils/types.utils.js.map +1 -1
- package/src/utils/uri-template.utils.d.ts +57 -0
- package/src/utils/uri-template.utils.js +113 -0
- package/src/utils/uri-template.utils.js.map +1 -0
- package/src/utils/uri-validation.utils.d.ts +40 -0
- package/src/utils/uri-validation.utils.js +76 -0
- package/src/utils/uri-validation.utils.js.map +1 -0
- package/src/__test-utils__/fixtures/hook.fixtures.d.ts +0 -46
- package/src/__test-utils__/fixtures/hook.fixtures.js +0 -114
- package/src/__test-utils__/fixtures/hook.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/index.d.ts +0 -7
- package/src/__test-utils__/fixtures/index.js +0 -11
- package/src/__test-utils__/fixtures/index.js.map +0 -1
- package/src/__test-utils__/fixtures/plugin.fixtures.d.ts +0 -46
- package/src/__test-utils__/fixtures/plugin.fixtures.js +0 -127
- package/src/__test-utils__/fixtures/plugin.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/provider.fixtures.d.ts +0 -69
- package/src/__test-utils__/fixtures/provider.fixtures.js +0 -131
- package/src/__test-utils__/fixtures/provider.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/scope.fixtures.d.ts +0 -14
- package/src/__test-utils__/fixtures/scope.fixtures.js +0 -59
- package/src/__test-utils__/fixtures/scope.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/tool.fixtures.d.ts +0 -36
- package/src/__test-utils__/fixtures/tool.fixtures.js +0 -91
- package/src/__test-utils__/fixtures/tool.fixtures.js.map +0 -1
- package/src/__test-utils__/helpers/assertion.helpers.d.ts +0 -45
- package/src/__test-utils__/helpers/assertion.helpers.js +0 -153
- package/src/__test-utils__/helpers/assertion.helpers.js.map +0 -1
- package/src/__test-utils__/helpers/async.helpers.d.ts +0 -48
- package/src/__test-utils__/helpers/async.helpers.js +0 -112
- package/src/__test-utils__/helpers/async.helpers.js.map +0 -1
- package/src/__test-utils__/helpers/index.d.ts +0 -6
- package/src/__test-utils__/helpers/index.js +0 -10
- package/src/__test-utils__/helpers/index.js.map +0 -1
- package/src/__test-utils__/helpers/setup.helpers.d.ts +0 -54
- package/src/__test-utils__/helpers/setup.helpers.js +0 -106
- package/src/__test-utils__/helpers/setup.helpers.js.map +0 -1
- package/src/__test-utils__/index.d.ts +0 -9
- package/src/__test-utils__/index.js +0 -14
- package/src/__test-utils__/index.js.map +0 -1
- package/src/__test-utils__/mocks/flow-instance.mock.d.ts +0 -50
- package/src/__test-utils__/mocks/flow-instance.mock.js +0 -72
- package/src/__test-utils__/mocks/flow-instance.mock.js.map +0 -1
- package/src/__test-utils__/mocks/hook-registry.mock.d.ts +0 -25
- package/src/__test-utils__/mocks/hook-registry.mock.js +0 -65
- package/src/__test-utils__/mocks/hook-registry.mock.js.map +0 -1
- package/src/__test-utils__/mocks/index.d.ts +0 -8
- package/src/__test-utils__/mocks/index.js +0 -12
- package/src/__test-utils__/mocks/index.js.map +0 -1
- package/src/__test-utils__/mocks/plugin-registry.mock.d.ts +0 -43
- package/src/__test-utils__/mocks/plugin-registry.mock.js +0 -70
- package/src/__test-utils__/mocks/plugin-registry.mock.js.map +0 -1
- package/src/__test-utils__/mocks/provider-registry.mock.d.ts +0 -39
- package/src/__test-utils__/mocks/provider-registry.mock.js +0 -72
- package/src/__test-utils__/mocks/provider-registry.mock.js.map +0 -1
- package/src/__test-utils__/mocks/tool-registry.mock.d.ts +0 -43
- package/src/__test-utils__/mocks/tool-registry.mock.js +0 -79
- package/src/__test-utils__/mocks/tool-registry.mock.js.map +0 -1
- package/src/auth/path.utils.d.ts +0 -20
- package/src/auth/path.utils.js +0 -71
- package/src/auth/path.utils.js.map +0 -1
- package/src/common/decorators-old/async-with.decorator.d.ts +0 -10
- package/src/common/decorators-old/async-with.decorator.js +0 -24
- package/src/common/decorators-old/async-with.decorator.js.map +0 -1
- package/src/common/decorators-old/auth-hook.decorator.d.ts +0 -14
- package/src/common/decorators-old/auth-hook.decorator.js +0 -27
- package/src/common/decorators-old/auth-hook.decorator.js.map +0 -1
- package/src/common/decorators-old/session-hook.decorator.d.ts +0 -14
- package/src/common/decorators-old/session-hook.decorator.js +0 -27
- package/src/common/decorators-old/session-hook.decorator.js.map +0 -1
|
@@ -10,6 +10,7 @@ exports.intentSchema = zod_1.z.union([
|
|
|
10
10
|
zod_1.z.literal('streamable-http'),
|
|
11
11
|
zod_1.z.literal('stateful-http'),
|
|
12
12
|
zod_1.z.literal('stateless-http'),
|
|
13
|
+
zod_1.z.literal('delete-session'),
|
|
13
14
|
zod_1.z.literal('unknown'),
|
|
14
15
|
]);
|
|
15
16
|
exports.decisionSchema = zod_1.z.object({
|
|
@@ -53,12 +54,13 @@ bit 10 LEGACY_EN (config: enableLegacySSE)
|
|
|
53
54
|
----------------------------------------------------------------------------- */
|
|
54
55
|
// --- Channels ---------------------------------------------------------------
|
|
55
56
|
const CH_OTHER = 0b000;
|
|
56
|
-
const CH_GET_SSE = 0b001;
|
|
57
|
+
const CH_GET_SSE = 0b001; // GET / + SSE (not handled, forward to next middleware)
|
|
57
58
|
const CH_POST_INIT_JSON = 0b010;
|
|
58
59
|
const CH_POST_INIT_SSE = 0b011;
|
|
59
60
|
const CH_POST_JSON = 0b100;
|
|
60
61
|
const CH_POST_SSE = 0b101;
|
|
61
|
-
const CH_POST_MESSAGE = 0b110; //
|
|
62
|
+
const CH_POST_MESSAGE = 0b110; // POST /message (legacy bridge)
|
|
63
|
+
const CH_GET_SSE_PATH = 0b111; // GET /sse path (legacy SSE initialize)
|
|
62
64
|
const CH_MASK = 0b00000111;
|
|
63
65
|
// --- Flags ------------------------------------------------------------------
|
|
64
66
|
const B_HAS_SESSION = 1 << 3; // 8
|
|
@@ -86,6 +88,10 @@ function pathOf(req) {
|
|
|
86
88
|
return String(raw).split('?')[0] || '/';
|
|
87
89
|
}
|
|
88
90
|
}
|
|
91
|
+
// Check if path is the legacy SSE path (/sse)
|
|
92
|
+
function isLegacySsePath(path) {
|
|
93
|
+
return path === '/sse' || path.endsWith('/sse');
|
|
94
|
+
}
|
|
89
95
|
/** Optionally extract transportType from base64 JSON session id, if you embed it. */
|
|
90
96
|
function tryDecodeTransportType(sessionId) {
|
|
91
97
|
if (!sessionId)
|
|
@@ -110,20 +116,23 @@ function computeBitmap(req, cfg) {
|
|
|
110
116
|
const acceptSSE = wantsSSE(accept);
|
|
111
117
|
const acceptJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);
|
|
112
118
|
const init = method === 'POST' && isInitialize(req.body);
|
|
113
|
-
const postToMessage = method === 'POST' && path === '/message';
|
|
119
|
+
const postToMessage = method === 'POST' && (path === '/message' || path.endsWith('/message'));
|
|
120
|
+
const getToSsePath = method === 'GET' && isLegacySsePath(path);
|
|
114
121
|
const channel = method === 'POST' && postToMessage
|
|
115
122
|
? CH_POST_MESSAGE
|
|
116
|
-
:
|
|
117
|
-
?
|
|
118
|
-
: method === '
|
|
119
|
-
?
|
|
120
|
-
: method === 'POST' && init &&
|
|
121
|
-
?
|
|
122
|
-
: method === 'POST' &&
|
|
123
|
-
?
|
|
124
|
-
: method === 'POST' && !init &&
|
|
125
|
-
?
|
|
126
|
-
:
|
|
123
|
+
: getToSsePath && acceptSSE
|
|
124
|
+
? CH_GET_SSE_PATH // GET /sse → legacy SSE channel
|
|
125
|
+
: method === 'GET' && acceptSSE
|
|
126
|
+
? CH_GET_SSE // GET / + SSE → forward to next middleware (unknown)
|
|
127
|
+
: method === 'POST' && init && acceptSSE
|
|
128
|
+
? CH_POST_INIT_SSE
|
|
129
|
+
: method === 'POST' && init && acceptJSON
|
|
130
|
+
? CH_POST_INIT_JSON
|
|
131
|
+
: method === 'POST' && !init && acceptSSE
|
|
132
|
+
? CH_POST_SSE
|
|
133
|
+
: method === 'POST' && !init && acceptJSON
|
|
134
|
+
? CH_POST_JSON
|
|
135
|
+
: CH_OTHER;
|
|
127
136
|
let flags = 0;
|
|
128
137
|
if (sessionId)
|
|
129
138
|
flags |= B_HAS_SESSION;
|
|
@@ -145,21 +154,47 @@ function computeBitmap(req, cfg) {
|
|
|
145
154
|
}
|
|
146
155
|
// --- Rules (merged semantics) -----------------------------------------------
|
|
147
156
|
const RULES = [
|
|
148
|
-
// A) Legacy SSE
|
|
157
|
+
// A) Legacy SSE via GET /sse path (without session) → requires legacy enabled
|
|
149
158
|
{
|
|
150
159
|
care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,
|
|
151
|
-
match:
|
|
152
|
-
outcome: { intent: 'legacy-sse', reason: 'GET
|
|
160
|
+
match: CH_GET_SSE_PATH | B_LEGACY_EN, // HAS_SESSION must be 0; it's in 'care' but not in 'match'
|
|
161
|
+
outcome: { intent: 'legacy-sse', reason: 'GET /sse without Mcp-Session-Id → legacy SSE.' },
|
|
153
162
|
},
|
|
154
163
|
{
|
|
155
164
|
care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,
|
|
156
|
-
match:
|
|
165
|
+
match: CH_GET_SSE_PATH /* legacy disabled; HAS_SESSION=0 */,
|
|
157
166
|
outcome: {
|
|
158
167
|
intent: 'unknown',
|
|
159
168
|
reason: 'Legacy SSE disabled.',
|
|
160
169
|
recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },
|
|
161
170
|
},
|
|
162
171
|
},
|
|
172
|
+
// A2) GET / + SSE (not /sse path) with session ID → SSE listener for streamable-http
|
|
173
|
+
// Per MCP 2025-11-25 spec, clients can open SSE stream via GET with session ID
|
|
174
|
+
{
|
|
175
|
+
care: CH_MASK | B_HAS_SESSION | B_SSE_LISTENER_EN | B_STREAMABLE_EN,
|
|
176
|
+
match: CH_GET_SSE | B_HAS_SESSION | B_SSE_LISTENER_EN | B_STREAMABLE_EN,
|
|
177
|
+
outcome: { intent: 'streamable-http', reason: 'GET / with session ID → SSE listener for streamable-http.' },
|
|
178
|
+
},
|
|
179
|
+
// A2b) GET / + SSE with session but listener/streamable disabled
|
|
180
|
+
{
|
|
181
|
+
care: CH_MASK | B_HAS_SESSION | B_SSE_LISTENER_EN,
|
|
182
|
+
match: CH_GET_SSE | B_HAS_SESSION /* listener disabled */,
|
|
183
|
+
outcome: {
|
|
184
|
+
intent: 'unknown',
|
|
185
|
+
reason: 'SSE listener disabled for GET / requests.',
|
|
186
|
+
recommendation: { httpStatus: 405, message: 'SSE listener disabled' },
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
// A2c) GET / + SSE without session → forward to next middleware
|
|
190
|
+
{
|
|
191
|
+
care: CH_MASK | B_HAS_SESSION,
|
|
192
|
+
match: CH_GET_SSE /* no session */,
|
|
193
|
+
outcome: {
|
|
194
|
+
intent: 'unknown',
|
|
195
|
+
reason: 'GET / with SSE requires session for MCP transport.',
|
|
196
|
+
},
|
|
197
|
+
},
|
|
163
198
|
// B) Legacy SSE: POST /message WITH session id
|
|
164
199
|
{
|
|
165
200
|
care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,
|
|
@@ -175,10 +210,10 @@ const RULES = [
|
|
|
175
210
|
recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },
|
|
176
211
|
},
|
|
177
212
|
},
|
|
178
|
-
// C) Modern SSE (GET
|
|
213
|
+
// C) Modern SSE (GET /sse with session) → requires SSE listener enabled
|
|
179
214
|
{
|
|
180
215
|
care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,
|
|
181
|
-
match:
|
|
216
|
+
match: CH_GET_SSE_PATH | B_HAS_SESSION /* listener disabled */,
|
|
182
217
|
outcome: {
|
|
183
218
|
intent: 'unknown',
|
|
184
219
|
reason: 'SSE listener disabled.',
|
|
@@ -187,10 +222,16 @@ const RULES = [
|
|
|
187
222
|
},
|
|
188
223
|
{
|
|
189
224
|
care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,
|
|
190
|
-
match:
|
|
191
|
-
outcome: { intent: 'sse', reason: 'GET
|
|
225
|
+
match: CH_GET_SSE_PATH | B_SSE_LISTENER_EN | B_HAS_SESSION,
|
|
226
|
+
outcome: { intent: 'sse', reason: 'GET /sse with Mcp-Session-Id.' },
|
|
192
227
|
},
|
|
193
228
|
// D) Initialize (POST → SSE)
|
|
229
|
+
// D1) Stateless initialize (no session, stateless enabled) - must come before streamable rules
|
|
230
|
+
{
|
|
231
|
+
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
|
|
232
|
+
match: CH_POST_INIT_SSE | B_STATELESS_EN /* no session */,
|
|
233
|
+
outcome: { intent: 'stateless-http', reason: 'Stateless initialize (no session).' },
|
|
234
|
+
},
|
|
194
235
|
{
|
|
195
236
|
care: CH_MASK | B_STREAMABLE_EN,
|
|
196
237
|
match: CH_POST_INIT_SSE /* streamable disabled */,
|
|
@@ -206,6 +247,12 @@ const RULES = [
|
|
|
206
247
|
outcome: { intent: 'streamable-http', reason: 'Initialize with SSE.' },
|
|
207
248
|
},
|
|
208
249
|
// E) Initialize (POST → JSON)
|
|
250
|
+
// E1) Stateless initialize JSON (no session, stateless enabled) - must come before stateful rules
|
|
251
|
+
{
|
|
252
|
+
care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,
|
|
253
|
+
match: CH_POST_INIT_JSON | B_STATELESS_EN /* no session */,
|
|
254
|
+
outcome: { intent: 'stateless-http', reason: 'Stateless initialize JSON (no session).' },
|
|
255
|
+
},
|
|
209
256
|
{
|
|
210
257
|
care: CH_MASK | B_STREAMABLE_EN,
|
|
211
258
|
match: CH_POST_INIT_JSON /* streamable disabled */,
|
|
@@ -292,9 +339,27 @@ const RULES = [
|
|
|
292
339
|
// --- Public API --------------------------------------------------------------
|
|
293
340
|
function decideIntent(req, cfg) {
|
|
294
341
|
const reasons = [];
|
|
342
|
+
const method = req.method.toUpperCase();
|
|
343
|
+
// Handle HTTP DELETE for session termination (MCP 2025-11-25 spec)
|
|
344
|
+
if (method === 'DELETE') {
|
|
345
|
+
const sessionId = h(req, 'mcp-session-id');
|
|
346
|
+
if (!sessionId) {
|
|
347
|
+
return {
|
|
348
|
+
intent: 'unknown',
|
|
349
|
+
reasons: ['DELETE requires Mcp-Session-Id header.'],
|
|
350
|
+
recommendation: { httpStatus: 400, message: 'Session ID required for DELETE' },
|
|
351
|
+
debug: { key: 0, channel: 0, flags: 0 },
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
return {
|
|
355
|
+
intent: 'delete-session',
|
|
356
|
+
reasons: ['DELETE with Mcp-Session-Id → session termination.'],
|
|
357
|
+
debug: { key: 0, channel: 0, flags: sessionId ? B_HAS_SESSION : 0 },
|
|
358
|
+
};
|
|
359
|
+
}
|
|
295
360
|
const { key, channel, flags, init } = computeBitmap(req, cfg);
|
|
296
361
|
// Optional strict Accept validation for POST (incl. /message)
|
|
297
|
-
if (
|
|
362
|
+
if (method === 'POST') {
|
|
298
363
|
const accept = h(req, 'accept');
|
|
299
364
|
const acceptsSSE = wantsSSE(accept);
|
|
300
365
|
const acceptsJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decide-request-intent.utils.js","sourceRoot":"","sources":["../../../../src/common/utils/decide-request-intent.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {ServerRequest} from \"../interfaces\";\n\n/* --------------------------------- Schemas --------------------------------- */\n\nexport const intentSchema = z.union([\n z.literal('legacy-sse'),\n z.literal('sse'),\n z.literal('streamable-http'),\n z.literal('stateful-http'),\n z.literal('stateless-http'),\n z.literal('unknown'),\n]);\n\nexport const decisionSchema = z.object({\n intent: intentSchema,\n reasons: z.array(z.string()),\n recommendation: z\n .object({\n httpStatus: z.number(),\n message: z.string(),\n })\n .optional(),\n // Echo back bits for debugging/telemetry if you like\n debug: z\n .object({\n key: z.number(),\n channel: z.number(),\n flags: z.number(),\n })\n .optional(),\n});\n\nexport type HttpRequestIntent =\n | 'legacy-sse'\n | 'sse'\n | 'streamable-http'\n | 'stateful-http'\n | 'stateless-http';\n\nexport type Intent = HttpRequestIntent | 'unknown';\n\nexport type Decision = {\n intent: Intent;\n reasons: string[];\n recommendation?: { httpStatus: number; message: string };\n // Echo back bits for debugging/telemetry if you like\n debug?: { key: number; channel: number; flags: number };\n};\n\nexport interface Config {\n enableLegacySSE: boolean;\n enableSseListener: boolean;\n enableStreamableHttp: boolean;\n enableStatefulHttp: boolean;\n enableStatelessHttp: boolean;\n requireSessionForStreamable: boolean;\n tolerateMissingAccept: boolean;\n}\n\n/* ------------------------------- Bit layout ---------------------------------\n\nbits 0..2 CHANNEL\n 000 OTHER\n 001 GET_SSE (GET + Accept: text/event-stream)\n 010 POST_INIT_JSON (POST initialize + Accept: application/json or default JSON)\n 011 POST_INIT_SSE (POST initialize + Accept: text/event-stream)\n 100 POST_JSON (POST non-init + Accept: application/json or default JSON)\n 101 POST_SSE (POST non-init + Accept: text/event-stream)\n 110 POST_MESSAGE (POST to /message) ← legacy bridge\n\nbit 3 HAS_SESSION (Mcp-Session-Id present)\nbit 4 STATELESS_EN (config: enableStatelessHttp)\nbit 5 REQ_SESSION (config: requireSessionForStreamable)\nbit 6 LEGACY_HINT (x-legacy-sse=true OR session.transportType=legacy-sse)\nbit 7 SSE_LISTENER_EN (config: enableSseListener)\nbit 8 STREAMABLE_EN (config: enableStreamableHttp)\nbit 9 STATEFUL_EN (config: enableStatefulHttp)\nbit 10 LEGACY_EN (config: enableLegacySSE)\n\n----------------------------------------------------------------------------- */\n\n// --- Channels ---------------------------------------------------------------\n\nconst CH_OTHER = 0b000;\nconst CH_GET_SSE = 0b001;\nconst CH_POST_INIT_JSON = 0b010;\nconst CH_POST_INIT_SSE = 0b011;\nconst CH_POST_JSON = 0b100;\nconst CH_POST_SSE = 0b101;\nconst CH_POST_MESSAGE = 0b110; // NEW: POST /message (legacy bridge)\n\nconst CH_MASK = 0b00000111;\n\n// --- Flags ------------------------------------------------------------------\n\nconst B_HAS_SESSION = 1 << 3; // 8\nconst B_STATELESS_EN = 1 << 4; // 16\nconst B_REQ_SESSION = 1 << 5; // 32\nconst B_LEGACY_HINT = 1 << 6; // 64 (kept for telemetry; not required by merged rules)\nconst B_SSE_LISTENER_EN = 1 << 7; // 128\nconst B_STREAMABLE_EN = 1 << 8; // 256\nconst B_STATEFUL_EN = 1 << 9; // 512\nconst B_LEGACY_EN = 1 << 10; // 1024\n\n// --- Minimal helpers ---------------------------------------------------------\n\nconst h = (req: ServerRequest, name: string) =>\n Object.entries(req.headers).find(([k]) => k.toLowerCase() === name.toLowerCase())?.[1];\n\nconst wantsSSE = (accept?: string) => (accept ?? '').toLowerCase().includes('text/event-stream');\nconst wantsJSON = (accept?: string) => (accept ?? '').toLowerCase().includes('application/json');\nconst isInitialize = (body: unknown) =>\n !!body && typeof body === 'object' && (body as any).method === 'initialize';\n\n// Robust path extractor (supports absolute/relative)\nfunction pathOf(req: ServerRequest): string {\n const anyReq = req as any;\n const raw = anyReq.path ?? anyReq.pathname ?? anyReq.url ?? '/';\n try {\n const u = new URL(String(raw), 'http://local');\n return u.pathname || '/';\n } catch {\n return String(raw).split('?')[0] || '/';\n }\n}\n\n/** Optionally extract transportType from base64 JSON session id, if you embed it. */\nfunction tryDecodeTransportType(sessionId?: string): string | undefined {\n if (!sessionId) return;\n try {\n const b64 = sessionId.replace(/-/g, '+').replace(/_/g, '/');\n const obj = JSON.parse(Buffer.from(b64, 'base64').toString('utf8'));\n return obj?.transportType;\n } catch {\n return;\n }\n}\n\n// --- Build the 11-bit key ----------------------------------------------------\n\nfunction computeBitmap(req: ServerRequest, cfg: Config) {\n const method = req.method.toUpperCase();\n const accept = h(req, 'accept');\n const sessionId = h(req, 'mcp-session-id');\n const legacyHeader = h(req, 'x-legacy-sse') === 'true';\n const transportType = tryDecodeTransportType(sessionId);\n const path = pathOf(req);\n\n const acceptSSE = wantsSSE(accept);\n const acceptJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);\n const init = method === 'POST' && isInitialize(req.body);\n const postToMessage = method === 'POST' && path === '/message';\n\n const channel =\n method === 'POST' && postToMessage\n ? CH_POST_MESSAGE\n : method === 'GET' && acceptSSE\n ? CH_GET_SSE\n : method === 'POST' && init && acceptSSE\n ? CH_POST_INIT_SSE\n : method === 'POST' && init && acceptJSON\n ? CH_POST_INIT_JSON\n : method === 'POST' && !init && acceptSSE\n ? CH_POST_SSE\n : method === 'POST' && !init && acceptJSON\n ? CH_POST_JSON\n : CH_OTHER;\n\n let flags = 0;\n if (sessionId) flags |= B_HAS_SESSION;\n if (cfg.enableStatelessHttp) flags |= B_STATELESS_EN;\n if (cfg.requireSessionForStreamable) flags |= B_REQ_SESSION;\n if (legacyHeader || transportType === 'legacy-sse') flags |= B_LEGACY_HINT; // informational\n if (cfg.enableSseListener) flags |= B_SSE_LISTENER_EN;\n if (cfg.enableStreamableHttp) flags |= B_STREAMABLE_EN;\n if (cfg.enableStatefulHttp) flags |= B_STATEFUL_EN;\n if (cfg.enableLegacySSE) flags |= B_LEGACY_EN;\n\n return { key: (channel & CH_MASK) | flags, channel, flags, init };\n}\n\n// --- Rule definition ---------------------------------------------------------\n\ntype Rule = {\n care: number; // which bits matter\n match: number; // the exact bit pattern to match (after masking)\n outcome: Omit<Decision, 'reasons' | 'debug'> & { reason: string };\n};\n\n// --- Rules (merged semantics) -----------------------------------------------\n\nconst RULES: Rule[] = [\n // A) Legacy SSE (GET SSE without session) → requires legacy enabled\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_GET_SSE | B_LEGACY_EN, // HAS_SESSION must be 0; it's in 'care' but not in 'match'\n outcome: { intent: 'legacy-sse', reason: 'GET SSE without Mcp-Session-Id → legacy SSE.' },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_GET_SSE /* legacy disabled; HAS_SESSION=0 */,\n outcome: {\n intent: 'unknown',\n reason: 'Legacy SSE disabled.',\n recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },\n },\n },\n\n // B) Legacy SSE: POST /message WITH session id\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_POST_MESSAGE | B_HAS_SESSION | B_LEGACY_EN,\n outcome: { intent: 'legacy-sse', reason: 'POST /message with Mcp-Session-Id → legacy SSE bridge.' },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_POST_MESSAGE | B_HAS_SESSION /* legacy disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Legacy /message endpoint disabled.',\n recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },\n },\n },\n\n // C) Modern SSE (GET SSE with session) → requires SSE listener enabled\n {\n care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,\n match: CH_GET_SSE | B_HAS_SESSION /* listener disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'SSE listener disabled.',\n recommendation: { httpStatus: 405, message: 'SSE listener disabled' },\n },\n },\n {\n care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,\n match: CH_GET_SSE | B_SSE_LISTENER_EN | B_HAS_SESSION,\n outcome: { intent: 'sse', reason: 'GET SSE with Mcp-Session-Id.' },\n },\n\n // D) Initialize (POST → SSE)\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_SSE /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Streamable HTTP disabled.',\n recommendation: { httpStatus: 405, message: 'Streamable HTTP disabled' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_SSE | B_STREAMABLE_EN,\n outcome: { intent: 'streamable-http', reason: 'Initialize with SSE.' },\n },\n\n // E) Initialize (POST → JSON)\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_JSON /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'JSON mode disabled.',\n recommendation: { httpStatus: 405, message: 'JSON mode disabled' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_JSON | B_STREAMABLE_EN,\n outcome: { intent: 'stateful-http', reason: 'Initialize with JSON.' },\n },\n\n // F) POST non-init → SSE\n {\n care: CH_MASK | B_REQ_SESSION | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_SSE | B_REQ_SESSION /* !HAS_SESSION & !STATELESS_EN */,\n outcome: {\n intent: 'unknown',\n reason: 'POST SSE requires session.',\n recommendation: { httpStatus: 400, message: 'Initialize required (no Mcp-Session-Id)' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_SSE /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Streamable HTTP disabled.',\n recommendation: { httpStatus: 405, message: 'Streamable HTTP disabled' },\n },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_SSE | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless short-lived SSE.' },\n },\n {\n care: CH_MASK,\n match: CH_POST_SSE,\n outcome: { intent: 'streamable-http', reason: 'Short-lived SSE for this request.' },\n },\n\n // G) POST non-init → JSON\n {\n care: CH_MASK | B_REQ_SESSION | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_JSON | B_REQ_SESSION /* !HAS_SESSION & !STATELESS_EN */,\n outcome: {\n intent: 'unknown',\n reason: 'POST JSON requires session.',\n recommendation: { httpStatus: 400, message: 'Initialize required (no Mcp-Session-Id)' },\n },\n },\n {\n care: CH_MASK | B_STATEFUL_EN | B_STREAMABLE_EN,\n match: CH_POST_JSON /* neither enabled */,\n outcome: {\n intent: 'unknown',\n reason: 'JSON mode disabled.',\n recommendation: { httpStatus: 405, message: 'JSON mode disabled' },\n },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_JSON | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless JSON request.' },\n },\n {\n care: CH_MASK,\n match: CH_POST_JSON,\n outcome: { intent: 'stateful-http', reason: 'Aggregated JSON response.' },\n },\n\n // H) Fallback\n {\n care: CH_MASK,\n match: CH_OTHER,\n outcome: {\n intent: 'unknown',\n reason: 'Method/Accept not allowed.',\n recommendation: { httpStatus: 405, message: 'Method/Accept not allowed' },\n },\n },\n];\n\n// --- Public API --------------------------------------------------------------\n\nexport function decideIntent(req: ServerRequest, cfg: Config): Decision {\n const reasons: string[] = [];\n const { key, channel, flags, init } = computeBitmap(req, cfg);\n\n // Optional strict Accept validation for POST (incl. /message)\n if (req.method.toUpperCase() === 'POST') {\n const accept = h(req, 'accept');\n const acceptsSSE = wantsSSE(accept);\n const acceptsJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);\n if (!acceptsSSE && !acceptsJSON) {\n return {\n intent: 'unknown',\n reasons: ['Client must accept application/json or text/event-stream.'],\n recommendation: { httpStatus: 406, message: 'Not acceptable' },\n debug: { key, channel, flags },\n };\n }\n }\n\n for (const rule of RULES) {\n if ((key & rule.care) === rule.match) {\n const { reason, ...rest } = rule.outcome;\n reasons.push(reason);\n if (init) reasons.push('Initialize body detected.');\n return { ...rest, reasons, debug: { key, channel, flags } };\n }\n }\n\n return {\n intent: 'unknown',\n reasons: ['No matching rule.'],\n recommendation: { httpStatus: 500, message: 'Unroutable request' },\n debug: { key, channel, flags },\n };\n}"]}
|
|
1
|
+
{"version":3,"file":"decide-request-intent.utils.js","sourceRoot":"","sources":["../../../../src/common/utils/decide-request-intent.utils.ts"],"names":[],"mappings":";;;AA4YA,oCAsDC;AAlcD,6BAAwB;AAGxB,iFAAiF;AAEpE,QAAA,YAAY,GAAG,OAAC,CAAC,KAAK,CAAC;IAClC,OAAC,CAAC,OAAO,CAAC,YAAY,CAAC;IACvB,OAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAChB,OAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC;IAC5B,OAAC,CAAC,OAAO,CAAC,eAAe,CAAC;IAC1B,OAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC;IAC3B,OAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC;IAC3B,OAAC,CAAC,OAAO,CAAC,SAAS,CAAC;CACrB,CAAC,CAAC;AAEU,QAAA,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,MAAM,EAAE,oBAAY;IACpB,OAAO,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,OAAC;SACd,MAAM,CAAC;QACN,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE;QACtB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;KACpB,CAAC;SACD,QAAQ,EAAE;IACb,qDAAqD;IACrD,KAAK,EAAE,OAAC;SACL,MAAM,CAAC;QACN,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE;QACf,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;QACnB,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;KAClB,CAAC;SACD,QAAQ,EAAE;CACd,CAAC,CAAC;AA8BH;;;;;;;;;;;;;;;;;;;;gFAoBgF;AAEhF,+EAA+E;AAE/E,MAAM,QAAQ,GAAG,KAAK,CAAC;AACvB,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,wDAAwD;AAClF,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAChC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAC/B,MAAM,YAAY,GAAG,KAAK,CAAC;AAC3B,MAAM,WAAW,GAAG,KAAK,CAAC;AAC1B,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,gCAAgC;AAC/D,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,wCAAwC;AAEvE,MAAM,OAAO,GAAG,UAAU,CAAC;AAE3B,+EAA+E;AAE/E,MAAM,aAAa,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;AAClC,MAAM,cAAc,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK;AACpC,MAAM,aAAa,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK;AACnC,MAAM,aAAa,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,wDAAwD;AACtF,MAAM,iBAAiB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;AACxC,MAAM,eAAe,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;AACtC,MAAM,aAAa,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;AACpC,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO;AAEpC,gFAAgF;AAEhF,MAAM,CAAC,GAAG,CAAC,GAAkB,EAAE,IAAY,EAAE,EAAE,CAC7C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAEzF,MAAM,QAAQ,GAAG,CAAC,MAAe,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;AACjG,MAAM,SAAS,GAAG,CAAC,MAAe,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;AACjG,MAAM,YAAY,GAAG,CAAC,IAAa,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAK,IAAY,CAAC,MAAM,KAAK,YAAY,CAAC;AAEpH,qDAAqD;AACrD,SAAS,MAAM,CAAC,GAAkB;IAChC,MAAM,MAAM,GAAG,GAAU,CAAC;IAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC;IAChE,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC,QAAQ,IAAI,GAAG,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,8CAA8C;AAC9C,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,qFAAqF;AACrF,SAAS,sBAAsB,CAAC,SAAkB;IAChD,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACpE,OAAO,GAAG,EAAE,aAAa,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;AACH,CAAC;AAED,gFAAgF;AAEhF,SAAS,aAAa,CAAC,GAAkB,EAAE,GAAW;IACpD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,KAAK,MAAM,CAAC;IACvD,MAAM,aAAa,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAEzB,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG,MAAM,KAAK,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IAC9F,MAAM,YAAY,GAAG,MAAM,KAAK,KAAK,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;IAE/D,MAAM,OAAO,GACX,MAAM,KAAK,MAAM,IAAI,aAAa;QAChC,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,YAAY,IAAI,SAAS;YAC3B,CAAC,CAAC,eAAe,CAAC,gCAAgC;YAClD,CAAC,CAAC,MAAM,KAAK,KAAK,IAAI,SAAS;gBAC/B,CAAC,CAAC,UAAU,CAAC,qDAAqD;gBAClE,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,IAAI,SAAS;oBACxC,CAAC,CAAC,gBAAgB;oBAClB,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,IAAI,UAAU;wBACzC,CAAC,CAAC,iBAAiB;wBACnB,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,IAAI,SAAS;4BACzC,CAAC,CAAC,WAAW;4BACb,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,IAAI,UAAU;gCAC1C,CAAC,CAAC,YAAY;gCACd,CAAC,CAAC,QAAQ,CAAC;IAEf,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,SAAS;QAAE,KAAK,IAAI,aAAa,CAAC;IACtC,IAAI,GAAG,CAAC,mBAAmB;QAAE,KAAK,IAAI,cAAc,CAAC;IACrD,IAAI,GAAG,CAAC,2BAA2B;QAAE,KAAK,IAAI,aAAa,CAAC;IAC5D,IAAI,YAAY,IAAI,aAAa,KAAK,YAAY;QAAE,KAAK,IAAI,aAAa,CAAC,CAAC,gBAAgB;IAC5F,IAAI,GAAG,CAAC,iBAAiB;QAAE,KAAK,IAAI,iBAAiB,CAAC;IACtD,IAAI,GAAG,CAAC,oBAAoB;QAAE,KAAK,IAAI,eAAe,CAAC;IACvD,IAAI,GAAG,CAAC,kBAAkB;QAAE,KAAK,IAAI,aAAa,CAAC;IACnD,IAAI,GAAG,CAAC,eAAe;QAAE,KAAK,IAAI,WAAW,CAAC;IAE9C,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACpE,CAAC;AAUD,+EAA+E;AAE/E,MAAM,KAAK,GAAW;IACpB,8EAA8E;IAC9E;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,WAAW;QAC3C,KAAK,EAAE,eAAe,GAAG,WAAW,EAAE,2DAA2D;QACjG,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,+CAA+C,EAAE;KAC3F;IACD;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,WAAW;QAC3C,KAAK,EAAE,eAAe,CAAC,oCAAoC;QAC3D,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,sBAAsB;YAC9B,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,qBAAqB,EAAE;SACpE;KACF;IAED,qFAAqF;IACrF,+EAA+E;IAC/E;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,iBAAiB,GAAG,eAAe;QACnE,KAAK,EAAE,UAAU,GAAG,aAAa,GAAG,iBAAiB,GAAG,eAAe;QACvE,OAAO,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,2DAA2D,EAAE;KAC5G;IACD,iEAAiE;IACjE;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,iBAAiB;QACjD,KAAK,EAAE,UAAU,GAAG,aAAa,CAAC,uBAAuB;QACzD,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,2CAA2C;YACnD,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,uBAAuB,EAAE;SACtE;KACF;IACD,gEAAgE;IAChE;QACE,IAAI,EAAE,OAAO,GAAG,aAAa;QAC7B,KAAK,EAAE,UAAU,CAAC,gBAAgB;QAClC,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,oDAAoD;SAC7D;KACF;IAED,+CAA+C;IAC/C;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,WAAW;QAC3C,KAAK,EAAE,eAAe,GAAG,aAAa,GAAG,WAAW;QACpD,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,wDAAwD,EAAE;KACpG;IACD;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,WAAW;QAC3C,KAAK,EAAE,eAAe,GAAG,aAAa,CAAC,qBAAqB;QAC5D,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,oCAAoC;YAC5C,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,qBAAqB,EAAE;SACpE;KACF;IAED,wEAAwE;IACxE;QACE,IAAI,EAAE,OAAO,GAAG,iBAAiB,GAAG,aAAa;QACjD,KAAK,EAAE,eAAe,GAAG,aAAa,CAAC,uBAAuB;QAC9D,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,wBAAwB;YAChC,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,uBAAuB,EAAE;SACtE;KACF;IACD;QACE,IAAI,EAAE,OAAO,GAAG,iBAAiB,GAAG,aAAa;QACjD,KAAK,EAAE,eAAe,GAAG,iBAAiB,GAAG,aAAa;QAC1D,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE;KACpE;IAED,6BAA6B;IAC7B,+FAA+F;IAC/F;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,cAAc;QAC9C,KAAK,EAAE,gBAAgB,GAAG,cAAc,CAAC,gBAAgB;QACzD,OAAO,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,oCAAoC,EAAE;KACpF;IACD;QACE,IAAI,EAAE,OAAO,GAAG,eAAe;QAC/B,KAAK,EAAE,gBAAgB,CAAC,yBAAyB;QACjD,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,2BAA2B;YACnC,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,0BAA0B,EAAE;SACzE;KACF;IACD;QACE,IAAI,EAAE,OAAO,GAAG,eAAe;QAC/B,KAAK,EAAE,gBAAgB,GAAG,eAAe;QACzC,OAAO,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,sBAAsB,EAAE;KACvE;IAED,8BAA8B;IAC9B,kGAAkG;IAClG;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,cAAc;QAC9C,KAAK,EAAE,iBAAiB,GAAG,cAAc,CAAC,gBAAgB;QAC1D,OAAO,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,yCAAyC,EAAE;KACzF;IACD;QACE,IAAI,EAAE,OAAO,GAAG,eAAe;QAC/B,KAAK,EAAE,iBAAiB,CAAC,yBAAyB;QAClD,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,qBAAqB;YAC7B,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,oBAAoB,EAAE;SACnE;KACF;IACD;QACE,IAAI,EAAE,OAAO,GAAG,eAAe;QAC/B,KAAK,EAAE,iBAAiB,GAAG,eAAe;QAC1C,OAAO,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,uBAAuB,EAAE;KACtE;IAED,yBAAyB;IACzB;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,aAAa,GAAG,cAAc;QAC9D,KAAK,EAAE,WAAW,GAAG,aAAa,CAAC,kCAAkC;QACrE,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,4BAA4B;YACpC,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,yCAAyC,EAAE;SACxF;KACF;IACD;QACE,IAAI,EAAE,OAAO,GAAG,eAAe;QAC/B,KAAK,EAAE,WAAW,CAAC,yBAAyB;QAC5C,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,2BAA2B;YACnC,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,0BAA0B,EAAE;SACzE;KACF;IACD;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,cAAc;QAC9C,KAAK,EAAE,WAAW,GAAG,cAAc,CAAC,gBAAgB;QACpD,OAAO,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,4BAA4B,EAAE;KAC5E;IACD;QACE,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,mCAAmC,EAAE;KACpF;IAED,0BAA0B;IAC1B;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,aAAa,GAAG,cAAc;QAC9D,KAAK,EAAE,YAAY,GAAG,aAAa,CAAC,kCAAkC;QACtE,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,6BAA6B;YACrC,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,yCAAyC,EAAE;SACxF;KACF;IACD;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,eAAe;QAC/C,KAAK,EAAE,YAAY,CAAC,qBAAqB;QACzC,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,qBAAqB;YAC7B,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,oBAAoB,EAAE;SACnE;KACF;IACD;QACE,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,cAAc;QAC9C,KAAK,EAAE,YAAY,GAAG,cAAc,CAAC,gBAAgB;QACrD,OAAO,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,yBAAyB,EAAE;KACzE;IACD;QACE,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,YAAY;QACnB,OAAO,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,2BAA2B,EAAE;KAC1E;IAED,cAAc;IACd;QACE,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,4BAA4B;YACpC,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,2BAA2B,EAAE;SAC1E;KACF;CACF,CAAC;AAEF,gFAAgF;AAEhF,SAAgB,YAAY,CAAC,GAAkB,EAAE,GAAW;IAC1D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;IAExC,mEAAmE;IACnE,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAC3C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;gBACL,MAAM,EAAE,SAAS;gBACjB,OAAO,EAAE,CAAC,wCAAwC,CAAC;gBACnD,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,gCAAgC,EAAE;gBAC9E,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;aACxC,CAAC;QACJ,CAAC;QACD,OAAO;YACL,MAAM,EAAE,gBAAgB;YACxB,OAAO,EAAE,CAAC,mDAAmD,CAAC;YAC9D,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE;SACpE,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAE9D,8DAA8D;IAC9D,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,qBAAqB,CAAC,CAAC;QAChF,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW,EAAE,CAAC;YAChC,OAAO;gBACL,MAAM,EAAE,SAAS;gBACjB,OAAO,EAAE,CAAC,2DAA2D,CAAC;gBACtE,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,EAAE;gBAC9D,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;aAC/B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACrC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrB,IAAI,IAAI;gBAAE,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YACpD,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,CAAC,mBAAmB,CAAC;QAC9B,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,oBAAoB,EAAE;QAClE,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;KAC/B,CAAC;AACJ,CAAC","sourcesContent":["import { z } from 'zod';\nimport { ServerRequest } from '../interfaces';\n\n/* --------------------------------- Schemas --------------------------------- */\n\nexport const intentSchema = z.union([\n z.literal('legacy-sse'),\n z.literal('sse'),\n z.literal('streamable-http'),\n z.literal('stateful-http'),\n z.literal('stateless-http'),\n z.literal('delete-session'),\n z.literal('unknown'),\n]);\n\nexport const decisionSchema = z.object({\n intent: intentSchema,\n reasons: z.array(z.string()),\n recommendation: z\n .object({\n httpStatus: z.number(),\n message: z.string(),\n })\n .optional(),\n // Echo back bits for debugging/telemetry if you like\n debug: z\n .object({\n key: z.number(),\n channel: z.number(),\n flags: z.number(),\n })\n .optional(),\n});\n\nexport type HttpRequestIntent =\n | 'legacy-sse'\n | 'sse'\n | 'streamable-http'\n | 'stateful-http'\n | 'stateless-http'\n | 'delete-session';\n\nexport type Intent = HttpRequestIntent | 'unknown';\n\nexport type Decision = {\n intent: Intent;\n reasons: string[];\n recommendation?: { httpStatus: number; message: string };\n // Echo back bits for debugging/telemetry if you like\n debug?: { key: number; channel: number; flags: number };\n};\n\nexport interface Config {\n enableLegacySSE: boolean;\n enableSseListener: boolean;\n enableStreamableHttp: boolean;\n enableStatefulHttp: boolean;\n enableStatelessHttp: boolean;\n requireSessionForStreamable: boolean;\n tolerateMissingAccept: boolean;\n}\n\n/* ------------------------------- Bit layout ---------------------------------\n\nbits 0..2 CHANNEL\n 000 OTHER\n 001 GET_SSE (GET + Accept: text/event-stream)\n 010 POST_INIT_JSON (POST initialize + Accept: application/json or default JSON)\n 011 POST_INIT_SSE (POST initialize + Accept: text/event-stream)\n 100 POST_JSON (POST non-init + Accept: application/json or default JSON)\n 101 POST_SSE (POST non-init + Accept: text/event-stream)\n 110 POST_MESSAGE (POST to /message) ← legacy bridge\n\nbit 3 HAS_SESSION (Mcp-Session-Id present)\nbit 4 STATELESS_EN (config: enableStatelessHttp)\nbit 5 REQ_SESSION (config: requireSessionForStreamable)\nbit 6 LEGACY_HINT (x-legacy-sse=true OR session.transportType=legacy-sse)\nbit 7 SSE_LISTENER_EN (config: enableSseListener)\nbit 8 STREAMABLE_EN (config: enableStreamableHttp)\nbit 9 STATEFUL_EN (config: enableStatefulHttp)\nbit 10 LEGACY_EN (config: enableLegacySSE)\n\n----------------------------------------------------------------------------- */\n\n// --- Channels ---------------------------------------------------------------\n\nconst CH_OTHER = 0b000;\nconst CH_GET_SSE = 0b001; // GET / + SSE (not handled, forward to next middleware)\nconst CH_POST_INIT_JSON = 0b010;\nconst CH_POST_INIT_SSE = 0b011;\nconst CH_POST_JSON = 0b100;\nconst CH_POST_SSE = 0b101;\nconst CH_POST_MESSAGE = 0b110; // POST /message (legacy bridge)\nconst CH_GET_SSE_PATH = 0b111; // GET /sse path (legacy SSE initialize)\n\nconst CH_MASK = 0b00000111;\n\n// --- Flags ------------------------------------------------------------------\n\nconst B_HAS_SESSION = 1 << 3; // 8\nconst B_STATELESS_EN = 1 << 4; // 16\nconst B_REQ_SESSION = 1 << 5; // 32\nconst B_LEGACY_HINT = 1 << 6; // 64 (kept for telemetry; not required by merged rules)\nconst B_SSE_LISTENER_EN = 1 << 7; // 128\nconst B_STREAMABLE_EN = 1 << 8; // 256\nconst B_STATEFUL_EN = 1 << 9; // 512\nconst B_LEGACY_EN = 1 << 10; // 1024\n\n// --- Minimal helpers ---------------------------------------------------------\n\nconst h = (req: ServerRequest, name: string) =>\n Object.entries(req.headers).find(([k]) => k.toLowerCase() === name.toLowerCase())?.[1];\n\nconst wantsSSE = (accept?: string) => (accept ?? '').toLowerCase().includes('text/event-stream');\nconst wantsJSON = (accept?: string) => (accept ?? '').toLowerCase().includes('application/json');\nconst isInitialize = (body: unknown) => !!body && typeof body === 'object' && (body as any).method === 'initialize';\n\n// Robust path extractor (supports absolute/relative)\nfunction pathOf(req: ServerRequest): string {\n const anyReq = req as any;\n const raw = anyReq.path ?? anyReq.pathname ?? anyReq.url ?? '/';\n try {\n const u = new URL(String(raw), 'http://local');\n return u.pathname || '/';\n } catch {\n return String(raw).split('?')[0] || '/';\n }\n}\n\n// Check if path is the legacy SSE path (/sse)\nfunction isLegacySsePath(path: string): boolean {\n return path === '/sse' || path.endsWith('/sse');\n}\n\n/** Optionally extract transportType from base64 JSON session id, if you embed it. */\nfunction tryDecodeTransportType(sessionId?: string): string | undefined {\n if (!sessionId) return;\n try {\n const b64 = sessionId.replace(/-/g, '+').replace(/_/g, '/');\n const obj = JSON.parse(Buffer.from(b64, 'base64').toString('utf8'));\n return obj?.transportType;\n } catch {\n return;\n }\n}\n\n// --- Build the 11-bit key ----------------------------------------------------\n\nfunction computeBitmap(req: ServerRequest, cfg: Config) {\n const method = req.method.toUpperCase();\n const accept = h(req, 'accept');\n const sessionId = h(req, 'mcp-session-id');\n const legacyHeader = h(req, 'x-legacy-sse') === 'true';\n const transportType = tryDecodeTransportType(sessionId);\n const path = pathOf(req);\n\n const acceptSSE = wantsSSE(accept);\n const acceptJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);\n const init = method === 'POST' && isInitialize(req.body);\n const postToMessage = method === 'POST' && (path === '/message' || path.endsWith('/message'));\n const getToSsePath = method === 'GET' && isLegacySsePath(path);\n\n const channel =\n method === 'POST' && postToMessage\n ? CH_POST_MESSAGE\n : getToSsePath && acceptSSE\n ? CH_GET_SSE_PATH // GET /sse → legacy SSE channel\n : method === 'GET' && acceptSSE\n ? CH_GET_SSE // GET / + SSE → forward to next middleware (unknown)\n : method === 'POST' && init && acceptSSE\n ? CH_POST_INIT_SSE\n : method === 'POST' && init && acceptJSON\n ? CH_POST_INIT_JSON\n : method === 'POST' && !init && acceptSSE\n ? CH_POST_SSE\n : method === 'POST' && !init && acceptJSON\n ? CH_POST_JSON\n : CH_OTHER;\n\n let flags = 0;\n if (sessionId) flags |= B_HAS_SESSION;\n if (cfg.enableStatelessHttp) flags |= B_STATELESS_EN;\n if (cfg.requireSessionForStreamable) flags |= B_REQ_SESSION;\n if (legacyHeader || transportType === 'legacy-sse') flags |= B_LEGACY_HINT; // informational\n if (cfg.enableSseListener) flags |= B_SSE_LISTENER_EN;\n if (cfg.enableStreamableHttp) flags |= B_STREAMABLE_EN;\n if (cfg.enableStatefulHttp) flags |= B_STATEFUL_EN;\n if (cfg.enableLegacySSE) flags |= B_LEGACY_EN;\n\n return { key: (channel & CH_MASK) | flags, channel, flags, init };\n}\n\n// --- Rule definition ---------------------------------------------------------\n\ntype Rule = {\n care: number; // which bits matter\n match: number; // the exact bit pattern to match (after masking)\n outcome: Omit<Decision, 'reasons' | 'debug'> & { reason: string };\n};\n\n// --- Rules (merged semantics) -----------------------------------------------\n\nconst RULES: Rule[] = [\n // A) Legacy SSE via GET /sse path (without session) → requires legacy enabled\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_GET_SSE_PATH | B_LEGACY_EN, // HAS_SESSION must be 0; it's in 'care' but not in 'match'\n outcome: { intent: 'legacy-sse', reason: 'GET /sse without Mcp-Session-Id → legacy SSE.' },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_GET_SSE_PATH /* legacy disabled; HAS_SESSION=0 */,\n outcome: {\n intent: 'unknown',\n reason: 'Legacy SSE disabled.',\n recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },\n },\n },\n\n // A2) GET / + SSE (not /sse path) with session ID → SSE listener for streamable-http\n // Per MCP 2025-11-25 spec, clients can open SSE stream via GET with session ID\n {\n care: CH_MASK | B_HAS_SESSION | B_SSE_LISTENER_EN | B_STREAMABLE_EN,\n match: CH_GET_SSE | B_HAS_SESSION | B_SSE_LISTENER_EN | B_STREAMABLE_EN,\n outcome: { intent: 'streamable-http', reason: 'GET / with session ID → SSE listener for streamable-http.' },\n },\n // A2b) GET / + SSE with session but listener/streamable disabled\n {\n care: CH_MASK | B_HAS_SESSION | B_SSE_LISTENER_EN,\n match: CH_GET_SSE | B_HAS_SESSION /* listener disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'SSE listener disabled for GET / requests.',\n recommendation: { httpStatus: 405, message: 'SSE listener disabled' },\n },\n },\n // A2c) GET / + SSE without session → forward to next middleware\n {\n care: CH_MASK | B_HAS_SESSION,\n match: CH_GET_SSE /* no session */,\n outcome: {\n intent: 'unknown',\n reason: 'GET / with SSE requires session for MCP transport.',\n },\n },\n\n // B) Legacy SSE: POST /message WITH session id\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_POST_MESSAGE | B_HAS_SESSION | B_LEGACY_EN,\n outcome: { intent: 'legacy-sse', reason: 'POST /message with Mcp-Session-Id → legacy SSE bridge.' },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_LEGACY_EN,\n match: CH_POST_MESSAGE | B_HAS_SESSION /* legacy disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Legacy /message endpoint disabled.',\n recommendation: { httpStatus: 405, message: 'Legacy SSE disabled' },\n },\n },\n\n // C) Modern SSE (GET /sse with session) → requires SSE listener enabled\n {\n care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,\n match: CH_GET_SSE_PATH | B_HAS_SESSION /* listener disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'SSE listener disabled.',\n recommendation: { httpStatus: 405, message: 'SSE listener disabled' },\n },\n },\n {\n care: CH_MASK | B_SSE_LISTENER_EN | B_HAS_SESSION,\n match: CH_GET_SSE_PATH | B_SSE_LISTENER_EN | B_HAS_SESSION,\n outcome: { intent: 'sse', reason: 'GET /sse with Mcp-Session-Id.' },\n },\n\n // D) Initialize (POST → SSE)\n // D1) Stateless initialize (no session, stateless enabled) - must come before streamable rules\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_INIT_SSE | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless initialize (no session).' },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_SSE /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Streamable HTTP disabled.',\n recommendation: { httpStatus: 405, message: 'Streamable HTTP disabled' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_SSE | B_STREAMABLE_EN,\n outcome: { intent: 'streamable-http', reason: 'Initialize with SSE.' },\n },\n\n // E) Initialize (POST → JSON)\n // E1) Stateless initialize JSON (no session, stateless enabled) - must come before stateful rules\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_INIT_JSON | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless initialize JSON (no session).' },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_JSON /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'JSON mode disabled.',\n recommendation: { httpStatus: 405, message: 'JSON mode disabled' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_INIT_JSON | B_STREAMABLE_EN,\n outcome: { intent: 'stateful-http', reason: 'Initialize with JSON.' },\n },\n\n // F) POST non-init → SSE\n {\n care: CH_MASK | B_REQ_SESSION | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_SSE | B_REQ_SESSION /* !HAS_SESSION & !STATELESS_EN */,\n outcome: {\n intent: 'unknown',\n reason: 'POST SSE requires session.',\n recommendation: { httpStatus: 400, message: 'Initialize required (no Mcp-Session-Id)' },\n },\n },\n {\n care: CH_MASK | B_STREAMABLE_EN,\n match: CH_POST_SSE /* streamable disabled */,\n outcome: {\n intent: 'unknown',\n reason: 'Streamable HTTP disabled.',\n recommendation: { httpStatus: 405, message: 'Streamable HTTP disabled' },\n },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_SSE | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless short-lived SSE.' },\n },\n {\n care: CH_MASK,\n match: CH_POST_SSE,\n outcome: { intent: 'streamable-http', reason: 'Short-lived SSE for this request.' },\n },\n\n // G) POST non-init → JSON\n {\n care: CH_MASK | B_REQ_SESSION | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_JSON | B_REQ_SESSION /* !HAS_SESSION & !STATELESS_EN */,\n outcome: {\n intent: 'unknown',\n reason: 'POST JSON requires session.',\n recommendation: { httpStatus: 400, message: 'Initialize required (no Mcp-Session-Id)' },\n },\n },\n {\n care: CH_MASK | B_STATEFUL_EN | B_STREAMABLE_EN,\n match: CH_POST_JSON /* neither enabled */,\n outcome: {\n intent: 'unknown',\n reason: 'JSON mode disabled.',\n recommendation: { httpStatus: 405, message: 'JSON mode disabled' },\n },\n },\n {\n care: CH_MASK | B_HAS_SESSION | B_STATELESS_EN,\n match: CH_POST_JSON | B_STATELESS_EN /* no session */,\n outcome: { intent: 'stateless-http', reason: 'Stateless JSON request.' },\n },\n {\n care: CH_MASK,\n match: CH_POST_JSON,\n outcome: { intent: 'stateful-http', reason: 'Aggregated JSON response.' },\n },\n\n // H) Fallback\n {\n care: CH_MASK,\n match: CH_OTHER,\n outcome: {\n intent: 'unknown',\n reason: 'Method/Accept not allowed.',\n recommendation: { httpStatus: 405, message: 'Method/Accept not allowed' },\n },\n },\n];\n\n// --- Public API --------------------------------------------------------------\n\nexport function decideIntent(req: ServerRequest, cfg: Config): Decision {\n const reasons: string[] = [];\n const method = req.method.toUpperCase();\n\n // Handle HTTP DELETE for session termination (MCP 2025-11-25 spec)\n if (method === 'DELETE') {\n const sessionId = h(req, 'mcp-session-id');\n if (!sessionId) {\n return {\n intent: 'unknown',\n reasons: ['DELETE requires Mcp-Session-Id header.'],\n recommendation: { httpStatus: 400, message: 'Session ID required for DELETE' },\n debug: { key: 0, channel: 0, flags: 0 },\n };\n }\n return {\n intent: 'delete-session',\n reasons: ['DELETE with Mcp-Session-Id → session termination.'],\n debug: { key: 0, channel: 0, flags: sessionId ? B_HAS_SESSION : 0 },\n };\n }\n\n const { key, channel, flags, init } = computeBitmap(req, cfg);\n\n // Optional strict Accept validation for POST (incl. /message)\n if (method === 'POST') {\n const accept = h(req, 'accept');\n const acceptsSSE = wantsSSE(accept);\n const acceptsJSON = wantsJSON(accept) || (!accept && cfg.tolerateMissingAccept);\n if (!acceptsSSE && !acceptsJSON) {\n return {\n intent: 'unknown',\n reasons: ['Client must accept application/json or text/event-stream.'],\n recommendation: { httpStatus: 406, message: 'Not acceptable' },\n debug: { key, channel, flags },\n };\n }\n }\n\n for (const rule of RULES) {\n if ((key & rule.care) === rule.match) {\n const { reason, ...rest } = rule.outcome;\n reasons.push(reason);\n if (init) reasons.push('Initialize body detected.');\n return { ...rest, reasons, debug: { key, channel, flags } };\n }\n }\n\n return {\n intent: 'unknown',\n reasons: ['No matching rule.'],\n recommendation: { httpStatus: 500, message: 'Unroutable request' },\n debug: { key, channel, flags },\n };\n}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { FlowBase, FlowRunOptions } from '../../common';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
declare const inputSchema: z.ZodObject<{
|
|
4
|
+
request: z.ZodObject<{
|
|
5
|
+
method: z.ZodLiteral<"completion/complete">;
|
|
6
|
+
params: z.ZodObject<{
|
|
7
|
+
_meta: z.ZodOptional<z.ZodObject<{
|
|
8
|
+
progressToken: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
|
|
9
|
+
}, z.core.$loose>>;
|
|
10
|
+
ref: z.ZodUnion<readonly [z.ZodObject<{
|
|
11
|
+
type: z.ZodLiteral<"ref/prompt">;
|
|
12
|
+
name: z.ZodString;
|
|
13
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
14
|
+
type: z.ZodLiteral<"ref/resource">;
|
|
15
|
+
uri: z.ZodString;
|
|
16
|
+
}, z.core.$strip>]>;
|
|
17
|
+
argument: z.ZodObject<{
|
|
18
|
+
name: z.ZodString;
|
|
19
|
+
value: z.ZodString;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
context: z.ZodOptional<z.ZodObject<{
|
|
22
|
+
arguments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
23
|
+
}, z.core.$strip>>;
|
|
24
|
+
}, z.core.$loose>;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
ctx: z.ZodUnknown;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
declare const outputSchema: z.ZodObject<{
|
|
29
|
+
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
30
|
+
completion: z.ZodObject<{
|
|
31
|
+
values: z.ZodArray<z.ZodString>;
|
|
32
|
+
total: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
hasMore: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
}, z.core.$loose>;
|
|
35
|
+
}, z.core.$loose>;
|
|
36
|
+
declare const stateSchema: z.ZodObject<{
|
|
37
|
+
ref: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
38
|
+
type: z.ZodLiteral<"ref/prompt">;
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
41
|
+
type: z.ZodLiteral<"ref/resource">;
|
|
42
|
+
uri: z.ZodString;
|
|
43
|
+
}, z.core.$strip>], "type">;
|
|
44
|
+
argument: z.ZodObject<{
|
|
45
|
+
name: z.ZodString;
|
|
46
|
+
value: z.ZodString;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
output: z.ZodObject<{
|
|
49
|
+
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
50
|
+
completion: z.ZodObject<{
|
|
51
|
+
values: z.ZodArray<z.ZodString>;
|
|
52
|
+
total: z.ZodOptional<z.ZodNumber>;
|
|
53
|
+
hasMore: z.ZodOptional<z.ZodBoolean>;
|
|
54
|
+
}, z.core.$loose>;
|
|
55
|
+
}, z.core.$loose>;
|
|
56
|
+
}, z.core.$strip>;
|
|
57
|
+
declare const plan: {
|
|
58
|
+
readonly pre: ["parseInput"];
|
|
59
|
+
readonly execute: ["complete"];
|
|
60
|
+
readonly finalize: ["finalize"];
|
|
61
|
+
};
|
|
62
|
+
declare global {
|
|
63
|
+
interface ExtendFlows {
|
|
64
|
+
'completion:complete': FlowRunOptions<CompleteFlow, typeof plan, typeof inputSchema, typeof outputSchema, typeof stateSchema>;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
declare const name: "completion:complete";
|
|
68
|
+
export default class CompleteFlow extends FlowBase<typeof name> {
|
|
69
|
+
logger: import("../../common").FrontMcpLogger;
|
|
70
|
+
parseInput(): Promise<void>;
|
|
71
|
+
complete(): Promise<void>;
|
|
72
|
+
finalize(): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
export {};
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// file: libs/sdk/src/completion/flows/complete.flow.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("../../common");
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
8
|
+
const errors_1 = require("../../errors");
|
|
9
|
+
const ui_1 = require("../../tool/ui");
|
|
10
|
+
const inputSchema = zod_1.z.object({
|
|
11
|
+
request: types_js_1.CompleteRequestSchema,
|
|
12
|
+
ctx: zod_1.z.unknown(),
|
|
13
|
+
});
|
|
14
|
+
const outputSchema = types_js_1.CompleteResultSchema;
|
|
15
|
+
/**
|
|
16
|
+
* Reference types for completion requests
|
|
17
|
+
*/
|
|
18
|
+
const PromptRefSchema = zod_1.z.object({
|
|
19
|
+
type: zod_1.z.literal('ref/prompt'),
|
|
20
|
+
name: zod_1.z.string(),
|
|
21
|
+
});
|
|
22
|
+
const ResourceRefSchema = zod_1.z.object({
|
|
23
|
+
type: zod_1.z.literal('ref/resource'),
|
|
24
|
+
uri: zod_1.z.string(),
|
|
25
|
+
});
|
|
26
|
+
const stateSchema = zod_1.z.object({
|
|
27
|
+
ref: zod_1.z.discriminatedUnion('type', [PromptRefSchema, ResourceRefSchema]),
|
|
28
|
+
argument: zod_1.z.object({
|
|
29
|
+
name: zod_1.z.string(),
|
|
30
|
+
value: zod_1.z.string(),
|
|
31
|
+
}),
|
|
32
|
+
output: outputSchema,
|
|
33
|
+
});
|
|
34
|
+
const plan = {
|
|
35
|
+
pre: ['parseInput'],
|
|
36
|
+
execute: ['complete'],
|
|
37
|
+
finalize: ['finalize'],
|
|
38
|
+
};
|
|
39
|
+
const name = 'completion:complete';
|
|
40
|
+
const { Stage } = (0, common_1.FlowHooksOf)(name);
|
|
41
|
+
let CompleteFlow = class CompleteFlow extends common_1.FlowBase {
|
|
42
|
+
logger = this.scopeLogger.child('CompleteFlow');
|
|
43
|
+
async parseInput() {
|
|
44
|
+
this.logger.verbose('parseInput:start');
|
|
45
|
+
let method;
|
|
46
|
+
let params;
|
|
47
|
+
try {
|
|
48
|
+
const inputData = inputSchema.parse(this.rawInput);
|
|
49
|
+
method = inputData.request.method;
|
|
50
|
+
params = inputData.request.params;
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
throw new errors_1.InvalidInputError('Invalid Input', e instanceof zod_1.z.ZodError ? e.issues : undefined);
|
|
54
|
+
}
|
|
55
|
+
if (method !== 'completion/complete') {
|
|
56
|
+
this.logger.warn(`parseInput: invalid method "${method}"`);
|
|
57
|
+
throw new errors_1.InvalidMethodError(method, 'completion/complete');
|
|
58
|
+
}
|
|
59
|
+
const { ref, argument } = params;
|
|
60
|
+
// Validate ref structure
|
|
61
|
+
if (!ref || !ref.type) {
|
|
62
|
+
throw new errors_1.InvalidInputError('Reference (ref) is required with type field');
|
|
63
|
+
}
|
|
64
|
+
if (ref.type !== 'ref/prompt' && ref.type !== 'ref/resource') {
|
|
65
|
+
// Cast needed because TypeScript exhaustively checks ref.type, making it 'never' in this branch
|
|
66
|
+
throw new errors_1.InvalidInputError(`Invalid reference type: ${ref.type}. Expected "ref/prompt" or "ref/resource"`);
|
|
67
|
+
}
|
|
68
|
+
// Validate argument structure
|
|
69
|
+
if (!argument || typeof argument.name !== 'string' || typeof argument.value !== 'string') {
|
|
70
|
+
throw new errors_1.InvalidInputError('Argument must have "name" and "value" string fields');
|
|
71
|
+
}
|
|
72
|
+
this.state.set({ ref, argument });
|
|
73
|
+
this.logger.verbose('parseInput:done');
|
|
74
|
+
}
|
|
75
|
+
async complete() {
|
|
76
|
+
this.logger.verbose('complete:start');
|
|
77
|
+
const { ref, argument } = this.state.required;
|
|
78
|
+
let values = [];
|
|
79
|
+
let total;
|
|
80
|
+
let hasMore;
|
|
81
|
+
if (ref.type === 'ref/prompt') {
|
|
82
|
+
// Get completion suggestions for a prompt argument
|
|
83
|
+
const { name: promptName } = ref;
|
|
84
|
+
const { name: argName, value: argValue } = argument;
|
|
85
|
+
this.logger.debug(`complete: prompt completion for "${promptName}" argument "${argName}" with value "${argValue}"`);
|
|
86
|
+
// Look up the prompt in the registry
|
|
87
|
+
const prompt = this.scope.prompts.findByName(promptName);
|
|
88
|
+
if (prompt) {
|
|
89
|
+
// Check if the prompt instance has a completer for this argument
|
|
90
|
+
// Completion support is optional - prompts can implement getArgumentCompleter to provide suggestions
|
|
91
|
+
const instance = prompt; // PromptInstance may have completer method
|
|
92
|
+
if (typeof instance.getArgumentCompleter === 'function') {
|
|
93
|
+
const completer = instance.getArgumentCompleter(argName);
|
|
94
|
+
if (completer) {
|
|
95
|
+
try {
|
|
96
|
+
const result = await completer(argValue);
|
|
97
|
+
values = result.values || [];
|
|
98
|
+
total = result.total;
|
|
99
|
+
hasMore = result.hasMore;
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
this.logger.warn(`complete: completer failed for prompt "${promptName}" argument "${argName}": ${e}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
this.logger.debug(`complete: prompt "${promptName}" not found`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else if (ref.type === 'ref/resource') {
|
|
112
|
+
// Get completion suggestions for a resource template URI
|
|
113
|
+
const { uri } = ref;
|
|
114
|
+
const { name: argName, value: argValue } = argument;
|
|
115
|
+
this.logger.debug(`complete: resource completion for URI "${uri}" argument "${argName}" with value "${argValue}"`);
|
|
116
|
+
// Special handling for ui:// widget URIs - complete with tool names that have UI config
|
|
117
|
+
if (uri.startsWith('ui://widget/') && argName === 'toolName') {
|
|
118
|
+
const toolsWithUI = this.scope.tools.getTools().filter((t) => (0, ui_1.hasUIConfig)(t.metadata));
|
|
119
|
+
const toolNames = toolsWithUI.map((t) => t.metadata.id ?? t.metadata.name);
|
|
120
|
+
// Filter by prefix if value is provided
|
|
121
|
+
const prefix = argValue.toLowerCase();
|
|
122
|
+
values = toolNames.filter((name) => name.toLowerCase().startsWith(prefix));
|
|
123
|
+
total = values.length;
|
|
124
|
+
this.logger.debug(`complete: found ${values.length} tools with UI config matching "${argValue}"`);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// Look up the resource template in the registry by URI
|
|
128
|
+
const resourceMatch = this.scope.resources.findResourceForUri(uri);
|
|
129
|
+
if (resourceMatch) {
|
|
130
|
+
// Check if the resource instance has a completer for this argument
|
|
131
|
+
// Completion support is optional - resources can implement getArgumentCompleter to provide suggestions
|
|
132
|
+
const instance = resourceMatch.instance; // ResourceInstance may have completer method
|
|
133
|
+
if (typeof instance.getArgumentCompleter === 'function') {
|
|
134
|
+
const completer = instance.getArgumentCompleter(argName);
|
|
135
|
+
if (completer) {
|
|
136
|
+
try {
|
|
137
|
+
const result = await completer(argValue);
|
|
138
|
+
values = result.values || [];
|
|
139
|
+
total = result.total;
|
|
140
|
+
hasMore = result.hasMore;
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
this.logger.warn(`complete: completer failed for resource "${uri}" argument "${argName}": ${e}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
this.logger.debug(`complete: resource "${uri}" not found`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Build the completion result
|
|
154
|
+
const completion = { values };
|
|
155
|
+
if (total !== undefined) {
|
|
156
|
+
completion.total = total;
|
|
157
|
+
}
|
|
158
|
+
if (hasMore !== undefined) {
|
|
159
|
+
completion.hasMore = hasMore;
|
|
160
|
+
}
|
|
161
|
+
this.state.set({ output: { completion } });
|
|
162
|
+
this.logger.verbose('complete:done');
|
|
163
|
+
}
|
|
164
|
+
async finalize() {
|
|
165
|
+
this.logger.verbose('finalize:start');
|
|
166
|
+
const { output } = this.state.required;
|
|
167
|
+
this.respond(output);
|
|
168
|
+
this.logger.verbose('finalize:done');
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
tslib_1.__decorate([
|
|
172
|
+
Stage('parseInput'),
|
|
173
|
+
tslib_1.__metadata("design:type", Function),
|
|
174
|
+
tslib_1.__metadata("design:paramtypes", []),
|
|
175
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
176
|
+
], CompleteFlow.prototype, "parseInput", null);
|
|
177
|
+
tslib_1.__decorate([
|
|
178
|
+
Stage('complete'),
|
|
179
|
+
tslib_1.__metadata("design:type", Function),
|
|
180
|
+
tslib_1.__metadata("design:paramtypes", []),
|
|
181
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
182
|
+
], CompleteFlow.prototype, "complete", null);
|
|
183
|
+
tslib_1.__decorate([
|
|
184
|
+
Stage('finalize'),
|
|
185
|
+
tslib_1.__metadata("design:type", Function),
|
|
186
|
+
tslib_1.__metadata("design:paramtypes", []),
|
|
187
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
188
|
+
], CompleteFlow.prototype, "finalize", null);
|
|
189
|
+
CompleteFlow = tslib_1.__decorate([
|
|
190
|
+
(0, common_1.Flow)({
|
|
191
|
+
name,
|
|
192
|
+
plan,
|
|
193
|
+
inputSchema,
|
|
194
|
+
outputSchema,
|
|
195
|
+
access: 'authorized',
|
|
196
|
+
})
|
|
197
|
+
], CompleteFlow);
|
|
198
|
+
exports.default = CompleteFlow;
|
|
199
|
+
//# sourceMappingURL=complete.flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete.flow.js","sourceRoot":"","sources":["../../../../src/completion/flows/complete.flow.ts"],"names":[],"mappings":"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","sourcesContent":["// file: libs/sdk/src/completion/flows/complete.flow.ts\n\nimport { Flow, FlowBase, FlowHooksOf, FlowPlan, FlowRunOptions } from '../../common';\nimport { z } from 'zod';\nimport { CompleteRequestSchema, CompleteResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { InvalidMethodError, InvalidInputError } from '../../errors';\nimport { hasUIConfig } from '../../tool/ui';\n\nconst inputSchema = z.object({\n request: CompleteRequestSchema,\n ctx: z.unknown(),\n});\n\nconst outputSchema = CompleteResultSchema;\n\n/**\n * Reference types for completion requests\n */\nconst PromptRefSchema = z.object({\n type: z.literal('ref/prompt'),\n name: z.string(),\n});\n\nconst ResourceRefSchema = z.object({\n type: z.literal('ref/resource'),\n uri: z.string(),\n});\n\nconst stateSchema = z.object({\n ref: z.discriminatedUnion('type', [PromptRefSchema, ResourceRefSchema]),\n argument: z.object({\n name: z.string(),\n value: z.string(),\n }),\n output: outputSchema,\n});\n\nconst plan = {\n pre: ['parseInput'],\n execute: ['complete'],\n finalize: ['finalize'],\n} as const satisfies FlowPlan<string>;\n\ndeclare global {\n interface ExtendFlows {\n 'completion:complete': FlowRunOptions<\n CompleteFlow,\n typeof plan,\n typeof inputSchema,\n typeof outputSchema,\n typeof stateSchema\n >;\n }\n}\n\nconst name = 'completion:complete' as const;\nconst { Stage } = FlowHooksOf<'completion:complete'>(name);\n\n@Flow({\n name,\n plan,\n inputSchema,\n outputSchema,\n access: 'authorized',\n})\nexport default class CompleteFlow extends FlowBase<typeof name> {\n logger = this.scopeLogger.child('CompleteFlow');\n\n @Stage('parseInput')\n async parseInput() {\n this.logger.verbose('parseInput:start');\n\n let method!: string;\n let params: z.infer<typeof CompleteRequestSchema>['params'];\n try {\n const inputData = inputSchema.parse(this.rawInput);\n method = inputData.request.method;\n params = inputData.request.params;\n } catch (e) {\n throw new InvalidInputError('Invalid Input', e instanceof z.ZodError ? e.issues : undefined);\n }\n\n if (method !== 'completion/complete') {\n this.logger.warn(`parseInput: invalid method \"${method}\"`);\n throw new InvalidMethodError(method, 'completion/complete');\n }\n\n const { ref, argument } = params;\n\n // Validate ref structure\n if (!ref || !ref.type) {\n throw new InvalidInputError('Reference (ref) is required with type field');\n }\n\n if (ref.type !== 'ref/prompt' && ref.type !== 'ref/resource') {\n // Cast needed because TypeScript exhaustively checks ref.type, making it 'never' in this branch\n throw new InvalidInputError(\n `Invalid reference type: ${(ref as { type: string }).type}. Expected \"ref/prompt\" or \"ref/resource\"`,\n );\n }\n\n // Validate argument structure\n if (!argument || typeof argument.name !== 'string' || typeof argument.value !== 'string') {\n throw new InvalidInputError('Argument must have \"name\" and \"value\" string fields');\n }\n\n this.state.set({ ref, argument });\n this.logger.verbose('parseInput:done');\n }\n\n @Stage('complete')\n async complete() {\n this.logger.verbose('complete:start');\n const { ref, argument } = this.state.required;\n\n let values: string[] = [];\n let total: number | undefined;\n let hasMore: boolean | undefined;\n\n if (ref.type === 'ref/prompt') {\n // Get completion suggestions for a prompt argument\n const { name: promptName } = ref;\n const { name: argName, value: argValue } = argument;\n\n this.logger.debug(\n `complete: prompt completion for \"${promptName}\" argument \"${argName}\" with value \"${argValue}\"`,\n );\n\n // Look up the prompt in the registry\n const prompt = this.scope.prompts.findByName(promptName);\n\n if (prompt) {\n // Check if the prompt instance has a completer for this argument\n // Completion support is optional - prompts can implement getArgumentCompleter to provide suggestions\n const instance = prompt as any; // PromptInstance may have completer method\n if (typeof instance.getArgumentCompleter === 'function') {\n const completer = instance.getArgumentCompleter(argName);\n if (completer) {\n try {\n const result = await completer(argValue);\n values = result.values || [];\n total = result.total;\n hasMore = result.hasMore;\n } catch (e) {\n this.logger.warn(`complete: completer failed for prompt \"${promptName}\" argument \"${argName}\": ${e}`);\n }\n }\n }\n } else {\n this.logger.debug(`complete: prompt \"${promptName}\" not found`);\n }\n } else if (ref.type === 'ref/resource') {\n // Get completion suggestions for a resource template URI\n const { uri } = ref;\n const { name: argName, value: argValue } = argument;\n\n this.logger.debug(\n `complete: resource completion for URI \"${uri}\" argument \"${argName}\" with value \"${argValue}\"`,\n );\n\n // Special handling for ui:// widget URIs - complete with tool names that have UI config\n if (uri.startsWith('ui://widget/') && argName === 'toolName') {\n const toolsWithUI = this.scope.tools.getTools().filter((t) => hasUIConfig(t.metadata));\n const toolNames = toolsWithUI.map((t) => t.metadata.id ?? t.metadata.name);\n\n // Filter by prefix if value is provided\n const prefix = argValue.toLowerCase();\n values = toolNames.filter((name) => name.toLowerCase().startsWith(prefix));\n total = values.length;\n\n this.logger.debug(`complete: found ${values.length} tools with UI config matching \"${argValue}\"`);\n } else {\n // Look up the resource template in the registry by URI\n const resourceMatch = this.scope.resources.findResourceForUri(uri);\n\n if (resourceMatch) {\n // Check if the resource instance has a completer for this argument\n // Completion support is optional - resources can implement getArgumentCompleter to provide suggestions\n const instance = resourceMatch.instance as any; // ResourceInstance may have completer method\n if (typeof instance.getArgumentCompleter === 'function') {\n const completer = instance.getArgumentCompleter(argName);\n if (completer) {\n try {\n const result = await completer(argValue);\n values = result.values || [];\n total = result.total;\n hasMore = result.hasMore;\n } catch (e) {\n this.logger.warn(`complete: completer failed for resource \"${uri}\" argument \"${argName}\": ${e}`);\n }\n }\n }\n } else {\n this.logger.debug(`complete: resource \"${uri}\" not found`);\n }\n }\n }\n\n // Build the completion result\n const completion: { values: string[]; total?: number; hasMore?: boolean } = { values };\n if (total !== undefined) {\n completion.total = total;\n }\n if (hasMore !== undefined) {\n completion.hasMore = hasMore;\n }\n\n this.state.set({ output: { completion } });\n this.logger.verbose('complete:done');\n }\n\n @Stage('finalize')\n async finalize() {\n this.logger.verbose('finalize:start');\n const { output } = this.state.required;\n this.respond(output);\n this.logger.verbose('finalize:done');\n }\n}\n"]}
|