@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,436 +0,0 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import {
|
|
3
|
-
CallToolRequestSchema,
|
|
4
|
-
CallToolResult,
|
|
5
|
-
ErrorCode,
|
|
6
|
-
ListToolsRequestSchema,
|
|
7
|
-
McpError,
|
|
8
|
-
} from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
-
import {
|
|
10
|
-
CanActivate,
|
|
11
|
-
ExecutionContext,
|
|
12
|
-
Inject,
|
|
13
|
-
Injectable,
|
|
14
|
-
Scope,
|
|
15
|
-
Type,
|
|
16
|
-
} from '@nestjs/common';
|
|
17
|
-
import { ContextIdFactory, ModuleRef, Reflector } from '@nestjs/core';
|
|
18
|
-
import {
|
|
19
|
-
DiscoveredCapability,
|
|
20
|
-
McpRegistryDiscoveryService,
|
|
21
|
-
} from '../mcp-registry-discovery.service';
|
|
22
|
-
import { ToolGuardExecutionContext, ToolMetadata } from '../../decorators';
|
|
23
|
-
import { McpHandlerBase } from './mcp-handler.base';
|
|
24
|
-
import { ZodType } from 'zod';
|
|
25
|
-
import { HttpRequest } from '../../interfaces/http-adapter.interface';
|
|
26
|
-
import { McpRequestWithUser } from 'src/authz';
|
|
27
|
-
import { ToolAuthorizationService } from '../tool-authorization.service';
|
|
28
|
-
import { toJsonSchemaCompat } from '@modelcontextprotocol/sdk/server/zod-json-schema-compat.js';
|
|
29
|
-
import { normalizeObjectSchema } from '@modelcontextprotocol/sdk/server/zod-compat.js';
|
|
30
|
-
import type { McpOptions } from '../../interfaces/mcp-options.interface';
|
|
31
|
-
import {
|
|
32
|
-
McpRegistryService,
|
|
33
|
-
DYNAMIC_TOOL_HANDLER_TOKEN,
|
|
34
|
-
} from '../mcp-dynamic-registry.service';
|
|
35
|
-
|
|
36
|
-
@Injectable({ scope: Scope.REQUEST })
|
|
37
|
-
export class McpToolsHandler extends McpHandlerBase {
|
|
38
|
-
private readonly moduleHasGuards: boolean;
|
|
39
|
-
|
|
40
|
-
constructor(
|
|
41
|
-
moduleRef: ModuleRef,
|
|
42
|
-
registry: McpRegistryDiscoveryService,
|
|
43
|
-
reflector: Reflector,
|
|
44
|
-
@Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,
|
|
45
|
-
@Inject('MCP_OPTIONS') private readonly options: McpOptions,
|
|
46
|
-
private readonly authService: ToolAuthorizationService,
|
|
47
|
-
) {
|
|
48
|
-
super(moduleRef, registry, reflector, McpToolsHandler.name, options);
|
|
49
|
-
this.moduleHasGuards =
|
|
50
|
-
this.options.guards !== undefined && this.options.guards.length > 0;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
private buildDefaultContentBlock(result: any) {
|
|
54
|
-
return [
|
|
55
|
-
{
|
|
56
|
-
type: 'text',
|
|
57
|
-
text: JSON.stringify(result),
|
|
58
|
-
},
|
|
59
|
-
];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private formatToolResult(result: any, outputSchema?: ZodType): any {
|
|
63
|
-
if (result && typeof result === 'object' && Array.isArray(result.content)) {
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (outputSchema) {
|
|
68
|
-
const validation = outputSchema.safeParse(result);
|
|
69
|
-
if (!validation.success) {
|
|
70
|
-
throw new McpError(
|
|
71
|
-
ErrorCode.InternalError,
|
|
72
|
-
`Tool result does not match outputSchema: ${validation.error.message}`,
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
return {
|
|
76
|
-
structuredContent: validation.data,
|
|
77
|
-
content: this.buildDefaultContentBlock(result),
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
content: this.buildDefaultContentBlock(result),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
protected override createErrorResponse(
|
|
87
|
-
errorText: string,
|
|
88
|
-
): CallToolResult | never {
|
|
89
|
-
return {
|
|
90
|
-
content: [{ type: 'text', text: errorText }],
|
|
91
|
-
isError: true,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Creates an ExecutionContext for @ToolGuards() evaluation.
|
|
97
|
-
*
|
|
98
|
-
* Only the fields documented in ToolGuardExecutionContext are available.
|
|
99
|
-
* Invalid fields throw with a descriptive message rather than silently
|
|
100
|
-
* returning garbage.
|
|
101
|
-
*
|
|
102
|
-
* The request object returned by `switchToHttp().getRequest()` is the raw
|
|
103
|
-
* framework request enriched with `body` and `params` from the adapted
|
|
104
|
-
* HttpRequest. During `tools/call`, `toolArguments` overrides `body` so
|
|
105
|
-
* guards can inspect the validated tool input.
|
|
106
|
-
*/
|
|
107
|
-
private createToolGuardExecutionContext(
|
|
108
|
-
httpRequest: HttpRequest,
|
|
109
|
-
tool: DiscoveredCapability<ToolMetadata>,
|
|
110
|
-
toolArguments?: Record<string, unknown>,
|
|
111
|
-
): ToolGuardExecutionContext & ExecutionContext {
|
|
112
|
-
const providerClass = tool.providerClass as Type;
|
|
113
|
-
const methodHandler =
|
|
114
|
-
providerClass.prototype?.[tool.methodName] ?? (() => {});
|
|
115
|
-
|
|
116
|
-
const unavailable = (method: string): never => {
|
|
117
|
-
throw new Error(
|
|
118
|
-
`${method} is not available in @ToolGuards() context. ` +
|
|
119
|
-
`MCP tools share a single HTTP endpoint, so only a limited API is available.` +
|
|
120
|
-
`See ToolGuardExecutionContext for the supported API.`,
|
|
121
|
-
);
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
// Build the guard request from the raw request, enriched with parsed body and params.
|
|
125
|
-
// During tools/call, toolArguments is passed so guards can inspect the tool input as `body`.
|
|
126
|
-
const guardRequest = Object.assign(
|
|
127
|
-
Object.create(Object.getPrototypeOf(httpRequest.raw ?? {})),
|
|
128
|
-
httpRequest.raw ?? {},
|
|
129
|
-
{
|
|
130
|
-
body: toolArguments ?? httpRequest.body,
|
|
131
|
-
params: httpRequest.params ?? {},
|
|
132
|
-
},
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
switchToHttp: () => ({
|
|
137
|
-
getRequest: <T = unknown>() => guardRequest as T,
|
|
138
|
-
getResponse: () => unavailable('switchToHttp().getResponse()'),
|
|
139
|
-
getNext: () => unavailable('switchToHttp().getNext()'),
|
|
140
|
-
}),
|
|
141
|
-
getClass: <T = unknown>() => providerClass as Type<T>,
|
|
142
|
-
getHandler: () => methodHandler as () => void,
|
|
143
|
-
getArgs: () => unavailable('getArgs()'),
|
|
144
|
-
getArgByIndex: () => unavailable('getArgByIndex()'),
|
|
145
|
-
getType: <TContext extends string = string>() => 'http' as TContext,
|
|
146
|
-
switchToRpc: () => unavailable('switchToRpc()'),
|
|
147
|
-
switchToWs: () => unavailable('switchToWs()'),
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Evaluates all @ToolGuards() for a tool.
|
|
153
|
-
* Returns true if the tool has no guards or all guards pass.
|
|
154
|
-
*/
|
|
155
|
-
private async checkToolGuards(
|
|
156
|
-
tool: DiscoveredCapability<ToolMetadata>,
|
|
157
|
-
httpRequest: HttpRequest,
|
|
158
|
-
toolArguments?: Record<string, unknown>,
|
|
159
|
-
): Promise<boolean> {
|
|
160
|
-
const guards = tool.metadata.guards;
|
|
161
|
-
if (!guards || guards.length === 0) {
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Guards require HTTP context - not available on STDIO
|
|
166
|
-
if (!httpRequest.raw) {
|
|
167
|
-
this.logger.warn(
|
|
168
|
-
`@ToolGuards() on tool '${tool.metadata.name}' cannot be evaluated without HTTP context (STDIO transport). ` +
|
|
169
|
-
`The tool will be hidden. Use HTTP transport to support guarded tools.`,
|
|
170
|
-
);
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const context = this.createToolGuardExecutionContext(httpRequest, tool, toolArguments);
|
|
175
|
-
|
|
176
|
-
for (const GuardClass of guards) {
|
|
177
|
-
try {
|
|
178
|
-
const guard = this.moduleRef.get<CanActivate>(GuardClass, {
|
|
179
|
-
strict: false,
|
|
180
|
-
});
|
|
181
|
-
const result = guard.canActivate(context);
|
|
182
|
-
const canActivate = result instanceof Promise ? await result : result;
|
|
183
|
-
if (!canActivate) {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
} catch (error) {
|
|
187
|
-
this.logger.warn(
|
|
188
|
-
`@ToolGuards() guard ${GuardClass.name} threw on tool '${tool.metadata.name}': ${error.message}. ` +
|
|
189
|
-
`The tool will be hidden. If this is unexpected, ensure the guard only uses ` +
|
|
190
|
-
`the API available in ToolGuardExecutionContext.`,
|
|
191
|
-
);
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
registerHandlers(mcpServer: McpServer, httpRequest: HttpRequest) {
|
|
199
|
-
if (this.registry.getTools(this.mcpModuleId).length === 0) {
|
|
200
|
-
this.logger.debug('No tools registered, skipping tool handlers');
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
mcpServer.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
205
|
-
// Extract user from request (may be undefined if not authenticated or STDIO)
|
|
206
|
-
// For STDIO transport, httpRequest.raw is undefined, so bypass auth entirely
|
|
207
|
-
const user = httpRequest.raw
|
|
208
|
-
? (httpRequest.raw as McpRequestWithUser).user
|
|
209
|
-
: undefined;
|
|
210
|
-
|
|
211
|
-
// Get all tools and filter based on user permissions
|
|
212
|
-
// STDIO: If no httpRequest.raw, disable guards (local dev mode)
|
|
213
|
-
const allTools = this.registry.getTools(this.mcpModuleId);
|
|
214
|
-
const effectiveModuleHasGuards = httpRequest.raw
|
|
215
|
-
? this.moduleHasGuards
|
|
216
|
-
: false;
|
|
217
|
-
const allowUnauthenticatedAccess =
|
|
218
|
-
this.options.allowUnauthenticatedAccess ?? false;
|
|
219
|
-
|
|
220
|
-
// Filter by JWT-based authorization (scopes, roles, public)
|
|
221
|
-
const jwtAuthorizedTools = allTools.filter((tool) =>
|
|
222
|
-
this.authService.canAccessTool(
|
|
223
|
-
user,
|
|
224
|
-
tool,
|
|
225
|
-
effectiveModuleHasGuards,
|
|
226
|
-
allowUnauthenticatedAccess,
|
|
227
|
-
),
|
|
228
|
-
);
|
|
229
|
-
|
|
230
|
-
// Filter by @ToolGuards() - evaluate each tool's guards
|
|
231
|
-
const authorizedTools: typeof jwtAuthorizedTools = [];
|
|
232
|
-
for (const tool of jwtAuthorizedTools) {
|
|
233
|
-
if (await this.checkToolGuards(tool, httpRequest)) {
|
|
234
|
-
authorizedTools.push(tool);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const tools = authorizedTools.map((tool) => {
|
|
239
|
-
// Create base schema
|
|
240
|
-
const toolSchema = {
|
|
241
|
-
name: tool.metadata.name,
|
|
242
|
-
description: tool.metadata.description,
|
|
243
|
-
annotations: tool.metadata.annotations,
|
|
244
|
-
_meta: tool.metadata._meta,
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
// Add security schemes
|
|
248
|
-
const securitySchemes = this.authService.generateSecuritySchemes(
|
|
249
|
-
tool,
|
|
250
|
-
effectiveModuleHasGuards,
|
|
251
|
-
);
|
|
252
|
-
if (securitySchemes.length > 0) {
|
|
253
|
-
toolSchema['securitySchemes'] = securitySchemes;
|
|
254
|
-
// Note: Currently securitySchemes are not supported in MCP sdk, adding to _meta as workaround
|
|
255
|
-
// (see https://developers.openai.com/apps-sdk/reference/)
|
|
256
|
-
toolSchema._meta = {
|
|
257
|
-
...toolSchema._meta,
|
|
258
|
-
securitySchemes,
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Add input schema if defined
|
|
263
|
-
const normalizedInputParameters = normalizeObjectSchema(
|
|
264
|
-
tool.metadata.parameters,
|
|
265
|
-
);
|
|
266
|
-
if (normalizedInputParameters) {
|
|
267
|
-
toolSchema['inputSchema'] = toJsonSchemaCompat(
|
|
268
|
-
normalizedInputParameters,
|
|
269
|
-
);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Add output schema if defined, ensuring it has type: 'object'
|
|
273
|
-
const normalizedOutputSchema = normalizeObjectSchema(
|
|
274
|
-
tool.metadata.outputSchema,
|
|
275
|
-
);
|
|
276
|
-
if (normalizedOutputSchema) {
|
|
277
|
-
const outputSchema = toJsonSchemaCompat(normalizedOutputSchema);
|
|
278
|
-
|
|
279
|
-
// Create a new object that explicitly includes type: 'object'
|
|
280
|
-
const jsonSchema = {
|
|
281
|
-
...outputSchema,
|
|
282
|
-
type: 'object',
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
toolSchema['outputSchema'] = jsonSchema;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
return toolSchema;
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
return {
|
|
292
|
-
tools,
|
|
293
|
-
};
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
mcpServer.server.setRequestHandler(
|
|
297
|
-
CallToolRequestSchema,
|
|
298
|
-
async (request) => {
|
|
299
|
-
this.logger.debug('CallToolRequestSchema is being called');
|
|
300
|
-
|
|
301
|
-
const toolInfo = this.registry.findTool(
|
|
302
|
-
this.mcpModuleId,
|
|
303
|
-
request.params.name,
|
|
304
|
-
);
|
|
305
|
-
|
|
306
|
-
if (!toolInfo) {
|
|
307
|
-
throw new McpError(
|
|
308
|
-
ErrorCode.MethodNotFound,
|
|
309
|
-
`Unknown tool: ${request.params.name}`,
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Validate authorization before execution
|
|
314
|
-
// For STDIO transport, bypass auth entirely (local dev mode)
|
|
315
|
-
const user = httpRequest.raw
|
|
316
|
-
? (httpRequest.raw as McpRequestWithUser).user
|
|
317
|
-
: undefined;
|
|
318
|
-
const effectiveModuleHasGuards = httpRequest.raw
|
|
319
|
-
? this.moduleHasGuards
|
|
320
|
-
: false;
|
|
321
|
-
const allowUnauthenticatedAccess =
|
|
322
|
-
this.options.allowUnauthenticatedAccess ?? false;
|
|
323
|
-
this.authService.validateToolAccess(
|
|
324
|
-
user,
|
|
325
|
-
toolInfo,
|
|
326
|
-
effectiveModuleHasGuards,
|
|
327
|
-
allowUnauthenticatedAccess,
|
|
328
|
-
);
|
|
329
|
-
|
|
330
|
-
// Validate @ToolGuards()
|
|
331
|
-
const guardsPassed = await this.checkToolGuards(toolInfo, httpRequest, request.params.arguments as Record<string, unknown>);
|
|
332
|
-
if (!guardsPassed) {
|
|
333
|
-
throw new McpError(
|
|
334
|
-
ErrorCode.InvalidRequest,
|
|
335
|
-
`Access denied: insufficient permissions for tool '${request.params.name}'`,
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
try {
|
|
340
|
-
// Validate input parameters against the tool's schema
|
|
341
|
-
if (toolInfo.metadata.parameters) {
|
|
342
|
-
const validation = toolInfo.metadata.parameters.safeParse(
|
|
343
|
-
request.params.arguments || {},
|
|
344
|
-
);
|
|
345
|
-
if (!validation.success) {
|
|
346
|
-
const issues = validation.error.issues
|
|
347
|
-
.map((issue) => {
|
|
348
|
-
const path =
|
|
349
|
-
issue.path.length > 0 ? issue.path.join('.') : '';
|
|
350
|
-
const location = path ? `[${path}]: ` : '';
|
|
351
|
-
return `${location}${issue.message}`;
|
|
352
|
-
})
|
|
353
|
-
.join('; ');
|
|
354
|
-
return {
|
|
355
|
-
content: [
|
|
356
|
-
{
|
|
357
|
-
type: 'text',
|
|
358
|
-
text: `Invalid parameters: ${issues}`,
|
|
359
|
-
},
|
|
360
|
-
],
|
|
361
|
-
isError: true,
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
// Use validated arguments to ensure defaults and transformations are applied
|
|
365
|
-
request.params.arguments = validation.data as Record<
|
|
366
|
-
string,
|
|
367
|
-
unknown
|
|
368
|
-
>;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
const contextId = ContextIdFactory.getByRequest(httpRequest);
|
|
372
|
-
this.moduleRef.registerRequestByContextId(httpRequest, contextId);
|
|
373
|
-
|
|
374
|
-
const context = this.createContext(mcpServer, request);
|
|
375
|
-
let result: any;
|
|
376
|
-
|
|
377
|
-
// Check if this is a dynamic tool (registered via McpRegistryService)
|
|
378
|
-
if (toolInfo.providerClass === DYNAMIC_TOOL_HANDLER_TOKEN) {
|
|
379
|
-
// Dynamic tool - get handler using static method with the correct moduleId
|
|
380
|
-
const handler = McpRegistryService.getHandlerByModuleId(
|
|
381
|
-
this.mcpModuleId,
|
|
382
|
-
request.params.name,
|
|
383
|
-
);
|
|
384
|
-
|
|
385
|
-
if (!handler) {
|
|
386
|
-
throw new McpError(
|
|
387
|
-
ErrorCode.MethodNotFound,
|
|
388
|
-
`Handler not found for dynamic tool: ${request.params.name}`,
|
|
389
|
-
);
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
result = await handler(
|
|
393
|
-
request.params.arguments || {},
|
|
394
|
-
context,
|
|
395
|
-
httpRequest.raw as McpRequestWithUser,
|
|
396
|
-
);
|
|
397
|
-
} else {
|
|
398
|
-
// Decorator-based tool - resolve provider instance and call method
|
|
399
|
-
const toolInstance = await this.moduleRef.resolve(
|
|
400
|
-
toolInfo.providerClass,
|
|
401
|
-
contextId,
|
|
402
|
-
{ strict: false },
|
|
403
|
-
);
|
|
404
|
-
|
|
405
|
-
if (!toolInstance) {
|
|
406
|
-
throw new McpError(
|
|
407
|
-
ErrorCode.MethodNotFound,
|
|
408
|
-
`Unknown tool: ${request.params.name}`,
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
result = await toolInstance[toolInfo.methodName].call(
|
|
413
|
-
toolInstance,
|
|
414
|
-
request.params.arguments,
|
|
415
|
-
context,
|
|
416
|
-
httpRequest.raw as McpRequestWithUser,
|
|
417
|
-
);
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
const transformedResult = this.formatToolResult(
|
|
421
|
-
result,
|
|
422
|
-
toolInfo.metadata.outputSchema,
|
|
423
|
-
);
|
|
424
|
-
|
|
425
|
-
this.logger.debug('CallToolRequestSchema result', transformedResult);
|
|
426
|
-
|
|
427
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
428
|
-
return transformedResult;
|
|
429
|
-
} catch (error) {
|
|
430
|
-
// We are assuming error as at least a message property
|
|
431
|
-
return this.handleError(error as Error, toolInfo, httpRequest);
|
|
432
|
-
}
|
|
433
|
-
},
|
|
434
|
-
);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import { Injectable, Inject, Logger } from '@nestjs/common';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import {
|
|
4
|
-
DynamicToolDefinition,
|
|
5
|
-
DynamicToolHandler,
|
|
6
|
-
} from '../interfaces/dynamic-tool.interface';
|
|
7
|
-
import {
|
|
8
|
-
DynamicResourceDefinition,
|
|
9
|
-
DynamicResourceHandler,
|
|
10
|
-
} from '../interfaces/dynamic-resource.interface';
|
|
11
|
-
import {
|
|
12
|
-
DynamicPromptDefinition,
|
|
13
|
-
DynamicPromptHandler,
|
|
14
|
-
} from '../interfaces/dynamic-prompt.interface';
|
|
15
|
-
import { McpRegistryDiscoveryService } from './mcp-registry-discovery.service';
|
|
16
|
-
import type { McpOptions } from '../interfaces';
|
|
17
|
-
import { createMcpLogger } from '../utils/mcp-logger.factory';
|
|
18
|
-
import { ToolMetadata } from '../decorators/tool.decorator';
|
|
19
|
-
import { ResourceMetadata } from '../decorators/resource.decorator';
|
|
20
|
-
import { PromptMetadata } from '../decorators/prompt.decorator';
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Symbol used to identify dynamic tools in the registry.
|
|
24
|
-
* When a tool's providerClass equals this token, it's a dynamic tool.
|
|
25
|
-
*/
|
|
26
|
-
export const DYNAMIC_TOOL_HANDLER_TOKEN = Symbol('DYNAMIC_TOOL_HANDLER');
|
|
27
|
-
export const DYNAMIC_RESOURCE_HANDLER_TOKEN = Symbol(
|
|
28
|
-
'DYNAMIC_RESOURCE_HANDLER',
|
|
29
|
-
);
|
|
30
|
-
export const DYNAMIC_PROMPT_HANDLER_TOKEN = Symbol('DYNAMIC_PROMPT_HANDLER');
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Global maps of dynamic capability handlers, scoped by moduleId.
|
|
34
|
-
* Using module-level Maps ensures handlers persist across different
|
|
35
|
-
* McpRegistryService instances that may be created by the DI container.
|
|
36
|
-
*/
|
|
37
|
-
const globalHandlers = new Map<string, Map<string, DynamicToolHandler>>();
|
|
38
|
-
const globalResourceHandlers = new Map<
|
|
39
|
-
string,
|
|
40
|
-
Map<string, DynamicResourceHandler>
|
|
41
|
-
>();
|
|
42
|
-
const globalPromptHandlers = new Map<
|
|
43
|
-
string,
|
|
44
|
-
Map<string, DynamicPromptHandler>
|
|
45
|
-
>();
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Service for programmatically registering MCP tools at runtime.
|
|
49
|
-
*
|
|
50
|
-
* Use this to register tools with descriptions/parameters from databases
|
|
51
|
-
* or other dynamic sources during application bootstrap.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```typescript
|
|
55
|
-
* @Injectable()
|
|
56
|
-
* export class DynamicToolsService implements OnModuleInit {
|
|
57
|
-
* constructor(
|
|
58
|
-
* private readonly capabilityBuilder: McpRegistryService,
|
|
59
|
-
* private readonly dbService: DatabaseService,
|
|
60
|
-
* ) {}
|
|
61
|
-
*
|
|
62
|
-
* async onModuleInit() {
|
|
63
|
-
* const collections = await this.dbService.getCollections();
|
|
64
|
-
*
|
|
65
|
-
* this.capabilityBuilder.registerTool({
|
|
66
|
-
* name: 'search-knowledge',
|
|
67
|
-
* description: `Search collections: ${collections.join(', ')}`,
|
|
68
|
-
* parameters: z.object({ query: z.string() }),
|
|
69
|
-
* handler: async (args, context) => {
|
|
70
|
-
* const results = await this.dbService.search(args.query);
|
|
71
|
-
* return { content: [{ type: 'text', text: JSON.stringify(results) }] };
|
|
72
|
-
* },
|
|
73
|
-
* });
|
|
74
|
-
* }
|
|
75
|
-
* }
|
|
76
|
-
* ```
|
|
77
|
-
*/
|
|
78
|
-
@Injectable()
|
|
79
|
-
export class McpRegistryService {
|
|
80
|
-
private readonly logger: Logger;
|
|
81
|
-
|
|
82
|
-
constructor(
|
|
83
|
-
private readonly registry: McpRegistryDiscoveryService,
|
|
84
|
-
@Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,
|
|
85
|
-
@Inject('MCP_OPTIONS') private readonly options: McpOptions,
|
|
86
|
-
) {
|
|
87
|
-
this.logger = createMcpLogger(McpRegistryService.name, this.options);
|
|
88
|
-
[globalHandlers, globalResourceHandlers, globalPromptHandlers].forEach(
|
|
89
|
-
(store) => {
|
|
90
|
-
if (!store.has(mcpModuleId)) {
|
|
91
|
-
store.set(mcpModuleId, new Map());
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Register a dynamic tool for the current MCP server.
|
|
99
|
-
*
|
|
100
|
-
* Tools registered here will appear in the `tools/list` response and
|
|
101
|
-
* can be called via `tools/call` just like decorator-based tools.
|
|
102
|
-
*
|
|
103
|
-
* @param definition - The tool definition including name, description, parameters, and handler
|
|
104
|
-
*
|
|
105
|
-
* @example
|
|
106
|
-
* ```typescript
|
|
107
|
-
* registry.registerTool({
|
|
108
|
-
* name: 'search-knowledge',
|
|
109
|
-
* description: await getDescriptionFromDB(),
|
|
110
|
-
* parameters: z.object({ query: z.string() }),
|
|
111
|
-
* handler: async (args, context) => {
|
|
112
|
-
* const results = await searchService.search(args.query);
|
|
113
|
-
* return { content: [{ type: 'text', text: JSON.stringify(results) }] };
|
|
114
|
-
* },
|
|
115
|
-
* });
|
|
116
|
-
* ```
|
|
117
|
-
*/
|
|
118
|
-
registerTool(definition: DynamicToolDefinition): void {
|
|
119
|
-
this.logger.debug(`Registering dynamic tool: ${definition.name}`);
|
|
120
|
-
|
|
121
|
-
// Store the handler for later execution (scoped by moduleId)
|
|
122
|
-
const moduleHandlers = globalHandlers.get(this.mcpModuleId)!;
|
|
123
|
-
moduleHandlers.set(definition.name, definition.handler);
|
|
124
|
-
|
|
125
|
-
// Default to empty object schema if no parameters provided (matches @Tool decorator behavior)
|
|
126
|
-
const parameters = definition.parameters ?? z.object({});
|
|
127
|
-
|
|
128
|
-
// Build metadata matching ToolMetadata interface
|
|
129
|
-
const metadata: ToolMetadata = {
|
|
130
|
-
name: definition.name,
|
|
131
|
-
description: definition.description,
|
|
132
|
-
parameters,
|
|
133
|
-
outputSchema: definition.outputSchema,
|
|
134
|
-
annotations: definition.annotations,
|
|
135
|
-
_meta: definition._meta,
|
|
136
|
-
isPublic: definition.isPublic,
|
|
137
|
-
requiredScopes: definition.requiredScopes,
|
|
138
|
-
requiredRoles: definition.requiredRoles,
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
// Register with the registry
|
|
142
|
-
this.registry.registerDynamicCapability(this.mcpModuleId, {
|
|
143
|
-
type: 'tool',
|
|
144
|
-
metadata,
|
|
145
|
-
providerClass: DYNAMIC_TOOL_HANDLER_TOKEN,
|
|
146
|
-
methodName: definition.name,
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
getHandler(toolName: string): DynamicToolHandler | undefined {
|
|
151
|
-
return globalHandlers.get(this.mcpModuleId)?.get(toolName);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
static getHandlerByModuleId(
|
|
155
|
-
mcpModuleId: string,
|
|
156
|
-
toolName: string,
|
|
157
|
-
): DynamicToolHandler | undefined {
|
|
158
|
-
return globalHandlers.get(mcpModuleId)?.get(toolName);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
registerResource(definition: DynamicResourceDefinition): void {
|
|
162
|
-
this.logger.debug(`Registering dynamic resource: ${definition.uri}`);
|
|
163
|
-
|
|
164
|
-
globalResourceHandlers
|
|
165
|
-
.get(this.mcpModuleId)!
|
|
166
|
-
.set(definition.uri, definition.handler);
|
|
167
|
-
|
|
168
|
-
const metadata: ResourceMetadata = {
|
|
169
|
-
uri: definition.uri,
|
|
170
|
-
name: definition.name ?? definition.uri,
|
|
171
|
-
description: definition.description,
|
|
172
|
-
mimeType: definition.mimeType,
|
|
173
|
-
_meta: definition._meta,
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
this.registry.registerDynamicCapability(this.mcpModuleId, {
|
|
177
|
-
type: 'resource',
|
|
178
|
-
metadata,
|
|
179
|
-
providerClass: DYNAMIC_RESOURCE_HANDLER_TOKEN,
|
|
180
|
-
methodName: definition.uri,
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
static getResourceHandlerByModuleId(
|
|
185
|
-
mcpModuleId: string,
|
|
186
|
-
uri: string,
|
|
187
|
-
): DynamicResourceHandler | undefined {
|
|
188
|
-
return globalResourceHandlers.get(mcpModuleId)?.get(uri);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
registerPrompt(definition: DynamicPromptDefinition): void {
|
|
192
|
-
this.logger.debug(`Registering dynamic prompt: ${definition.name}`);
|
|
193
|
-
|
|
194
|
-
globalPromptHandlers
|
|
195
|
-
.get(this.mcpModuleId)!
|
|
196
|
-
.set(definition.name, definition.handler);
|
|
197
|
-
|
|
198
|
-
const metadata: PromptMetadata = {
|
|
199
|
-
name: definition.name,
|
|
200
|
-
description: definition.description,
|
|
201
|
-
parameters: definition.parameters,
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
this.registry.registerDynamicCapability(this.mcpModuleId, {
|
|
205
|
-
type: 'prompt',
|
|
206
|
-
metadata,
|
|
207
|
-
providerClass: DYNAMIC_PROMPT_HANDLER_TOKEN,
|
|
208
|
-
methodName: definition.name,
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
static getPromptHandlerByModuleId(
|
|
213
|
-
mcpModuleId: string,
|
|
214
|
-
name: string,
|
|
215
|
-
): DynamicPromptHandler | undefined {
|
|
216
|
-
return globalPromptHandlers.get(mcpModuleId)?.get(name);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
removeTool(name: string): void {
|
|
220
|
-
this.logger.debug(`Removing dynamic tool: ${name}`);
|
|
221
|
-
globalHandlers.get(this.mcpModuleId)?.delete(name);
|
|
222
|
-
this.registry.removeDynamicCapability(this.mcpModuleId, 'tool', name);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
removeResource(uri: string): void {
|
|
226
|
-
this.logger.debug(`Removing dynamic resource: ${uri}`);
|
|
227
|
-
globalResourceHandlers.get(this.mcpModuleId)?.delete(uri);
|
|
228
|
-
this.registry.removeDynamicCapability(this.mcpModuleId, 'resource', uri);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
removePrompt(name: string): void {
|
|
232
|
-
this.logger.debug(`Removing dynamic prompt: ${name}`);
|
|
233
|
-
globalPromptHandlers.get(this.mcpModuleId)?.delete(name);
|
|
234
|
-
this.registry.removeDynamicCapability(this.mcpModuleId, 'prompt', name);
|
|
235
|
-
}
|
|
236
|
-
}
|