@rekog/mcp-nest 1.9.0-alpha.0 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/README.md +3 -4
  2. package/dist/authz/guards/jwt-auth.guard.d.ts +3 -1
  3. package/dist/authz/guards/jwt-auth.guard.d.ts.map +1 -1
  4. package/dist/mcp/decorators/index.d.ts +3 -0
  5. package/dist/mcp/decorators/index.d.ts.map +1 -1
  6. package/dist/mcp/decorators/index.js +3 -0
  7. package/dist/mcp/decorators/index.js.map +1 -1
  8. package/dist/mcp/decorators/prompt.decorator.d.ts +2 -2
  9. package/dist/mcp/decorators/prompt.decorator.d.ts.map +1 -1
  10. package/dist/mcp/decorators/prompt.decorator.js.map +1 -1
  11. package/dist/mcp/decorators/tool.decorator.d.ts +14 -4
  12. package/dist/mcp/decorators/tool.decorator.d.ts.map +1 -1
  13. package/dist/mcp/decorators/tool.decorator.js.map +1 -1
  14. package/dist/mcp/mcp.module.d.ts.map +1 -1
  15. package/dist/mcp/services/handlers/mcp-tools.handler.d.ts +6 -2
  16. package/dist/mcp/services/handlers/mcp-tools.handler.d.ts.map +1 -1
  17. package/dist/mcp/services/handlers/mcp-tools.handler.js +39 -9
  18. package/dist/mcp/services/handlers/mcp-tools.handler.js.map +1 -1
  19. package/dist/mcp/services/mcp-executor.service.d.ts +3 -2
  20. package/dist/mcp/services/mcp-executor.service.d.ts.map +1 -1
  21. package/dist/mcp/services/mcp-registry.service.d.ts.map +1 -1
  22. package/dist/mcp/services/mcp-registry.service.js +25 -1
  23. package/dist/mcp/services/mcp-registry.service.js.map +1 -1
  24. package/dist/mcp/services/tool-authorization.service.d.ts +11 -0
  25. package/dist/mcp/services/tool-authorization.service.d.ts.map +1 -0
  26. package/dist/mcp/services/tool-authorization.service.js +109 -0
  27. package/dist/mcp/services/tool-authorization.service.js.map +1 -0
  28. package/package.json +3 -4
  29. package/src/authz/guards/jwt-auth.guard.ts +33 -1
  30. package/src/mcp/decorators/index.ts +3 -0
  31. package/src/mcp/decorators/prompt.decorator.ts +2 -4
  32. package/src/mcp/decorators/public.decorator.ts +29 -0
  33. package/src/mcp/decorators/require-roles.decorator.ts +44 -0
  34. package/src/mcp/decorators/require-scopes.decorator.ts +51 -0
  35. package/src/mcp/decorators/tool-roles.decorator.ts +45 -0
  36. package/src/mcp/decorators/tool-scopes.decorator.ts +52 -0
  37. package/src/mcp/decorators/tool.decorator.ts +18 -6
  38. package/src/mcp/interfaces/mcp-options.interface.ts +16 -0
  39. package/src/mcp/mcp.module.ts +4 -1
  40. package/src/mcp/services/handlers/mcp-tools.handler.ts +73 -12
  41. package/src/mcp/services/mcp-executor.service.ts +11 -3
  42. package/src/mcp/services/mcp-registry.service.ts +43 -5
  43. package/src/mcp/services/tool-authorization.service.ts +211 -0
  44. package/dist/authz/guards/jwt-auth.guard.js +0 -85
  45. package/dist/authz/guards/jwt-auth.guard.js.map +0 -1
  46. package/dist/authz/index.js +0 -27
  47. package/dist/authz/index.js.map +0 -1
  48. package/dist/authz/interfaces/request-with-user.d.ts +0 -13
  49. package/dist/authz/interfaces/request-with-user.d.ts.map +0 -1
  50. package/dist/authz/interfaces/request-with-user.js +0 -3
  51. package/dist/authz/interfaces/request-with-user.js.map +0 -1
  52. package/dist/authz/mcp-oauth.controller.d.ts +0 -81
  53. package/dist/authz/mcp-oauth.controller.d.ts.map +0 -1
  54. package/dist/authz/mcp-oauth.controller.js +0 -540
  55. package/dist/authz/mcp-oauth.controller.js.map +0 -1
  56. package/dist/authz/mcp-oauth.module.js +0 -271
  57. package/dist/authz/mcp-oauth.module.js.map +0 -1
  58. package/dist/authz/providers/azure-ad.provider.d.ts +0 -3
  59. package/dist/authz/providers/azure-ad.provider.d.ts.map +0 -1
  60. package/dist/authz/providers/azure-ad.provider.js +0 -37
  61. package/dist/authz/providers/azure-ad.provider.js.map +0 -1
  62. package/dist/authz/providers/github.provider.d.ts +0 -3
  63. package/dist/authz/providers/github.provider.d.ts.map +0 -1
  64. package/dist/authz/providers/github.provider.js +0 -24
  65. package/dist/authz/providers/github.provider.js.map +0 -1
  66. package/dist/authz/providers/google.provider.d.ts +0 -3
  67. package/dist/authz/providers/google.provider.d.ts.map +0 -1
  68. package/dist/authz/providers/google.provider.js +0 -25
  69. package/dist/authz/providers/google.provider.js.map +0 -1
  70. package/dist/authz/providers/oauth-provider.interface.d.ts +0 -126
  71. package/dist/authz/providers/oauth-provider.interface.d.ts.map +0 -1
  72. package/dist/authz/providers/oauth-provider.interface.js +0 -3
  73. package/dist/authz/providers/oauth-provider.interface.js.map +0 -1
  74. package/dist/authz/services/client.service.d.ts +0 -12
  75. package/dist/authz/services/client.service.d.ts.map +0 -1
  76. package/dist/authz/services/client.service.js +0 -81
  77. package/dist/authz/services/client.service.js.map +0 -1
  78. package/dist/authz/services/jwt-token.service.d.ts +0 -37
  79. package/dist/authz/services/jwt-token.service.d.ts.map +0 -1
  80. package/dist/authz/services/jwt-token.service.js +0 -182
  81. package/dist/authz/services/jwt-token.service.js.map +0 -1
  82. package/dist/authz/services/jwt-token.service.spec.d.ts +0 -2
  83. package/dist/authz/services/jwt-token.service.spec.d.ts.map +0 -1
  84. package/dist/authz/services/jwt-token.service.spec.js +0 -86
  85. package/dist/authz/services/jwt-token.service.spec.js.map +0 -1
  86. package/dist/authz/services/oauth-strategy.service.d.ts +0 -13
  87. package/dist/authz/services/oauth-strategy.service.d.ts.map +0 -1
  88. package/dist/authz/services/oauth-strategy.service.js +0 -71
  89. package/dist/authz/services/oauth-strategy.service.js.map +0 -1
  90. package/dist/authz/stores/memory-store.service.d.ts +0 -27
  91. package/dist/authz/stores/memory-store.service.d.ts.map +0 -1
  92. package/dist/authz/stores/memory-store.service.js +0 -107
  93. package/dist/authz/stores/memory-store.service.js.map +0 -1
  94. package/dist/authz/stores/memory-store.service.spec.d.ts +0 -2
  95. package/dist/authz/stores/memory-store.service.spec.d.ts.map +0 -1
  96. package/dist/authz/stores/memory-store.service.spec.js +0 -382
  97. package/dist/authz/stores/memory-store.service.spec.js.map +0 -1
  98. package/dist/authz/stores/oauth-store.interface.d.ts +0 -60
  99. package/dist/authz/stores/oauth-store.interface.d.ts.map +0 -1
  100. package/dist/authz/stores/oauth-store.interface.js +0 -3
  101. package/dist/authz/stores/oauth-store.interface.js.map +0 -1
  102. package/dist/authz/stores/typeorm/constants.d.ts +0 -3
  103. package/dist/authz/stores/typeorm/constants.d.ts.map +0 -1
  104. package/dist/authz/stores/typeorm/constants.js +0 -6
  105. package/dist/authz/stores/typeorm/constants.js.map +0 -1
  106. package/dist/authz/stores/typeorm/entities/authorization-code.entity.d.ts +0 -15
  107. package/dist/authz/stores/typeorm/entities/authorization-code.entity.d.ts.map +0 -1
  108. package/dist/authz/stores/typeorm/entities/authorization-code.entity.js +0 -69
  109. package/dist/authz/stores/typeorm/entities/authorization-code.entity.js.map +0 -1
  110. package/dist/authz/stores/typeorm/entities/index.d.ts +0 -5
  111. package/dist/authz/stores/typeorm/entities/index.d.ts.map +0 -1
  112. package/dist/authz/stores/typeorm/entities/index.js +0 -12
  113. package/dist/authz/stores/typeorm/entities/index.js.map +0 -1
  114. package/dist/authz/stores/typeorm/entities/oauth-client.entity.d.ts +0 -17
  115. package/dist/authz/stores/typeorm/entities/oauth-client.entity.d.ts.map +0 -1
  116. package/dist/authz/stores/typeorm/entities/oauth-client.entity.js +0 -77
  117. package/dist/authz/stores/typeorm/entities/oauth-client.entity.js.map +0 -1
  118. package/dist/authz/stores/typeorm/entities/oauth-session.entity.d.ts +0 -14
  119. package/dist/authz/stores/typeorm/entities/oauth-session.entity.d.ts.map +0 -1
  120. package/dist/authz/stores/typeorm/entities/oauth-session.entity.js +0 -65
  121. package/dist/authz/stores/typeorm/entities/oauth-session.entity.js.map +0 -1
  122. package/dist/authz/stores/typeorm/entities/user-profile.entity.d.ts +0 -13
  123. package/dist/authz/stores/typeorm/entities/user-profile.entity.d.ts.map +0 -1
  124. package/dist/authz/stores/typeorm/entities/user-profile.entity.js +0 -62
  125. package/dist/authz/stores/typeorm/entities/user-profile.entity.js.map +0 -1
  126. package/dist/authz/stores/typeorm/typeorm-store.service.d.ts +0 -28
  127. package/dist/authz/stores/typeorm/typeorm-store.service.d.ts.map +0 -1
  128. package/dist/authz/stores/typeorm/typeorm-store.service.js +0 -138
  129. package/dist/authz/stores/typeorm/typeorm-store.service.js.map +0 -1
  130. package/dist/authz/stores/typeorm/typeorm-store.service.spec.d.ts +0 -2
  131. package/dist/authz/stores/typeorm/typeorm-store.service.spec.d.ts.map +0 -1
  132. package/dist/authz/stores/typeorm/typeorm-store.service.spec.js +0 -340
  133. package/dist/authz/stores/typeorm/typeorm-store.service.spec.js.map +0 -1
  134. package/dist/index.js +0 -19
  135. package/dist/index.js.map +0 -1
  136. package/dist/mcp/adapters/express-http.adapter.d.ts +0 -7
  137. package/dist/mcp/adapters/express-http.adapter.d.ts.map +0 -1
  138. package/dist/mcp/adapters/express-http.adapter.js +0 -50
  139. package/dist/mcp/adapters/express-http.adapter.js.map +0 -1
  140. package/dist/mcp/adapters/fastify-http.adapter.d.ts +0 -23
  141. package/dist/mcp/adapters/fastify-http.adapter.d.ts.map +0 -1
  142. package/dist/mcp/adapters/fastify-http.adapter.js +0 -57
  143. package/dist/mcp/adapters/fastify-http.adapter.js.map +0 -1
  144. package/dist/mcp/adapters/http-adapter.factory.d.ts +0 -11
  145. package/dist/mcp/adapters/http-adapter.factory.d.ts.map +0 -1
  146. package/dist/mcp/adapters/http-adapter.factory.js +0 -61
  147. package/dist/mcp/adapters/http-adapter.factory.js.map +0 -1
  148. package/dist/mcp/adapters/index.d.ts +0 -4
  149. package/dist/mcp/adapters/index.d.ts.map +0 -1
  150. package/dist/mcp/adapters/index.js +0 -20
  151. package/dist/mcp/adapters/index.js.map +0 -1
  152. package/dist/mcp/decorators/constants.d.ts +0 -5
  153. package/dist/mcp/decorators/constants.d.ts.map +0 -1
  154. package/dist/mcp/decorators/constants.js +0 -8
  155. package/dist/mcp/decorators/constants.js.map +0 -1
  156. package/dist/mcp/decorators/resource-template.decorator.d.ts +0 -16
  157. package/dist/mcp/decorators/resource-template.decorator.d.ts.map +0 -1
  158. package/dist/mcp/decorators/resource-template.decorator.js +0 -10
  159. package/dist/mcp/decorators/resource-template.decorator.js.map +0 -1
  160. package/dist/mcp/decorators/resource.decorator.d.ts +0 -16
  161. package/dist/mcp/decorators/resource.decorator.d.ts.map +0 -1
  162. package/dist/mcp/decorators/resource.decorator.js +0 -10
  163. package/dist/mcp/decorators/resource.decorator.js.map +0 -1
  164. package/dist/mcp/index.js +0 -24
  165. package/dist/mcp/index.js.map +0 -1
  166. package/dist/mcp/interfaces/http-adapter.interface.d.ts +0 -27
  167. package/dist/mcp/interfaces/http-adapter.interface.d.ts.map +0 -1
  168. package/dist/mcp/interfaces/http-adapter.interface.js +0 -3
  169. package/dist/mcp/interfaces/http-adapter.interface.js.map +0 -1
  170. package/dist/mcp/interfaces/index.d.ts +0 -4
  171. package/dist/mcp/interfaces/index.d.ts.map +0 -1
  172. package/dist/mcp/interfaces/index.js +0 -20
  173. package/dist/mcp/interfaces/index.js.map +0 -1
  174. package/dist/mcp/interfaces/mcp-options.interface.d.ts +0 -45
  175. package/dist/mcp/interfaces/mcp-options.interface.d.ts.map +0 -1
  176. package/dist/mcp/interfaces/mcp-options.interface.js +0 -10
  177. package/dist/mcp/interfaces/mcp-options.interface.js.map +0 -1
  178. package/dist/mcp/interfaces/mcp-tool.interface.d.ts +0 -21
  179. package/dist/mcp/interfaces/mcp-tool.interface.d.ts.map +0 -1
  180. package/dist/mcp/interfaces/mcp-tool.interface.js +0 -3
  181. package/dist/mcp/interfaces/mcp-tool.interface.js.map +0 -1
  182. package/dist/mcp/mcp.module.js +0 -202
  183. package/dist/mcp/mcp.module.js.map +0 -1
  184. package/dist/mcp/services/handlers/mcp-handler.base.js +0 -86
  185. package/dist/mcp/services/handlers/mcp-handler.base.js.map +0 -1
  186. package/dist/mcp/services/handlers/mcp-prompts.handler.js +0 -90
  187. package/dist/mcp/services/handlers/mcp-prompts.handler.js.map +0 -1
  188. package/dist/mcp/services/handlers/mcp-resources.handler.js +0 -110
  189. package/dist/mcp/services/handlers/mcp-resources.handler.js.map +0 -1
  190. package/dist/mcp/services/mcp-executor.service.js +0 -46
  191. package/dist/mcp/services/mcp-executor.service.js.map +0 -1
  192. package/dist/mcp/services/mcp-sse.service.js +0 -97
  193. package/dist/mcp/services/mcp-sse.service.js.map +0 -1
  194. package/dist/mcp/services/mcp-streamable-http.service.js +0 -337
  195. package/dist/mcp/services/mcp-streamable-http.service.js.map +0 -1
  196. package/dist/mcp/services/sse-ping.service.d.ts +0 -23
  197. package/dist/mcp/services/sse-ping.service.d.ts.map +0 -1
  198. package/dist/mcp/services/sse-ping.service.js +0 -99
  199. package/dist/mcp/services/sse-ping.service.js.map +0 -1
  200. package/dist/mcp/transport/custom-decorator.spec.js +0 -34
  201. package/dist/mcp/transport/custom-decorator.spec.js.map +0 -1
  202. package/dist/mcp/transport/sse.controller.factory.js +0 -67
  203. package/dist/mcp/transport/sse.controller.factory.js.map +0 -1
  204. package/dist/mcp/transport/stdio.service.js +0 -61
  205. package/dist/mcp/transport/stdio.service.js.map +0 -1
  206. package/dist/mcp/transport/streamable-http.controller.factory.js +0 -74
  207. package/dist/mcp/transport/streamable-http.controller.factory.js.map +0 -1
  208. package/dist/mcp/utils/capabilities-builder.js +0 -25
  209. package/dist/mcp/utils/capabilities-builder.js.map +0 -1
  210. package/dist/mcp/utils/mcp-logger.factory.d.ts +0 -4
  211. package/dist/mcp/utils/mcp-logger.factory.d.ts.map +0 -1
  212. package/dist/mcp/utils/mcp-logger.factory.js +0 -60
  213. package/dist/mcp/utils/mcp-logger.factory.js.map +0 -1
  214. package/dist/mcp/utils/mcp-logger.factory.spec.d.ts +0 -2
  215. package/dist/mcp/utils/mcp-logger.factory.spec.d.ts.map +0 -1
  216. package/dist/mcp/utils/mcp-logger.factory.spec.js +0 -150
  217. package/dist/mcp/utils/mcp-logger.factory.spec.js.map +0 -1
  218. package/dist/mcp/utils/normalize-endpoint.d.ts +0 -2
  219. package/dist/mcp/utils/normalize-endpoint.d.ts.map +0 -1
  220. package/dist/mcp/utils/normalize-endpoint.js +0 -30
  221. package/dist/mcp/utils/normalize-endpoint.js.map +0 -1
  222. package/dist/mcp/utils/normalize-endpoint.spec.d.ts +0 -2
  223. package/dist/mcp/utils/normalize-endpoint.spec.d.ts.map +0 -1
  224. package/dist/mcp/utils/normalize-endpoint.spec.js +0 -40
  225. package/dist/mcp/utils/normalize-endpoint.spec.js.map +0 -1
