@rekog/mcp-nest 1.9.10 → 2.0.0-alpha.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 +76 -29
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/decorators/constants.d.ts +1 -0
- package/dist/mcp/decorators/constants.d.ts.map +1 -1
- package/dist/mcp/decorators/constants.js +2 -1
- package/dist/mcp/decorators/constants.js.map +1 -1
- package/dist/mcp/decorators/index.d.ts +3 -1
- package/dist/mcp/decorators/index.d.ts.map +1 -1
- package/dist/mcp/decorators/index.js +3 -1
- package/dist/mcp/decorators/index.js.map +1 -1
- package/dist/mcp/decorators/mcp-controller.decorator.d.ts +6 -0
- package/dist/mcp/decorators/mcp-controller.decorator.d.ts.map +1 -0
- package/dist/mcp/decorators/mcp-controller.decorator.js +43 -0
- package/dist/mcp/decorators/mcp-controller.decorator.js.map +1 -0
- package/dist/mcp/decorators/mcp-message-pattern.d.ts +3 -0
- package/dist/mcp/decorators/mcp-message-pattern.d.ts.map +1 -0
- package/dist/mcp/decorators/mcp-message-pattern.js +13 -0
- package/dist/mcp/decorators/mcp-message-pattern.js.map +1 -0
- package/dist/mcp/decorators/prompt.decorator.d.ts +1 -1
- package/dist/mcp/decorators/prompt.decorator.d.ts.map +1 -1
- package/dist/mcp/decorators/prompt.decorator.js +2 -1
- package/dist/mcp/decorators/prompt.decorator.js.map +1 -1
- package/dist/mcp/decorators/public.decorator.js.map +1 -1
- package/dist/mcp/decorators/raw-request.decorator.d.ts +2 -0
- package/dist/mcp/decorators/raw-request.decorator.d.ts.map +1 -0
- package/dist/mcp/decorators/raw-request.decorator.js +6 -0
- package/dist/mcp/decorators/raw-request.decorator.js.map +1 -0
- package/dist/mcp/decorators/resource-template.decorator.d.ts +1 -1
- package/dist/mcp/decorators/resource-template.decorator.d.ts.map +1 -1
- package/dist/mcp/decorators/resource-template.decorator.js +2 -1
- package/dist/mcp/decorators/resource-template.decorator.js.map +1 -1
- package/dist/mcp/decorators/resource.decorator.d.ts +1 -1
- package/dist/mcp/decorators/resource.decorator.d.ts.map +1 -1
- package/dist/mcp/decorators/resource.decorator.js +2 -1
- package/dist/mcp/decorators/resource.decorator.js.map +1 -1
- package/dist/mcp/decorators/tool.decorator.d.ts +1 -3
- package/dist/mcp/decorators/tool.decorator.d.ts.map +1 -1
- package/dist/mcp/decorators/tool.decorator.js +2 -1
- package/dist/mcp/decorators/tool.decorator.js.map +1 -1
- package/dist/mcp/filters/mcp-exception.filter.d.ts +6 -0
- package/dist/mcp/filters/mcp-exception.filter.d.ts.map +1 -0
- package/dist/mcp/filters/mcp-exception.filter.js +26 -0
- package/dist/mcp/filters/mcp-exception.filter.js.map +1 -0
- package/dist/mcp/index.d.ts +11 -7
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +11 -7
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/interfaces/authenticated-user.interface.d.ts +9 -0
- package/dist/mcp/interfaces/authenticated-user.interface.d.ts.map +1 -0
- package/dist/{authz/interfaces/request-with-user.js → mcp/interfaces/authenticated-user.interface.js} +1 -1
- package/dist/mcp/interfaces/authenticated-user.interface.js.map +1 -0
- package/dist/mcp/interfaces/dynamic-prompt.interface.d.ts +1 -1
- package/dist/mcp/interfaces/dynamic-prompt.interface.d.ts.map +1 -1
- package/dist/mcp/interfaces/dynamic-prompt.interface.js.map +1 -1
- package/dist/mcp/interfaces/dynamic-resource.interface.d.ts +1 -1
- package/dist/mcp/interfaces/dynamic-resource.interface.d.ts.map +1 -1
- package/dist/mcp/interfaces/dynamic-resource.interface.js.map +1 -1
- package/dist/mcp/interfaces/dynamic-tool.interface.d.ts +1 -1
- package/dist/mcp/interfaces/dynamic-tool.interface.d.ts.map +1 -1
- package/dist/mcp/interfaces/dynamic-tool.interface.js.map +1 -1
- package/dist/mcp/interfaces/index.d.ts +2 -2
- package/dist/mcp/interfaces/index.d.ts.map +1 -1
- package/dist/mcp/interfaces/index.js +0 -3
- package/dist/mcp/interfaces/index.js.map +1 -1
- package/dist/mcp/services/tool-authorization.service.d.ts +7 -5
- package/dist/mcp/services/tool-authorization.service.d.ts.map +1 -1
- package/dist/mcp/services/tool-authorization.service.js +9 -6
- package/dist/mcp/services/tool-authorization.service.js.map +1 -1
- package/dist/mcp/transport/mcp-context.d.ts +34 -0
- package/dist/mcp/transport/mcp-context.d.ts.map +1 -0
- package/dist/mcp/transport/mcp-context.js +74 -0
- package/dist/mcp/transport/mcp-context.js.map +1 -0
- package/dist/mcp/transport/mcp-http-handler.d.ts +7 -0
- package/dist/mcp/transport/mcp-http-handler.d.ts.map +1 -0
- package/dist/mcp/transport/mcp-http-handler.js +5 -0
- package/dist/mcp/transport/mcp-http-handler.js.map +1 -0
- package/dist/mcp/transport/mcp-server-options.interface.d.ts +23 -0
- package/dist/mcp/transport/mcp-server-options.interface.d.ts.map +1 -0
- package/dist/{authz/providers/oauth-provider.interface.js → mcp/transport/mcp-server-options.interface.js} +1 -1
- package/dist/mcp/transport/mcp-server-options.interface.js.map +1 -0
- package/dist/mcp/transport/mcp-transport.constants.d.ts +19 -0
- package/dist/mcp/transport/mcp-transport.constants.d.ts.map +1 -0
- package/dist/mcp/transport/mcp-transport.constants.js +21 -0
- package/dist/mcp/transport/mcp-transport.constants.js.map +1 -0
- package/dist/mcp/transport/mcp-transport.interface.d.ts +17 -0
- package/dist/mcp/transport/mcp-transport.interface.d.ts.map +1 -0
- package/dist/{authz/interfaces/oauth-common.interface.js → mcp/transport/mcp-transport.interface.js} +1 -1
- package/dist/mcp/transport/mcp-transport.interface.js.map +1 -0
- package/dist/mcp/transport/mcp.strategy.d.ts +56 -0
- package/dist/mcp/transport/mcp.strategy.d.ts.map +1 -0
- package/dist/mcp/transport/mcp.strategy.js +446 -0
- package/dist/mcp/transport/mcp.strategy.js.map +1 -0
- package/dist/mcp/transport/resource-matcher.d.ts +13 -0
- package/dist/mcp/transport/resource-matcher.d.ts.map +1 -0
- package/dist/mcp/transport/resource-matcher.js +83 -0
- package/dist/mcp/transport/resource-matcher.js.map +1 -0
- package/dist/mcp/transport/streamable-http.controller.d.ts +16 -0
- package/dist/mcp/transport/streamable-http.controller.d.ts.map +1 -0
- package/dist/mcp/transport/streamable-http.controller.js +98 -0
- package/dist/mcp/transport/streamable-http.controller.js.map +1 -0
- package/dist/mcp/transport/transports/index.d.ts +3 -0
- package/dist/mcp/transport/transports/index.d.ts.map +1 -0
- package/dist/{authz → mcp/transport/transports}/index.js +2 -10
- package/dist/mcp/transport/transports/index.js.map +1 -0
- package/dist/mcp/transport/transports/read-body.d.ts +3 -0
- package/dist/mcp/transport/transports/read-body.d.ts.map +1 -0
- package/dist/mcp/transport/transports/read-body.js +32 -0
- package/dist/mcp/transport/transports/read-body.js.map +1 -0
- package/dist/mcp/transport/transports/stdio.transport.d.ts +9 -0
- package/dist/mcp/transport/transports/stdio.transport.d.ts.map +1 -0
- package/dist/mcp/transport/transports/stdio.transport.js +27 -0
- package/dist/mcp/transport/transports/stdio.transport.js.map +1 -0
- package/dist/mcp/transport/transports/streamable-http.transport.d.ts +33 -0
- package/dist/mcp/transport/transports/streamable-http.transport.d.ts.map +1 -0
- package/dist/mcp/transport/transports/streamable-http.transport.js +216 -0
- package/dist/mcp/transport/transports/streamable-http.transport.js.map +1 -0
- package/dist/mcp/utils/mcp-logger.factory.d.ts +6 -2
- package/dist/mcp/utils/mcp-logger.factory.d.ts.map +1 -1
- package/dist/mcp/utils/mcp-logger.factory.js.map +1 -1
- package/package.json +3 -66
- package/src/index.ts +0 -1
- package/src/mcp/decorators/constants.ts +1 -0
- package/src/mcp/decorators/index.ts +3 -1
- package/src/mcp/decorators/mcp-controller.decorator.ts +126 -0
- package/src/mcp/decorators/mcp-message-pattern.ts +38 -0
- package/src/mcp/decorators/prompt.decorator.ts +6 -2
- package/src/mcp/decorators/public.decorator.ts +3 -3
- package/src/mcp/decorators/raw-request.decorator.ts +32 -0
- package/src/mcp/decorators/resource-template.decorator.ts +6 -2
- package/src/mcp/decorators/resource.decorator.ts +6 -2
- package/src/mcp/decorators/tool.decorator.ts +6 -3
- package/src/mcp/filters/mcp-exception.filter.ts +47 -0
- package/src/mcp/index.ts +13 -7
- package/src/mcp/interfaces/authenticated-user.interface.ts +22 -0
- package/src/mcp/interfaces/dynamic-prompt.interface.ts +1 -1
- package/src/mcp/interfaces/dynamic-resource.interface.ts +1 -1
- package/src/mcp/interfaces/dynamic-tool.interface.ts +2 -2
- package/src/mcp/interfaces/index.ts +3 -7
- package/src/mcp/services/tool-authorization.service.ts +52 -72
- package/src/mcp/transport/mcp-context.ts +138 -0
- package/src/mcp/transport/mcp-http-handler.ts +32 -0
- package/src/mcp/transport/mcp-server-options.interface.ts +75 -0
- package/src/mcp/transport/mcp-transport.constants.ts +99 -0
- package/src/mcp/transport/mcp-transport.interface.ts +50 -0
- package/src/mcp/transport/mcp.strategy.ts +752 -0
- package/src/mcp/transport/resource-matcher.ts +107 -0
- package/src/mcp/transport/streamable-http.controller.ts +114 -0
- package/src/mcp/transport/transports/index.ts +2 -0
- package/src/mcp/transport/transports/read-body.ts +39 -0
- package/src/mcp/transport/transports/stdio.transport.ts +35 -0
- package/src/mcp/transport/transports/streamable-http.transport.ts +384 -0
- package/src/mcp/utils/mcp-logger.factory.spec.ts +8 -22
- package/src/mcp/utils/mcp-logger.factory.ts +13 -2
- package/dist/authz/guards/jwt-auth.guard.d.ts +0 -19
- package/dist/authz/guards/jwt-auth.guard.d.ts.map +0 -1
- package/dist/authz/guards/jwt-auth.guard.js +0 -108
- package/dist/authz/guards/jwt-auth.guard.js.map +0 -1
- package/dist/authz/index.d.ts +0 -11
- package/dist/authz/index.d.ts.map +0 -1
- package/dist/authz/index.js.map +0 -1
- package/dist/authz/interfaces/oauth-common.interface.d.ts +0 -21
- package/dist/authz/interfaces/oauth-common.interface.d.ts.map +0 -1
- package/dist/authz/interfaces/oauth-common.interface.js.map +0 -1
- package/dist/authz/interfaces/request-with-user.d.ts +0 -13
- package/dist/authz/interfaces/request-with-user.d.ts.map +0 -1
- package/dist/authz/interfaces/request-with-user.js.map +0 -1
- package/dist/authz/mcp-oauth.controller.d.ts +0 -81
- package/dist/authz/mcp-oauth.controller.d.ts.map +0 -1
- package/dist/authz/mcp-oauth.controller.js +0 -540
- package/dist/authz/mcp-oauth.controller.js.map +0 -1
- package/dist/authz/mcp-oauth.module.d.ts +0 -12
- package/dist/authz/mcp-oauth.module.d.ts.map +0 -1
- package/dist/authz/mcp-oauth.module.js +0 -271
- package/dist/authz/mcp-oauth.module.js.map +0 -1
- package/dist/authz/providers/azure-ad.provider.d.ts +0 -3
- package/dist/authz/providers/azure-ad.provider.d.ts.map +0 -1
- package/dist/authz/providers/azure-ad.provider.js +0 -37
- package/dist/authz/providers/azure-ad.provider.js.map +0 -1
- package/dist/authz/providers/github.provider.d.ts +0 -3
- package/dist/authz/providers/github.provider.d.ts.map +0 -1
- package/dist/authz/providers/github.provider.js +0 -24
- package/dist/authz/providers/github.provider.js.map +0 -1
- package/dist/authz/providers/google.provider.d.ts +0 -3
- package/dist/authz/providers/google.provider.d.ts.map +0 -1
- package/dist/authz/providers/google.provider.js +0 -25
- package/dist/authz/providers/google.provider.js.map +0 -1
- package/dist/authz/providers/oauth-provider.interface.d.ts +0 -107
- package/dist/authz/providers/oauth-provider.interface.d.ts.map +0 -1
- package/dist/authz/providers/oauth-provider.interface.js.map +0 -1
- package/dist/authz/services/client.service.d.ts +0 -12
- package/dist/authz/services/client.service.d.ts.map +0 -1
- package/dist/authz/services/client.service.js +0 -81
- package/dist/authz/services/client.service.js.map +0 -1
- package/dist/authz/services/jwt-token.service.d.ts +0 -37
- package/dist/authz/services/jwt-token.service.d.ts.map +0 -1
- package/dist/authz/services/jwt-token.service.js +0 -182
- package/dist/authz/services/jwt-token.service.js.map +0 -1
- package/dist/authz/services/oauth-strategy.service.d.ts +0 -13
- package/dist/authz/services/oauth-strategy.service.d.ts.map +0 -1
- package/dist/authz/services/oauth-strategy.service.js +0 -71
- package/dist/authz/services/oauth-strategy.service.js.map +0 -1
- package/dist/authz/stores/memory-store.service.d.ts +0 -27
- package/dist/authz/stores/memory-store.service.d.ts.map +0 -1
- package/dist/authz/stores/memory-store.service.js +0 -107
- package/dist/authz/stores/memory-store.service.js.map +0 -1
- package/dist/authz/stores/oauth-store.interface.d.ts +0 -61
- package/dist/authz/stores/oauth-store.interface.d.ts.map +0 -1
- package/dist/authz/stores/oauth-store.interface.js +0 -5
- package/dist/authz/stores/oauth-store.interface.js.map +0 -1
- package/dist/authz/stores/typeorm/constants.d.ts +0 -3
- package/dist/authz/stores/typeorm/constants.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/constants.js +0 -6
- package/dist/authz/stores/typeorm/constants.js.map +0 -1
- package/dist/authz/stores/typeorm/entities/authorization-code.entity.d.ts +0 -15
- package/dist/authz/stores/typeorm/entities/authorization-code.entity.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/entities/authorization-code.entity.js +0 -69
- package/dist/authz/stores/typeorm/entities/authorization-code.entity.js.map +0 -1
- package/dist/authz/stores/typeorm/entities/index.d.ts +0 -5
- package/dist/authz/stores/typeorm/entities/index.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/entities/index.js +0 -12
- package/dist/authz/stores/typeorm/entities/index.js.map +0 -1
- package/dist/authz/stores/typeorm/entities/oauth-client.entity.d.ts +0 -17
- package/dist/authz/stores/typeorm/entities/oauth-client.entity.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/entities/oauth-client.entity.js +0 -77
- package/dist/authz/stores/typeorm/entities/oauth-client.entity.js.map +0 -1
- package/dist/authz/stores/typeorm/entities/oauth-session.entity.d.ts +0 -14
- package/dist/authz/stores/typeorm/entities/oauth-session.entity.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/entities/oauth-session.entity.js +0 -65
- package/dist/authz/stores/typeorm/entities/oauth-session.entity.js.map +0 -1
- package/dist/authz/stores/typeorm/entities/user-profile.entity.d.ts +0 -13
- package/dist/authz/stores/typeorm/entities/user-profile.entity.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/entities/user-profile.entity.js +0 -62
- package/dist/authz/stores/typeorm/entities/user-profile.entity.js.map +0 -1
- package/dist/authz/stores/typeorm/typeorm-store.service.d.ts +0 -28
- package/dist/authz/stores/typeorm/typeorm-store.service.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/typeorm-store.service.js +0 -138
- package/dist/authz/stores/typeorm/typeorm-store.service.js.map +0 -1
- package/dist/mcp/constants/feature-registration.constants.d.ts +0 -7
- package/dist/mcp/constants/feature-registration.constants.d.ts.map +0 -1
- package/dist/mcp/constants/feature-registration.constants.js +0 -5
- package/dist/mcp/constants/feature-registration.constants.js.map +0 -1
- package/dist/mcp/decorators/tool-guards.decorator.d.ts +0 -12
- package/dist/mcp/decorators/tool-guards.decorator.d.ts.map +0 -1
- package/dist/mcp/decorators/tool-guards.decorator.js +0 -13
- package/dist/mcp/decorators/tool-guards.decorator.js.map +0 -1
- package/dist/mcp/interfaces/mcp-options.interface.d.ts +0 -53
- package/dist/mcp/interfaces/mcp-options.interface.d.ts.map +0 -1
- package/dist/mcp/interfaces/mcp-options.interface.js +0 -10
- package/dist/mcp/interfaces/mcp-options.interface.js.map +0 -1
- package/dist/mcp/mcp.module.d.ts +0 -15
- package/dist/mcp/mcp.module.d.ts.map +0 -1
- package/dist/mcp/mcp.module.js +0 -248
- package/dist/mcp/mcp.module.js.map +0 -1
- package/dist/mcp/services/handlers/mcp-handler.base.d.ts +0 -117
- package/dist/mcp/services/handlers/mcp-handler.base.d.ts.map +0 -1
- package/dist/mcp/services/handlers/mcp-handler.base.js +0 -125
- package/dist/mcp/services/handlers/mcp-handler.base.js.map +0 -1
- package/dist/mcp/services/handlers/mcp-prompts.handler.d.ts +0 -12
- package/dist/mcp/services/handlers/mcp-prompts.handler.d.ts.map +0 -1
- package/dist/mcp/services/handlers/mcp-prompts.handler.js +0 -98
- package/dist/mcp/services/handlers/mcp-prompts.handler.js.map +0 -1
- package/dist/mcp/services/handlers/mcp-resources.handler.d.ts +0 -13
- package/dist/mcp/services/handlers/mcp-resources.handler.d.ts.map +0 -1
- package/dist/mcp/services/handlers/mcp-resources.handler.js +0 -117
- package/dist/mcp/services/handlers/mcp-resources.handler.js.map +0 -1
- package/dist/mcp/services/handlers/mcp-tools.handler.d.ts +0 -22
- package/dist/mcp/services/handlers/mcp-tools.handler.d.ts.map +0 -1
- package/dist/mcp/services/handlers/mcp-tools.handler.js +0 -258
- package/dist/mcp/services/handlers/mcp-tools.handler.js.map +0 -1
- package/dist/mcp/services/mcp-dynamic-registry.service.d.ts +0 -26
- package/dist/mcp/services/mcp-dynamic-registry.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-dynamic-registry.service.js +0 -133
- package/dist/mcp/services/mcp-dynamic-registry.service.js.map +0 -1
- package/dist/mcp/services/mcp-executor.service.d.ts +0 -15
- package/dist/mcp/services/mcp-executor.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-executor.service.js +0 -47
- package/dist/mcp/services/mcp-executor.service.js.map +0 -1
- package/dist/mcp/services/mcp-registry-discovery.service.d.ts +0 -63
- package/dist/mcp/services/mcp-registry-discovery.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-registry-discovery.service.js +0 -397
- package/dist/mcp/services/mcp-registry-discovery.service.js.map +0 -1
- package/dist/mcp/services/mcp-sse.service.d.ts +0 -20
- package/dist/mcp/services/mcp-sse.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-sse.service.js +0 -91
- package/dist/mcp/services/mcp-sse.service.js.map +0 -1
- package/dist/mcp/services/mcp-streamable-http.service.d.ts +0 -32
- package/dist/mcp/services/mcp-streamable-http.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-streamable-http.service.js +0 -327
- package/dist/mcp/services/mcp-streamable-http.service.js.map +0 -1
- package/dist/mcp/services/sse-ping.service.d.ts +0 -23
- package/dist/mcp/services/sse-ping.service.d.ts.map +0 -1
- package/dist/mcp/services/sse-ping.service.js +0 -99
- package/dist/mcp/services/sse-ping.service.js.map +0 -1
- package/dist/mcp/transport/sse.controller.factory.d.ts +0 -14
- package/dist/mcp/transport/sse.controller.factory.d.ts.map +0 -1
- package/dist/mcp/transport/sse.controller.factory.js +0 -67
- package/dist/mcp/transport/sse.controller.factory.js.map +0 -1
- package/dist/mcp/transport/stdio.service.d.ts +0 -14
- package/dist/mcp/transport/stdio.service.d.ts.map +0 -1
- package/dist/mcp/transport/stdio.service.js +0 -66
- package/dist/mcp/transport/stdio.service.js.map +0 -1
- package/dist/mcp/transport/streamable-http.controller.factory.d.ts +0 -14
- package/dist/mcp/transport/streamable-http.controller.factory.d.ts.map +0 -1
- package/dist/mcp/transport/streamable-http.controller.factory.js +0 -74
- package/dist/mcp/transport/streamable-http.controller.factory.js.map +0 -1
- package/dist/mcp/utils/capabilities-builder.d.ts +0 -5
- package/dist/mcp/utils/capabilities-builder.d.ts.map +0 -1
- package/dist/mcp/utils/capabilities-builder.js +0 -25
- package/dist/mcp/utils/capabilities-builder.js.map +0 -1
- package/dist/mcp/utils/mcp-server.factory.d.ts +0 -6
- package/dist/mcp/utils/mcp-server.factory.d.ts.map +0 -1
- package/dist/mcp/utils/mcp-server.factory.js +0 -22
- package/dist/mcp/utils/mcp-server.factory.js.map +0 -1
- package/src/authz/guards/jwt-auth.guard.ts +0 -127
- package/src/authz/index.ts +0 -10
- package/src/authz/interfaces/oauth-common.interface.ts +0 -21
- package/src/authz/interfaces/request-with-user.ts +0 -16
- package/src/authz/mcp-oauth.controller.ts +0 -860
- package/src/authz/mcp-oauth.module.ts +0 -384
- package/src/authz/providers/azure-ad.provider.ts +0 -40
- package/src/authz/providers/github.provider.ts +0 -22
- package/src/authz/providers/google.provider.ts +0 -23
- package/src/authz/providers/oauth-provider.interface.ts +0 -147
- package/src/authz/services/client.service.ts +0 -125
- package/src/authz/services/jwt-token.service.spec.ts +0 -67
- package/src/authz/services/jwt-token.service.ts +0 -188
- package/src/authz/services/oauth-strategy.service.ts +0 -64
- package/src/authz/stores/memory-store.service.spec.ts +0 -475
- package/src/authz/stores/memory-store.service.ts +0 -141
- package/src/authz/stores/oauth-store.interface.ts +0 -131
- package/src/authz/stores/typeorm/README.md +0 -140
- package/src/authz/stores/typeorm/constants.ts +0 -6
- package/src/authz/stores/typeorm/entities/authorization-code.entity.ts +0 -41
- package/src/authz/stores/typeorm/entities/index.ts +0 -4
- package/src/authz/stores/typeorm/entities/oauth-client.entity.ts +0 -53
- package/src/authz/stores/typeorm/entities/oauth-session.entity.ts +0 -38
- package/src/authz/stores/typeorm/entities/user-profile.entity.ts +0 -46
- package/src/authz/stores/typeorm/typeorm-store.service.spec.ts +0 -494
- package/src/authz/stores/typeorm/typeorm-store.service.ts +0 -165
- package/src/mcp/constants/feature-registration.constants.ts +0 -24
- package/src/mcp/decorators/tool-guards.decorator.ts +0 -82
- package/src/mcp/interfaces/mcp-options.interface.ts +0 -95
- package/src/mcp/mcp.module.ts +0 -349
- package/src/mcp/services/handlers/mcp-handler.base.ts +0 -203
- package/src/mcp/services/handlers/mcp-prompts.handler.ts +0 -143
- package/src/mcp/services/handlers/mcp-resources.handler.ts +0 -183
- package/src/mcp/services/handlers/mcp-tools.handler.spec.ts +0 -41
- package/src/mcp/services/handlers/mcp-tools.handler.ts +0 -436
- package/src/mcp/services/mcp-dynamic-registry.service.ts +0 -236
- package/src/mcp/services/mcp-executor.service.ts +0 -64
- package/src/mcp/services/mcp-registry-discovery.service.spec.ts +0 -306
- package/src/mcp/services/mcp-registry-discovery.service.ts +0 -849
- package/src/mcp/services/mcp-sse.service.ts +0 -124
- package/src/mcp/services/mcp-streamable-http.service.ts +0 -472
- package/src/mcp/services/sse-ping.service.ts +0 -144
- package/src/mcp/transport/custom-decorator.spec.ts +0 -75
- package/src/mcp/transport/sse.controller.factory.ts +0 -84
- package/src/mcp/transport/stdio.service.ts +0 -75
- package/src/mcp/transport/streamable-http.controller.factory.ts +0 -80
- package/src/mcp/utils/capabilities-builder.ts +0 -43
- package/src/mcp/utils/mcp-server.factory.ts +0 -33
|
@@ -1,849 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Injectable,
|
|
3
|
-
InjectionToken,
|
|
4
|
-
Logger,
|
|
5
|
-
OnApplicationBootstrap,
|
|
6
|
-
Inject,
|
|
7
|
-
Optional,
|
|
8
|
-
} from '@nestjs/common';
|
|
9
|
-
import {
|
|
10
|
-
DiscoveryService,
|
|
11
|
-
MetadataScanner,
|
|
12
|
-
ModulesContainer,
|
|
13
|
-
} from '@nestjs/core';
|
|
14
|
-
import {
|
|
15
|
-
MCP_PROMPT_METADATA_KEY,
|
|
16
|
-
MCP_RESOURCE_METADATA_KEY,
|
|
17
|
-
MCP_RESOURCE_TEMPLATE_METADATA_KEY,
|
|
18
|
-
MCP_TOOL_METADATA_KEY,
|
|
19
|
-
MCP_PUBLIC_METADATA_KEY,
|
|
20
|
-
MCP_SCOPES_METADATA_KEY,
|
|
21
|
-
MCP_ROLES_METADATA_KEY,
|
|
22
|
-
MCP_GUARDS_METADATA_KEY,
|
|
23
|
-
ToolMetadata,
|
|
24
|
-
} from '../decorators';
|
|
25
|
-
import { ResourceMetadata } from '../decorators/resource.decorator';
|
|
26
|
-
import { match } from 'path-to-regexp';
|
|
27
|
-
import { PromptMetadata } from '../decorators/prompt.decorator';
|
|
28
|
-
import { Module } from '@nestjs/core/injector/module';
|
|
29
|
-
import { ResourceTemplateMetadata } from '../decorators/resource-template.decorator';
|
|
30
|
-
import type { McpOptions } from '../interfaces';
|
|
31
|
-
import { createMcpLogger } from '../utils/mcp-logger.factory';
|
|
32
|
-
import {
|
|
33
|
-
MCP_FEATURE_REGISTRATION,
|
|
34
|
-
McpFeatureRegistration,
|
|
35
|
-
} from '../constants/feature-registration.constants';
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Interface representing a discovered capability
|
|
39
|
-
*/
|
|
40
|
-
export type DiscoveredCapability<T extends object> = {
|
|
41
|
-
type: 'tool' | 'resource' | 'resource-template' | 'prompt';
|
|
42
|
-
metadata: T;
|
|
43
|
-
providerClass: InjectionToken;
|
|
44
|
-
methodName: string;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export type InjectionTokenWithName = InjectionToken & { name: string };
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Singleton service that discovers and registers tools during application bootstrap
|
|
51
|
-
*/
|
|
52
|
-
@Injectable()
|
|
53
|
-
export class McpRegistryDiscoveryService implements OnApplicationBootstrap {
|
|
54
|
-
private readonly logger: Logger;
|
|
55
|
-
private discoveredCapabilitiesByMcpModuleId: Map<
|
|
56
|
-
string,
|
|
57
|
-
DiscoveredCapability<any>[]
|
|
58
|
-
> = new Map();
|
|
59
|
-
|
|
60
|
-
constructor(
|
|
61
|
-
private readonly discovery: DiscoveryService,
|
|
62
|
-
private readonly metadataScanner: MetadataScanner,
|
|
63
|
-
private readonly modulesContainer: ModulesContainer,
|
|
64
|
-
@Optional() @Inject('MCP_OPTIONS') private readonly options?: McpOptions,
|
|
65
|
-
) {
|
|
66
|
-
this.logger = createMcpLogger(
|
|
67
|
-
McpRegistryDiscoveryService.name,
|
|
68
|
-
this.options,
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
onApplicationBootstrap() {
|
|
73
|
-
this.discoverTools();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Finds all modules that import the McpModule and scans only the root module providers and controllers.
|
|
78
|
-
* This prevents unintentionally exposing tools from imported dependencies.
|
|
79
|
-
*/
|
|
80
|
-
private discoverTools() {
|
|
81
|
-
// First, build a map of server names to module IDs
|
|
82
|
-
const serverNameToModuleId = this.buildServerNameToModuleIdMap();
|
|
83
|
-
|
|
84
|
-
// Then, collect feature registrations
|
|
85
|
-
const featureRegistrations = this.collectFeatureRegistrations();
|
|
86
|
-
|
|
87
|
-
const getImportedMcpModules = (module: Module) =>
|
|
88
|
-
Array.from(module.imports).filter(
|
|
89
|
-
(m) =>
|
|
90
|
-
(m.instance as any).__isMcpModule &&
|
|
91
|
-
!(m.instance as any).__isMcpFeatureModule,
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
const pairs = Array.from(this.modulesContainer.values())
|
|
95
|
-
.map((module): [Module, Module[]] => [
|
|
96
|
-
module,
|
|
97
|
-
getImportedMcpModules(module),
|
|
98
|
-
])
|
|
99
|
-
.filter(([, importedMcpModules]) => importedMcpModules.length > 0);
|
|
100
|
-
|
|
101
|
-
for (const [rootModule, mcpModules] of pairs) {
|
|
102
|
-
this.logger.debug(
|
|
103
|
-
`Discovering tools, resources, resource templates, and prompts for module: ${rootModule.name}`,
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
for (const mcpModule of mcpModules) {
|
|
107
|
-
const mcpModuleId =
|
|
108
|
-
mcpModule.getProviderByKey<string>('MCP_MODULE_ID')?.instance;
|
|
109
|
-
|
|
110
|
-
this.discoverToolsForModuleSubtree(mcpModuleId, [rootModule]);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Process feature registrations
|
|
115
|
-
this.processFeatureRegistrations(
|
|
116
|
-
featureRegistrations,
|
|
117
|
-
serverNameToModuleId,
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Builds a map from server names to their module IDs.
|
|
123
|
-
*/
|
|
124
|
-
private buildServerNameToModuleIdMap(): Map<string, string> {
|
|
125
|
-
const map = new Map<string, string>();
|
|
126
|
-
|
|
127
|
-
for (const module of this.modulesContainer.values()) {
|
|
128
|
-
if ((module.instance as any)?.__isMcpModule) {
|
|
129
|
-
const moduleId =
|
|
130
|
-
module.getProviderByKey<string>('MCP_MODULE_ID')?.instance;
|
|
131
|
-
const options =
|
|
132
|
-
module.getProviderByKey<McpOptions>('MCP_OPTIONS')?.instance;
|
|
133
|
-
|
|
134
|
-
if (moduleId && options?.name) {
|
|
135
|
-
map.set(options.name, moduleId);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return map;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Collects all feature registrations from modules that import McpModule.forFeature().
|
|
145
|
-
*/
|
|
146
|
-
private collectFeatureRegistrations(): Array<{
|
|
147
|
-
registration: McpFeatureRegistration;
|
|
148
|
-
sourceModule: Module;
|
|
149
|
-
}> {
|
|
150
|
-
const registrations: Array<{
|
|
151
|
-
registration: McpFeatureRegistration;
|
|
152
|
-
sourceModule: Module;
|
|
153
|
-
}> = [];
|
|
154
|
-
|
|
155
|
-
for (const module of this.modulesContainer.values()) {
|
|
156
|
-
// Check for feature registration providers (tokens start with MCP_FEATURE_REGISTRATION)
|
|
157
|
-
for (const [key, provider] of module.providers) {
|
|
158
|
-
if (
|
|
159
|
-
typeof key === 'string' &&
|
|
160
|
-
key.startsWith(MCP_FEATURE_REGISTRATION) &&
|
|
161
|
-
provider?.instance
|
|
162
|
-
) {
|
|
163
|
-
registrations.push({
|
|
164
|
-
registration: provider.instance as McpFeatureRegistration,
|
|
165
|
-
sourceModule: module,
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return registrations;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Processes feature registrations and discovers tools from their providers.
|
|
176
|
-
*/
|
|
177
|
-
private processFeatureRegistrations(
|
|
178
|
-
registrations: Array<{
|
|
179
|
-
registration: McpFeatureRegistration;
|
|
180
|
-
sourceModule: Module;
|
|
181
|
-
}>,
|
|
182
|
-
serverNameToModuleId: Map<string, string>,
|
|
183
|
-
) {
|
|
184
|
-
for (const { registration, sourceModule } of registrations) {
|
|
185
|
-
const mcpModuleId = serverNameToModuleId.get(registration.serverName);
|
|
186
|
-
|
|
187
|
-
if (!mcpModuleId) {
|
|
188
|
-
this.logger.warn(
|
|
189
|
-
`McpModule.forFeature: No MCP server found with name '${registration.serverName}'. ` +
|
|
190
|
-
`Make sure McpModule.forRoot({ name: '${registration.serverName}', ... }) is imported.`,
|
|
191
|
-
);
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
this.logger.debug(
|
|
196
|
-
`Processing forFeature registration for server '${registration.serverName}' ` +
|
|
197
|
-
`with ${registration.providerTokens.length} provider(s)`,
|
|
198
|
-
);
|
|
199
|
-
|
|
200
|
-
// Find the module that actually provides these providers
|
|
201
|
-
// The sourceModule imports the forFeature module, so we look at its parent
|
|
202
|
-
const parentModule = this.findModuleWithProviders(
|
|
203
|
-
registration.providerTokens,
|
|
204
|
-
sourceModule,
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
if (parentModule) {
|
|
208
|
-
this.discoverToolsFromProviders(
|
|
209
|
-
mcpModuleId,
|
|
210
|
-
registration.providerTokens,
|
|
211
|
-
parentModule,
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Finds a module that contains the specified providers.
|
|
219
|
-
* Searches the source module and its parent modules.
|
|
220
|
-
*/
|
|
221
|
-
private findModuleWithProviders(
|
|
222
|
-
providerTokens: InjectionToken[],
|
|
223
|
-
sourceModule: Module,
|
|
224
|
-
): Module | undefined {
|
|
225
|
-
// First check if the source module's parent has the providers
|
|
226
|
-
for (const module of this.modulesContainer.values()) {
|
|
227
|
-
if (module.imports.has(sourceModule)) {
|
|
228
|
-
// This module imports our source module, check if it has the providers
|
|
229
|
-
const hasAllProviders = providerTokens.every((token) =>
|
|
230
|
-
module.getProviderByKey(token),
|
|
231
|
-
);
|
|
232
|
-
if (hasAllProviders) {
|
|
233
|
-
return module;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Fallback: search all modules
|
|
239
|
-
for (const module of this.modulesContainer.values()) {
|
|
240
|
-
const hasAllProviders = providerTokens.every((token) =>
|
|
241
|
-
module.getProviderByKey(token),
|
|
242
|
-
);
|
|
243
|
-
if (hasAllProviders) {
|
|
244
|
-
return module;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return undefined;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Discovers tools from specific providers within a module.
|
|
253
|
-
*/
|
|
254
|
-
private discoverToolsFromProviders(
|
|
255
|
-
mcpModuleId: string,
|
|
256
|
-
providerTokens: InjectionToken[],
|
|
257
|
-
module: Module,
|
|
258
|
-
) {
|
|
259
|
-
for (const token of providerTokens) {
|
|
260
|
-
const provider = module.getProviderByKey(token);
|
|
261
|
-
if (!provider?.instance || typeof provider.instance !== 'object') {
|
|
262
|
-
this.logger.warn(
|
|
263
|
-
`McpModule.forFeature: Provider '${String(token)}' not found or not instantiated`,
|
|
264
|
-
);
|
|
265
|
-
continue;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const instance = provider.instance as object;
|
|
269
|
-
this.metadataScanner.getAllMethodNames(instance).forEach((methodName) => {
|
|
270
|
-
const methodRef = instance[methodName] as object;
|
|
271
|
-
const methodMetaKeys = Reflect.getOwnMetadataKeys(methodRef);
|
|
272
|
-
|
|
273
|
-
if (methodMetaKeys.includes(MCP_TOOL_METADATA_KEY)) {
|
|
274
|
-
this.addDiscoveryTool(
|
|
275
|
-
mcpModuleId,
|
|
276
|
-
methodRef,
|
|
277
|
-
token as InjectionTokenWithName,
|
|
278
|
-
methodName,
|
|
279
|
-
);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (methodMetaKeys.includes(MCP_RESOURCE_METADATA_KEY)) {
|
|
283
|
-
this.addDiscoveryResource(
|
|
284
|
-
mcpModuleId,
|
|
285
|
-
methodRef,
|
|
286
|
-
token as InjectionTokenWithName,
|
|
287
|
-
methodName,
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
if (methodMetaKeys.includes(MCP_RESOURCE_TEMPLATE_METADATA_KEY)) {
|
|
292
|
-
this.addDiscoveryResourceTemplate(
|
|
293
|
-
mcpModuleId,
|
|
294
|
-
methodRef,
|
|
295
|
-
token as InjectionTokenWithName,
|
|
296
|
-
methodName,
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
if (methodMetaKeys.includes(MCP_PROMPT_METADATA_KEY)) {
|
|
301
|
-
this.addDiscoveryPrompt(
|
|
302
|
-
mcpModuleId,
|
|
303
|
-
methodRef,
|
|
304
|
-
token as InjectionTokenWithName,
|
|
305
|
-
methodName,
|
|
306
|
-
);
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Scans all providers and controllers for @Tool decorators
|
|
314
|
-
*/
|
|
315
|
-
private discoverToolsForModuleSubtree(
|
|
316
|
-
mcpModuleId: string,
|
|
317
|
-
modules: Module[],
|
|
318
|
-
) {
|
|
319
|
-
const providers = this.discovery.getProviders(undefined, modules);
|
|
320
|
-
const controllers = this.discovery.getControllers(undefined, modules);
|
|
321
|
-
const allInstances = [...providers, ...controllers]
|
|
322
|
-
.filter(
|
|
323
|
-
(wrapper) =>
|
|
324
|
-
wrapper.instance &&
|
|
325
|
-
typeof wrapper.instance === 'object' &&
|
|
326
|
-
wrapper.instance !== null,
|
|
327
|
-
)
|
|
328
|
-
.map((wrapper) => ({
|
|
329
|
-
instance: wrapper.instance as object,
|
|
330
|
-
token: wrapper.token,
|
|
331
|
-
}));
|
|
332
|
-
|
|
333
|
-
allInstances.forEach(({ instance, token }) => {
|
|
334
|
-
this.metadataScanner.getAllMethodNames(instance).forEach((methodName) => {
|
|
335
|
-
const methodRef = instance[methodName] as object;
|
|
336
|
-
const methodMetaKeys = Reflect.getOwnMetadataKeys(methodRef);
|
|
337
|
-
|
|
338
|
-
if (methodMetaKeys.includes(MCP_TOOL_METADATA_KEY)) {
|
|
339
|
-
this.addDiscoveryTool(
|
|
340
|
-
mcpModuleId,
|
|
341
|
-
methodRef,
|
|
342
|
-
token as InjectionTokenWithName,
|
|
343
|
-
methodName,
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (methodMetaKeys.includes(MCP_RESOURCE_METADATA_KEY)) {
|
|
348
|
-
this.addDiscoveryResource(
|
|
349
|
-
mcpModuleId,
|
|
350
|
-
methodRef,
|
|
351
|
-
token as InjectionTokenWithName,
|
|
352
|
-
methodName,
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
if (methodMetaKeys.includes(MCP_RESOURCE_TEMPLATE_METADATA_KEY)) {
|
|
357
|
-
this.addDiscoveryResourceTemplate(
|
|
358
|
-
mcpModuleId,
|
|
359
|
-
methodRef,
|
|
360
|
-
token as InjectionTokenWithName,
|
|
361
|
-
methodName,
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
if (methodMetaKeys.includes(MCP_PROMPT_METADATA_KEY)) {
|
|
366
|
-
this.addDiscoveryPrompt(
|
|
367
|
-
mcpModuleId,
|
|
368
|
-
methodRef,
|
|
369
|
-
token as InjectionTokenWithName,
|
|
370
|
-
methodName,
|
|
371
|
-
);
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Adds a discovered tool to the registry
|
|
379
|
-
*/
|
|
380
|
-
private addDiscovery<T>(
|
|
381
|
-
type: 'tool' | 'resource' | 'resource-template' | 'prompt',
|
|
382
|
-
metadataKey: string,
|
|
383
|
-
mcpModuleId: string,
|
|
384
|
-
methodRef: object,
|
|
385
|
-
token: InjectionTokenWithName,
|
|
386
|
-
methodName: string,
|
|
387
|
-
) {
|
|
388
|
-
const metadata: T = Reflect.getMetadata(metadataKey, methodRef);
|
|
389
|
-
|
|
390
|
-
if (!metadata['name']) {
|
|
391
|
-
metadata['name'] = methodName;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (!this.discoveredCapabilitiesByMcpModuleId.has(mcpModuleId)) {
|
|
395
|
-
this.discoveredCapabilitiesByMcpModuleId.set(mcpModuleId, []);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
this.discoveredCapabilitiesByMcpModuleId.get(mcpModuleId)?.push({
|
|
399
|
-
type,
|
|
400
|
-
metadata,
|
|
401
|
-
providerClass: token,
|
|
402
|
-
methodName,
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
private addDiscoveryPrompt(
|
|
407
|
-
mcpModuleId: string,
|
|
408
|
-
methodRef: object,
|
|
409
|
-
token: InjectionTokenWithName,
|
|
410
|
-
methodName: string,
|
|
411
|
-
) {
|
|
412
|
-
this.logger.debug(
|
|
413
|
-
`Prompt discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,
|
|
414
|
-
);
|
|
415
|
-
this.addDiscovery<PromptMetadata>(
|
|
416
|
-
'prompt',
|
|
417
|
-
MCP_PROMPT_METADATA_KEY,
|
|
418
|
-
mcpModuleId,
|
|
419
|
-
methodRef,
|
|
420
|
-
token,
|
|
421
|
-
methodName,
|
|
422
|
-
);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
private addDiscoveryTool(
|
|
426
|
-
mcpModuleId: string,
|
|
427
|
-
methodRef: object,
|
|
428
|
-
token: InjectionTokenWithName,
|
|
429
|
-
methodName: string,
|
|
430
|
-
) {
|
|
431
|
-
this.logger.debug(
|
|
432
|
-
`Tool discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,
|
|
433
|
-
);
|
|
434
|
-
|
|
435
|
-
// Collect security metadata from decorators
|
|
436
|
-
const isPublic = Reflect.getMetadata(MCP_PUBLIC_METADATA_KEY, methodRef);
|
|
437
|
-
const requiredScopes = Reflect.getMetadata(
|
|
438
|
-
MCP_SCOPES_METADATA_KEY,
|
|
439
|
-
methodRef,
|
|
440
|
-
);
|
|
441
|
-
const requiredRoles = Reflect.getMetadata(
|
|
442
|
-
MCP_ROLES_METADATA_KEY,
|
|
443
|
-
methodRef,
|
|
444
|
-
);
|
|
445
|
-
const guards = Reflect.getMetadata(MCP_GUARDS_METADATA_KEY, methodRef);
|
|
446
|
-
|
|
447
|
-
// Add tool with security metadata
|
|
448
|
-
const baseMetadata: ToolMetadata = Reflect.getMetadata(
|
|
449
|
-
MCP_TOOL_METADATA_KEY,
|
|
450
|
-
methodRef,
|
|
451
|
-
);
|
|
452
|
-
|
|
453
|
-
if (!baseMetadata.name) {
|
|
454
|
-
baseMetadata.name = methodName;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
// Enrich with security metadata
|
|
458
|
-
if (isPublic !== undefined) {
|
|
459
|
-
baseMetadata.isPublic = isPublic;
|
|
460
|
-
}
|
|
461
|
-
if (requiredScopes) {
|
|
462
|
-
baseMetadata.requiredScopes = requiredScopes;
|
|
463
|
-
}
|
|
464
|
-
if (requiredRoles) {
|
|
465
|
-
baseMetadata.requiredRoles = requiredRoles;
|
|
466
|
-
}
|
|
467
|
-
if (guards) {
|
|
468
|
-
baseMetadata.guards = guards;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
if (!this.discoveredCapabilitiesByMcpModuleId.has(mcpModuleId)) {
|
|
472
|
-
this.discoveredCapabilitiesByMcpModuleId.set(mcpModuleId, []);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
this.discoveredCapabilitiesByMcpModuleId.get(mcpModuleId)?.push({
|
|
476
|
-
type: 'tool',
|
|
477
|
-
metadata: baseMetadata,
|
|
478
|
-
providerClass: token,
|
|
479
|
-
methodName,
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
private addDiscoveryResource(
|
|
484
|
-
mcpModuleId: string,
|
|
485
|
-
methodRef: object,
|
|
486
|
-
token: InjectionTokenWithName,
|
|
487
|
-
methodName: string,
|
|
488
|
-
) {
|
|
489
|
-
this.logger.debug(
|
|
490
|
-
`Resource discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,
|
|
491
|
-
);
|
|
492
|
-
this.addDiscovery<ResourceMetadata>(
|
|
493
|
-
'resource',
|
|
494
|
-
MCP_RESOURCE_METADATA_KEY,
|
|
495
|
-
mcpModuleId,
|
|
496
|
-
methodRef,
|
|
497
|
-
token,
|
|
498
|
-
methodName,
|
|
499
|
-
);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
private addDiscoveryResourceTemplate(
|
|
503
|
-
mcpModuleId: string,
|
|
504
|
-
methodRef: object,
|
|
505
|
-
token: InjectionTokenWithName,
|
|
506
|
-
methodName: string,
|
|
507
|
-
) {
|
|
508
|
-
this.logger.debug(
|
|
509
|
-
`Resource Template discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,
|
|
510
|
-
);
|
|
511
|
-
this.addDiscovery<ResourceTemplateMetadata>(
|
|
512
|
-
'resource-template',
|
|
513
|
-
MCP_RESOURCE_TEMPLATE_METADATA_KEY,
|
|
514
|
-
mcpModuleId,
|
|
515
|
-
methodRef,
|
|
516
|
-
token,
|
|
517
|
-
methodName,
|
|
518
|
-
);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Return all discovered MCP module IDs
|
|
523
|
-
*/
|
|
524
|
-
getMcpModuleIds(): string[] {
|
|
525
|
-
return Array.from(this.discoveredCapabilitiesByMcpModuleId.keys());
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
/**
|
|
529
|
-
* Get all discovered tools
|
|
530
|
-
*/
|
|
531
|
-
getTools(mcpModuleId: string): DiscoveredCapability<ToolMetadata>[] {
|
|
532
|
-
return (
|
|
533
|
-
this.discoveredCapabilitiesByMcpModuleId
|
|
534
|
-
.get(mcpModuleId)
|
|
535
|
-
?.filter((tool) => tool.type === 'tool') ?? []
|
|
536
|
-
);
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
/**
|
|
540
|
-
* Find a tool by name
|
|
541
|
-
*/
|
|
542
|
-
findTool(
|
|
543
|
-
mcpModuleId: string,
|
|
544
|
-
name: string,
|
|
545
|
-
): DiscoveredCapability<ToolMetadata> | undefined {
|
|
546
|
-
return this.getTools(mcpModuleId).find(
|
|
547
|
-
(tool) => tool.metadata.name === name,
|
|
548
|
-
);
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
/**
|
|
552
|
-
* Get all discovered resources
|
|
553
|
-
*/
|
|
554
|
-
getResources(mcpModuleId: string): DiscoveredCapability<ResourceMetadata>[] {
|
|
555
|
-
return (
|
|
556
|
-
this.discoveredCapabilitiesByMcpModuleId
|
|
557
|
-
.get(mcpModuleId)
|
|
558
|
-
?.filter((tool) => tool.type === 'resource') ?? []
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
/**
|
|
563
|
-
* Find a resource by name
|
|
564
|
-
*/
|
|
565
|
-
findResource(
|
|
566
|
-
mcpModuleId: string,
|
|
567
|
-
name: string,
|
|
568
|
-
): DiscoveredCapability<ResourceMetadata> | undefined {
|
|
569
|
-
return this.getResources(mcpModuleId).find(
|
|
570
|
-
(tool) => tool.metadata.name === name,
|
|
571
|
-
);
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Get all discovered resource templates
|
|
576
|
-
*/
|
|
577
|
-
getResourceTemplates(
|
|
578
|
-
mcpModuleId: string,
|
|
579
|
-
): DiscoveredCapability<ResourceTemplateMetadata>[] {
|
|
580
|
-
return (
|
|
581
|
-
this.discoveredCapabilitiesByMcpModuleId
|
|
582
|
-
.get(mcpModuleId)
|
|
583
|
-
?.filter((tool) => tool.type === 'resource-template') ?? []
|
|
584
|
-
);
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
* Find a resource by name
|
|
589
|
-
*/
|
|
590
|
-
findResourceTemplate(
|
|
591
|
-
mcpModuleId: string,
|
|
592
|
-
name: string,
|
|
593
|
-
): DiscoveredCapability<ResourceTemplateMetadata> | undefined {
|
|
594
|
-
return this.getResourceTemplates(mcpModuleId).find(
|
|
595
|
-
(tool) => tool.metadata.name === name,
|
|
596
|
-
);
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
/**
|
|
600
|
-
* Get all discovered prompts
|
|
601
|
-
*/
|
|
602
|
-
getPrompts(mcpModuleId: string): DiscoveredCapability<PromptMetadata>[] {
|
|
603
|
-
return (
|
|
604
|
-
this.discoveredCapabilitiesByMcpModuleId
|
|
605
|
-
.get(mcpModuleId)
|
|
606
|
-
?.filter((tool) => tool.type === 'prompt') ?? []
|
|
607
|
-
);
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
/**
|
|
611
|
-
* Find a prompt by name
|
|
612
|
-
*/
|
|
613
|
-
findPrompt(
|
|
614
|
-
mcpModuleId: string,
|
|
615
|
-
name: string,
|
|
616
|
-
): DiscoveredCapability<PromptMetadata> | undefined {
|
|
617
|
-
return this.getPrompts(mcpModuleId).find(
|
|
618
|
-
(tool) => tool.metadata.name === name,
|
|
619
|
-
);
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
/**
|
|
623
|
-
* Convert RFC 6570 URI template to path-to-regexp compatible format.
|
|
624
|
-
* Handles both path parameters {param} and query parameters {?param} or {?param1,param2}
|
|
625
|
-
*/
|
|
626
|
-
private convertTemplate(template: string): string {
|
|
627
|
-
if (!template) return template;
|
|
628
|
-
|
|
629
|
-
// Remove RFC 6570 query parameter syntax {?...} from the template
|
|
630
|
-
// These will be handled separately via URL query string parsing
|
|
631
|
-
const withoutQueryParams = template.replace(/\{\?[^}]+\}/g, '');
|
|
632
|
-
|
|
633
|
-
// Convert path parameters {param} to path-to-regexp format :param
|
|
634
|
-
return withoutQueryParams.replace(/{(\w+)}/g, ':$1');
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
/**
|
|
638
|
-
* Extract query parameter names from an RFC 6570 URI template.
|
|
639
|
-
* E.g., 'mcp://example{?foo,bar}' returns ['foo', 'bar']
|
|
640
|
-
*/
|
|
641
|
-
private extractTemplateQueryParams(template: string): string[] {
|
|
642
|
-
const queryParamMatch = template.match(/\{\?([^}]+)\}/);
|
|
643
|
-
if (!queryParamMatch) return [];
|
|
644
|
-
return queryParamMatch[1].split(',').map((p) => p.trim());
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
/**
|
|
648
|
-
* Parse query string from a URI and return as key-value pairs.
|
|
649
|
-
*/
|
|
650
|
-
private parseQueryString(uri: string): Record<string, string> {
|
|
651
|
-
const queryIndex = uri.indexOf('?');
|
|
652
|
-
if (queryIndex === -1) return {};
|
|
653
|
-
|
|
654
|
-
const queryString = uri.substring(queryIndex + 1);
|
|
655
|
-
const params: Record<string, string> = {};
|
|
656
|
-
|
|
657
|
-
for (const pair of queryString.split('&')) {
|
|
658
|
-
const [key, value] = pair.split('=');
|
|
659
|
-
if (key) {
|
|
660
|
-
params[decodeURIComponent(key)] = value
|
|
661
|
-
? decodeURIComponent(value)
|
|
662
|
-
: '';
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
return params;
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
/**
|
|
670
|
-
* Strip query string from a URI, returning only the path portion.
|
|
671
|
-
*/
|
|
672
|
-
private stripQueryString(uri: string): string {
|
|
673
|
-
const queryIndex = uri.indexOf('?');
|
|
674
|
-
return queryIndex === -1 ? uri : uri.substring(0, queryIndex);
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
private convertUri(uri: string): string {
|
|
678
|
-
if (uri.includes('://')) {
|
|
679
|
-
return uri.split('://')[1];
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
return uri;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
/**
|
|
686
|
-
* Find a resource by uri
|
|
687
|
-
* @returns An object containing the found resource and extracted parameters, or undefined if no resource is found
|
|
688
|
-
*/
|
|
689
|
-
findResourceByUri(
|
|
690
|
-
mcpModuleId: string,
|
|
691
|
-
uri: string,
|
|
692
|
-
):
|
|
693
|
-
| {
|
|
694
|
-
resource: DiscoveredCapability<ResourceMetadata>;
|
|
695
|
-
params: Record<string, string>;
|
|
696
|
-
}
|
|
697
|
-
| undefined {
|
|
698
|
-
const resources = this.getResources(mcpModuleId).map((tool) => ({
|
|
699
|
-
name: tool.metadata.name,
|
|
700
|
-
uri: tool.metadata.uri,
|
|
701
|
-
}));
|
|
702
|
-
|
|
703
|
-
const strippedInputUri = this.convertUri(uri);
|
|
704
|
-
|
|
705
|
-
for (const t of resources) {
|
|
706
|
-
if (!t.uri) continue;
|
|
707
|
-
|
|
708
|
-
const rawTemplate = t.uri;
|
|
709
|
-
const templatePath = this.convertTemplate(this.convertUri(rawTemplate));
|
|
710
|
-
const matcher = match(templatePath, { decode: decodeURIComponent });
|
|
711
|
-
const result = matcher(strippedInputUri);
|
|
712
|
-
|
|
713
|
-
if (result) {
|
|
714
|
-
const foundResource = this.findResource(mcpModuleId, t.name);
|
|
715
|
-
if (!foundResource) continue;
|
|
716
|
-
|
|
717
|
-
return {
|
|
718
|
-
resource: foundResource,
|
|
719
|
-
params: result.params as Record<string, string>,
|
|
720
|
-
};
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
return undefined;
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
/**
|
|
728
|
-
* Find a resource template by uri
|
|
729
|
-
* @returns An object containing the found resource template and extracted parameters, or undefined if no resource template is found
|
|
730
|
-
*/
|
|
731
|
-
findResourceTemplateByUri(
|
|
732
|
-
mcpModuleId: string,
|
|
733
|
-
uri: string,
|
|
734
|
-
):
|
|
735
|
-
| {
|
|
736
|
-
resourceTemplate: DiscoveredCapability<ResourceTemplateMetadata>;
|
|
737
|
-
params: Record<string, string>;
|
|
738
|
-
}
|
|
739
|
-
| undefined {
|
|
740
|
-
const resourceTemplates = this.getResourceTemplates(mcpModuleId).map(
|
|
741
|
-
(tool) => ({
|
|
742
|
-
name: tool.metadata.name,
|
|
743
|
-
uriTemplate: tool.metadata.uriTemplate,
|
|
744
|
-
}),
|
|
745
|
-
);
|
|
746
|
-
|
|
747
|
-
// Strip query string from input URI for path matching
|
|
748
|
-
const strippedInputUri = this.stripQueryString(this.convertUri(uri));
|
|
749
|
-
// Parse query parameters from input URI
|
|
750
|
-
const inputQueryParams = this.parseQueryString(uri);
|
|
751
|
-
|
|
752
|
-
for (const t of resourceTemplates) {
|
|
753
|
-
if (!t.uriTemplate) continue;
|
|
754
|
-
|
|
755
|
-
const rawTemplate = t.uriTemplate;
|
|
756
|
-
// Convert template (removes {?...} query params and converts {param} to :param)
|
|
757
|
-
const templatePath = this.convertTemplate(this.convertUri(rawTemplate));
|
|
758
|
-
const matcher = match(templatePath, { decode: decodeURIComponent });
|
|
759
|
-
const result = matcher(strippedInputUri);
|
|
760
|
-
|
|
761
|
-
if (result) {
|
|
762
|
-
const foundResourceTemplate = this.findResourceTemplate(
|
|
763
|
-
mcpModuleId,
|
|
764
|
-
t.name,
|
|
765
|
-
);
|
|
766
|
-
if (!foundResourceTemplate) continue;
|
|
767
|
-
|
|
768
|
-
// Get path params from matching
|
|
769
|
-
const pathParams = result.params as Record<string, string>;
|
|
770
|
-
|
|
771
|
-
// Get expected query params from template and filter input query params
|
|
772
|
-
const expectedQueryParams =
|
|
773
|
-
this.extractTemplateQueryParams(rawTemplate);
|
|
774
|
-
const queryParams: Record<string, string> = {};
|
|
775
|
-
for (const paramName of expectedQueryParams) {
|
|
776
|
-
if (inputQueryParams[paramName] !== undefined) {
|
|
777
|
-
queryParams[paramName] = inputQueryParams[paramName];
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
return {
|
|
782
|
-
resourceTemplate: foundResourceTemplate,
|
|
783
|
-
params: { ...pathParams, ...queryParams },
|
|
784
|
-
};
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
return undefined;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
/**
|
|
792
|
-
* Register a tool programmatically (for dynamic tools).
|
|
793
|
-
* Use McpRegistryService.registerTool() instead of calling this directly.
|
|
794
|
-
*
|
|
795
|
-
* @param mcpModuleId - The module ID to register the tool with
|
|
796
|
-
* @param capability - The discovered capability object to register
|
|
797
|
-
*/
|
|
798
|
-
registerDynamicCapability<T extends object>(
|
|
799
|
-
mcpModuleId: string,
|
|
800
|
-
capability: DiscoveredCapability<T>,
|
|
801
|
-
): void {
|
|
802
|
-
if (!this.discoveredCapabilitiesByMcpModuleId.has(mcpModuleId)) {
|
|
803
|
-
this.discoveredCapabilitiesByMcpModuleId.set(mcpModuleId, []);
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
const capabilities =
|
|
807
|
-
this.discoveredCapabilitiesByMcpModuleId.get(mcpModuleId)!;
|
|
808
|
-
|
|
809
|
-
const existingIndex = capabilities.findIndex(
|
|
810
|
-
(c) =>
|
|
811
|
-
c.type === capability.type && c.methodName === capability.methodName,
|
|
812
|
-
);
|
|
813
|
-
|
|
814
|
-
if (existingIndex !== -1) {
|
|
815
|
-
this.logger.warn(
|
|
816
|
-
`Dynamic ${capability.type} '${capability.methodName}' already registered in module: ${mcpModuleId}. Overwriting.`,
|
|
817
|
-
);
|
|
818
|
-
capabilities[existingIndex] = capability;
|
|
819
|
-
} else {
|
|
820
|
-
this.logger.debug(
|
|
821
|
-
`Dynamic ${capability.type} registered: ${capability.metadata['name']} in module: ${mcpModuleId}`,
|
|
822
|
-
);
|
|
823
|
-
capabilities.push(capability);
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
removeDynamicCapability(
|
|
828
|
-
mcpModuleId: string,
|
|
829
|
-
type: DiscoveredCapability<object>['type'],
|
|
830
|
-
identifier: string,
|
|
831
|
-
): void {
|
|
832
|
-
const capabilities =
|
|
833
|
-
this.discoveredCapabilitiesByMcpModuleId.get(mcpModuleId);
|
|
834
|
-
if (!capabilities) {
|
|
835
|
-
return;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
this.logger.debug(
|
|
839
|
-
`Dynamic ${type} removed: ${identifier} in module: ${mcpModuleId}`,
|
|
840
|
-
);
|
|
841
|
-
|
|
842
|
-
this.discoveredCapabilitiesByMcpModuleId.set(
|
|
843
|
-
mcpModuleId,
|
|
844
|
-
capabilities.filter(
|
|
845
|
-
(c) => !(c.type === type && c.methodName === identifier),
|
|
846
|
-
),
|
|
847
|
-
);
|
|
848
|
-
}
|
|
849
|
-
}
|