package/README.md CHANGED
@@ -20,8 +20,8 @@ With `@rekog/mcp-nest` you define tools, resources, and prompts in a way that's
20
20
  - 🚀 **[Multi-Transport Support](docs/server-examples.md#multiple-transport-types)**: HTTP+SSE, Streamable HTTP, and STDIO
21
21
  - 🔧 **[Tools](docs/tools.md)**: Expose NestJS methods as MCP tools with automatic discovery and Zod validation
22
22
  - 🛠️ **[Elicitation](docs/tools.md#interactive-tool-calls)**: Interactive tool calls with user input elicitation
23
- - 📊 **[Progress Notifications](docs/tools.md#tool-with-progress-reporting)**: Real-time progress updates for long-running operations
24
23
  - 🌐 **[HTTP Request Access](docs/tools.md#understanding-tool-method-parameters)**: Full access to request context within MCP handlers
24
+ - 🔐 **[Per-Tool Authorization](./per-tool-authorization.md)**: Implement fine-grained authorization for tools
25
25
  - 📁 **[Resources](docs/resources.md)**: Serve content and data through MCP resource system
26
26
  - 📚 **[Resource Templates](docs/resource-templates.md)**: Dynamic resources with parameterized URIs
27
27
  - 💬 **[Prompts](docs/prompts.md)**: Define reusable prompt templates for AI interactions
@@ -29,15 +29,14 @@ With `@rekog/mcp-nest` you define tools, resources, and prompts in a way that's
29
29
  - 🏠 **[Built-in Authorization Server](docs/built-in-authorization-server.md)** — Using the built-in Authorization Server for easy setups. **(Beta)**
30
30
  - 🌐 **[External Authorization Server](docs/external-authorization-server/README.md)** — Securing your MCP server with an external authorization server (Keycloak, Auth0, etc).
31
31
  - 💉 **[Dependency Injection](docs/dependency-injection.md)**: Leverage NestJS DI system throughout MCP components
32
- - 📝 **[Logging Configuration](docs/server-examples.md#logging-configuration)**: Fine-grained control over MCP module logging levels
33
32
 
34
- **Are you interested to build ChatGPT widgets (with the OpenAI SDK)?**
33
+ **Are you interested to build ChatGPT widgets (with the OpenAI SDK)?**
35
34
  Find out how to do that with `@rekog/MCP-Nest` in this repository [MCP-Nest-Samples/pizzaz-openai-apps-sdk](https://github.com/rinormaloku/MCP-Nest-Samples/tree/main/pizzaz-openai-apps-sdk)
36
35
 
37
36
  ## Installation
38
37
 
39
38
  ```bash
40
- npm install @rekog/mcp-nest @modelcontextprotocol/sdk zod@^3
39
+ npm install @rekog/mcp-nest @modelcontextprotocol/sdk zod@^4
41
40
  ```
42
41
 
43
42
  ### Optional dependencies
@@ -3,6 +3,7 @@ import { ModuleRef } from '@nestjs/core';
3
3
  import { Request } from 'express';
4
4
  import { JwtPayload, JwtTokenService } from '../services/jwt-token.service';
5
5
  import { IOAuthStore } from '../stores/oauth-store.interface';
6
+ import { McpOptions } from '../../mcp';
6
7
  export interface AuthenticatedRequest extends Request {
7
8
  user: JwtPayload;
8
9
  }
@@ -10,7 +11,8 @@ export declare class McpAuthJwtGuard implements CanActivate {
10
11
  private readonly jwtTokenService;
11
12
  private readonly store;
12
13
  private readonly moduleRef;
13
- constructor(jwtTokenService: JwtTokenService | null, store: IOAuthStore | null, moduleRef: ModuleRef);
14
+ private readonly options?;
15
+ constructor(jwtTokenService: JwtTokenService | null, store: IOAuthStore | null, moduleRef: ModuleRef, options?: McpOptions | undefined);
14
16
  canActivate(context: ExecutionContext): Promise<boolean>;
15
17
  private extractTokenFromHeader;
16
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-auth.guard.d.ts","sourceRoot":"","sources":["../../../src/authz/guards/jwt-auth.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,gBAAgB,EAIjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,MAAM,WAAW,oBAAqB,SAAQ,OAAO;IACnD,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,qBACa,eAAgB,YAAW,WAAW;IAEnC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAG5C,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAJG,eAAe,EAAE,eAAe,GAAG,IAAI,EAGnD,KAAK,EAAE,WAAW,GAAG,IAAI,EACzB,SAAS,EAAE,SAAS;IAGjC,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IA0D9D,OAAO,CAAC,sBAAsB;CAS/B"}
1
+ {"version":3,"file":"jwt-auth.guard.d.ts","sourceRoot":"","sources":["../../../src/authz/guards/jwt-auth.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,gBAAgB,EAIjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,WAAW,oBAAqB,SAAQ,OAAO;IACnD,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,qBACa,eAAgB,YAAW,WAAW;IAEnC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAG5C,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAG1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAPI,eAAe,EAAE,eAAe,GAAG,IAAI,EAGnD,KAAK,EAAE,WAAW,GAAG,IAAI,EACzB,SAAS,EAAE,SAAS,EAGpB,OAAO,CAAC,EAAE,UAAU,YAAA;IAGjC,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAsF9D,OAAO,CAAC,sBAAsB;CAS/B"}
@@ -3,4 +3,7 @@ export * from './constants';
3
3
  export * from './resource.decorator';
4
4
  export * from './resource-template.decorator';
5
5
  export * from './prompt.decorator';
6
+ export * from './public.decorator';
7
+ export * from './tool-scopes.decorator';
8
+ export * from './tool-roles.decorator';
6
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC"}
@@ -19,4 +19,7 @@ __exportStar(require("./constants"), exports);
19
19
  __exportStar(require("./resource.decorator"), exports);
20
20
  __exportStar(require("./resource-template.decorator"), exports);
21
21
  __exportStar(require("./prompt.decorator"), exports);
22
+ __exportStar(require("./public.decorator"), exports);
23
+ __exportStar(require("./tool-scopes.decorator"), exports);
24
+ __exportStar(require("./tool-roles.decorator"), exports);
22
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,8CAA4B;AAC5B,uDAAqC;AACrC,gEAA8C;AAC9C,qDAAmC","sourcesContent":["export * from './tool.decorator';\nexport * from './constants';\nexport * from './resource.decorator';\nexport * from './resource-template.decorator';\nexport * from './prompt.decorator';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,8CAA4B;AAC5B,uDAAqC;AACrC,gEAA8C;AAC9C,qDAAmC;AACnC,qDAAmC;AACnC,0DAAwC;AACxC,yDAAuC","sourcesContent":["export * from './tool.decorator';\nexport * from './constants';\nexport * from './resource.decorator';\nexport * from './resource-template.decorator';\nexport * from './prompt.decorator';\nexport * from './public.decorator';\nexport * from './tool-scopes.decorator';\nexport * from './tool-roles.decorator';\n"]}
@@ -1,6 +1,6 @@
1
- import { ZodType, ZodTypeDef, ZodOptional, ZodObject } from 'zod';
1
+ import { ZodObject, ZodType } from 'zod';
2
2
  type PromptArgsRawShape = {
3
- [k: string]: ZodType<string, ZodTypeDef, string> | ZodOptional<ZodType<string, ZodTypeDef, string>>;
3
+ [k: string]: ZodType;
4
4
  };
5
5
  export interface PromptMetadata {
6
6
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.decorator.d.ts","sourceRoot":"","sources":["../../../src/mcp/decorators/prompt.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAElE,KAAK,kBAAkB,GAAG;IACxB,CAAC,CAAC,EAAE,MAAM,GACN,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,GACnC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;CACtD,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;CAC5C;AAED,eAAO,MAAM,MAAM,GAAI,SAAS,aAAa,qDAE5C,CAAC"}
1
+ {"version":3,"file":"prompt.decorator.d.ts","sourceRoot":"","sources":["../../../src/mcp/decorators/prompt.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEzC,KAAK,kBAAkB,GAAG;IACxB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;CAC5C;AAED,eAAO,MAAM,MAAM,GAAI,SAAS,aAAa,qDAE5C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.decorator.js","sourceRoot":"","sources":["../../../src/mcp/decorators/prompt.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,2CAAsD;AAqB/C,MAAM,MAAM,GAAG,CAAC,OAAsB,EAAE,EAAE;IAC/C,OAAO,IAAA,oBAAW,EAAC,mCAAuB,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC,CAAC;AAFW,QAAA,MAAM,UAEjB","sourcesContent":["import { SetMetadata } from '@nestjs/common';\nimport { MCP_PROMPT_METADATA_KEY } from './constants';\nimport { ZodType, ZodTypeDef, ZodOptional, ZodObject } from 'zod';\n\ntype PromptArgsRawShape = {\n [k: string]:\n | ZodType<string, ZodTypeDef, string>\n | ZodOptional<ZodType<string, ZodTypeDef, string>>;\n};\n\nexport interface PromptMetadata {\n name: string;\n description: string;\n parameters?: ZodObject<PromptArgsRawShape>;\n}\n\nexport interface PromptOptions {\n name?: string;\n description: string;\n parameters?: ZodObject<PromptArgsRawShape>;\n}\n\nexport const Prompt = (options: PromptOptions) => {\n return SetMetadata(MCP_PROMPT_METADATA_KEY, options);\n};\n"]}
1
+ {"version":3,"file":"prompt.decorator.js","sourceRoot":"","sources":["../../../src/mcp/decorators/prompt.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,2CAAsD;AAmB/C,MAAM,MAAM,GAAG,CAAC,OAAsB,EAAE,EAAE;IAC/C,OAAO,IAAA,oBAAW,EAAC,mCAAuB,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC,CAAC;AAFW,QAAA,MAAM,UAEjB","sourcesContent":["import { SetMetadata } from '@nestjs/common';\nimport { MCP_PROMPT_METADATA_KEY } from './constants';\nimport { ZodObject, ZodType } from 'zod';\n\ntype PromptArgsRawShape = {\n [k: string]: ZodType;\n};\n\nexport interface PromptMetadata {\n name: string;\n description: string;\n parameters?: ZodObject<PromptArgsRawShape>;\n}\n\nexport interface PromptOptions {\n name?: string;\n description: string;\n parameters?: ZodObject<PromptArgsRawShape>;\n}\n\nexport const Prompt = (options: PromptOptions) => {\n return SetMetadata(MCP_PROMPT_METADATA_KEY, options);\n};\n"]}
@@ -1,20 +1,30 @@
1
1
  import { z } from 'zod';
2
2
  import { ToolAnnotations as SdkToolAnnotations } from '@modelcontextprotocol/sdk/types.js';
3
+ export type SecurityScheme = {
4
+ type: 'noauth';
5
+ } | {
6
+ type: 'oauth2';
7
+ scopes?: string[];
8
+ };
3
9
  export interface ToolMetadata {
4
10
  name: string;
5
11
  description: string;
6
- parameters?: z.ZodTypeAny;
7
- outputSchema?: z.ZodTypeAny;
12
+ parameters?: z.ZodType;
13
+ outputSchema?: z.ZodType;
8
14
  annotations?: SdkToolAnnotations;
9
15
  _meta?: Record<string, any>;
16
+ securitySchemes?: SecurityScheme[];
17
+ isPublic?: boolean;
18
+ requiredScopes?: string[];
19
+ requiredRoles?: string[];
10
20
  }
11
21
  export interface ToolAnnotations extends SdkToolAnnotations {
12
22
  }
13
23
  export interface ToolOptions {
14
24
  name?: string;
15
25
  description?: string;
16
- parameters?: z.ZodTypeAny;
17
- outputSchema?: z.ZodTypeAny;
26
+ parameters?: z.ZodType;
27
+ outputSchema?: z.ZodType;
18
28
  annotations?: ToolAnnotations;
19
29
  _meta?: Record<string, any>;
20
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tool.decorator.d.ts","sourceRoot":"","sources":["../../../src/mcp/decorators/tool.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,IAAI,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE3F,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;IAC5B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC7B;AAGD,MAAM,WAAW,eAAgB,SAAQ,kBAAkB;CAAG;AAE9D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;IAC5B,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC7B;AAWD,eAAO,MAAM,IAAI,GAAI,SAAS,WAAW,qDAMxC,CAAC"}
1
+ {"version":3,"file":"tool.decorator.d.ts","sourceRoot":"","sources":["../../../src/mcp/decorators/tool.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,IAAI,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAK3F,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE1C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE5B,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAGD,MAAM,WAAW,eAAgB,SAAQ,kBAAkB;CAAG;AAE9D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC7B;AAWD,eAAO,MAAM,IAAI,GAAI,SAAS,WAAW,qDAMxC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool.decorator.js","sourceRoot":"","sources":["../../../src/mcp/decorators/tool.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,2CAAoD;AACpD,6BAAwB;AAiCjB,MAAM,IAAI,GAAG,CAAC,OAAoB,EAAE,EAAE;IAC3C,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,CAAC,UAAU,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,IAAA,oBAAW,EAAC,iCAAqB,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC,CAAC;AANW,QAAA,IAAI,QAMf","sourcesContent":["import { SetMetadata } from '@nestjs/common';\nimport { MCP_TOOL_METADATA_KEY } from './constants';\nimport { z } from 'zod';\nimport { ToolAnnotations as SdkToolAnnotations } from '@modelcontextprotocol/sdk/types.js';\n\nexport interface ToolMetadata {\n name: string;\n description: string;\n parameters?: z.ZodTypeAny;\n outputSchema?: z.ZodTypeAny;\n annotations?: SdkToolAnnotations;\n _meta?: Record<string, any>;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface ToolAnnotations extends SdkToolAnnotations {}\n\nexport interface ToolOptions {\n name?: string;\n description?: string;\n parameters?: z.ZodTypeAny;\n outputSchema?: z.ZodTypeAny;\n annotations?: ToolAnnotations;\n _meta?: Record<string, any>;\n}\n\n/**\n * Decorator that marks a controller method as an MCP tool.\n * @param {Object} options - The options for the decorator\n * @param {string} options.name - The name of the tool\n * @param {string} options.description - The description of the tool\n * @param {z.ZodTypeAny} [options.parameters] - The parameters of the tool\n * @param {z.ZodTypeAny} [options.outputSchema] - The output schema of the tool\n * @returns {MethodDecorator} - The decorator\n */\nexport const Tool = (options: ToolOptions) => {\n if (options.parameters === undefined) {\n options.parameters = z.object({});\n }\n\n return SetMetadata(MCP_TOOL_METADATA_KEY, options);\n};\n"]}
1
+ {"version":3,"file":"tool.decorator.js","sourceRoot":"","sources":["../../../src/mcp/decorators/tool.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,2CAAoD;AACpD,6BAAwB;AA6CjB,MAAM,IAAI,GAAG,CAAC,OAAoB,EAAE,EAAE;IAC3C,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,CAAC,UAAU,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,IAAA,oBAAW,EAAC,iCAAqB,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC,CAAC;AANW,QAAA,IAAI,QAMf","sourcesContent":["import { SetMetadata } from '@nestjs/common';\nimport { MCP_TOOL_METADATA_KEY } from './constants';\nimport { z } from 'zod';\nimport { ToolAnnotations as SdkToolAnnotations } from '@modelcontextprotocol/sdk/types.js';\n\n/**\n * Security scheme type for MCP tools\n */\nexport type SecurityScheme =\n | { type: 'noauth' }\n | { type: 'oauth2'; scopes?: string[] };\n\nexport interface ToolMetadata {\n name: string;\n description: string;\n parameters?: z.ZodType;\n outputSchema?: z.ZodType;\n annotations?: SdkToolAnnotations;\n _meta?: Record<string, any>;\n // Security-related metadata\n securitySchemes?: SecurityScheme[];\n isPublic?: boolean;\n requiredScopes?: string[];\n requiredRoles?: string[];\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface ToolAnnotations extends SdkToolAnnotations {}\n\nexport interface ToolOptions {\n name?: string;\n description?: string;\n parameters?: z.ZodType;\n outputSchema?: z.ZodType;\n annotations?: ToolAnnotations;\n _meta?: Record<string, any>;\n}\n\n/**\n * Decorator that marks a controller method as an MCP tool.\n * @param {Object} options - The options for the decorator\n * @param {string} options.name - The name of the tool\n * @param {string} options.description - The description of the tool\n * @param {z.ZodType} [options.parameters] - The parameters of the tool\n * @param {z.ZodType} [options.outputSchema] - The output schema of the tool\n * @returns {MethodDecorator} - The decorator\n */\nexport const Tool = (options: ToolOptions) => {\n if (options.parameters === undefined) {\n options.parameters = z.object({});\n }\n\n return SetMetadata(MCP_TOOL_METADATA_KEY, options);\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.module.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA0B,MAAM,gBAAgB,CAAC;AAGvE,OAAO,KAAK,EACV,UAAU,EACV,qBAAqB,EAGtB,MAAM,cAAc,CAAC;AAatB,qBAIa,SAAS;IAIpB,QAAQ,CAAC,aAAa,QAAQ;IAE9B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,aAAa;IAoDlD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa;IA8BlE,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAgDnC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IA2B5C,OAAO,CAAC,MAAM,CAAC,4BAA4B;IA4C3C,OAAO,CAAC,MAAM,CAAC,0BAA0B;CAuB1C"}
1
+ {"version":3,"file":"mcp.module.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA0B,MAAM,gBAAgB,CAAC;AAGvE,OAAO,KAAK,EACV,UAAU,EACV,qBAAqB,EAGtB,MAAM,cAAc,CAAC;AActB,qBAIa,SAAS;IAIpB,QAAQ,CAAC,aAAa,QAAQ;IAE9B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,aAAa;IAoDlD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa;IA+BlE,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAgDnC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IA2B5C,OAAO,CAAC,MAAM,CAAC,4BAA4B;IA4C3C,OAAO,CAAC,MAAM,CAAC,0BAA0B;CAwB1C"}
@@ -3,10 +3,14 @@ import { ModuleRef } from '@nestjs/core';
3
3
  import { McpRegistryService } from '../mcp-registry.service';
4
4
  import { McpHandlerBase } from './mcp-handler.base';
5
5
  import { HttpRequest } from '../../interfaces/http-adapter.interface';
6
- import { McpOptions } from '../../interfaces';
6
+ import { ToolAuthorizationService } from '../tool-authorization.service';
7
+ import { McpOptions } from '../../interfaces/mcp-options.interface';
7
8
  export declare class McpToolsHandler extends McpHandlerBase {
8
9
  private readonly mcpModuleId;
9
- constructor(moduleRef: ModuleRef, registry: McpRegistryService, mcpModuleId: string, options?: McpOptions);
10
+ private readonly options;
11
+ private readonly authService;
12
+ private readonly moduleHasGuards;
13
+ constructor(moduleRef: ModuleRef, registry: McpRegistryService, mcpModuleId: string, options: McpOptions, authService: ToolAuthorizationService);
10
14
  private buildDefaultContentBlock;
11
15
  private formatToolResult;
12
16
  registerHandlers(mcpServer: McpServer, httpRequest: HttpRequest): void;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-tools.handler.d.ts","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-tools.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAEtE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,qBACa,eAAgB,SAAQ,cAAc;IAItB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAFrD,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,kBAAkB,EACc,WAAW,EAAE,MAAM,EAC1B,OAAO,CAAC,EAAE,UAAU;IAKzD,OAAO,CAAC,wBAAwB;IAShC,OAAO,CAAC,gBAAgB;IAwBxB,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW;CA4HhE"}
1
+ {"version":3,"file":"mcp-tools.handler.d.ts","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-tools.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAEtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAIpE,qBACa,eAAgB,SAAQ,cAAc;IAMtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW;IAP9B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;gBAGxC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,kBAAkB,EACc,WAAW,EAAE,MAAM,EACrB,OAAO,EAAE,UAAU,EAC1C,WAAW,EAAE,wBAAwB;IAOxD,OAAO,CAAC,wBAAwB;IAShC,OAAO,CAAC,gBAAgB;IAwBxB,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW;CAkLhE"}
@@ -17,13 +17,19 @@ exports.McpToolsHandler = void 0;
17
17
  const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
18
18
  const common_1 = require("@nestjs/common");
19
19
  const core_1 = require("@nestjs/core");
20
- const zod_to_json_schema_1 = require("zod-to-json-schema");
21
20
  const mcp_registry_service_1 = require("../mcp-registry.service");
22
21
  const mcp_handler_base_1 = require("./mcp-handler.base");
22
+ const tool_authorization_service_1 = require("../tool-authorization.service");
23
+ const zod_json_schema_compat_js_1 = require("@modelcontextprotocol/sdk/server/zod-json-schema-compat.js");
24
+ const zod_compat_js_1 = require("@modelcontextprotocol/sdk/server/zod-compat.js");
23
25
  let McpToolsHandler = McpToolsHandler_1 = class McpToolsHandler extends mcp_handler_base_1.McpHandlerBase {
24
- constructor(moduleRef, registry, mcpModuleId, options) {
26
+ constructor(moduleRef, registry, mcpModuleId, options, authService) {
25
27
  super(moduleRef, registry, McpToolsHandler_1.name, options);
26
28
  this.mcpModuleId = mcpModuleId;
29
+ this.options = options;
30
+ this.authService = authService;
31
+ this.moduleHasGuards =
32
+ this.options.guards !== undefined && this.options.guards.length > 0;
27
33
  }
28
34
  buildDefaultContentBlock(result) {
29
35
  return [
@@ -57,18 +63,36 @@ let McpToolsHandler = McpToolsHandler_1 = class McpToolsHandler extends mcp_hand
57
63
  return;
58
64
  }
59
65
  mcpServer.server.setRequestHandler(types_js_1.ListToolsRequestSchema, () => {
60
- const tools = this.registry.getTools(this.mcpModuleId).map((tool) => {
66
+ const user = httpRequest.raw
67
+ ? httpRequest.raw.user
68
+ : undefined;
69
+ const allTools = this.registry.getTools(this.mcpModuleId);
70
+ const effectiveModuleHasGuards = httpRequest.raw
71
+ ? this.moduleHasGuards
72
+ : false;
73
+ const authorizedTools = allTools.filter((tool) => this.authService.canAccessTool(user, tool, effectiveModuleHasGuards));
74
+ const tools = authorizedTools.map((tool) => {
61
75
  const toolSchema = {
62
76
  name: tool.metadata.name,
63
77
  description: tool.metadata.description,
64
78
  annotations: tool.metadata.annotations,
65
79
  _meta: tool.metadata._meta,
66
80
  };
67
- if (tool.metadata.parameters) {
68
- toolSchema['inputSchema'] = (0, zod_to_json_schema_1.zodToJsonSchema)(tool.metadata.parameters);
81
+ const securitySchemes = this.authService.generateSecuritySchemes(tool, effectiveModuleHasGuards);
82
+ if (securitySchemes.length > 0) {
83
+ toolSchema['securitySchemes'] = securitySchemes;
84
+ toolSchema._meta = {
85
+ ...toolSchema._meta,
86
+ securitySchemes,
87
+ };
88
+ }
89
+ const normalizedInputParameters = (0, zod_compat_js_1.normalizeObjectSchema)(tool.metadata.parameters);
90
+ if (normalizedInputParameters) {
91
+ toolSchema['inputSchema'] = (0, zod_json_schema_compat_js_1.toJsonSchemaCompat)(normalizedInputParameters);
69
92
  }
70
- if (tool.metadata.outputSchema) {
71
- const outputSchema = (0, zod_to_json_schema_1.zodToJsonSchema)(tool.metadata.outputSchema);
93
+ const normalizedOutputSchema = (0, zod_compat_js_1.normalizeObjectSchema)(tool.metadata.outputSchema);
94
+ if (normalizedOutputSchema) {
95
+ const outputSchema = (0, zod_json_schema_compat_js_1.toJsonSchemaCompat)(normalizedOutputSchema);
72
96
  const jsonSchema = {
73
97
  ...outputSchema,
74
98
  type: 'object',
@@ -87,6 +111,13 @@ let McpToolsHandler = McpToolsHandler_1 = class McpToolsHandler extends mcp_hand
87
111
  if (!toolInfo) {
88
112
  throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
89
113
  }
114
+ const user = httpRequest.raw
115
+ ? httpRequest.raw.user
116
+ : undefined;
117
+ const effectiveModuleHasGuards = httpRequest.raw
118
+ ? this.moduleHasGuards
119
+ : false;
120
+ this.authService.validateToolAccess(user, toolInfo, effectiveModuleHasGuards);
90
121
  try {
91
122
  if (toolInfo.metadata.parameters) {
92
123
  const validation = toolInfo.metadata.parameters.safeParse(request.params.arguments || {});
@@ -124,9 +155,8 @@ exports.McpToolsHandler = McpToolsHandler;
124
155
  exports.McpToolsHandler = McpToolsHandler = McpToolsHandler_1 = __decorate([
125
156
  (0, common_1.Injectable)({ scope: common_1.Scope.REQUEST }),
126
157
  __param(2, (0, common_1.Inject)('MCP_MODULE_ID')),
127
- __param(3, (0, common_1.Optional)()),
128
158
  __param(3, (0, common_1.Inject)('MCP_OPTIONS')),
129
159
  __metadata("design:paramtypes", [core_1.ModuleRef,
130
- mcp_registry_service_1.McpRegistryService, String, Object])
160
+ mcp_registry_service_1.McpRegistryService, String, Object, tool_authorization_service_1.ToolAuthorizationService])
131
161
  ], McpToolsHandler);
132
162
  //# sourceMappingURL=mcp-tools.handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-tools.handler.js","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-tools.handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n CallToolRequestSchema,\n ErrorCode,\n ListToolsRequestSchema,\n McpError,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { Inject, Injectable, Optional, Scope } from '@nestjs/common';\nimport { ContextIdFactory, ModuleRef } from '@nestjs/core';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport { McpRegistryService } from '../mcp-registry.service';\nimport { McpHandlerBase } from './mcp-handler.base';\nimport { ZodTypeAny } from 'zod';\nimport { HttpRequest } from '../../interfaces/http-adapter.interface';\nimport { McpRequestWithUser } from 'src/authz';\nimport { McpOptions } from '../../interfaces';\n\n@Injectable({ scope: Scope.REQUEST })\nexport class McpToolsHandler extends McpHandlerBase {\n constructor(\n moduleRef: ModuleRef,\n registry: McpRegistryService,\n @Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,\n @Optional() @Inject('MCP_OPTIONS') options?: McpOptions,\n ) {\n super(moduleRef, registry, McpToolsHandler.name, options);\n }\n\n private buildDefaultContentBlock(result: any) {\n return [\n {\n type: 'text',\n text: JSON.stringify(result),\n },\n ];\n }\n\n private formatToolResult(result: any, outputSchema?: ZodTypeAny): any {\n if (result && typeof result === 'object' && Array.isArray(result.content)) {\n return result;\n }\n\n if (outputSchema) {\n const validation = outputSchema.safeParse(result);\n if (!validation.success) {\n throw new McpError(\n ErrorCode.InternalError,\n `Tool result does not match outputSchema: ${validation.error.message}`,\n );\n }\n return {\n structuredContent: result,\n content: this.buildDefaultContentBlock(result),\n };\n }\n\n return {\n content: this.buildDefaultContentBlock(result),\n };\n }\n\n registerHandlers(mcpServer: McpServer, httpRequest: HttpRequest) {\n if (this.registry.getTools(this.mcpModuleId).length === 0) {\n this.logger.debug('No tools registered, skipping tool handlers');\n return;\n }\n\n mcpServer.server.setRequestHandler(ListToolsRequestSchema, () => {\n const tools = this.registry.getTools(this.mcpModuleId).map((tool) => {\n // Create base schema\n const toolSchema = {\n name: tool.metadata.name,\n description: tool.metadata.description,\n annotations: tool.metadata.annotations,\n _meta: tool.metadata._meta,\n };\n\n // Add input schema if defined\n if (tool.metadata.parameters) {\n toolSchema['inputSchema'] = zodToJsonSchema(tool.metadata.parameters);\n }\n\n // Add output schema if defined, ensuring it has type: 'object'\n if (tool.metadata.outputSchema) {\n const outputSchema = zodToJsonSchema(tool.metadata.outputSchema);\n\n // Create a new object that explicitly includes type: 'object'\n const jsonSchema = {\n ...outputSchema,\n type: 'object',\n };\n\n toolSchema['outputSchema'] = jsonSchema;\n }\n\n return toolSchema;\n });\n\n return {\n tools,\n };\n });\n\n mcpServer.server.setRequestHandler(\n CallToolRequestSchema,\n async (request) => {\n this.logger.debug('CallToolRequestSchema is being called');\n\n const toolInfo = this.registry.findTool(\n this.mcpModuleId,\n request.params.name,\n );\n\n if (!toolInfo) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown tool: ${request.params.name}`,\n );\n }\n\n try {\n // Validate input parameters against the tool's schema\n if (toolInfo.metadata.parameters) {\n const validation = toolInfo.metadata.parameters.safeParse(\n request.params.arguments || {},\n );\n if (!validation.success) {\n throw new McpError(\n ErrorCode.InvalidParams,\n `Invalid parameters: ${validation.error.message}`,\n );\n }\n // Use validated arguments to ensure defaults and transformations are applied\n request.params.arguments = validation.data;\n }\n\n const contextId = ContextIdFactory.getByRequest(httpRequest);\n this.moduleRef.registerRequestByContextId(httpRequest, contextId);\n\n const toolInstance = await this.moduleRef.resolve(\n toolInfo.providerClass,\n contextId,\n { strict: false },\n );\n\n const context = this.createContext(mcpServer, request);\n\n if (!toolInstance) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown tool: ${request.params.name}`,\n );\n }\n\n const result = await toolInstance[toolInfo.methodName].call(\n toolInstance,\n request.params.arguments,\n context,\n httpRequest.raw as McpRequestWithUser,\n );\n\n const transformedResult = this.formatToolResult(\n result,\n toolInfo.metadata.outputSchema,\n );\n\n this.logger.debug(transformedResult, 'CallToolRequestSchema result');\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return transformedResult;\n } catch (error) {\n this.logger.error(error);\n // Re-throw McpErrors (like validation errors) so they are handled by the MCP protocol layer\n if (error instanceof McpError) {\n throw error;\n }\n // For other errors, return formatted error response\n return {\n content: [{ type: 'text', text: error.message }],\n isError: true,\n };\n }\n },\n );\n }\n}\n"]}
1
+ {"version":3,"file":"mcp-tools.handler.js","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-tools.handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n CallToolRequestSchema,\n ErrorCode,\n ListToolsRequestSchema,\n McpError,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { Inject, Injectable, Scope } from '@nestjs/common';\nimport { ContextIdFactory, ModuleRef } from '@nestjs/core';\nimport { McpRegistryService } from '../mcp-registry.service';\nimport { McpHandlerBase } from './mcp-handler.base';\nimport { ZodType } from 'zod';\nimport { HttpRequest } from '../../interfaces/http-adapter.interface';\nimport { McpRequestWithUser } from 'src/authz';\nimport { ToolAuthorizationService } from '../tool-authorization.service';\nimport { McpOptions } from '../../interfaces/mcp-options.interface';\nimport { toJsonSchemaCompat } from '@modelcontextprotocol/sdk/server/zod-json-schema-compat.js';\nimport { normalizeObjectSchema } from '@modelcontextprotocol/sdk/server/zod-compat.js';\n\n@Injectable({ scope: Scope.REQUEST })\nexport class McpToolsHandler extends McpHandlerBase {\n private readonly moduleHasGuards: boolean;\n\n constructor(\n moduleRef: ModuleRef,\n registry: McpRegistryService,\n @Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,\n @Inject('MCP_OPTIONS') private readonly options: McpOptions,\n private readonly authService: ToolAuthorizationService,\n ) {\n super(moduleRef, registry, McpToolsHandler.name, options);\n this.moduleHasGuards =\n this.options.guards !== undefined && this.options.guards.length > 0;\n }\n\n private buildDefaultContentBlock(result: any) {\n return [\n {\n type: 'text',\n text: JSON.stringify(result),\n },\n ];\n }\n\n private formatToolResult(result: any, outputSchema?: ZodType): any {\n if (result && typeof result === 'object' && Array.isArray(result.content)) {\n return result;\n }\n\n if (outputSchema) {\n const validation = outputSchema.safeParse(result);\n if (!validation.success) {\n throw new McpError(\n ErrorCode.InternalError,\n `Tool result does not match outputSchema: ${validation.error.message}`,\n );\n }\n return {\n structuredContent: result,\n content: this.buildDefaultContentBlock(result),\n };\n }\n\n return {\n content: this.buildDefaultContentBlock(result),\n };\n }\n\n registerHandlers(mcpServer: McpServer, httpRequest: HttpRequest) {\n if (this.registry.getTools(this.mcpModuleId).length === 0) {\n this.logger.debug('No tools registered, skipping tool handlers');\n return;\n }\n\n mcpServer.server.setRequestHandler(ListToolsRequestSchema, () => {\n // Extract user from request (may be undefined if not authenticated or STDIO)\n // For STDIO transport, httpRequest.raw is undefined, so bypass auth entirely\n const user = httpRequest.raw\n ? (httpRequest.raw as McpRequestWithUser).user\n : undefined;\n\n // Get all tools and filter based on user permissions\n // STDIO: If no httpRequest.raw, disable guards (local dev mode)\n const allTools = this.registry.getTools(this.mcpModuleId);\n const effectiveModuleHasGuards = httpRequest.raw\n ? this.moduleHasGuards\n : false;\n const authorizedTools = allTools.filter((tool) =>\n this.authService.canAccessTool(user, tool, effectiveModuleHasGuards),\n );\n\n const tools = authorizedTools.map((tool) => {\n // Create base schema\n const toolSchema = {\n name: tool.metadata.name,\n description: tool.metadata.description,\n annotations: tool.metadata.annotations,\n _meta: tool.metadata._meta,\n };\n\n // Add security schemes\n const securitySchemes = this.authService.generateSecuritySchemes(\n tool,\n effectiveModuleHasGuards,\n );\n if (securitySchemes.length > 0) {\n toolSchema['securitySchemes'] = securitySchemes;\n // Note: Currently securitySchemes are not supported in MCP sdk, adding to _meta as workaround\n // (see https://developers.openai.com/apps-sdk/reference/)\n toolSchema._meta = {\n ...toolSchema._meta,\n securitySchemes,\n };\n }\n\n // Add input schema if defined\n const normalizedInputParameters = normalizeObjectSchema(\n tool.metadata.parameters,\n );\n if (normalizedInputParameters) {\n toolSchema['inputSchema'] = toJsonSchemaCompat(normalizedInputParameters);\n }\n\n // Add output schema if defined, ensuring it has type: 'object'\n const normalizedOutputSchema = normalizeObjectSchema(\n tool.metadata.outputSchema,\n );\n if (normalizedOutputSchema) {\n const outputSchema = toJsonSchemaCompat(normalizedOutputSchema);\n\n // Create a new object that explicitly includes type: 'object'\n const jsonSchema = {\n ...outputSchema,\n type: 'object',\n };\n\n toolSchema['outputSchema'] = jsonSchema;\n }\n\n return toolSchema;\n });\n\n return {\n tools,\n };\n });\n\n mcpServer.server.setRequestHandler(\n CallToolRequestSchema,\n async (request) => {\n this.logger.debug('CallToolRequestSchema is being called');\n\n const toolInfo = this.registry.findTool(\n this.mcpModuleId,\n request.params.name,\n );\n\n if (!toolInfo) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown tool: ${request.params.name}`,\n );\n }\n\n // Validate authorization before execution\n // For STDIO transport, bypass auth entirely (local dev mode)\n const user = httpRequest.raw\n ? (httpRequest.raw as McpRequestWithUser).user\n : undefined;\n const effectiveModuleHasGuards = httpRequest.raw\n ? this.moduleHasGuards\n : false;\n this.authService.validateToolAccess(\n user,\n toolInfo,\n effectiveModuleHasGuards,\n );\n\n try {\n // Validate input parameters against the tool's schema\n if (toolInfo.metadata.parameters) {\n const validation = toolInfo.metadata.parameters.safeParse(\n request.params.arguments || {},\n );\n if (!validation.success) {\n throw new McpError(\n ErrorCode.InvalidParams,\n `Invalid parameters: ${validation.error.message}`,\n );\n }\n // Use validated arguments to ensure defaults and transformations are applied\n request.params.arguments = validation.data as Record<\n string,\n unknown\n >;\n }\n\n const contextId = ContextIdFactory.getByRequest(httpRequest);\n this.moduleRef.registerRequestByContextId(httpRequest, contextId);\n\n const toolInstance = await this.moduleRef.resolve(\n toolInfo.providerClass,\n contextId,\n { strict: false },\n );\n\n const context = this.createContext(mcpServer, request);\n\n if (!toolInstance) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown tool: ${request.params.name}`,\n );\n }\n\n const result = await toolInstance[toolInfo.methodName].call(\n toolInstance,\n request.params.arguments,\n context,\n httpRequest.raw as McpRequestWithUser,\n );\n\n const transformedResult = this.formatToolResult(\n result,\n toolInfo.metadata.outputSchema,\n );\n\n this.logger.debug(transformedResult, 'CallToolRequestSchema result');\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return transformedResult;\n } catch (error) {\n this.logger.error(error);\n // Re-throw McpErrors (like validation errors) so they are handled by the MCP protocol layer\n if (error instanceof McpError) {\n throw error;\n }\n // For other errors, return formatted error response\n return {\n content: [{ type: 'text', text: error.message }],\n isError: true,\n };\n }\n },\n );\n }\n}\n"]}
@@ -2,13 +2,14 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { ModuleRef } from '@nestjs/core';
3
3
  import { McpRegistryService } from './mcp-registry.service';
4
4
  import { HttpRequest } from '../interfaces/http-adapter.interface';
5
- import { McpOptions } from '../interfaces';
5
+ import { ToolAuthorizationService } from './tool-authorization.service';
6
+ import { McpOptions } from '../interfaces/mcp-options.interface';
6
7
  export declare class McpExecutorService {
7
8
  private logger;
8
9
  private toolsHandler;
9
10
  private resourcesHandler;
10
11
  private promptsHandler;
11
- constructor(moduleRef: ModuleRef, registry: McpRegistryService, mcpModuleId: string, options?: McpOptions);
12
+ constructor(moduleRef: ModuleRef, registry: McpRegistryService, mcpModuleId: string, options: McpOptions, authService: ToolAuthorizationService);
12
13
  registerRequestHandlers(mcpServer: McpServer, httpRequest: HttpRequest): void;
13
14
  }
14
15
  //# sourceMappingURL=mcp-executor.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-executor.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp-executor.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAI5D,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAM3C,qBACa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,cAAc,CAAoB;gBAGxC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,kBAAkB,EACH,WAAW,EAAE,MAAM,EACT,OAAO,CAAC,EAAE,UAAU;IAqBzD,uBAAuB,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW;CAKvE"}
1
+ {"version":3,"file":"mcp-executor.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp-executor.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAI5D,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAMjE,qBACa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,cAAc,CAAoB;gBAGxC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,kBAAkB,EACH,WAAW,EAAE,MAAM,EACrB,OAAO,EAAE,UAAU,EAC1C,WAAW,EAAE,wBAAwB;IA2BvC,uBAAuB,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW;CAKvE"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-registry.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp-registry.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-registry.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp-registry.service.ts"],"names":[],"mappings":"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"}
@@ -98,7 +98,31 @@ let McpRegistryService = McpRegistryService_1 = class McpRegistryService {
98
98
  }
99
99
  addDiscoveryTool(mcpModuleId, methodRef, token, methodName) {
100
100
  this.logger.debug(`Tool discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`);
101
- this.addDiscovery('tool', decorators_1.MCP_TOOL_METADATA_KEY, mcpModuleId, methodRef, token, methodName);
101
+ const isPublic = Reflect.getMetadata(decorators_1.MCP_PUBLIC_METADATA_KEY, methodRef);
102
+ const requiredScopes = Reflect.getMetadata(decorators_1.MCP_SCOPES_METADATA_KEY, methodRef);
103
+ const requiredRoles = Reflect.getMetadata(decorators_1.MCP_ROLES_METADATA_KEY, methodRef);
104
+ const baseMetadata = Reflect.getMetadata(decorators_1.MCP_TOOL_METADATA_KEY, methodRef);
105
+ if (!baseMetadata.name) {
106
+ baseMetadata.name = methodName;
107
+ }
108
+ if (isPublic !== undefined) {
109
+ baseMetadata.isPublic = isPublic;
110
+ }
111
+ if (requiredScopes) {
112
+ baseMetadata.requiredScopes = requiredScopes;
113
+ }
114
+ if (requiredRoles) {
115
+ baseMetadata.requiredRoles = requiredRoles;
116
+ }
117
+ if (!this.discoveredToolsByMcpModuleId.has(mcpModuleId)) {
118
+ this.discoveredToolsByMcpModuleId.set(mcpModuleId, []);
119
+ }
120
+ this.discoveredToolsByMcpModuleId.get(mcpModuleId)?.push({
121
+ type: 'tool',
122
+ metadata: baseMetadata,
123
+ providerClass: token,
124
+ methodName,
125
+ });
102
126
  }
103
127
  addDiscoveryResource(mcpModuleId, methodRef, token, methodName) {
104
128
  this.logger.debug(`Resource discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`);
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-registry.service.js","sourceRoot":"","sources":["../../../src/mcp/services/mcp-registry.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Injectable,\n InjectionToken,\n Logger,\n OnApplicationBootstrap,\n Inject,\n Optional,\n} from '@nestjs/common';\nimport {\n DiscoveryService,\n MetadataScanner,\n ModulesContainer,\n} from '@nestjs/core';\nimport {\n MCP_PROMPT_METADATA_KEY,\n MCP_RESOURCE_METADATA_KEY,\n MCP_RESOURCE_TEMPLATE_METADATA_KEY,\n MCP_TOOL_METADATA_KEY,\n ToolMetadata,\n} from '../decorators';\nimport { ResourceMetadata } from '../decorators/resource.decorator';\nimport { match } from 'path-to-regexp';\nimport { PromptMetadata } from '../decorators/prompt.decorator';\nimport { Module } from '@nestjs/core/injector/module';\nimport { ResourceTemplateMetadata } from '../decorators/resource-template.decorator';\nimport { McpOptions } from '../interfaces';\nimport { createMcpLogger } from '../utils/mcp-logger.factory';\n\n/**\n * Interface representing a discovered tool\n */\nexport type DiscoveredTool<T extends object> = {\n type: 'tool' | 'resource' | 'resource-template' | 'prompt';\n metadata: T;\n providerClass: InjectionToken;\n methodName: string;\n};\n\nexport type InjectionTokenWithName = InjectionToken & { name: string };\n\n/**\n * Singleton service that discovers and registers tools during application bootstrap\n */\n@Injectable()\nexport class McpRegistryService implements OnApplicationBootstrap {\n private readonly logger: Logger;\n private discoveredToolsByMcpModuleId: Map<string, DiscoveredTool<any>[]> =\n new Map();\n\n constructor(\n private readonly discovery: DiscoveryService,\n private readonly metadataScanner: MetadataScanner,\n private readonly modulesContainer: ModulesContainer,\n @Optional() @Inject('MCP_OPTIONS') private readonly options?: McpOptions,\n ) {\n this.logger = createMcpLogger(McpRegistryService.name, this.options);\n }\n\n onApplicationBootstrap() {\n this.discoverTools();\n }\n\n /**\n * Finds all modules that import the McpModule and scans only the root module providers and controllers.\n * This prevents unintentionally exposing tools from imported dependencies.\n */\n private discoverTools() {\n const getImportedMcpModules = (module: Module) =>\n Array.from(module.imports).filter(\n (m) => (m.instance as any).__isMcpModule,\n );\n\n const pairs = Array.from(this.modulesContainer.values())\n .map((module): [Module, Module[]] => [\n module,\n getImportedMcpModules(module),\n ])\n .filter(([, importedMcpModules]) => importedMcpModules.length > 0);\n\n for (const [rootModule, mcpModules] of pairs) {\n this.logger.debug(\n `Discovering tools, resources, resource templates, and prompts for module: ${rootModule.name}`,\n );\n\n for (const mcpModule of mcpModules) {\n const mcpModuleId =\n mcpModule.getProviderByKey<string>('MCP_MODULE_ID')?.instance;\n\n this.discoverToolsForModuleSubtree(mcpModuleId, [rootModule]);\n }\n }\n }\n\n /**\n * Scans all providers and controllers for @Tool decorators\n */\n private discoverToolsForModuleSubtree(\n mcpModuleId: string,\n modules: Module[],\n ) {\n const providers = this.discovery.getProviders(undefined, modules);\n const controllers = this.discovery.getControllers(undefined, modules);\n const allInstances = [...providers, ...controllers]\n .filter(\n (wrapper) =>\n wrapper.instance &&\n typeof wrapper.instance === 'object' &&\n wrapper.instance !== null,\n )\n .map((wrapper) => ({\n instance: wrapper.instance as object,\n token: wrapper.token,\n }));\n\n allInstances.forEach(({ instance, token }) => {\n this.metadataScanner.getAllMethodNames(instance).forEach((methodName) => {\n const methodRef = instance[methodName] as object;\n const methodMetaKeys = Reflect.getOwnMetadataKeys(methodRef);\n\n if (methodMetaKeys.includes(MCP_TOOL_METADATA_KEY)) {\n this.addDiscoveryTool(\n mcpModuleId,\n methodRef,\n token as InjectionTokenWithName,\n methodName,\n );\n }\n\n if (methodMetaKeys.includes(MCP_RESOURCE_METADATA_KEY)) {\n this.addDiscoveryResource(\n mcpModuleId,\n methodRef,\n token as InjectionTokenWithName,\n methodName,\n );\n }\n\n if (methodMetaKeys.includes(MCP_RESOURCE_TEMPLATE_METADATA_KEY)) {\n this.addDiscoveryResourceTemplate(\n mcpModuleId,\n methodRef,\n token as InjectionTokenWithName,\n methodName,\n );\n }\n\n if (methodMetaKeys.includes(MCP_PROMPT_METADATA_KEY)) {\n this.addDiscoveryPrompt(\n mcpModuleId,\n methodRef,\n token as InjectionTokenWithName,\n methodName,\n );\n }\n });\n });\n }\n\n /**\n * Adds a discovered tool to the registry\n */\n private addDiscovery<T>(\n type: 'tool' | 'resource' | 'resource-template' | 'prompt',\n metadataKey: string,\n mcpModuleId: string,\n methodRef: object,\n token: InjectionTokenWithName,\n methodName: string,\n ) {\n const metadata: T = Reflect.getMetadata(metadataKey, methodRef);\n\n if (!metadata['name']) {\n metadata['name'] = methodName;\n }\n\n if (!this.discoveredToolsByMcpModuleId.has(mcpModuleId)) {\n this.discoveredToolsByMcpModuleId.set(mcpModuleId, []);\n }\n\n this.discoveredToolsByMcpModuleId.get(mcpModuleId)?.push({\n type,\n metadata,\n providerClass: token,\n methodName,\n });\n }\n\n private addDiscoveryPrompt(\n mcpModuleId: string,\n methodRef: object,\n token: InjectionTokenWithName,\n methodName: string,\n ) {\n this.logger.debug(\n `Prompt discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,\n );\n this.addDiscovery<PromptMetadata>(\n 'prompt',\n MCP_PROMPT_METADATA_KEY,\n mcpModuleId,\n methodRef,\n token,\n methodName,\n );\n }\n\n private addDiscoveryTool(\n mcpModuleId: string,\n methodRef: object,\n token: InjectionTokenWithName,\n methodName: string,\n ) {\n this.logger.debug(\n `Tool discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,\n );\n this.addDiscovery<ToolMetadata>(\n 'tool',\n MCP_TOOL_METADATA_KEY,\n mcpModuleId,\n methodRef,\n token,\n methodName,\n );\n }\n\n private addDiscoveryResource(\n mcpModuleId: string,\n methodRef: object,\n token: InjectionTokenWithName,\n methodName: string,\n ) {\n this.logger.debug(\n `Resource discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,\n );\n this.addDiscovery<ResourceMetadata>(\n 'resource',\n MCP_RESOURCE_METADATA_KEY,\n mcpModuleId,\n methodRef,\n token,\n methodName,\n );\n }\n\n private addDiscoveryResourceTemplate(\n mcpModuleId: string,\n methodRef: object,\n token: InjectionTokenWithName,\n methodName: string,\n ) {\n this.logger.debug(\n `Resource Template discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,\n );\n this.addDiscovery<ResourceTemplateMetadata>(\n 'resource-template',\n MCP_RESOURCE_TEMPLATE_METADATA_KEY,\n mcpModuleId,\n methodRef,\n token,\n methodName,\n );\n }\n\n /**\n * Return all discovered MCP module IDs\n */\n getMcpModuleIds(): string[] {\n return Array.from(this.discoveredToolsByMcpModuleId.keys());\n }\n\n /**\n * Get all discovered tools\n */\n getTools(mcpModuleId: string): DiscoveredTool<ToolMetadata>[] {\n return (\n this.discoveredToolsByMcpModuleId\n .get(mcpModuleId)\n ?.filter((tool) => tool.type === 'tool') ?? []\n );\n }\n\n /**\n * Find a tool by name\n */\n findTool(\n mcpModuleId: string,\n name: string,\n ): DiscoveredTool<ToolMetadata> | undefined {\n return this.getTools(mcpModuleId).find(\n (tool) => tool.metadata.name === name,\n );\n }\n\n /**\n * Get all discovered resources\n */\n getResources(mcpModuleId: string): DiscoveredTool<ResourceMetadata>[] {\n return (\n this.discoveredToolsByMcpModuleId\n .get(mcpModuleId)\n ?.filter((tool) => tool.type === 'resource') ?? []\n );\n }\n\n /**\n * Find a resource by name\n */\n findResource(\n mcpModuleId: string,\n name: string,\n ): DiscoveredTool<ResourceMetadata> | undefined {\n return this.getResources(mcpModuleId).find(\n (tool) => tool.metadata.name === name,\n );\n }\n\n /**\n * Get all discovered resource templates\n */\n getResourceTemplates(\n mcpModuleId: string,\n ): DiscoveredTool<ResourceTemplateMetadata>[] {\n return (\n this.discoveredToolsByMcpModuleId\n .get(mcpModuleId)\n ?.filter((tool) => tool.type === 'resource-template') ?? []\n );\n }\n\n /**\n * Find a resource by name\n */\n findResourceTemplate(\n mcpModuleId: string,\n name: string,\n ): DiscoveredTool<ResourceTemplateMetadata> | undefined {\n return this.getResourceTemplates(mcpModuleId).find(\n (tool) => tool.metadata.name === name,\n );\n }\n\n /**\n * Get all discovered prompts\n */\n getPrompts(mcpModuleId: string): DiscoveredTool<PromptMetadata>[] {\n return (\n this.discoveredToolsByMcpModuleId\n .get(mcpModuleId)\n ?.filter((tool) => tool.type === 'prompt') ?? []\n );\n }\n\n /**\n * Find a prompt by name\n */\n findPrompt(\n mcpModuleId: string,\n name: string,\n ): DiscoveredTool<PromptMetadata> | undefined {\n return this.getPrompts(mcpModuleId).find(\n (tool) => tool.metadata.name === name,\n );\n }\n\n private convertTemplate(template: string): string {\n return template?.replace(/{(\\w+)}/g, ':$1');\n }\n\n private convertUri(uri: string): string {\n if (uri.includes('://')) {\n return uri.split('://')[1];\n }\n\n return uri;\n }\n\n /**\n * Find a resource by uri\n * @returns An object containing the found resource and extracted parameters, or undefined if no resource is found\n */\n findResourceByUri(\n mcpModuleId: string,\n uri: string,\n ):\n | {\n resource: DiscoveredTool<ResourceMetadata>;\n params: Record<string, string>;\n }\n | undefined {\n const resources = this.getResources(mcpModuleId).map((tool) => ({\n name: tool.metadata.name,\n uri: tool.metadata.uri,\n }));\n\n const strippedInputUri = this.convertUri(uri);\n\n for (const t of resources) {\n if (!t.uri) continue;\n\n const rawTemplate = t.uri;\n const templatePath = this.convertTemplate(this.convertUri(rawTemplate));\n const matcher = match(templatePath, { decode: decodeURIComponent });\n const result = matcher(strippedInputUri);\n\n if (result) {\n const foundResource = this.findResource(mcpModuleId, t.name);\n if (!foundResource) continue;\n\n return {\n resource: foundResource,\n params: result.params as Record<string, string>,\n };\n }\n }\n\n return undefined;\n }\n\n /**\n * Find a resource template by uri\n * @returns An object containing the found resource template and extracted parameters, or undefined if no resource template is found\n */\n findResourceTemplateByUri(\n mcpModuleId: string,\n uri: string,\n ):\n | {\n resourceTemplate: DiscoveredTool<ResourceTemplateMetadata>;\n params: Record<string, string>;\n }\n | undefined {\n const resourceTemplates = this.getResourceTemplates(mcpModuleId).map(\n (tool) => ({\n name: tool.metadata.name,\n uriTemplate: tool.metadata.uriTemplate,\n }),\n );\n\n const strippedInputUri = this.convertUri(uri);\n\n for (const t of resourceTemplates) {\n if (!t.uriTemplate) continue;\n\n const rawTemplate = t.uriTemplate;\n const templatePath = this.convertTemplate(this.convertUri(rawTemplate));\n const matcher = match(templatePath, { decode: decodeURIComponent });\n const result = matcher(strippedInputUri);\n\n if (result) {\n const foundResourceTemplate = this.findResourceTemplate(\n mcpModuleId,\n t.name,\n );\n if (!foundResourceTemplate) continue;\n\n return {\n resourceTemplate: foundResourceTemplate,\n params: result.params as Record<string, string>,\n };\n }\n }\n\n return undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"mcp-registry.service.js","sourceRoot":"","sources":["../../../src/mcp/services/mcp-registry.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Injectable,\n InjectionToken,\n Logger,\n OnApplicationBootstrap,\n Inject,\n Optional,\n} from '@nestjs/common';\nimport {\n DiscoveryService,\n MetadataScanner,\n ModulesContainer,\n} from '@nestjs/core';\nimport {\n MCP_PROMPT_METADATA_KEY,\n MCP_RESOURCE_METADATA_KEY,\n MCP_RESOURCE_TEMPLATE_METADATA_KEY,\n MCP_TOOL_METADATA_KEY,\n MCP_PUBLIC_METADATA_KEY,\n MCP_SCOPES_METADATA_KEY,\n MCP_ROLES_METADATA_KEY,\n ToolMetadata,\n} from '../decorators';\nimport { ResourceMetadata } from '../decorators/resource.decorator';\nimport { match } from 'path-to-regexp';\nimport { PromptMetadata } from '../decorators/prompt.decorator';\nimport { Module } from '@nestjs/core/injector/module';\nimport { ResourceTemplateMetadata } from '../decorators/resource-template.decorator';\nimport { McpOptions } from '../interfaces';\nimport { createMcpLogger } from '../utils/mcp-logger.factory';\n\n/**\n * Interface representing a discovered tool\n */\nexport type DiscoveredTool<T extends object> = {\n type: 'tool' | 'resource' | 'resource-template' | 'prompt';\n metadata: T;\n providerClass: InjectionToken;\n methodName: string;\n};\n\nexport type InjectionTokenWithName = InjectionToken & { name: string };\n\n/**\n * Singleton service that discovers and registers tools during application bootstrap\n */\n@Injectable()\nexport class McpRegistryService implements OnApplicationBootstrap {\n private readonly logger: Logger;\n private discoveredToolsByMcpModuleId: Map<string, DiscoveredTool<any>[]> =\n new Map();\n\n constructor(\n private readonly discovery: DiscoveryService,\n private readonly metadataScanner: MetadataScanner,\n private readonly modulesContainer: ModulesContainer,\n @Optional() @Inject('MCP_OPTIONS') private readonly options?: McpOptions,\n ) {\n this.logger = createMcpLogger(McpRegistryService.name, this.options);\n }\n\n onApplicationBootstrap() {\n this.discoverTools();\n }\n\n /**\n * Finds all modules that import the McpModule and scans only the root module providers and controllers.\n * This prevents unintentionally exposing tools from imported dependencies.\n */\n private discoverTools() {\n const getImportedMcpModules = (module: Module) =>\n Array.from(module.imports).filter(\n (m) => (m.instance as any).__isMcpModule,\n );\n\n const pairs = Array.from(this.modulesContainer.values())\n .map((module): [Module, Module[]] => [\n module,\n getImportedMcpModules(module),\n ])\n .filter(([, importedMcpModules]) => importedMcpModules.length > 0);\n\n for (const [rootModule, mcpModules] of pairs) {\n this.logger.debug(\n `Discovering tools, resources, resource templates, and prompts for module: ${rootModule.name}`,\n );\n\n for (const mcpModule of mcpModules) {\n const mcpModuleId =\n mcpModule.getProviderByKey<string>('MCP_MODULE_ID')?.instance;\n\n this.discoverToolsForModuleSubtree(mcpModuleId, [rootModule]);\n }\n }\n }\n\n /**\n * Scans all providers and controllers for @Tool decorators\n */\n private discoverToolsForModuleSubtree(\n mcpModuleId: string,\n modules: Module[],\n ) {\n const providers = this.discovery.getProviders(undefined, modules);\n const controllers = this.discovery.getControllers(undefined, modules);\n const allInstances = [...providers, ...controllers]\n .filter(\n (wrapper) =>\n wrapper.instance &&\n typeof wrapper.instance === 'object' &&\n wrapper.instance !== null,\n )\n .map((wrapper) => ({\n instance: wrapper.instance as object,\n token: wrapper.token,\n }));\n\n allInstances.forEach(({ instance, token }) => {\n this.metadataScanner.getAllMethodNames(instance).forEach((methodName) => {\n const methodRef = instance[methodName] as object;\n const methodMetaKeys = Reflect.getOwnMetadataKeys(methodRef);\n\n if (methodMetaKeys.includes(MCP_TOOL_METADATA_KEY)) {\n this.addDiscoveryTool(\n mcpModuleId,\n methodRef,\n token as InjectionTokenWithName,\n methodName,\n );\n }\n\n if (methodMetaKeys.includes(MCP_RESOURCE_METADATA_KEY)) {\n this.addDiscoveryResource(\n mcpModuleId,\n methodRef,\n token as InjectionTokenWithName,\n methodName,\n );\n }\n\n if (methodMetaKeys.includes(MCP_RESOURCE_TEMPLATE_METADATA_KEY)) {\n this.addDiscoveryResourceTemplate(\n mcpModuleId,\n methodRef,\n token as InjectionTokenWithName,\n methodName,\n );\n }\n\n if (methodMetaKeys.includes(MCP_PROMPT_METADATA_KEY)) {\n this.addDiscoveryPrompt(\n mcpModuleId,\n methodRef,\n token as InjectionTokenWithName,\n methodName,\n );\n }\n });\n });\n }\n\n /**\n * Adds a discovered tool to the registry\n */\n private addDiscovery<T>(\n type: 'tool' | 'resource' | 'resource-template' | 'prompt',\n metadataKey: string,\n mcpModuleId: string,\n methodRef: object,\n token: InjectionTokenWithName,\n methodName: string,\n ) {\n const metadata: T = Reflect.getMetadata(metadataKey, methodRef);\n\n if (!metadata['name']) {\n metadata['name'] = methodName;\n }\n\n if (!this.discoveredToolsByMcpModuleId.has(mcpModuleId)) {\n this.discoveredToolsByMcpModuleId.set(mcpModuleId, []);\n }\n\n this.discoveredToolsByMcpModuleId.get(mcpModuleId)?.push({\n type,\n metadata,\n providerClass: token,\n methodName,\n });\n }\n\n private addDiscoveryPrompt(\n mcpModuleId: string,\n methodRef: object,\n token: InjectionTokenWithName,\n methodName: string,\n ) {\n this.logger.debug(\n `Prompt discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,\n );\n this.addDiscovery<PromptMetadata>(\n 'prompt',\n MCP_PROMPT_METADATA_KEY,\n mcpModuleId,\n methodRef,\n token,\n methodName,\n );\n }\n\n private addDiscoveryTool(\n mcpModuleId: string,\n methodRef: object,\n token: InjectionTokenWithName,\n methodName: string,\n ) {\n this.logger.debug(\n `Tool discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,\n );\n\n // Collect security metadata from decorators\n const isPublic = Reflect.getMetadata(MCP_PUBLIC_METADATA_KEY, methodRef);\n const requiredScopes = Reflect.getMetadata(\n MCP_SCOPES_METADATA_KEY,\n methodRef,\n );\n const requiredRoles = Reflect.getMetadata(\n MCP_ROLES_METADATA_KEY,\n methodRef,\n );\n\n // Add tool with security metadata\n const baseMetadata: ToolMetadata = Reflect.getMetadata(\n MCP_TOOL_METADATA_KEY,\n methodRef,\n );\n\n if (!baseMetadata.name) {\n baseMetadata.name = methodName;\n }\n\n // Enrich with security metadata\n if (isPublic !== undefined) {\n baseMetadata.isPublic = isPublic;\n }\n if (requiredScopes) {\n baseMetadata.requiredScopes = requiredScopes;\n }\n if (requiredRoles) {\n baseMetadata.requiredRoles = requiredRoles;\n }\n\n if (!this.discoveredToolsByMcpModuleId.has(mcpModuleId)) {\n this.discoveredToolsByMcpModuleId.set(mcpModuleId, []);\n }\n\n this.discoveredToolsByMcpModuleId.get(mcpModuleId)?.push({\n type: 'tool',\n metadata: baseMetadata,\n providerClass: token,\n methodName,\n });\n }\n\n private addDiscoveryResource(\n mcpModuleId: string,\n methodRef: object,\n token: InjectionTokenWithName,\n methodName: string,\n ) {\n this.logger.debug(\n `Resource discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,\n );\n this.addDiscovery<ResourceMetadata>(\n 'resource',\n MCP_RESOURCE_METADATA_KEY,\n mcpModuleId,\n methodRef,\n token,\n methodName,\n );\n }\n\n private addDiscoveryResourceTemplate(\n mcpModuleId: string,\n methodRef: object,\n token: InjectionTokenWithName,\n methodName: string,\n ) {\n this.logger.debug(\n `Resource Template discovered: ${token.name}.${methodName} in module: ${mcpModuleId}`,\n );\n this.addDiscovery<ResourceTemplateMetadata>(\n 'resource-template',\n MCP_RESOURCE_TEMPLATE_METADATA_KEY,\n mcpModuleId,\n methodRef,\n token,\n methodName,\n );\n }\n\n /**\n * Return all discovered MCP module IDs\n */\n getMcpModuleIds(): string[] {\n return Array.from(this.discoveredToolsByMcpModuleId.keys());\n }\n\n /**\n * Get all discovered tools\n */\n getTools(mcpModuleId: string): DiscoveredTool<ToolMetadata>[] {\n return (\n this.discoveredToolsByMcpModuleId\n .get(mcpModuleId)\n ?.filter((tool) => tool.type === 'tool') ?? []\n );\n }\n\n /**\n * Find a tool by name\n */\n findTool(\n mcpModuleId: string,\n name: string,\n ): DiscoveredTool<ToolMetadata> | undefined {\n return this.getTools(mcpModuleId).find(\n (tool) => tool.metadata.name === name,\n );\n }\n\n /**\n * Get all discovered resources\n */\n getResources(mcpModuleId: string): DiscoveredTool<ResourceMetadata>[] {\n return (\n this.discoveredToolsByMcpModuleId\n .get(mcpModuleId)\n ?.filter((tool) => tool.type === 'resource') ?? []\n );\n }\n\n /**\n * Find a resource by name\n */\n findResource(\n mcpModuleId: string,\n name: string,\n ): DiscoveredTool<ResourceMetadata> | undefined {\n return this.getResources(mcpModuleId).find(\n (tool) => tool.metadata.name === name,\n );\n }\n\n /**\n * Get all discovered resource templates\n */\n getResourceTemplates(\n mcpModuleId: string,\n ): DiscoveredTool<ResourceTemplateMetadata>[] {\n return (\n this.discoveredToolsByMcpModuleId\n .get(mcpModuleId)\n ?.filter((tool) => tool.type === 'resource-template') ?? []\n );\n }\n\n /**\n * Find a resource by name\n */\n findResourceTemplate(\n mcpModuleId: string,\n name: string,\n ): DiscoveredTool<ResourceTemplateMetadata> | undefined {\n return this.getResourceTemplates(mcpModuleId).find(\n (tool) => tool.metadata.name === name,\n );\n }\n\n /**\n * Get all discovered prompts\n */\n getPrompts(mcpModuleId: string): DiscoveredTool<PromptMetadata>[] {\n return (\n this.discoveredToolsByMcpModuleId\n .get(mcpModuleId)\n ?.filter((tool) => tool.type === 'prompt') ?? []\n );\n }\n\n /**\n * Find a prompt by name\n */\n findPrompt(\n mcpModuleId: string,\n name: string,\n ): DiscoveredTool<PromptMetadata> | undefined {\n return this.getPrompts(mcpModuleId).find(\n (tool) => tool.metadata.name === name,\n );\n }\n\n private convertTemplate(template: string): string {\n return template?.replace(/{(\\w+)}/g, ':$1');\n }\n\n private convertUri(uri: string): string {\n if (uri.includes('://')) {\n return uri.split('://')[1];\n }\n\n return uri;\n }\n\n /**\n * Find a resource by uri\n * @returns An object containing the found resource and extracted parameters, or undefined if no resource is found\n */\n findResourceByUri(\n mcpModuleId: string,\n uri: string,\n ):\n | {\n resource: DiscoveredTool<ResourceMetadata>;\n params: Record<string, string>;\n }\n | undefined {\n const resources = this.getResources(mcpModuleId).map((tool) => ({\n name: tool.metadata.name,\n uri: tool.metadata.uri,\n }));\n\n const strippedInputUri = this.convertUri(uri);\n\n for (const t of resources) {\n if (!t.uri) continue;\n\n const rawTemplate = t.uri;\n const templatePath = this.convertTemplate(this.convertUri(rawTemplate));\n const matcher = match(templatePath, { decode: decodeURIComponent });\n const result = matcher(strippedInputUri);\n\n if (result) {\n const foundResource = this.findResource(mcpModuleId, t.name);\n if (!foundResource) continue;\n\n return {\n resource: foundResource,\n params: result.params as Record<string, string>,\n };\n }\n }\n\n return undefined;\n }\n\n /**\n * Find a resource template by uri\n * @returns An object containing the found resource template and extracted parameters, or undefined if no resource template is found\n */\n findResourceTemplateByUri(\n mcpModuleId: string,\n uri: string,\n ):\n | {\n resourceTemplate: DiscoveredTool<ResourceTemplateMetadata>;\n params: Record<string, string>;\n }\n | undefined {\n const resourceTemplates = this.getResourceTemplates(mcpModuleId).map(\n (tool) => ({\n name: tool.metadata.name,\n uriTemplate: tool.metadata.uriTemplate,\n }),\n );\n\n const strippedInputUri = this.convertUri(uri);\n\n for (const t of resourceTemplates) {\n if (!t.uriTemplate) continue;\n\n const rawTemplate = t.uriTemplate;\n const templatePath = this.convertTemplate(this.convertUri(rawTemplate));\n const matcher = match(templatePath, { decode: decodeURIComponent });\n const result = matcher(strippedInputUri);\n\n if (result) {\n const foundResourceTemplate = this.findResourceTemplate(\n mcpModuleId,\n t.name,\n );\n if (!foundResourceTemplate) continue;\n\n return {\n resourceTemplate: foundResourceTemplate,\n params: result.params as Record<string, string>,\n };\n }\n }\n\n return undefined;\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { DiscoveredTool } from './mcp-registry.service';
2
+ import { ToolMetadata, SecurityScheme } from '../decorators/tool.decorator';
3
+ import { JwtPayload } from '../../authz/services/jwt-token.service';
4
+ export declare class ToolAuthorizationService {
5
+ generateSecuritySchemes(tool: DiscoveredTool<ToolMetadata>, moduleHasGuards: boolean): SecurityScheme[];
6
+ canAccessTool(user: JwtPayload | undefined, tool: DiscoveredTool<ToolMetadata>, moduleHasGuards: boolean): boolean;
7
+ validateToolAccess(user: JwtPayload | undefined, tool: DiscoveredTool<ToolMetadata>, moduleHasGuards: boolean): void;
8
+ private hasRequiredScopes;
9
+ private hasRequiredRoles;
10
+ }
11
+ //# sourceMappingURL=tool-authorization.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-authorization.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/tool-authorization.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAKpE,qBACa,wBAAwB;IAQnC,uBAAuB,CACrB,IAAI,EAAE,cAAc,CAAC,YAAY,CAAC,EAClC,eAAe,EAAE,OAAO,GACvB,cAAc,EAAE;IAkCnB,aAAa,CACX,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,IAAI,EAAE,cAAc,CAAC,YAAY,CAAC,EAClC,eAAe,EAAE,OAAO,GACvB,OAAO;IA2CV,kBAAkB,CAChB,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,IAAI,EAAE,cAAc,CAAC,YAAY,CAAC,EAClC,eAAe,EAAE,OAAO,GACvB,IAAI;IAkDP,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,gBAAgB;CAwBzB"}