@rekog/mcp-nest 1.8.1-alpha.4 → 1.8.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 (51) hide show
  1. package/dist/authz/guards/jwt-auth.guard.d.ts +1 -1
  2. package/dist/authz/guards/jwt-auth.guard.d.ts.map +1 -1
  3. package/dist/authz/guards/jwt-auth.guard.js.map +1 -1
  4. package/dist/authz/mcp-oauth.controller.d.ts +1 -1
  5. package/dist/authz/mcp-oauth.controller.d.ts.map +1 -1
  6. package/dist/authz/mcp-oauth.controller.js.map +1 -1
  7. package/dist/authz/providers/oauth-provider.interface.d.ts +1 -1
  8. package/dist/authz/providers/oauth-provider.interface.d.ts.map +1 -1
  9. package/dist/authz/providers/oauth-provider.interface.js.map +1 -1
  10. package/dist/authz/services/client.service.d.ts +1 -2
  11. package/dist/authz/services/client.service.d.ts.map +1 -1
  12. package/dist/authz/services/client.service.js.map +1 -1
  13. package/dist/authz/stores/memory-store.service.d.ts +1 -2
  14. package/dist/authz/stores/memory-store.service.d.ts.map +1 -1
  15. package/dist/authz/stores/memory-store.service.js.map +1 -1
  16. package/dist/authz/stores/typeorm/typeorm-store.service.d.ts +1 -2
  17. package/dist/authz/stores/typeorm/typeorm-store.service.d.ts.map +1 -1
  18. package/dist/authz/stores/typeorm/typeorm-store.service.js.map +1 -1
  19. package/dist/mcp/mcp.module.js.map +1 -1
  20. package/dist/mcp/services/mcp-sse.service.d.ts +1 -1
  21. package/dist/mcp/services/mcp-sse.service.d.ts.map +1 -1
  22. package/dist/mcp/services/mcp-sse.service.js.map +1 -1
  23. package/dist/mcp/services/mcp-streamable-http.service.d.ts +1 -1
  24. package/dist/mcp/services/mcp-streamable-http.service.d.ts.map +1 -1
  25. package/dist/mcp/services/mcp-streamable-http.service.js.map +1 -1
  26. package/dist/mcp/transport/sse.controller.factory.d.ts +1 -1
  27. package/dist/mcp/transport/sse.controller.factory.d.ts.map +1 -1
  28. package/dist/mcp/transport/sse.controller.factory.js.map +1 -1
  29. package/dist/mcp/transport/stdio.service.d.ts +1 -1
  30. package/dist/mcp/transport/stdio.service.d.ts.map +1 -1
  31. package/dist/mcp/transport/stdio.service.js.map +1 -1
  32. package/dist/mcp/transport/streamable-http.controller.factory.d.ts +1 -1
  33. package/dist/mcp/transport/streamable-http.controller.factory.d.ts.map +1 -1
  34. package/dist/mcp/transport/streamable-http.controller.factory.js.map +1 -1
  35. package/dist/mcp/utils/capabilities-builder.d.ts +1 -1
  36. package/dist/mcp/utils/capabilities-builder.d.ts.map +1 -1
  37. package/dist/mcp/utils/capabilities-builder.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/authz/guards/jwt-auth.guard.ts +1 -1
  40. package/src/authz/mcp-oauth.controller.ts +1 -1
  41. package/src/authz/providers/oauth-provider.interface.ts +1 -1
  42. package/src/authz/services/client.service.ts +1 -1
  43. package/src/authz/stores/memory-store.service.ts +5 -2
  44. package/src/authz/stores/typeorm/typeorm-store.service.ts +5 -2
  45. package/src/mcp/mcp.module.ts +1 -1
  46. package/src/mcp/services/mcp-sse.service.ts +1 -1
  47. package/src/mcp/services/mcp-streamable-http.service.ts +1 -1
  48. package/src/mcp/transport/sse.controller.factory.ts +1 -1
  49. package/src/mcp/transport/stdio.service.ts +1 -2
  50. package/src/mcp/transport/streamable-http.controller.factory.ts +1 -1
  51. package/src/mcp/utils/capabilities-builder.ts +1 -1
@@ -1,7 +1,7 @@
1
1
  import { CanActivate, ExecutionContext } from '@nestjs/common';
2
2
  import { Request } from 'express';
3
3
  import { JwtPayload, JwtTokenService } from '../services/jwt-token.service';
4
- import type { IOAuthStore } from '../stores/oauth-store.interface';
4
+ import { IOAuthStore } from '../stores/oauth-store.interface';
5
5
  export interface AuthenticatedRequest extends Request {
6
6
  user: JwtPayload;
7
7
  }
@@ -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,EAGjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,MAAM,WAAW,oBAAqB,SAAQ,OAAO;IACnD,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,qBACa,eAAgB,YAAW,WAAW;IAE/C,OAAO,CAAC,QAAQ,CAAC,eAAe;IACT,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAD5B,eAAe,EAAE,eAAe,EACT,KAAK,EAAE,WAAW;IAGtD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IA8C9D,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,EAGjB,MAAM,gBAAgB,CAAC;AACxB,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;IAE/C,OAAO,CAAC,QAAQ,CAAC,eAAe;IACT,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAD5B,eAAe,EAAE,eAAe,EACT,KAAK,EAAE,WAAW;IAGtD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IA8C9D,OAAO,CAAC,sBAAsB;CAS/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-auth.guard.js","sourceRoot":"","sources":["../../../src/authz/guards/jwt-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAMwB;AAExB,qEAA4E;AAQrE,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B,YACmB,eAAgC,EACT,KAAkB;QADzC,oBAAe,GAAf,eAAe,CAAiB;QACT,UAAK,GAAL,KAAK,CAAa;IACzD,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAwB,CAAC;QAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,8BAAqB,CAAC,uBAAuB,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE1D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,8BAAqB,CAAC,iCAAiC,CAAC,CAAC;QACrE,CAAC;QAGD,MAAM,QAAQ,GAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,eAAe,EAAE,CAAC;gBACpD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CACjD,QAAQ,CAAC,eAAe,CACzB,CAAC;gBACF,IAAI,OAAO,EAAE,CAAC;oBACZ,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC;gBAC/B,CAAC;YACH,CAAC;YACD,MAAM,EAAE,GAAG,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC;YAEpC,QAAQ,CAAC,QAAQ;gBACf,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,IAAI,QAAQ,CAAC,GAAG,CAAC;YAC5D,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC;YAC5C,QAAQ,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,IAAI,EAAE,CAAC,WAAW,CAAC;YAC9D,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,SAAS,CAAC;YACxD,QAAQ,CAAC,IAAI;gBACX,QAAQ,CAAC,IAAI;oBACb,EAAE,CAAC,WAAW;oBACd,EAAE,CAAC,QAAQ;oBACX,EAAE,CAAC,KAAK;oBACR,QAAQ,CAAC,GAAG,CAAC;QACjB,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QAED,OAAO,CAAC,IAAI,GAAG,QAAsB,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,sBAAsB,CAAC,OAAgB;QAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5C,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,CAAC;CACF,CAAA;AA7DY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;IAIR,WAAA,IAAA,eAAM,EAAC,aAAa,CAAC,CAAA;qCADY,mCAAe;GAFxC,eAAe,CA6D3B","sourcesContent":["import {\n Injectable,\n CanActivate,\n ExecutionContext,\n UnauthorizedException,\n Inject,\n} from '@nestjs/common';\nimport { Request } from 'express';\nimport { JwtPayload, JwtTokenService } from '../services/jwt-token.service';\nimport type { IOAuthStore } from '../stores/oauth-store.interface';\n\nexport interface AuthenticatedRequest extends Request {\n user: JwtPayload;\n}\n\n@Injectable()\nexport class McpAuthJwtGuard implements CanActivate {\n constructor(\n private readonly jwtTokenService: JwtTokenService,\n @Inject('IOAuthStore') private readonly store: IOAuthStore,\n ) {}\n\n async canActivate(context: ExecutionContext): Promise<boolean> {\n const request = context.switchToHttp().getRequest<AuthenticatedRequest>();\n const token = this.extractTokenFromHeader(request);\n\n if (!token) {\n throw new UnauthorizedException('Access token required');\n }\n\n const payload = this.jwtTokenService.validateToken(token);\n\n if (!payload) {\n throw new UnauthorizedException('Invalid or expired access token');\n }\n\n // Enrich request.user with friendly fields for tools\n const enriched: any = { ...payload };\n try {\n if (!enriched.user_data && enriched.user_profile_id) {\n const profile = await this.store.getUserProfileById(\n enriched.user_profile_id,\n );\n if (profile) {\n enriched.user_data = profile;\n }\n }\n const ud = enriched.user_data || {};\n // Provide convenient top-level fields commonly used by tools\n enriched.username =\n enriched.username || ud.username || ud.id || enriched.sub;\n enriched.email = enriched.email || ud.email;\n enriched.displayName = enriched.displayName || ud.displayName;\n enriched.avatarUrl = enriched.avatarUrl || ud.avatarUrl;\n enriched.name =\n enriched.name ||\n ud.displayName ||\n ud.username ||\n ud.email ||\n enriched.sub;\n } catch {\n // Non-fatal; proceed with raw payload\n }\n\n request.user = enriched as JwtPayload;\n return true;\n }\n\n private extractTokenFromHeader(request: Request): string | undefined {\n const authHeader = request.headers.authorization;\n if (!authHeader) {\n return undefined;\n }\n\n const [type, token] = authHeader.split(' ');\n return type === 'Bearer' ? token : undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"jwt-auth.guard.js","sourceRoot":"","sources":["../../../src/authz/guards/jwt-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAMwB;AAExB,qEAA4E;AAQrE,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B,YACmB,eAAgC,EACT,KAAkB;QADzC,oBAAe,GAAf,eAAe,CAAiB;QACT,UAAK,GAAL,KAAK,CAAa;IACzD,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAwB,CAAC;QAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,8BAAqB,CAAC,uBAAuB,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE1D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,8BAAqB,CAAC,iCAAiC,CAAC,CAAC;QACrE,CAAC;QAGD,MAAM,QAAQ,GAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,eAAe,EAAE,CAAC;gBACpD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CACjD,QAAQ,CAAC,eAAe,CACzB,CAAC;gBACF,IAAI,OAAO,EAAE,CAAC;oBACZ,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC;gBAC/B,CAAC;YACH,CAAC;YACD,MAAM,EAAE,GAAG,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC;YAEpC,QAAQ,CAAC,QAAQ;gBACf,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,IAAI,QAAQ,CAAC,GAAG,CAAC;YAC5D,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC;YAC5C,QAAQ,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,IAAI,EAAE,CAAC,WAAW,CAAC;YAC9D,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,SAAS,CAAC;YACxD,QAAQ,CAAC,IAAI;gBACX,QAAQ,CAAC,IAAI;oBACb,EAAE,CAAC,WAAW;oBACd,EAAE,CAAC,QAAQ;oBACX,EAAE,CAAC,KAAK;oBACR,QAAQ,CAAC,GAAG,CAAC;QACjB,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QAED,OAAO,CAAC,IAAI,GAAG,QAAsB,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,sBAAsB,CAAC,OAAgB;QAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5C,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,CAAC;CACF,CAAA;AA7DY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;IAIR,WAAA,IAAA,eAAM,EAAC,aAAa,CAAC,CAAA;qCADY,mCAAe;GAFxC,eAAe,CA6D3B","sourcesContent":["import {\n Injectable,\n CanActivate,\n ExecutionContext,\n UnauthorizedException,\n Inject,\n} from '@nestjs/common';\nimport { Request } from 'express';\nimport { JwtPayload, JwtTokenService } from '../services/jwt-token.service';\nimport { IOAuthStore } from '../stores/oauth-store.interface';\n\nexport interface AuthenticatedRequest extends Request {\n user: JwtPayload;\n}\n\n@Injectable()\nexport class McpAuthJwtGuard implements CanActivate {\n constructor(\n private readonly jwtTokenService: JwtTokenService,\n @Inject('IOAuthStore') private readonly store: IOAuthStore,\n ) {}\n\n async canActivate(context: ExecutionContext): Promise<boolean> {\n const request = context.switchToHttp().getRequest<AuthenticatedRequest>();\n const token = this.extractTokenFromHeader(request);\n\n if (!token) {\n throw new UnauthorizedException('Access token required');\n }\n\n const payload = this.jwtTokenService.validateToken(token);\n\n if (!payload) {\n throw new UnauthorizedException('Invalid or expired access token');\n }\n\n // Enrich request.user with friendly fields for tools\n const enriched: any = { ...payload };\n try {\n if (!enriched.user_data && enriched.user_profile_id) {\n const profile = await this.store.getUserProfileById(\n enriched.user_profile_id,\n );\n if (profile) {\n enriched.user_data = profile;\n }\n }\n const ud = enriched.user_data || {};\n // Provide convenient top-level fields commonly used by tools\n enriched.username =\n enriched.username || ud.username || ud.id || enriched.sub;\n enriched.email = enriched.email || ud.email;\n enriched.displayName = enriched.displayName || ud.displayName;\n enriched.avatarUrl = enriched.avatarUrl || ud.avatarUrl;\n enriched.name =\n enriched.name ||\n ud.displayName ||\n ud.username ||\n ud.email ||\n enriched.sub;\n } catch {\n // Non-fatal; proceed with raw payload\n }\n\n request.user = enriched as JwtPayload;\n return true;\n }\n\n private extractTokenFromHeader(request: Request): string | undefined {\n const authHeader = request.headers.authorization;\n if (!authHeader) {\n return undefined;\n }\n\n const [type, token] = authHeader.split(' ');\n return type === 'Bearer' ? token : undefined;\n }\n}\n"]}
@@ -3,7 +3,7 @@ import { Request as ExpressRequest, NextFunction, Response } from 'express';
3
3
  import { OAuthEndpointConfiguration, OAuthModuleOptions, OAuthUserProfile } from './providers/oauth-provider.interface';
4
4
  import { ClientService } from './services/client.service';
5
5
  import { JwtTokenService, TokenPair } from './services/jwt-token.service';
6
- import type { IOAuthStore } from './stores/oauth-store.interface';
6
+ import { IOAuthStore } from './stores/oauth-store.interface';
7
7
  interface OAuthCallbackRequest extends ExpressRequest {
8
8
  user?: {
9
9
  profile: OAuthUserProfile;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-oauth.controller.d.ts","sourceRoot":"","sources":["../../src/authz/mcp-oauth.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,MAAM,EAMP,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG5E,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EAElB,gBAAgB,EACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAElE,UAAU,oBAAqB,SAAQ,cAAc;IACnD,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,gBAAgB,CAAC;QAC1B,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAGD,UAAU,kBAAmB,SAAQ,cAAc;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,wBAAwB,CACtC,SAAS,GAAE,0BAA+B,EAC1C,OAAO,CAAC,EAAE;IACR,yCAAyC,CAAC,EAAE,OAAO,CAAC;IACpD,2CAA2C,CAAC,EAAE,OAAO,CAAC;CACvD;kBAgC4C,kBAAkB,SACpB,WAAW,mBACxB,eAAe,iBACjB,aAAa;;4BARnB,MAAM;+BACH,OAAO;0BACZ,kBAAkB;wBAIK,WAAW;kCACxB,eAAe;gCACjB,aAAa;+BAWhB,GAAG,QAAQ,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;4BA+CtD,kBAAkB,OAAO,QAAQ,QAAQ,YAAY;;;;;;;;;;;;;;;;;;;;;wCAoI3B,GAAG;yBAM/B,GAAG,OAEd,GAAG,OACI,QAAQ,QACN,YAAY;oCA2Ed,oBAAoB,OACpB,QAAQ,QACN,YAAY;0CA2BrB,oBAAoB,OACpB,QAAQ;4BAmFC,GAAG,OACL,kBAAkB,OACG,QAAQ,GACxC,OAAO,CAAC,SAAS,CAAC;yCA6CP,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,OAC1B,kBAAkB,GACtB,OAAO,CAAC,SAAS,CAAC;sCA4Dd,kBAAkB,QACjB,GAAG,GACR;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE;6CA+BtC,GAAG,qBACQ;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,GAC/D,IAAI;2CAqCC,MAAM,iBACG,MAAM,iBACN,MAAM,qBACF;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,GAC/D,OAAO,CAAC,SAAS,CAAC;+CA4FJ,MAAM,qBACF;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,GAC/D,OAAO,CAAC,SAAS,CAAC;oCA6EJ,MAAM,kBACL,MAAM,UACd,MAAM,GACb,OAAO;;EAcb"}
1
+ {"version":3,"file":"mcp-oauth.controller.d.ts","sourceRoot":"","sources":["../../src/authz/mcp-oauth.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,MAAM,EAMP,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG5E,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EAElB,gBAAgB,EACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE1E,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAE7D,UAAU,oBAAqB,SAAQ,cAAc;IACnD,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,gBAAgB,CAAC;QAC1B,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAGD,UAAU,kBAAmB,SAAQ,cAAc;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,wBAAwB,CACtC,SAAS,GAAE,0BAA+B,EAC1C,OAAO,CAAC,EAAE;IACR,yCAAyC,CAAC,EAAE,OAAO,CAAC;IACpD,2CAA2C,CAAC,EAAE,OAAO,CAAC;CACvD;kBAgC4C,kBAAkB,SACpB,WAAW,mBACxB,eAAe,iBACjB,aAAa;;4BARnB,MAAM;+BACH,OAAO;0BACZ,kBAAkB;wBAIK,WAAW;kCACxB,eAAe;gCACjB,aAAa;+BAWhB,GAAG,QAAQ,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;4BA+CtD,kBAAkB,OAAO,QAAQ,QAAQ,YAAY;;;;;;;;;;;;;;;;;;;;;wCAoI3B,GAAG;yBAM/B,GAAG,OAEd,GAAG,OACI,QAAQ,QACN,YAAY;oCA2Ed,oBAAoB,OACpB,QAAQ,QACN,YAAY;0CA2BrB,oBAAoB,OACpB,QAAQ;4BAmFC,GAAG,OACL,kBAAkB,OACG,QAAQ,GACxC,OAAO,CAAC,SAAS,CAAC;yCA6CP,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,OAC1B,kBAAkB,GACtB,OAAO,CAAC,SAAS,CAAC;sCA4Dd,kBAAkB,QACjB,GAAG,GACR;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE;6CA+BtC,GAAG,qBACQ;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,GAC/D,IAAI;2CAqCC,MAAM,iBACG,MAAM,iBACN,MAAM,qBACF;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,GAC/D,OAAO,CAAC,SAAS,CAAC;+CA4FJ,MAAM,qBACF;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,aAAa,CAAC,EAAE,MAAM,CAAA;SAAE,GAC/D,OAAO,CAAC,SAAS,CAAC;oCA6EJ,MAAM,kBACL,MAAM,UACd,MAAM,GACb,OAAO;;EAcb"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-oauth.controller.js","sourceRoot":"","sources":["../../src/authz/mcp-oauth.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BadRequestException,\n Body,\n Controller,\n Get,\n Header,\n HttpCode,\n Inject,\n Logger,\n Next,\n Post,\n Query,\n Req,\n Res,\n} from '@nestjs/common';\nimport { createHash, randomBytes } from 'crypto';\nimport { Request as ExpressRequest, NextFunction, Response } from 'express';\nimport passport from 'passport';\nimport { normalizeEndpoint } from '../mcp/utils/normalize-endpoint';\nimport {\n OAuthEndpointConfiguration,\n OAuthModuleOptions,\n OAuthSession,\n OAuthUserProfile,\n} from './providers/oauth-provider.interface';\nimport { ClientService } from './services/client.service';\nimport { JwtTokenService, TokenPair } from './services/jwt-token.service';\nimport { STRATEGY_NAME } from './services/oauth-strategy.service';\nimport type { IOAuthStore } from './stores/oauth-store.interface';\n\ninterface OAuthCallbackRequest extends ExpressRequest {\n user?: {\n profile: OAuthUserProfile;\n accessToken: string;\n provider: string;\n };\n}\n\n// Add this interface to properly type the Express request with raw body\ninterface RequestWithRawBody extends ExpressRequest {\n rawBody?: Buffer;\n textBody?: string;\n}\n\nexport function createMcpOAuthController(\n endpoints: OAuthEndpointConfiguration = {},\n options?: {\n disableWellKnownProtectedResourceMetadata?: boolean;\n disableWellKnownAuthorizationServerMetadata?: boolean;\n },\n) {\n // Optional decorator helpers\n const OptionalGet = (\n path: string | string[] | undefined,\n enabled: boolean,\n ): MethodDecorator => {\n return enabled && path\n ? (Get as unknown as (p?: any) => MethodDecorator)(path)\n : ((() => {}) as unknown as MethodDecorator);\n };\n const OptionalHeader = (\n name: string,\n value: string,\n enabled: boolean,\n ): MethodDecorator => {\n return enabled\n ? (Header as unknown as (n: string, v: string) => MethodDecorator)(\n name,\n value,\n )\n : ((() => {}) as unknown as MethodDecorator);\n };\n\n @Controller()\n class McpOAuthController {\n readonly logger = new Logger(McpOAuthController.name);\n readonly serverUrl: string;\n readonly isProduction: boolean;\n readonly options: OAuthModuleOptions;\n\n constructor(\n @Inject('OAUTH_MODULE_OPTIONS') options: OAuthModuleOptions,\n @Inject('IOAuthStore') readonly store: IOAuthStore,\n readonly jwtTokenService: JwtTokenService,\n readonly clientService: ClientService,\n ) {\n this.serverUrl = options.serverUrl;\n this.isProduction = options.cookieSecure;\n this.options = options;\n }\n\n /**\n * Utility function to parse form-encoded or JSON bodies\n * Handles both string (raw form data) and object bodies\n */\n parseRequestBody(body: any, req?: RequestWithRawBody): Record<string, any> {\n // If body is already a parsed object with properties, return it\n if (body && typeof body === 'object' && Object.keys(body).length > 0) {\n return body;\n }\n\n // If body is a string (raw form data), parse it\n if (typeof body === 'string' && body.length > 0) {\n const params = new URLSearchParams(body);\n const parsedBody: Record<string, any> = {};\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n return parsedBody;\n }\n\n // Check if we have a text body stored on the request (from our middleware)\n if (req?.textBody) {\n const params = new URLSearchParams(req.textBody);\n const parsedBody: Record<string, any> = {};\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n return parsedBody;\n }\n\n // Check if we have a raw body buffer stored on the request\n if (req?.rawBody) {\n const bodyString = req.rawBody.toString('utf-8');\n if (bodyString) {\n const params = new URLSearchParams(bodyString);\n const parsedBody: Record<string, any> = {};\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n return parsedBody;\n }\n }\n\n // Return empty object if no valid body\n return {};\n }\n\n /**\n * Middleware to capture raw body for form-encoded requests\n * This is needed when bodyParser is disabled in the main app\n */\n captureRawBody(req: RequestWithRawBody, res: Response, next: NextFunction) {\n if (\n req.headers['content-type']?.includes(\n 'application/x-www-form-urlencoded',\n )\n ) {\n let rawBody = '';\n\n req.on('data', (chunk: Buffer) => {\n rawBody += chunk.toString('utf-8');\n });\n\n req.on('end', () => {\n req.textBody = rawBody;\n // Also parse and set it as body for NestJS\n if (rawBody) {\n const params = new URLSearchParams(rawBody);\n const parsedBody: any = {};\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n (req as any).body = parsedBody;\n }\n next();\n });\n\n req.on('error', (err) => {\n this.logger.error('Error reading request body:', err);\n next(err);\n });\n } else {\n next();\n }\n }\n\n @OptionalGet(\n endpoints.wellKnownProtectedResourceMetadata,\n !options?.disableWellKnownProtectedResourceMetadata,\n )\n @OptionalHeader(\n 'content-type',\n 'application/json',\n !options?.disableWellKnownProtectedResourceMetadata,\n )\n getProtectedResourceMetadata() {\n // The issuer URL of your authorization server.\n const authorizationServerIssuer = this.options.jwtIssuer;\n\n // The canonical URI of the MCP server resource itself.\n const resourceIdentifier = this.options.resource;\n\n const metadata = {\n /**\n * REQUIRED by MCP Spec.\n * A list of authorization server issuer URLs that can issue tokens for this resource.\n */\n authorization_servers: [authorizationServerIssuer],\n\n /**\n * RECOMMENDED by RFC 9728.\n * The identifier for this resource server.\n */\n resource: resourceIdentifier,\n\n /**\n * RECOMMENDED by RFC 9728.\n * A list of scopes that this resource server understands.\n */\n scopes_supported:\n this.options.protectedResourceMetadata.scopesSupported,\n\n /**\n * RECOMMENDED by RFC 9728.\n * A list of methods clients can use to present the access token.\n */\n bearer_methods_supported:\n this.options.protectedResourceMetadata.bearerMethodsSupported,\n\n /**\n * OPTIONAL but helpful custom metadata.\n * Declares which version of the MCP spec this server supports.\n */\n mcp_versions_supported:\n this.options.protectedResourceMetadata.mcpVersionsSupported,\n };\n\n return metadata;\n }\n\n // OAuth endpoints\n @OptionalGet(\n endpoints.wellKnownAuthorizationServerMetadata,\n !options?.disableWellKnownAuthorizationServerMetadata,\n )\n @OptionalHeader(\n 'content-type',\n 'application/json',\n !options?.disableWellKnownAuthorizationServerMetadata,\n )\n getAuthorizationServerMetadata() {\n return {\n issuer: this.serverUrl,\n authorization_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.authorize}`,\n ),\n token_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.token}`,\n ),\n registration_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.register}`,\n ),\n response_types_supported:\n this.options.authorizationServerMetadata.responseTypesSupported,\n response_modes_supported:\n this.options.authorizationServerMetadata.responseModesSupported,\n grant_types_supported:\n this.options.authorizationServerMetadata.grantTypesSupported,\n token_endpoint_auth_methods_supported:\n this.options.authorizationServerMetadata\n .tokenEndpointAuthMethodsSupported,\n scopes_supported:\n this.options.authorizationServerMetadata.scopesSupported,\n revocation_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints?.revoke}`,\n ),\n code_challenge_methods_supported:\n this.options.authorizationServerMetadata\n .codeChallengeMethodsSupported,\n };\n }\n\n @Post(endpoints.register)\n async registerClient(@Body() registrationDto: any) {\n return await this.clientService.registerClient(registrationDto);\n }\n\n @Get(endpoints.authorize)\n async authorize(\n @Query() query: any,\n @Req()\n req: any,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n const {\n response_type,\n client_id,\n redirect_uri,\n code_challenge,\n code_challenge_method,\n state,\n scope,\n } = query;\n const resource = this.options.resource;\n if (response_type !== 'code') {\n throw new BadRequestException('Only response_type=code is supported');\n }\n\n if (!client_id) {\n throw new BadRequestException('Missing required parameters');\n }\n\n // Validate client and redirect URI\n const client = await this.clientService.getClient(client_id);\n if (!client) {\n throw new BadRequestException('Invalid client_id');\n }\n\n const validRedirect = await this.clientService.validateRedirectUri(\n client_id,\n redirect_uri,\n );\n if (!validRedirect) {\n throw new BadRequestException('Invalid redirect_uri');\n }\n\n // Create OAuth session\n const sessionId = randomBytes(32).toString('base64url');\n const sessionState = randomBytes(32).toString('base64url');\n\n const oauthSession: OAuthSession = {\n sessionId,\n state: sessionState,\n clientId: client_id,\n redirectUri: redirect_uri,\n codeChallenge: code_challenge,\n codeChallengeMethod: code_challenge_method || 'plain',\n oauthState: state,\n scope: scope,\n resource,\n expiresAt: Date.now() + this.options.oauthSessionExpiresIn,\n };\n\n await this.store.storeOAuthSession(sessionId, oauthSession);\n\n // Set session cookie\n res.cookie('oauth_session', sessionId, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.oauthSessionExpiresIn,\n });\n\n // Store state for passport\n res.cookie('oauth_state', sessionState, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.oauthSessionExpiresIn,\n });\n\n // Redirect to the provider's auth endpoint\n passport.authenticate(STRATEGY_NAME, {\n state: req.cookies?.oauth_state,\n })(req, res, next);\n }\n\n @Get(endpoints.callback)\n handleProviderCallback(\n @Req() req: OAuthCallbackRequest,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n // Use a custom callback to handle the authentication result\n passport.authenticate(\n STRATEGY_NAME,\n { session: false },\n async (err: any, user: any) => {\n try {\n if (err) {\n this.logger.error('OAuth callback error:', err);\n throw new BadRequestException('Authentication failed');\n }\n\n if (!user) {\n throw new BadRequestException('Authentication failed');\n }\n\n req.user = user;\n await this.processAuthenticationSuccess(req, res);\n } catch (error) {\n next(error);\n }\n },\n )(req, res, next);\n }\n\n async processAuthenticationSuccess(\n req: OAuthCallbackRequest,\n res: Response,\n ) {\n const user = req.user;\n if (!user) {\n throw new BadRequestException('Authentication failed');\n }\n\n const sessionId = req.cookies?.oauth_session;\n if (!sessionId) {\n throw new BadRequestException('Missing OAuth session');\n }\n\n const session = await this.store.getOAuthSession(sessionId);\n if (!session) {\n throw new BadRequestException('Invalid or expired OAuth session');\n }\n\n // Verify state\n const stateFromCookie = req.cookies?.oauth_state;\n if (session.state !== stateFromCookie) {\n throw new BadRequestException('Invalid state parameter');\n }\n\n // Generate JWT for UI access\n const jwt = this.jwtTokenService.generateUserToken(\n user.profile.username,\n user.profile,\n );\n\n // Set JWT token as cookie for UI endpoints\n res.cookie('auth_token', jwt, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.cookieMaxAge,\n });\n\n // Clear temporary cookies\n res.clearCookie('oauth_session');\n res.clearCookie('oauth_state');\n\n // Persist user profile and get stable profile_id\n const user_profile_id = await this.store.upsertUserProfile(\n user.profile,\n user.provider,\n );\n\n // Generate authorization code\n const authCode = randomBytes(32).toString('base64url');\n\n // Store the auth code\n await this.store.storeAuthCode({\n code: authCode,\n user_id: user.profile.username,\n client_id: session.clientId!,\n redirect_uri: session.redirectUri!,\n code_challenge: session.codeChallenge!,\n code_challenge_method: session.codeChallengeMethod!,\n expires_at: Date.now() + this.options.authCodeExpiresIn,\n resource: session.resource,\n scope: session.scope,\n github_access_token: '', // No longer provider-specific\n user_profile_id,\n });\n\n // Build redirect URL with authorization code\n const redirectUrl = new URL(session.redirectUri!);\n redirectUrl.searchParams.set('code', authCode);\n if (session.oauthState) {\n redirectUrl.searchParams.set('state', session.oauthState);\n }\n\n // Clean up session\n await this.store.removeOAuthSession(sessionId);\n\n res.redirect(redirectUrl.toString());\n }\n\n @Post(endpoints.token)\n @Header('content-type', 'application/json')\n @Header('Cache-Control', 'no-store')\n @Header('Pragma', 'no-cache')\n @HttpCode(200)\n async exchangeToken(\n @Body() body: any,\n @Req() req: RequestWithRawBody,\n @Res({ passthrough: true }) res: Response,\n ): Promise<TokenPair> {\n // Apply middleware to capture raw body if needed\n const isFormUrlEncoded = req.headers['content-type']?.includes(\n 'application/x-www-form-urlencoded',\n );\n const isBodyEmpty =\n !body ||\n (typeof body === 'object' &&\n Object.keys(body as Record<string, unknown>).length === 0);\n\n if (isFormUrlEncoded && isBodyEmpty) {\n return new Promise((resolve, reject) => {\n this.captureRawBody(req, res, (err?: any) => {\n if (err) {\n reject(\n err instanceof Error ? err : new Error(String(err ?? 'error')),\n );\n return;\n }\n\n // Avoid returning a Promise from the callback; use an IIFE\n void (async () => {\n try {\n // Re-parse the body after middleware has captured it\n const parsedBody = this.parseRequestBody(req.body || body, req);\n const result = await this.processTokenExchange(parsedBody, req);\n resolve(result);\n } catch (error) {\n reject(\n error instanceof Error\n ? error\n : new Error(String(error ?? 'error')),\n );\n }\n })();\n });\n });\n }\n\n // Body is already parsed, process directly\n const parsedBody = this.parseRequestBody(body, req);\n return this.processTokenExchange(parsedBody, req);\n }\n\n async processTokenExchange(\n parsedBody: Record<string, any>,\n req: RequestWithRawBody,\n ): Promise<TokenPair> {\n const { grant_type, code, code_verifier, redirect_uri, refresh_token } =\n parsedBody;\n\n // Add debugging to help identify issues\n if (!grant_type) {\n this.logger.error('Missing grant_type in request body:', {\n parsedBodyKeys: Object.keys(parsedBody),\n contentType: req.headers['content-type'],\n textBody: req.textBody,\n parsedBody,\n });\n throw new BadRequestException('Missing grant_type parameter');\n }\n\n switch (grant_type) {\n case 'authorization_code': {\n // Extract client credentials based on authentication method\n const clientCredentials = this.extractClientCredentials(\n req,\n parsedBody,\n );\n return await this.handleAuthorizationCodeGrant(\n typeof code === 'string' ? code : String(code ?? ''),\n typeof code_verifier === 'string'\n ? code_verifier\n : String(code_verifier ?? ''),\n typeof redirect_uri === 'string'\n ? redirect_uri\n : String(redirect_uri ?? ''),\n clientCredentials,\n );\n }\n case 'refresh_token': {\n // For refresh tokens, try to extract client credentials, but allow fallback to token-based extraction\n let clientCredentials: { client_id: string; client_secret?: string };\n try {\n clientCredentials = this.extractClientCredentials(req, parsedBody);\n } catch {\n // If we can't extract credentials, we'll try to get them from the refresh token\n clientCredentials = { client_id: '' }; // Will be filled from token\n }\n return await this.handleRefreshTokenGrant(\n typeof refresh_token === 'string'\n ? refresh_token\n : String(refresh_token ?? ''),\n clientCredentials,\n );\n }\n default:\n throw new BadRequestException(\n `Unsupported grant_type: ${grant_type}`,\n );\n }\n }\n\n /**\n * Extract client credentials from request based on authentication method\n */\n extractClientCredentials(\n req: RequestWithRawBody,\n body: any,\n ): { client_id: string; client_secret?: string } {\n // Parse the body using the shared utility function\n const parsedBody = this.parseRequestBody(body, req);\n\n // Try client_secret_basic first (Authorization header)\n const authHeader = req.headers?.authorization;\n if (authHeader && authHeader.startsWith('Basic ')) {\n const credentials = Buffer.from(authHeader.slice(6), 'base64').toString(\n 'utf-8',\n );\n const [client_id, client_secret] = credentials.split(':', 2);\n if (client_id) {\n return { client_id, client_secret };\n }\n }\n\n // Try client_secret_post (body parameters)\n if (parsedBody.client_id) {\n return {\n client_id: parsedBody.client_id,\n client_secret: parsedBody.client_secret,\n };\n }\n\n throw new BadRequestException('Missing client credentials');\n }\n\n /**\n * Validate client authentication based on the client's configured method\n */\n validateClientAuthentication(\n client: any,\n clientCredentials: { client_id: string; client_secret?: string },\n ): void {\n if (!client) {\n throw new BadRequestException('Invalid client_id');\n }\n\n const { token_endpoint_auth_method } = client;\n\n switch (token_endpoint_auth_method) {\n case 'client_secret_basic':\n case 'client_secret_post':\n if (!clientCredentials.client_secret) {\n throw new BadRequestException(\n 'Client secret required for this authentication method',\n );\n }\n if (client.client_secret !== clientCredentials.client_secret) {\n throw new BadRequestException('Invalid client credentials');\n }\n break;\n\n case 'none':\n // Public client - no secret required\n if (clientCredentials.client_secret) {\n throw new BadRequestException(\n 'Client secret not allowed for public clients',\n );\n }\n break;\n\n default:\n throw new BadRequestException(\n `Unsupported authentication method: ${token_endpoint_auth_method}`,\n );\n }\n }\n\n async handleAuthorizationCodeGrant(\n code: string,\n code_verifier: string,\n _redirect_uri: string,\n clientCredentials: { client_id: string; client_secret?: string },\n ): Promise<TokenPair> {\n this.logger.debug('handleAuthorizationCodeGrant - Params:', {\n code,\n client_id: clientCredentials.client_id,\n });\n\n // Get and validate the authorization code\n const authCode = await this.store.getAuthCode(code);\n if (!authCode) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Invalid authorization code:',\n code,\n );\n throw new BadRequestException('Invalid authorization code');\n }\n if (authCode.expires_at < Date.now()) {\n await this.store.removeAuthCode(code);\n this.logger.error(\n 'handleAuthorizationCodeGrant - Authorization code expired:',\n code,\n );\n throw new BadRequestException('Authorization code has expired');\n }\n if (authCode.client_id !== clientCredentials.client_id) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Client ID mismatch:',\n { expected: authCode.client_id, got: clientCredentials.client_id },\n );\n throw new BadRequestException('Client ID mismatch');\n }\n\n // Get client and validate authentication\n const client = await this.clientService.getClient(\n clientCredentials.client_id,\n );\n this.validateClientAuthentication(client, clientCredentials);\n if (authCode.code_challenge) {\n const isValid = this.validatePKCE(\n code_verifier,\n authCode.code_challenge,\n authCode.code_challenge_method,\n );\n if (!isValid) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Invalid PKCE verification',\n );\n throw new BadRequestException('Invalid PKCE verification');\n }\n }\n if (!authCode.resource) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - No resource associated with code',\n );\n throw new BadRequestException(\n 'Authorization code is not associated with a resource',\n );\n }\n\n let userData: Record<string, unknown> | undefined = undefined;\n if (authCode.user_profile_id) {\n try {\n const profile = await this.store.getUserProfileById(\n authCode.user_profile_id,\n );\n if (profile) {\n // Avoid circular/large raw payloads if present\n userData = { ...profile };\n }\n } catch (e) {\n this.logger.warn('Failed to load user profile for token payload', e);\n }\n }\n\n const tokens = this.jwtTokenService.generateTokenPair(\n authCode.user_id,\n clientCredentials.client_id,\n authCode.scope,\n authCode.resource,\n {\n user_profile_id: authCode.user_profile_id,\n user_data: userData,\n },\n );\n await this.store.removeAuthCode(code);\n this.logger.debug(\n 'handleAuthorizationCodeGrant - Token pair generated for user:',\n authCode.user_id,\n );\n return tokens;\n }\n\n async handleRefreshTokenGrant(\n refresh_token: string,\n clientCredentials: { client_id: string; client_secret?: string },\n ): Promise<TokenPair> {\n // Verify the refresh token first to get client_id from token if not provided\n const payload = this.jwtTokenService.validateToken(refresh_token);\n if (!payload || payload.type !== 'refresh') {\n throw new BadRequestException('Invalid or expired refresh token');\n }\n\n // Use client_id from token if not provided in credentials\n const clientId = clientCredentials.client_id || payload.client_id;\n if (!clientId) {\n throw new BadRequestException('Unable to determine client_id');\n }\n\n // Get client and validate authentication\n const client = await this.clientService.getClient(clientId);\n\n // For refresh token grants, we can be more lenient with client authentication\n // if the token already contains the client_id and the client is public\n if (client?.token_endpoint_auth_method !== 'none') {\n this.validateClientAuthentication(client, {\n ...clientCredentials,\n client_id: clientId,\n });\n }\n\n // Verify the refresh token belongs to the client\n if (payload.client_id !== clientId) {\n throw new BadRequestException(\n 'Invalid refresh token or token does not belong to this client',\n );\n }\n\n let newTokens: TokenPair | null = null;\n try {\n const payload = this.jwtTokenService.validateToken(refresh_token);\n if (!payload || payload.type !== 'refresh') {\n throw new BadRequestException('Invalid or expired refresh token');\n }\n\n let userData: Record<string, unknown> | undefined = undefined;\n if (payload.user_profile_id) {\n try {\n const profile = await this.store.getUserProfileById(\n payload.user_profile_id,\n );\n if (profile) userData = { ...profile };\n } catch (e) {\n this.logger.warn(\n 'Failed to load user profile for refreshed token payload',\n e,\n );\n }\n }\n\n newTokens = this.jwtTokenService.generateTokenPair(\n payload.sub,\n clientId,\n payload.scope,\n payload.resource,\n {\n user_profile_id: payload.user_profile_id,\n user_data: userData,\n },\n );\n } catch (e) {\n this.logger.warn(\n 'Refresh flow failed using enriched path, fallback',\n e,\n );\n newTokens = this.jwtTokenService.refreshAccessToken(refresh_token);\n }\n\n if (!newTokens) throw new BadRequestException('Failed to refresh token');\n return newTokens;\n }\n\n validatePKCE(\n code_verifier: string,\n code_challenge: string,\n method: string,\n ): boolean {\n if (method === 'plain') {\n return code_verifier === code_challenge;\n } else if (method === 'S256') {\n const hash = createHash('sha256')\n .update(code_verifier)\n .digest('base64url');\n return hash === code_challenge;\n }\n return false;\n }\n }\n\n return McpOAuthController;\n}\n"]}
1
+ {"version":3,"file":"mcp-oauth.controller.js","sourceRoot":"","sources":["../../src/authz/mcp-oauth.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BadRequestException,\n Body,\n Controller,\n Get,\n Header,\n HttpCode,\n Inject,\n Logger,\n Next,\n Post,\n Query,\n Req,\n Res,\n} from '@nestjs/common';\nimport { createHash, randomBytes } from 'crypto';\nimport { Request as ExpressRequest, NextFunction, Response } from 'express';\nimport passport from 'passport';\nimport { normalizeEndpoint } from '../mcp/utils/normalize-endpoint';\nimport {\n OAuthEndpointConfiguration,\n OAuthModuleOptions,\n OAuthSession,\n OAuthUserProfile,\n} from './providers/oauth-provider.interface';\nimport { ClientService } from './services/client.service';\nimport { JwtTokenService, TokenPair } from './services/jwt-token.service';\nimport { STRATEGY_NAME } from './services/oauth-strategy.service';\nimport { IOAuthStore } from './stores/oauth-store.interface';\n\ninterface OAuthCallbackRequest extends ExpressRequest {\n user?: {\n profile: OAuthUserProfile;\n accessToken: string;\n provider: string;\n };\n}\n\n// Add this interface to properly type the Express request with raw body\ninterface RequestWithRawBody extends ExpressRequest {\n rawBody?: Buffer;\n textBody?: string;\n}\n\nexport function createMcpOAuthController(\n endpoints: OAuthEndpointConfiguration = {},\n options?: {\n disableWellKnownProtectedResourceMetadata?: boolean;\n disableWellKnownAuthorizationServerMetadata?: boolean;\n },\n) {\n // Optional decorator helpers\n const OptionalGet = (\n path: string | string[] | undefined,\n enabled: boolean,\n ): MethodDecorator => {\n return enabled && path\n ? (Get as unknown as (p?: any) => MethodDecorator)(path)\n : ((() => {}) as unknown as MethodDecorator);\n };\n const OptionalHeader = (\n name: string,\n value: string,\n enabled: boolean,\n ): MethodDecorator => {\n return enabled\n ? (Header as unknown as (n: string, v: string) => MethodDecorator)(\n name,\n value,\n )\n : ((() => {}) as unknown as MethodDecorator);\n };\n\n @Controller()\n class McpOAuthController {\n readonly logger = new Logger(McpOAuthController.name);\n readonly serverUrl: string;\n readonly isProduction: boolean;\n readonly options: OAuthModuleOptions;\n\n constructor(\n @Inject('OAUTH_MODULE_OPTIONS') options: OAuthModuleOptions,\n @Inject('IOAuthStore') readonly store: IOAuthStore,\n readonly jwtTokenService: JwtTokenService,\n readonly clientService: ClientService,\n ) {\n this.serverUrl = options.serverUrl;\n this.isProduction = options.cookieSecure;\n this.options = options;\n }\n\n /**\n * Utility function to parse form-encoded or JSON bodies\n * Handles both string (raw form data) and object bodies\n */\n parseRequestBody(body: any, req?: RequestWithRawBody): Record<string, any> {\n // If body is already a parsed object with properties, return it\n if (body && typeof body === 'object' && Object.keys(body).length > 0) {\n return body;\n }\n\n // If body is a string (raw form data), parse it\n if (typeof body === 'string' && body.length > 0) {\n const params = new URLSearchParams(body);\n const parsedBody: Record<string, any> = {};\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n return parsedBody;\n }\n\n // Check if we have a text body stored on the request (from our middleware)\n if (req?.textBody) {\n const params = new URLSearchParams(req.textBody);\n const parsedBody: Record<string, any> = {};\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n return parsedBody;\n }\n\n // Check if we have a raw body buffer stored on the request\n if (req?.rawBody) {\n const bodyString = req.rawBody.toString('utf-8');\n if (bodyString) {\n const params = new URLSearchParams(bodyString);\n const parsedBody: Record<string, any> = {};\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n return parsedBody;\n }\n }\n\n // Return empty object if no valid body\n return {};\n }\n\n /**\n * Middleware to capture raw body for form-encoded requests\n * This is needed when bodyParser is disabled in the main app\n */\n captureRawBody(req: RequestWithRawBody, res: Response, next: NextFunction) {\n if (\n req.headers['content-type']?.includes(\n 'application/x-www-form-urlencoded',\n )\n ) {\n let rawBody = '';\n\n req.on('data', (chunk: Buffer) => {\n rawBody += chunk.toString('utf-8');\n });\n\n req.on('end', () => {\n req.textBody = rawBody;\n // Also parse and set it as body for NestJS\n if (rawBody) {\n const params = new URLSearchParams(rawBody);\n const parsedBody: any = {};\n for (const [key, value] of params.entries()) {\n parsedBody[key] = value;\n }\n (req as any).body = parsedBody;\n }\n next();\n });\n\n req.on('error', (err) => {\n this.logger.error('Error reading request body:', err);\n next(err);\n });\n } else {\n next();\n }\n }\n\n @OptionalGet(\n endpoints.wellKnownProtectedResourceMetadata,\n !options?.disableWellKnownProtectedResourceMetadata,\n )\n @OptionalHeader(\n 'content-type',\n 'application/json',\n !options?.disableWellKnownProtectedResourceMetadata,\n )\n getProtectedResourceMetadata() {\n // The issuer URL of your authorization server.\n const authorizationServerIssuer = this.options.jwtIssuer;\n\n // The canonical URI of the MCP server resource itself.\n const resourceIdentifier = this.options.resource;\n\n const metadata = {\n /**\n * REQUIRED by MCP Spec.\n * A list of authorization server issuer URLs that can issue tokens for this resource.\n */\n authorization_servers: [authorizationServerIssuer],\n\n /**\n * RECOMMENDED by RFC 9728.\n * The identifier for this resource server.\n */\n resource: resourceIdentifier,\n\n /**\n * RECOMMENDED by RFC 9728.\n * A list of scopes that this resource server understands.\n */\n scopes_supported:\n this.options.protectedResourceMetadata.scopesSupported,\n\n /**\n * RECOMMENDED by RFC 9728.\n * A list of methods clients can use to present the access token.\n */\n bearer_methods_supported:\n this.options.protectedResourceMetadata.bearerMethodsSupported,\n\n /**\n * OPTIONAL but helpful custom metadata.\n * Declares which version of the MCP spec this server supports.\n */\n mcp_versions_supported:\n this.options.protectedResourceMetadata.mcpVersionsSupported,\n };\n\n return metadata;\n }\n\n // OAuth endpoints\n @OptionalGet(\n endpoints.wellKnownAuthorizationServerMetadata,\n !options?.disableWellKnownAuthorizationServerMetadata,\n )\n @OptionalHeader(\n 'content-type',\n 'application/json',\n !options?.disableWellKnownAuthorizationServerMetadata,\n )\n getAuthorizationServerMetadata() {\n return {\n issuer: this.serverUrl,\n authorization_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.authorize}`,\n ),\n token_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.token}`,\n ),\n registration_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.register}`,\n ),\n response_types_supported:\n this.options.authorizationServerMetadata.responseTypesSupported,\n response_modes_supported:\n this.options.authorizationServerMetadata.responseModesSupported,\n grant_types_supported:\n this.options.authorizationServerMetadata.grantTypesSupported,\n token_endpoint_auth_methods_supported:\n this.options.authorizationServerMetadata\n .tokenEndpointAuthMethodsSupported,\n scopes_supported:\n this.options.authorizationServerMetadata.scopesSupported,\n revocation_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints?.revoke}`,\n ),\n code_challenge_methods_supported:\n this.options.authorizationServerMetadata\n .codeChallengeMethodsSupported,\n };\n }\n\n @Post(endpoints.register)\n async registerClient(@Body() registrationDto: any) {\n return await this.clientService.registerClient(registrationDto);\n }\n\n @Get(endpoints.authorize)\n async authorize(\n @Query() query: any,\n @Req()\n req: any,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n const {\n response_type,\n client_id,\n redirect_uri,\n code_challenge,\n code_challenge_method,\n state,\n scope,\n } = query;\n const resource = this.options.resource;\n if (response_type !== 'code') {\n throw new BadRequestException('Only response_type=code is supported');\n }\n\n if (!client_id) {\n throw new BadRequestException('Missing required parameters');\n }\n\n // Validate client and redirect URI\n const client = await this.clientService.getClient(client_id);\n if (!client) {\n throw new BadRequestException('Invalid client_id');\n }\n\n const validRedirect = await this.clientService.validateRedirectUri(\n client_id,\n redirect_uri,\n );\n if (!validRedirect) {\n throw new BadRequestException('Invalid redirect_uri');\n }\n\n // Create OAuth session\n const sessionId = randomBytes(32).toString('base64url');\n const sessionState = randomBytes(32).toString('base64url');\n\n const oauthSession: OAuthSession = {\n sessionId,\n state: sessionState,\n clientId: client_id,\n redirectUri: redirect_uri,\n codeChallenge: code_challenge,\n codeChallengeMethod: code_challenge_method || 'plain',\n oauthState: state,\n scope: scope,\n resource,\n expiresAt: Date.now() + this.options.oauthSessionExpiresIn,\n };\n\n await this.store.storeOAuthSession(sessionId, oauthSession);\n\n // Set session cookie\n res.cookie('oauth_session', sessionId, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.oauthSessionExpiresIn,\n });\n\n // Store state for passport\n res.cookie('oauth_state', sessionState, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.oauthSessionExpiresIn,\n });\n\n // Redirect to the provider's auth endpoint\n passport.authenticate(STRATEGY_NAME, {\n state: req.cookies?.oauth_state,\n })(req, res, next);\n }\n\n @Get(endpoints.callback)\n handleProviderCallback(\n @Req() req: OAuthCallbackRequest,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n // Use a custom callback to handle the authentication result\n passport.authenticate(\n STRATEGY_NAME,\n { session: false },\n async (err: any, user: any) => {\n try {\n if (err) {\n this.logger.error('OAuth callback error:', err);\n throw new BadRequestException('Authentication failed');\n }\n\n if (!user) {\n throw new BadRequestException('Authentication failed');\n }\n\n req.user = user;\n await this.processAuthenticationSuccess(req, res);\n } catch (error) {\n next(error);\n }\n },\n )(req, res, next);\n }\n\n async processAuthenticationSuccess(\n req: OAuthCallbackRequest,\n res: Response,\n ) {\n const user = req.user;\n if (!user) {\n throw new BadRequestException('Authentication failed');\n }\n\n const sessionId = req.cookies?.oauth_session;\n if (!sessionId) {\n throw new BadRequestException('Missing OAuth session');\n }\n\n const session = await this.store.getOAuthSession(sessionId);\n if (!session) {\n throw new BadRequestException('Invalid or expired OAuth session');\n }\n\n // Verify state\n const stateFromCookie = req.cookies?.oauth_state;\n if (session.state !== stateFromCookie) {\n throw new BadRequestException('Invalid state parameter');\n }\n\n // Generate JWT for UI access\n const jwt = this.jwtTokenService.generateUserToken(\n user.profile.username,\n user.profile,\n );\n\n // Set JWT token as cookie for UI endpoints\n res.cookie('auth_token', jwt, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.cookieMaxAge,\n });\n\n // Clear temporary cookies\n res.clearCookie('oauth_session');\n res.clearCookie('oauth_state');\n\n // Persist user profile and get stable profile_id\n const user_profile_id = await this.store.upsertUserProfile(\n user.profile,\n user.provider,\n );\n\n // Generate authorization code\n const authCode = randomBytes(32).toString('base64url');\n\n // Store the auth code\n await this.store.storeAuthCode({\n code: authCode,\n user_id: user.profile.username,\n client_id: session.clientId!,\n redirect_uri: session.redirectUri!,\n code_challenge: session.codeChallenge!,\n code_challenge_method: session.codeChallengeMethod!,\n expires_at: Date.now() + this.options.authCodeExpiresIn,\n resource: session.resource,\n scope: session.scope,\n github_access_token: '', // No longer provider-specific\n user_profile_id,\n });\n\n // Build redirect URL with authorization code\n const redirectUrl = new URL(session.redirectUri!);\n redirectUrl.searchParams.set('code', authCode);\n if (session.oauthState) {\n redirectUrl.searchParams.set('state', session.oauthState);\n }\n\n // Clean up session\n await this.store.removeOAuthSession(sessionId);\n\n res.redirect(redirectUrl.toString());\n }\n\n @Post(endpoints.token)\n @Header('content-type', 'application/json')\n @Header('Cache-Control', 'no-store')\n @Header('Pragma', 'no-cache')\n @HttpCode(200)\n async exchangeToken(\n @Body() body: any,\n @Req() req: RequestWithRawBody,\n @Res({ passthrough: true }) res: Response,\n ): Promise<TokenPair> {\n // Apply middleware to capture raw body if needed\n const isFormUrlEncoded = req.headers['content-type']?.includes(\n 'application/x-www-form-urlencoded',\n );\n const isBodyEmpty =\n !body ||\n (typeof body === 'object' &&\n Object.keys(body as Record<string, unknown>).length === 0);\n\n if (isFormUrlEncoded && isBodyEmpty) {\n return new Promise((resolve, reject) => {\n this.captureRawBody(req, res, (err?: any) => {\n if (err) {\n reject(\n err instanceof Error ? err : new Error(String(err ?? 'error')),\n );\n return;\n }\n\n // Avoid returning a Promise from the callback; use an IIFE\n void (async () => {\n try {\n // Re-parse the body after middleware has captured it\n const parsedBody = this.parseRequestBody(req.body || body, req);\n const result = await this.processTokenExchange(parsedBody, req);\n resolve(result);\n } catch (error) {\n reject(\n error instanceof Error\n ? error\n : new Error(String(error ?? 'error')),\n );\n }\n })();\n });\n });\n }\n\n // Body is already parsed, process directly\n const parsedBody = this.parseRequestBody(body, req);\n return this.processTokenExchange(parsedBody, req);\n }\n\n async processTokenExchange(\n parsedBody: Record<string, any>,\n req: RequestWithRawBody,\n ): Promise<TokenPair> {\n const { grant_type, code, code_verifier, redirect_uri, refresh_token } =\n parsedBody;\n\n // Add debugging to help identify issues\n if (!grant_type) {\n this.logger.error('Missing grant_type in request body:', {\n parsedBodyKeys: Object.keys(parsedBody),\n contentType: req.headers['content-type'],\n textBody: req.textBody,\n parsedBody,\n });\n throw new BadRequestException('Missing grant_type parameter');\n }\n\n switch (grant_type) {\n case 'authorization_code': {\n // Extract client credentials based on authentication method\n const clientCredentials = this.extractClientCredentials(\n req,\n parsedBody,\n );\n return await this.handleAuthorizationCodeGrant(\n typeof code === 'string' ? code : String(code ?? ''),\n typeof code_verifier === 'string'\n ? code_verifier\n : String(code_verifier ?? ''),\n typeof redirect_uri === 'string'\n ? redirect_uri\n : String(redirect_uri ?? ''),\n clientCredentials,\n );\n }\n case 'refresh_token': {\n // For refresh tokens, try to extract client credentials, but allow fallback to token-based extraction\n let clientCredentials: { client_id: string; client_secret?: string };\n try {\n clientCredentials = this.extractClientCredentials(req, parsedBody);\n } catch {\n // If we can't extract credentials, we'll try to get them from the refresh token\n clientCredentials = { client_id: '' }; // Will be filled from token\n }\n return await this.handleRefreshTokenGrant(\n typeof refresh_token === 'string'\n ? refresh_token\n : String(refresh_token ?? ''),\n clientCredentials,\n );\n }\n default:\n throw new BadRequestException(\n `Unsupported grant_type: ${grant_type}`,\n );\n }\n }\n\n /**\n * Extract client credentials from request based on authentication method\n */\n extractClientCredentials(\n req: RequestWithRawBody,\n body: any,\n ): { client_id: string; client_secret?: string } {\n // Parse the body using the shared utility function\n const parsedBody = this.parseRequestBody(body, req);\n\n // Try client_secret_basic first (Authorization header)\n const authHeader = req.headers?.authorization;\n if (authHeader && authHeader.startsWith('Basic ')) {\n const credentials = Buffer.from(authHeader.slice(6), 'base64').toString(\n 'utf-8',\n );\n const [client_id, client_secret] = credentials.split(':', 2);\n if (client_id) {\n return { client_id, client_secret };\n }\n }\n\n // Try client_secret_post (body parameters)\n if (parsedBody.client_id) {\n return {\n client_id: parsedBody.client_id,\n client_secret: parsedBody.client_secret,\n };\n }\n\n throw new BadRequestException('Missing client credentials');\n }\n\n /**\n * Validate client authentication based on the client's configured method\n */\n validateClientAuthentication(\n client: any,\n clientCredentials: { client_id: string; client_secret?: string },\n ): void {\n if (!client) {\n throw new BadRequestException('Invalid client_id');\n }\n\n const { token_endpoint_auth_method } = client;\n\n switch (token_endpoint_auth_method) {\n case 'client_secret_basic':\n case 'client_secret_post':\n if (!clientCredentials.client_secret) {\n throw new BadRequestException(\n 'Client secret required for this authentication method',\n );\n }\n if (client.client_secret !== clientCredentials.client_secret) {\n throw new BadRequestException('Invalid client credentials');\n }\n break;\n\n case 'none':\n // Public client - no secret required\n if (clientCredentials.client_secret) {\n throw new BadRequestException(\n 'Client secret not allowed for public clients',\n );\n }\n break;\n\n default:\n throw new BadRequestException(\n `Unsupported authentication method: ${token_endpoint_auth_method}`,\n );\n }\n }\n\n async handleAuthorizationCodeGrant(\n code: string,\n code_verifier: string,\n _redirect_uri: string,\n clientCredentials: { client_id: string; client_secret?: string },\n ): Promise<TokenPair> {\n this.logger.debug('handleAuthorizationCodeGrant - Params:', {\n code,\n client_id: clientCredentials.client_id,\n });\n\n // Get and validate the authorization code\n const authCode = await this.store.getAuthCode(code);\n if (!authCode) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Invalid authorization code:',\n code,\n );\n throw new BadRequestException('Invalid authorization code');\n }\n if (authCode.expires_at < Date.now()) {\n await this.store.removeAuthCode(code);\n this.logger.error(\n 'handleAuthorizationCodeGrant - Authorization code expired:',\n code,\n );\n throw new BadRequestException('Authorization code has expired');\n }\n if (authCode.client_id !== clientCredentials.client_id) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Client ID mismatch:',\n { expected: authCode.client_id, got: clientCredentials.client_id },\n );\n throw new BadRequestException('Client ID mismatch');\n }\n\n // Get client and validate authentication\n const client = await this.clientService.getClient(\n clientCredentials.client_id,\n );\n this.validateClientAuthentication(client, clientCredentials);\n if (authCode.code_challenge) {\n const isValid = this.validatePKCE(\n code_verifier,\n authCode.code_challenge,\n authCode.code_challenge_method,\n );\n if (!isValid) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Invalid PKCE verification',\n );\n throw new BadRequestException('Invalid PKCE verification');\n }\n }\n if (!authCode.resource) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - No resource associated with code',\n );\n throw new BadRequestException(\n 'Authorization code is not associated with a resource',\n );\n }\n\n let userData: Record<string, unknown> | undefined = undefined;\n if (authCode.user_profile_id) {\n try {\n const profile = await this.store.getUserProfileById(\n authCode.user_profile_id,\n );\n if (profile) {\n // Avoid circular/large raw payloads if present\n userData = { ...profile };\n }\n } catch (e) {\n this.logger.warn('Failed to load user profile for token payload', e);\n }\n }\n\n const tokens = this.jwtTokenService.generateTokenPair(\n authCode.user_id,\n clientCredentials.client_id,\n authCode.scope,\n authCode.resource,\n {\n user_profile_id: authCode.user_profile_id,\n user_data: userData,\n },\n );\n await this.store.removeAuthCode(code);\n this.logger.debug(\n 'handleAuthorizationCodeGrant - Token pair generated for user:',\n authCode.user_id,\n );\n return tokens;\n }\n\n async handleRefreshTokenGrant(\n refresh_token: string,\n clientCredentials: { client_id: string; client_secret?: string },\n ): Promise<TokenPair> {\n // Verify the refresh token first to get client_id from token if not provided\n const payload = this.jwtTokenService.validateToken(refresh_token);\n if (!payload || payload.type !== 'refresh') {\n throw new BadRequestException('Invalid or expired refresh token');\n }\n\n // Use client_id from token if not provided in credentials\n const clientId = clientCredentials.client_id || payload.client_id;\n if (!clientId) {\n throw new BadRequestException('Unable to determine client_id');\n }\n\n // Get client and validate authentication\n const client = await this.clientService.getClient(clientId);\n\n // For refresh token grants, we can be more lenient with client authentication\n // if the token already contains the client_id and the client is public\n if (client?.token_endpoint_auth_method !== 'none') {\n this.validateClientAuthentication(client, {\n ...clientCredentials,\n client_id: clientId,\n });\n }\n\n // Verify the refresh token belongs to the client\n if (payload.client_id !== clientId) {\n throw new BadRequestException(\n 'Invalid refresh token or token does not belong to this client',\n );\n }\n\n let newTokens: TokenPair | null = null;\n try {\n const payload = this.jwtTokenService.validateToken(refresh_token);\n if (!payload || payload.type !== 'refresh') {\n throw new BadRequestException('Invalid or expired refresh token');\n }\n\n let userData: Record<string, unknown> | undefined = undefined;\n if (payload.user_profile_id) {\n try {\n const profile = await this.store.getUserProfileById(\n payload.user_profile_id,\n );\n if (profile) userData = { ...profile };\n } catch (e) {\n this.logger.warn(\n 'Failed to load user profile for refreshed token payload',\n e,\n );\n }\n }\n\n newTokens = this.jwtTokenService.generateTokenPair(\n payload.sub,\n clientId,\n payload.scope,\n payload.resource,\n {\n user_profile_id: payload.user_profile_id,\n user_data: userData,\n },\n );\n } catch (e) {\n this.logger.warn(\n 'Refresh flow failed using enriched path, fallback',\n e,\n );\n newTokens = this.jwtTokenService.refreshAccessToken(refresh_token);\n }\n\n if (!newTokens) throw new BadRequestException('Failed to refresh token');\n return newTokens;\n }\n\n validatePKCE(\n code_verifier: string,\n code_challenge: string,\n method: string,\n ): boolean {\n if (method === 'plain') {\n return code_verifier === code_challenge;\n } else if (method === 'S256') {\n const hash = createHash('sha256')\n .update(code_verifier)\n .digest('base64url');\n return hash === code_challenge;\n }\n return false;\n }\n }\n\n return McpOAuthController;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { TypeOrmModuleOptions } from '@nestjs/typeorm';
2
- import type { IOAuthStore } from '../stores/oauth-store.interface';
2
+ import { IOAuthStore } from '../stores/oauth-store.interface';
3
3
  export interface OAuthProviderConfig {
4
4
  name: string;
5
5
  displayName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-provider.interface.d.ts","sourceRoot":"","sources":["../../../src/authz/providers/oauth-provider.interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oauth-provider.interface.d.ts","sourceRoot":"","sources":["../../../src/authz/providers/oauth-provider.interface.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-provider.interface.js","sourceRoot":"","sources":["../../../src/authz/providers/oauth-provider.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { TypeOrmModuleOptions } from '@nestjs/typeorm';\nimport type { IOAuthStore } from '../stores/oauth-store.interface';\n\nexport interface OAuthProviderConfig {\n name: string;\n displayName?: string;\n strategy: any; // Passport Strategy constructor\n strategyOptions: (options: {\n serverUrl: string;\n clientId: string;\n clientSecret: string;\n callbackPath?: string; // Optional custom callback path\n }) => any;\n scope?: string[];\n profileMapper: (profile: any) => OAuthUserProfile;\n}\n\nexport interface OAuthUserProfile {\n id: string;\n username: string;\n email?: string;\n displayName?: string;\n avatarUrl?: string;\n raw?: any; // Original profile data\n}\n\n// Store configuration union type\nexport type StoreConfiguration =\n | { type: 'typeorm'; options: TypeOrmModuleOptions }\n | { type: 'custom'; store: IOAuthStore }\n | { type: 'memory' }\n | undefined; // Default to memory store\n\nexport interface OAuthEndpointConfiguration {\n wellKnownAuthorizationServerMetadata?: string; // Default: '/.well-known/oauth-authorization-server'\n wellKnownProtectedResourceMetadata?: string | string[]; // Default: '/.well-known/oauth-protected-resource'\n register?: string; // Default: '/register'\n authorize?: string; // Default: '/authorize'\n callback?: string; // Default: '/callback'\n token?: string; // Default: '/token'\n revoke?: string; // Default: '/revoke'\n}\n\nexport interface OAuthEndpointDisableOptions {\n wellKnownAuthorizationServerMetadata?: boolean;\n wellKnownProtectedResourceMetadata?: boolean;\n}\n\nexport interface OAuthUserModuleOptions {\n provider: OAuthProviderConfig;\n\n // Required OAuth Provider Credentials\n clientId: string;\n clientSecret: string;\n\n // Required JWT Configuration\n jwtSecret: string;\n\n // Server Configuration\n serverUrl?: string;\n resource?: string; // should be the endpoint clients connect to, e.g.: 'https://localhost:3000/mcp'\n // JWT Configuration\n jwtIssuer?: string;\n jwtAudience?: string;\n jwtAccessTokenExpiresIn?: string;\n jwtRefreshTokenExpiresIn?: string;\n\n // Cookie Configuration\n cookieSecure?: boolean;\n cookieMaxAge?: number;\n\n // OAuth Session Configuration\n oauthSessionExpiresIn?: number; // in milliseconds\n authCodeExpiresIn?: number; // in milliseconds\n\n // Protected Resource Metadata Configuration\n protectedResourceMetadata?: {\n scopesSupported?: string[];\n bearerMethodsSupported?: string[];\n mcpVersionsSupported?: string[];\n };\n\n // Authorization Server Metadata Configuration\n authorizationServerMetadata?: {\n responseTypesSupported?: string[];\n responseModesSupported?: string[];\n grantTypesSupported?: string[];\n tokenEndpointAuthMethodsSupported?: string[];\n scopesSupported?: string[];\n codeChallengeMethodsSupported?: string[];\n };\n\n // Storage Configuration - single property for all storage options\n storeConfiguration?: StoreConfiguration;\n apiPrefix?: string;\n\n // Endpoint Configuration\n endpoints?: OAuthEndpointConfiguration;\n disableEndpoints?: OAuthEndpointDisableOptions;\n}\n\nexport interface OAuthModuleDefaults {\n serverUrl: string;\n resource: string; // Default resource URL\n jwtIssuer: string;\n jwtAudience: string;\n jwtAccessTokenExpiresIn: string;\n jwtRefreshTokenExpiresIn: string;\n cookieMaxAge: number;\n oauthSessionExpiresIn: number;\n authCodeExpiresIn: number;\n nodeEnv: string;\n apiPrefix: string;\n endpoints: OAuthEndpointConfiguration;\n disableEndpoints: OAuthEndpointDisableOptions;\n protectedResourceMetadata: {\n scopesSupported: string[];\n bearerMethodsSupported: string[];\n mcpVersionsSupported: string[];\n };\n authorizationServerMetadata: {\n responseTypesSupported: string[];\n responseModesSupported: string[];\n grantTypesSupported: string[];\n tokenEndpointAuthMethodsSupported: string[];\n scopesSupported: string[];\n codeChallengeMethodsSupported: string[];\n };\n}\n\n// Resolved options after merging with defaults\nexport type OAuthModuleOptions = Required<\n Pick<\n OAuthUserModuleOptions,\n 'provider' | 'clientId' | 'clientSecret' | 'jwtSecret'\n >\n> &\n Required<OAuthModuleDefaults> & {\n // Optional fields that may remain undefined\n cookieSecure: boolean;\n storeConfiguration?: StoreConfiguration;\n };\n\nexport interface OAuthSession {\n sessionId: string;\n state: string;\n clientId?: string;\n redirectUri?: string;\n codeChallenge?: string;\n codeChallengeMethod?: string;\n oauthState?: string;\n scope?: string;\n resource?: string;\n expiresAt: number;\n}\n"]}
1
+ {"version":3,"file":"oauth-provider.interface.js","sourceRoot":"","sources":["../../../src/authz/providers/oauth-provider.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { TypeOrmModuleOptions } from '@nestjs/typeorm';\nimport { IOAuthStore } from '../stores/oauth-store.interface';\n\nexport interface OAuthProviderConfig {\n name: string;\n displayName?: string;\n strategy: any; // Passport Strategy constructor\n strategyOptions: (options: {\n serverUrl: string;\n clientId: string;\n clientSecret: string;\n callbackPath?: string; // Optional custom callback path\n }) => any;\n scope?: string[];\n profileMapper: (profile: any) => OAuthUserProfile;\n}\n\nexport interface OAuthUserProfile {\n id: string;\n username: string;\n email?: string;\n displayName?: string;\n avatarUrl?: string;\n raw?: any; // Original profile data\n}\n\n// Store configuration union type\nexport type StoreConfiguration =\n | { type: 'typeorm'; options: TypeOrmModuleOptions }\n | { type: 'custom'; store: IOAuthStore }\n | { type: 'memory' }\n | undefined; // Default to memory store\n\nexport interface OAuthEndpointConfiguration {\n wellKnownAuthorizationServerMetadata?: string; // Default: '/.well-known/oauth-authorization-server'\n wellKnownProtectedResourceMetadata?: string | string[]; // Default: '/.well-known/oauth-protected-resource'\n register?: string; // Default: '/register'\n authorize?: string; // Default: '/authorize'\n callback?: string; // Default: '/callback'\n token?: string; // Default: '/token'\n revoke?: string; // Default: '/revoke'\n}\n\nexport interface OAuthEndpointDisableOptions {\n wellKnownAuthorizationServerMetadata?: boolean;\n wellKnownProtectedResourceMetadata?: boolean;\n}\n\nexport interface OAuthUserModuleOptions {\n provider: OAuthProviderConfig;\n\n // Required OAuth Provider Credentials\n clientId: string;\n clientSecret: string;\n\n // Required JWT Configuration\n jwtSecret: string;\n\n // Server Configuration\n serverUrl?: string;\n resource?: string; // should be the endpoint clients connect to, e.g.: 'https://localhost:3000/mcp'\n // JWT Configuration\n jwtIssuer?: string;\n jwtAudience?: string;\n jwtAccessTokenExpiresIn?: string;\n jwtRefreshTokenExpiresIn?: string;\n\n // Cookie Configuration\n cookieSecure?: boolean;\n cookieMaxAge?: number;\n\n // OAuth Session Configuration\n oauthSessionExpiresIn?: number; // in milliseconds\n authCodeExpiresIn?: number; // in milliseconds\n\n // Protected Resource Metadata Configuration\n protectedResourceMetadata?: {\n scopesSupported?: string[];\n bearerMethodsSupported?: string[];\n mcpVersionsSupported?: string[];\n };\n\n // Authorization Server Metadata Configuration\n authorizationServerMetadata?: {\n responseTypesSupported?: string[];\n responseModesSupported?: string[];\n grantTypesSupported?: string[];\n tokenEndpointAuthMethodsSupported?: string[];\n scopesSupported?: string[];\n codeChallengeMethodsSupported?: string[];\n };\n\n // Storage Configuration - single property for all storage options\n storeConfiguration?: StoreConfiguration;\n apiPrefix?: string;\n\n // Endpoint Configuration\n endpoints?: OAuthEndpointConfiguration;\n disableEndpoints?: OAuthEndpointDisableOptions;\n}\n\nexport interface OAuthModuleDefaults {\n serverUrl: string;\n resource: string; // Default resource URL\n jwtIssuer: string;\n jwtAudience: string;\n jwtAccessTokenExpiresIn: string;\n jwtRefreshTokenExpiresIn: string;\n cookieMaxAge: number;\n oauthSessionExpiresIn: number;\n authCodeExpiresIn: number;\n nodeEnv: string;\n apiPrefix: string;\n endpoints: OAuthEndpointConfiguration;\n disableEndpoints: OAuthEndpointDisableOptions;\n protectedResourceMetadata: {\n scopesSupported: string[];\n bearerMethodsSupported: string[];\n mcpVersionsSupported: string[];\n };\n authorizationServerMetadata: {\n responseTypesSupported: string[];\n responseModesSupported: string[];\n grantTypesSupported: string[];\n tokenEndpointAuthMethodsSupported: string[];\n scopesSupported: string[];\n codeChallengeMethodsSupported: string[];\n };\n}\n\n// Resolved options after merging with defaults\nexport type OAuthModuleOptions = Required<\n Pick<\n OAuthUserModuleOptions,\n 'provider' | 'clientId' | 'clientSecret' | 'jwtSecret'\n >\n> &\n Required<OAuthModuleDefaults> & {\n // Optional fields that may remain undefined\n cookieSecure: boolean;\n storeConfiguration?: StoreConfiguration;\n };\n\nexport interface OAuthSession {\n sessionId: string;\n state: string;\n clientId?: string;\n redirectUri?: string;\n codeChallenge?: string;\n codeChallengeMethod?: string;\n oauthState?: string;\n scope?: string;\n resource?: string;\n expiresAt: number;\n}\n"]}
@@ -1,5 +1,4 @@
1
- import type { IOAuthStore } from '../stores/oauth-store.interface';
2
- import { ClientRegistrationDto, OAuthClient } from '../stores/oauth-store.interface';
1
+ import { ClientRegistrationDto, IOAuthStore, OAuthClient } from '../stores/oauth-store.interface';
3
2
  import { OAuthModuleOptions } from '../providers/oauth-provider.interface';
4
3
  export declare class ClientService {
5
4
  private readonly store;
@@ -1 +1 @@
1
- {"version":3,"file":"client.service.d.ts","sourceRoot":"","sources":["../../../src/authz/services/client.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EACL,qBAAqB,EACrB,WAAW,EACZ,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,qBACa,aAAa;IAEC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAE7C,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFgB,KAAK,EAAE,WAAW,EAEzC,OAAO,EAAE,kBAAkB;IAUxC,cAAc,CAClB,eAAe,EAAE,qBAAqB,GACrC,OAAO,CAAC,WAAW,CAAC;cAuEP,qBAAqB,CACnC,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC;IAIV,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAcxD,mBAAmB,CACvB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC;CAIpB"}
1
+ {"version":3,"file":"client.service.d.ts","sourceRoot":"","sources":["../../../src/authz/services/client.service.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,WAAW,EACZ,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,qBACa,aAAa;IAEC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAE7C,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFgB,KAAK,EAAE,WAAW,EAEzC,OAAO,EAAE,kBAAkB;IAUxC,cAAc,CAClB,eAAe,EAAE,qBAAqB,GACrC,OAAO,CAAC,WAAW,CAAC;cAuEP,qBAAqB,CACnC,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC;IAIV,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAcxD,mBAAmB,CACvB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC;CAIpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"client.service.js","sourceRoot":"","sources":["../../../src/authz/services/client.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BadRequestException, Injectable, Inject } from '@nestjs/common';\nimport type { IOAuthStore } from '../stores/oauth-store.interface';\nimport {\n ClientRegistrationDto,\n OAuthClient,\n} from '../stores/oauth-store.interface';\nimport { randomBytes } from 'crypto';\nimport { OAuthModuleOptions } from '../providers/oauth-provider.interface';\n\n@Injectable()\nexport class ClientService {\n constructor(\n @Inject('IOAuthStore') private readonly store: IOAuthStore,\n @Inject('OAUTH_MODULE_OPTIONS')\n private readonly options: OAuthModuleOptions,\n ) {}\n\n /**\n * Register a client application.\n * Always creates a new client record. client_name is not treated as unique.\n *\n * Note: Left open for future enhancements (e.g., software statements,\n * URL-based Client ID Metadata Documents) via preRegistrationChecks().\n */\n async registerClient(\n registrationDto: ClientRegistrationDto,\n ): Promise<OAuthClient> {\n // Validate required fields\n if (\n !registrationDto.redirect_uris ||\n !Array.isArray(registrationDto.redirect_uris)\n ) {\n throw new BadRequestException(\n 'redirect_uris is required and must be an array',\n );\n }\n\n // Validate token_endpoint_auth_method if provided\n const supportedAuthMethods = [\n 'client_secret_basic',\n 'client_secret_post',\n 'none',\n ];\n if (\n registrationDto.token_endpoint_auth_method &&\n !supportedAuthMethods.includes(registrationDto.token_endpoint_auth_method)\n ) {\n throw new BadRequestException(\n `Unsupported token_endpoint_auth_method. Supported methods: ${supportedAuthMethods.join(', ')}`,\n );\n }\n\n // Default values for new clients\n const defaultClientValues = {\n grant_types: ['authorization_code', 'refresh_token'],\n response_types: ['code'],\n token_endpoint_auth_method:\n registrationDto.token_endpoint_auth_method || 'none',\n };\n\n // Future-proofing: hook for software statements / metadata URL validations\n await this.preRegistrationChecks(registrationDto);\n\n const now = new Date();\n\n // Create new client - merge defaults with registration data\n const client_id = this.store.generateClientId(\n registrationDto as OAuthClient,\n );\n\n // Only generate client_secret for methods that require it\n const authMethod = registrationDto.token_endpoint_auth_method || 'none';\n const client_secret =\n authMethod !== 'none' ? randomBytes(32).toString('hex') : undefined;\n\n const newClient: OAuthClient = {\n ...defaultClientValues,\n ...registrationDto,\n client_id,\n client_secret,\n created_at: now,\n updated_at: now,\n };\n const client = await this.store.storeClient(newClient);\n const filteredClient = Object.fromEntries(\n Object.entries(client).filter(([, value]) => value !== null),\n ) as OAuthClient;\n\n return filteredClient;\n }\n\n /**\n * Hook for future registration policies (e.g., software statements per RFC 7591/7592,\n * or URL-based Client Registration using Client ID Metadata Documents).\n * Currently a no-op to keep behavior: always create a new client.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected async preRegistrationChecks(\n _dto: ClientRegistrationDto,\n ): Promise<void> {\n // Intentionally left blank. Implement validations/attestations in the future.\n }\n\n async getClient(clientId: string): Promise<OAuthClient | null> {\n const client = await this.store.getClient(clientId);\n if (!client) {\n return null;\n }\n\n // Remove null fields from the client object\n const filteredClient = Object.fromEntries(\n Object.entries(client).filter(([, value]) => value !== null),\n ) as OAuthClient;\n\n return filteredClient;\n }\n\n async validateRedirectUri(\n clientId: string,\n redirectUri: string,\n ): Promise<boolean> {\n const client = await this.getClient(clientId);\n return client ? client.redirect_uris.includes(redirectUri) : false;\n }\n}\n"]}
1
+ {"version":3,"file":"client.service.js","sourceRoot":"","sources":["../../../src/authz/services/client.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BadRequestException, Injectable, Inject } from '@nestjs/common';\nimport {\n ClientRegistrationDto,\n IOAuthStore,\n OAuthClient,\n} from '../stores/oauth-store.interface';\nimport { randomBytes } from 'crypto';\nimport { OAuthModuleOptions } from '../providers/oauth-provider.interface';\n\n@Injectable()\nexport class ClientService {\n constructor(\n @Inject('IOAuthStore') private readonly store: IOAuthStore,\n @Inject('OAUTH_MODULE_OPTIONS')\n private readonly options: OAuthModuleOptions,\n ) {}\n\n /**\n * Register a client application.\n * Always creates a new client record. client_name is not treated as unique.\n *\n * Note: Left open for future enhancements (e.g., software statements,\n * URL-based Client ID Metadata Documents) via preRegistrationChecks().\n */\n async registerClient(\n registrationDto: ClientRegistrationDto,\n ): Promise<OAuthClient> {\n // Validate required fields\n if (\n !registrationDto.redirect_uris ||\n !Array.isArray(registrationDto.redirect_uris)\n ) {\n throw new BadRequestException(\n 'redirect_uris is required and must be an array',\n );\n }\n\n // Validate token_endpoint_auth_method if provided\n const supportedAuthMethods = [\n 'client_secret_basic',\n 'client_secret_post',\n 'none',\n ];\n if (\n registrationDto.token_endpoint_auth_method &&\n !supportedAuthMethods.includes(registrationDto.token_endpoint_auth_method)\n ) {\n throw new BadRequestException(\n `Unsupported token_endpoint_auth_method. Supported methods: ${supportedAuthMethods.join(', ')}`,\n );\n }\n\n // Default values for new clients\n const defaultClientValues = {\n grant_types: ['authorization_code', 'refresh_token'],\n response_types: ['code'],\n token_endpoint_auth_method:\n registrationDto.token_endpoint_auth_method || 'none',\n };\n\n // Future-proofing: hook for software statements / metadata URL validations\n await this.preRegistrationChecks(registrationDto);\n\n const now = new Date();\n\n // Create new client - merge defaults with registration data\n const client_id = this.store.generateClientId(\n registrationDto as OAuthClient,\n );\n\n // Only generate client_secret for methods that require it\n const authMethod = registrationDto.token_endpoint_auth_method || 'none';\n const client_secret =\n authMethod !== 'none' ? randomBytes(32).toString('hex') : undefined;\n\n const newClient: OAuthClient = {\n ...defaultClientValues,\n ...registrationDto,\n client_id,\n client_secret,\n created_at: now,\n updated_at: now,\n };\n const client = await this.store.storeClient(newClient);\n const filteredClient = Object.fromEntries(\n Object.entries(client).filter(([, value]) => value !== null),\n ) as OAuthClient;\n\n return filteredClient;\n }\n\n /**\n * Hook for future registration policies (e.g., software statements per RFC 7591/7592,\n * or URL-based Client Registration using Client ID Metadata Documents).\n * Currently a no-op to keep behavior: always create a new client.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected async preRegistrationChecks(\n _dto: ClientRegistrationDto,\n ): Promise<void> {\n // Intentionally left blank. Implement validations/attestations in the future.\n }\n\n async getClient(clientId: string): Promise<OAuthClient | null> {\n const client = await this.store.getClient(clientId);\n if (!client) {\n return null;\n }\n\n // Remove null fields from the client object\n const filteredClient = Object.fromEntries(\n Object.entries(client).filter(([, value]) => value !== null),\n ) as OAuthClient;\n\n return filteredClient;\n }\n\n async validateRedirectUri(\n clientId: string,\n redirectUri: string,\n ): Promise<boolean> {\n const client = await this.getClient(clientId);\n return client ? client.redirect_uris.includes(redirectUri) : false;\n }\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  import { OAuthSession, OAuthUserProfile } from '../providers/oauth-provider.interface';
2
- import { AuthorizationCode, OAuthClient } from './oauth-store.interface';
3
- import type { IOAuthStore } from './oauth-store.interface';
2
+ import { AuthorizationCode, IOAuthStore, OAuthClient } from './oauth-store.interface';
4
3
  export declare class MemoryStore implements IOAuthStore {
5
4
  private clients;
6
5
  private authCodes;
@@ -1 +1 @@
1
- {"version":3,"file":"memory-store.service.d.ts","sourceRoot":"","sources":["../../../src/authz/stores/memory-store.service.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,YAAY,EACZ,gBAAgB,EACjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAG3D,qBACa,WAAY,YAAW,WAAW;IAC7C,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,SAAS,CAAwC;IACzD,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,YAAY,CAGhB;IACJ,OAAO,CAAC,iBAAiB,CAA6B;IAEhD,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAKtD,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAI9D,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IASjE,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAIjE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAIV,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IASrE,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAa7C,OAAO,CAAC,qBAAqB;IAqBvB,iBAAiB,CACrB,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAgBZ,kBAAkB,CACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CACR,CAAC,gBAAgB,GAAG;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAC1E;IAID,OAAO,CAAC,iBAAiB;CAI1B"}
1
+ {"version":3,"file":"memory-store.service.d.ts","sourceRoot":"","sources":["../../../src/authz/stores/memory-store.service.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,YAAY,EACZ,gBAAgB,EACjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,WAAW,EACZ,MAAM,yBAAyB,CAAC;AAGjC,qBACa,WAAY,YAAW,WAAW;IAC7C,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,SAAS,CAAwC;IACzD,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,YAAY,CAGhB;IACJ,OAAO,CAAC,iBAAiB,CAA6B;IAEhD,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAKtD,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAI9D,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IASjE,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAIjE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAIV,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IASrE,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAa7C,OAAO,CAAC,qBAAqB;IAqBvB,iBAAiB,CACrB,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAgBZ,kBAAkB,CACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CACR,CAAC,gBAAgB,GAAG;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAC1E;IAID,OAAO,CAAC,iBAAiB;CAI1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"memory-store.service.js","sourceRoot":"","sources":["../../../src/authz/stores/memory-store.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@nestjs/common';\nimport { createHash } from 'crypto';\nimport {\n OAuthSession,\n OAuthUserProfile,\n} from '../providers/oauth-provider.interface';\nimport { AuthorizationCode, OAuthClient } from './oauth-store.interface';\nimport type { IOAuthStore } from './oauth-store.interface';\n\n// In-memory storage (in production, use a database)\n@Injectable()\nexport class MemoryStore implements IOAuthStore {\n private clients = new Map<string, OAuthClient>();\n private authCodes = new Map<string, AuthorizationCode>();\n private oauthSessions = new Map<string, OAuthSession>();\n private userProfiles = new Map<\n string,\n OAuthUserProfile & { profile_id: string; provider: string }\n >(); // profile_id -> profile\n private providerUserIndex = new Map<string, string>(); // key(provider:userId) -> profile_id\n\n async storeClient(client: OAuthClient): Promise<OAuthClient> {\n this.clients.set(client.client_id, client);\n return client;\n }\n\n async getClient(client_id: string): Promise<OAuthClient | undefined> {\n return this.clients.get(client_id);\n }\n\n async findClient(client_name: string): Promise<OAuthClient | undefined> {\n for (const client of this.clients.values()) {\n if (client.client_name === client_name) {\n return client;\n }\n }\n return undefined;\n }\n\n async storeAuthCode(code: AuthorizationCode): Promise<void> {\n this.authCodes.set(code.code, code);\n }\n\n async getAuthCode(code: string): Promise<AuthorizationCode | undefined> {\n return this.authCodes.get(code);\n }\n\n async removeAuthCode(code: string): Promise<void> {\n this.authCodes.delete(code);\n }\n\n // New OAuth session methods for provider-agnostic flow\n async storeOAuthSession(\n sessionId: string,\n session: OAuthSession,\n ): Promise<void> {\n this.oauthSessions.set(sessionId, session);\n }\n\n async getOAuthSession(sessionId: string): Promise<OAuthSession | undefined> {\n const session = this.oauthSessions.get(sessionId);\n if (session && session.expiresAt < Date.now()) {\n this.oauthSessions.delete(sessionId);\n return undefined;\n }\n return session;\n }\n\n async removeOAuthSession(sessionId: string): Promise<void> {\n this.oauthSessions.delete(sessionId);\n }\n\n generateClientId(client: OAuthClient): string {\n // Create deterministic client ID based on entire client object\n const normalizedClient = this.normalizeClientObject(client);\n const clientString = JSON.stringify(normalizedClient);\n const hash = createHash('sha256').update(clientString).digest('hex');\n\n // Use first 16 characters of hash with client name prefix for readability\n const normalizedName = client.client_name\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '');\n return `${normalizedName}_${hash.substring(0, 16)}`;\n }\n\n private normalizeClientObject(client: OAuthClient): any {\n // Create a normalized version of the client object for consistent hashing\n const normalized: any = {};\n\n // Sort object keys to ensure consistent ordering\n const sortedKeys = Object.keys(client).sort();\n\n for (const key of sortedKeys) {\n const value = (client as any)[key];\n if (Array.isArray(value)) {\n // Sort arrays to ensure consistent ordering\n normalized[key] = [...value].sort();\n } else {\n normalized[key] = value;\n }\n }\n\n return normalized;\n }\n\n // User profile management\n async upsertUserProfile(\n profile: OAuthUserProfile,\n provider: string,\n ): Promise<string> {\n const key = `${provider}:${profile.id}`;\n let profileId = this.providerUserIndex.get(key);\n if (!profileId) {\n // create new\n profileId = this.generateProfileId(provider, profile.id);\n this.providerUserIndex.set(key, profileId);\n }\n this.userProfiles.set(profileId, {\n profile_id: profileId,\n provider,\n ...profile,\n });\n return profileId;\n }\n\n async getUserProfileById(\n profileId: string,\n ): Promise<\n (OAuthUserProfile & { profile_id: string; provider: string }) | undefined\n > {\n return this.userProfiles.get(profileId);\n }\n\n private generateProfileId(provider: string, providerUserId: string): string {\n const input = `${provider}:${providerUserId}`;\n return createHash('sha256').update(input).digest('hex').slice(0, 24);\n }\n}\n"]}
1
+ {"version":3,"file":"memory-store.service.js","sourceRoot":"","sources":["../../../src/authz/stores/memory-store.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@nestjs/common';\nimport { createHash } from 'crypto';\nimport {\n OAuthSession,\n OAuthUserProfile,\n} from '../providers/oauth-provider.interface';\nimport {\n AuthorizationCode,\n IOAuthStore,\n OAuthClient,\n} from './oauth-store.interface';\n\n// In-memory storage (in production, use a database)\n@Injectable()\nexport class MemoryStore implements IOAuthStore {\n private clients = new Map<string, OAuthClient>();\n private authCodes = new Map<string, AuthorizationCode>();\n private oauthSessions = new Map<string, OAuthSession>();\n private userProfiles = new Map<\n string,\n OAuthUserProfile & { profile_id: string; provider: string }\n >(); // profile_id -> profile\n private providerUserIndex = new Map<string, string>(); // key(provider:userId) -> profile_id\n\n async storeClient(client: OAuthClient): Promise<OAuthClient> {\n this.clients.set(client.client_id, client);\n return client;\n }\n\n async getClient(client_id: string): Promise<OAuthClient | undefined> {\n return this.clients.get(client_id);\n }\n\n async findClient(client_name: string): Promise<OAuthClient | undefined> {\n for (const client of this.clients.values()) {\n if (client.client_name === client_name) {\n return client;\n }\n }\n return undefined;\n }\n\n async storeAuthCode(code: AuthorizationCode): Promise<void> {\n this.authCodes.set(code.code, code);\n }\n\n async getAuthCode(code: string): Promise<AuthorizationCode | undefined> {\n return this.authCodes.get(code);\n }\n\n async removeAuthCode(code: string): Promise<void> {\n this.authCodes.delete(code);\n }\n\n // New OAuth session methods for provider-agnostic flow\n async storeOAuthSession(\n sessionId: string,\n session: OAuthSession,\n ): Promise<void> {\n this.oauthSessions.set(sessionId, session);\n }\n\n async getOAuthSession(sessionId: string): Promise<OAuthSession | undefined> {\n const session = this.oauthSessions.get(sessionId);\n if (session && session.expiresAt < Date.now()) {\n this.oauthSessions.delete(sessionId);\n return undefined;\n }\n return session;\n }\n\n async removeOAuthSession(sessionId: string): Promise<void> {\n this.oauthSessions.delete(sessionId);\n }\n\n generateClientId(client: OAuthClient): string {\n // Create deterministic client ID based on entire client object\n const normalizedClient = this.normalizeClientObject(client);\n const clientString = JSON.stringify(normalizedClient);\n const hash = createHash('sha256').update(clientString).digest('hex');\n\n // Use first 16 characters of hash with client name prefix for readability\n const normalizedName = client.client_name\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '');\n return `${normalizedName}_${hash.substring(0, 16)}`;\n }\n\n private normalizeClientObject(client: OAuthClient): any {\n // Create a normalized version of the client object for consistent hashing\n const normalized: any = {};\n\n // Sort object keys to ensure consistent ordering\n const sortedKeys = Object.keys(client).sort();\n\n for (const key of sortedKeys) {\n const value = (client as any)[key];\n if (Array.isArray(value)) {\n // Sort arrays to ensure consistent ordering\n normalized[key] = [...value].sort();\n } else {\n normalized[key] = value;\n }\n }\n\n return normalized;\n }\n\n // User profile management\n async upsertUserProfile(\n profile: OAuthUserProfile,\n provider: string,\n ): Promise<string> {\n const key = `${provider}:${profile.id}`;\n let profileId = this.providerUserIndex.get(key);\n if (!profileId) {\n // create new\n profileId = this.generateProfileId(provider, profile.id);\n this.providerUserIndex.set(key, profileId);\n }\n this.userProfiles.set(profileId, {\n profile_id: profileId,\n provider,\n ...profile,\n });\n return profileId;\n }\n\n async getUserProfileById(\n profileId: string,\n ): Promise<\n (OAuthUserProfile & { profile_id: string; provider: string }) | undefined\n > {\n return this.userProfiles.get(profileId);\n }\n\n private generateProfileId(provider: string, providerUserId: string): string {\n const input = `${provider}:${providerUserId}`;\n return createHash('sha256').update(input).digest('hex').slice(0, 24);\n }\n}\n"]}
@@ -1,8 +1,7 @@
1
1
  import { Repository } from 'typeorm';
2
2
  import { OAuthClientEntity, AuthorizationCodeEntity, OAuthSessionEntity, OAuthUserProfileEntity } from './entities';
3
3
  import { OAuthSession, OAuthUserProfile } from '../../providers/oauth-provider.interface';
4
- import { AuthorizationCode, OAuthClient } from '../oauth-store.interface';
5
- import type { IOAuthStore } from '../oauth-store.interface';
4
+ import { AuthorizationCode, IOAuthStore, OAuthClient } from '../oauth-store.interface';
6
5
  export declare class TypeOrmStore implements IOAuthStore {
7
6
  private readonly clientRepository;
8
7
  private readonly authCodeRepository;
@@ -1 +1 @@
1
- {"version":3,"file":"typeorm-store.service.d.ts","sourceRoot":"","sources":["../../../../src/authz/stores/typeorm/typeorm-store.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,YAAY,EACZ,gBAAgB,EACjB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,qBACa,YAAa,YAAW,WAAW;IAG5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAEjC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBANrB,gBAAgB,EAAE,UAAU,CAAC,iBAAiB,CAAC,EAE/C,kBAAkB,EAAE,UAAU,CAAC,uBAAuB,CAAC,EAEvD,iBAAiB,EAAE,UAAU,CAAC,kBAAkB,CAAC,EAEjD,qBAAqB,EAAE,UAAU,CAAC,sBAAsB,CAAC;IAItE,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAKtD,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAO9D,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAQjE,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAUjE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAIV,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAWrE,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAUvC,iBAAiB,CACrB,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IA8BZ,kBAAkB,CACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CACR,CAAC,gBAAgB,GAAG;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAC1E;IAiBD,OAAO,CAAC,iBAAiB;CAI1B"}
1
+ {"version":3,"file":"typeorm-store.service.d.ts","sourceRoot":"","sources":["../../../../src/authz/stores/typeorm/typeorm-store.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,YAAY,EACZ,gBAAgB,EACjB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAElC,qBACa,YAAa,YAAW,WAAW;IAG5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAEjC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBANrB,gBAAgB,EAAE,UAAU,CAAC,iBAAiB,CAAC,EAE/C,kBAAkB,EAAE,UAAU,CAAC,uBAAuB,CAAC,EAEvD,iBAAiB,EAAE,UAAU,CAAC,kBAAkB,CAAC,EAEjD,qBAAqB,EAAE,UAAU,CAAC,sBAAsB,CAAC;IAItE,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAKtD,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAO9D,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAQjE,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAUjE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC;IAIV,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAWrE,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAUvC,iBAAiB,CACrB,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IA8BZ,kBAAkB,CACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CACR,CAAC,gBAAgB,GAAG;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAC1E;IAiBD,OAAO,CAAC,iBAAiB;CAI1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"typeorm-store.service.js","sourceRoot":"","sources":["../../../../src/authz/stores/typeorm/typeorm-store.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@nestjs/common';\nimport { InjectRepository } from '@nestjs/typeorm';\nimport { Repository } from 'typeorm';\nimport { randomBytes, createHash } from 'crypto';\nimport {\n OAuthClientEntity,\n AuthorizationCodeEntity,\n OAuthSessionEntity,\n OAuthUserProfileEntity,\n} from './entities';\nimport { OAUTH_TYPEORM_CONNECTION_NAME } from './constants';\nimport {\n OAuthSession,\n OAuthUserProfile,\n} from '../../providers/oauth-provider.interface';\nimport { AuthorizationCode, OAuthClient } from '../oauth-store.interface';\nimport type { IOAuthStore } from '../oauth-store.interface';\n\n@Injectable()\nexport class TypeOrmStore implements IOAuthStore {\n constructor(\n @InjectRepository(OAuthClientEntity, OAUTH_TYPEORM_CONNECTION_NAME)\n private readonly clientRepository: Repository<OAuthClientEntity>,\n @InjectRepository(AuthorizationCodeEntity, OAUTH_TYPEORM_CONNECTION_NAME)\n private readonly authCodeRepository: Repository<AuthorizationCodeEntity>,\n @InjectRepository(OAuthSessionEntity, OAUTH_TYPEORM_CONNECTION_NAME)\n private readonly sessionRepository: Repository<OAuthSessionEntity>,\n @InjectRepository(OAuthUserProfileEntity, OAUTH_TYPEORM_CONNECTION_NAME)\n private readonly userProfileRepository: Repository<OAuthUserProfileEntity>,\n ) {}\n\n // Client management\n async storeClient(client: OAuthClient): Promise<OAuthClient> {\n const savedClient = await this.clientRepository.save(client);\n return savedClient;\n }\n\n async getClient(client_id: string): Promise<OAuthClient | undefined> {\n return (\n (await this.clientRepository.findOne({ where: { client_id } })) ??\n undefined\n );\n }\n\n async findClient(client_name: string): Promise<OAuthClient | undefined> {\n return (\n (await this.clientRepository.findOne({ where: { client_name } })) ??\n undefined\n );\n }\n\n // Authorization code management\n async storeAuthCode(code: AuthorizationCode): Promise<void> {\n await this.authCodeRepository.save(code);\n }\n\n async getAuthCode(code: string): Promise<AuthorizationCode | undefined> {\n const authCode = await this.authCodeRepository.findOne({ where: { code } });\n // Check if expired\n if (authCode && authCode.expires_at < Date.now()) {\n await this.authCodeRepository.delete({ code });\n return undefined;\n }\n return authCode ?? undefined;\n }\n\n async removeAuthCode(code: string): Promise<void> {\n await this.authCodeRepository.delete({ code });\n }\n\n // OAuth session management\n async storeOAuthSession(\n sessionId: string,\n session: OAuthSession,\n ): Promise<void> {\n await this.sessionRepository.save({ ...session, sessionId });\n }\n\n async getOAuthSession(sessionId: string): Promise<OAuthSession | undefined> {\n const session = await this.sessionRepository.findOne({\n where: { sessionId },\n });\n if (session && session.expiresAt < Date.now()) {\n await this.sessionRepository.delete({ sessionId });\n return undefined;\n }\n return session ?? undefined;\n }\n\n async removeOAuthSession(sessionId: string): Promise<void> {\n await this.sessionRepository.delete({ sessionId });\n }\n\n generateClientId(client: OAuthClient): string {\n // Create deterministic client ID based on name + random salt\n const normalizedName = client.client_name\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '');\n const salt = randomBytes(4).toString('hex');\n return `${normalizedName}_${salt}`;\n }\n\n // User profile management\n async upsertUserProfile(\n profile: OAuthUserProfile,\n provider: string,\n ): Promise<string> {\n // Try find by provider+provider_user_id\n const existing = await this.userProfileRepository.findOne({\n where: { provider, provider_user_id: profile.id },\n });\n if (existing) {\n // Update fields that may change\n existing.username = profile.username;\n existing.email = profile.email;\n existing.displayName = profile.displayName;\n existing.avatarUrl = profile.avatarUrl;\n existing.raw = profile.raw ? JSON.stringify(profile.raw) : existing.raw;\n await this.userProfileRepository.save(existing);\n return existing.profile_id;\n }\n // Create new\n const entity = this.userProfileRepository.create({\n profile_id: this.generateProfileId(provider, profile.id),\n provider_user_id: profile.id,\n provider,\n username: profile.username,\n email: profile.email,\n displayName: profile.displayName,\n avatarUrl: profile.avatarUrl,\n raw: profile.raw ? JSON.stringify(profile.raw) : undefined,\n });\n const saved = await this.userProfileRepository.save(entity);\n return saved.profile_id;\n }\n\n async getUserProfileById(\n profileId: string,\n ): Promise<\n (OAuthUserProfile & { profile_id: string; provider: string }) | undefined\n > {\n const entity = await this.userProfileRepository.findOne({\n where: { profile_id: profileId },\n });\n if (!entity) return undefined;\n return {\n profile_id: entity.profile_id,\n provider: entity.provider,\n id: entity.provider_user_id,\n username: entity.username,\n email: entity.email,\n displayName: entity.displayName,\n avatarUrl: entity.avatarUrl,\n raw: entity.raw ? JSON.parse(entity.raw) : undefined,\n };\n }\n\n private generateProfileId(provider: string, providerUserId: string): string {\n const input = `${provider}:${providerUserId}`;\n return createHash('sha256').update(input).digest('hex').slice(0, 24);\n }\n}\n"]}
1
+ {"version":3,"file":"typeorm-store.service.js","sourceRoot":"","sources":["../../../../src/authz/stores/typeorm/typeorm-store.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@nestjs/common';\nimport { InjectRepository } from '@nestjs/typeorm';\nimport { Repository } from 'typeorm';\nimport { randomBytes, createHash } from 'crypto';\nimport {\n OAuthClientEntity,\n AuthorizationCodeEntity,\n OAuthSessionEntity,\n OAuthUserProfileEntity,\n} from './entities';\nimport { OAUTH_TYPEORM_CONNECTION_NAME } from './constants';\nimport {\n OAuthSession,\n OAuthUserProfile,\n} from '../../providers/oauth-provider.interface';\nimport {\n AuthorizationCode,\n IOAuthStore,\n OAuthClient,\n} from '../oauth-store.interface';\n\n@Injectable()\nexport class TypeOrmStore implements IOAuthStore {\n constructor(\n @InjectRepository(OAuthClientEntity, OAUTH_TYPEORM_CONNECTION_NAME)\n private readonly clientRepository: Repository<OAuthClientEntity>,\n @InjectRepository(AuthorizationCodeEntity, OAUTH_TYPEORM_CONNECTION_NAME)\n private readonly authCodeRepository: Repository<AuthorizationCodeEntity>,\n @InjectRepository(OAuthSessionEntity, OAUTH_TYPEORM_CONNECTION_NAME)\n private readonly sessionRepository: Repository<OAuthSessionEntity>,\n @InjectRepository(OAuthUserProfileEntity, OAUTH_TYPEORM_CONNECTION_NAME)\n private readonly userProfileRepository: Repository<OAuthUserProfileEntity>,\n ) {}\n\n // Client management\n async storeClient(client: OAuthClient): Promise<OAuthClient> {\n const savedClient = await this.clientRepository.save(client);\n return savedClient;\n }\n\n async getClient(client_id: string): Promise<OAuthClient | undefined> {\n return (\n (await this.clientRepository.findOne({ where: { client_id } })) ??\n undefined\n );\n }\n\n async findClient(client_name: string): Promise<OAuthClient | undefined> {\n return (\n (await this.clientRepository.findOne({ where: { client_name } })) ??\n undefined\n );\n }\n\n // Authorization code management\n async storeAuthCode(code: AuthorizationCode): Promise<void> {\n await this.authCodeRepository.save(code);\n }\n\n async getAuthCode(code: string): Promise<AuthorizationCode | undefined> {\n const authCode = await this.authCodeRepository.findOne({ where: { code } });\n // Check if expired\n if (authCode && authCode.expires_at < Date.now()) {\n await this.authCodeRepository.delete({ code });\n return undefined;\n }\n return authCode ?? undefined;\n }\n\n async removeAuthCode(code: string): Promise<void> {\n await this.authCodeRepository.delete({ code });\n }\n\n // OAuth session management\n async storeOAuthSession(\n sessionId: string,\n session: OAuthSession,\n ): Promise<void> {\n await this.sessionRepository.save({ ...session, sessionId });\n }\n\n async getOAuthSession(sessionId: string): Promise<OAuthSession | undefined> {\n const session = await this.sessionRepository.findOne({\n where: { sessionId },\n });\n if (session && session.expiresAt < Date.now()) {\n await this.sessionRepository.delete({ sessionId });\n return undefined;\n }\n return session ?? undefined;\n }\n\n async removeOAuthSession(sessionId: string): Promise<void> {\n await this.sessionRepository.delete({ sessionId });\n }\n\n generateClientId(client: OAuthClient): string {\n // Create deterministic client ID based on name + random salt\n const normalizedName = client.client_name\n .toLowerCase()\n .replace(/[^a-z0-9]/g, '');\n const salt = randomBytes(4).toString('hex');\n return `${normalizedName}_${salt}`;\n }\n\n // User profile management\n async upsertUserProfile(\n profile: OAuthUserProfile,\n provider: string,\n ): Promise<string> {\n // Try find by provider+provider_user_id\n const existing = await this.userProfileRepository.findOne({\n where: { provider, provider_user_id: profile.id },\n });\n if (existing) {\n // Update fields that may change\n existing.username = profile.username;\n existing.email = profile.email;\n existing.displayName = profile.displayName;\n existing.avatarUrl = profile.avatarUrl;\n existing.raw = profile.raw ? JSON.stringify(profile.raw) : existing.raw;\n await this.userProfileRepository.save(existing);\n return existing.profile_id;\n }\n // Create new\n const entity = this.userProfileRepository.create({\n profile_id: this.generateProfileId(provider, profile.id),\n provider_user_id: profile.id,\n provider,\n username: profile.username,\n email: profile.email,\n displayName: profile.displayName,\n avatarUrl: profile.avatarUrl,\n raw: profile.raw ? JSON.stringify(profile.raw) : undefined,\n });\n const saved = await this.userProfileRepository.save(entity);\n return saved.profile_id;\n }\n\n async getUserProfileById(\n profileId: string,\n ): Promise<\n (OAuthUserProfile & { profile_id: string; provider: string }) | undefined\n > {\n const entity = await this.userProfileRepository.findOne({\n where: { profile_id: profileId },\n });\n if (!entity) return undefined;\n return {\n profile_id: entity.profile_id,\n provider: entity.provider,\n id: entity.provider_user_id,\n username: entity.username,\n email: entity.email,\n displayName: entity.displayName,\n avatarUrl: entity.avatarUrl,\n raw: entity.raw ? JSON.parse(entity.raw) : undefined,\n };\n }\n\n private generateProfileId(provider: string, providerUserId: string): string {\n const input = `${provider}:${providerUserId}`;\n return createHash('sha256').update(input).digest('hex').slice(0, 24);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.module.js","sourceRoot":"","sources":["../../src/mcp/mcp.module.ts"],"names":[],"mappings":"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","sourcesContent":["import { DynamicModule, Module, Provider, Type } from '@nestjs/common';\nimport { DiscoveryModule } from '@nestjs/core';\nimport { McpTransportType } from './interfaces';\nimport type {\n McpOptions,\n McpModuleAsyncOptions,\n McpOptionsFactory,\n McpAsyncOptions,\n} from './interfaces';\nimport { McpExecutorService } from './services/mcp-executor.service';\nimport { McpRegistryService } from './services/mcp-registry.service';\nimport { McpSseService } from './services/mcp-sse.service';\nimport { McpStreamableHttpService } from './services/mcp-streamable-http.service';\nimport { SsePingService } from './services/sse-ping.service';\nimport { createSseController } from './transport/sse.controller.factory';\nimport { StdioService } from './transport/stdio.service';\nimport { createStreamableHttpController } from './transport/streamable-http.controller.factory';\nimport { normalizeEndpoint } from './utils/normalize-endpoint';\n\nlet instanceIdCounter = 0;\n\n@Module({\n imports: [DiscoveryModule],\n providers: [McpRegistryService, McpExecutorService],\n})\nexport class McpModule {\n /**\n * To avoid import circular dependency issues, we use a marker property.\n */\n readonly __isMcpModule = true;\n\n static forRoot(options: McpOptions): DynamicModule {\n const defaultOptions: Partial<McpOptions> = {\n transport: [\n McpTransportType.SSE,\n McpTransportType.STREAMABLE_HTTP,\n McpTransportType.STDIO,\n ],\n sseEndpoint: 'sse',\n messagesEndpoint: 'messages',\n mcpEndpoint: 'mcp',\n guards: [],\n decorators: [],\n streamableHttp: {\n enableJsonResponse: true,\n sessionIdGenerator: undefined,\n statelessMode: true,\n },\n sse: {\n pingEnabled: true,\n pingIntervalMs: 30000,\n },\n };\n const mergedOptions = { ...defaultOptions, ...options } as McpOptions;\n mergedOptions.sseEndpoint = normalizeEndpoint(mergedOptions.sseEndpoint);\n mergedOptions.messagesEndpoint = normalizeEndpoint(\n mergedOptions.messagesEndpoint,\n );\n mergedOptions.mcpEndpoint = normalizeEndpoint(mergedOptions.mcpEndpoint);\n\n const moduleId = `mcp-module-${instanceIdCounter++}`;\n const providers = this.createProvidersFromOptions(mergedOptions, moduleId);\n const controllers = this.createControllersFromOptions(mergedOptions);\n return {\n module: McpModule,\n controllers,\n providers,\n exports: [McpRegistryService, McpSseService, McpStreamableHttpService],\n };\n }\n\n /**\n * Asynchronous variant of forRoot. Controllers are NOT auto-registered here because\n * they must be declared synchronously at module definition time. This keeps the\n * API explicit: when using forRootAsync, you are responsible for creating and\n * registering any transport controllers (e.g. via createSseController / createStreamableHttpController).\n *\n * The exposed async options intentionally omit the `transport` property. Transport\n * selection only influences automatic controller creation (which does not occur here)\n * and STDIO auto-start. If you need STDIO with forRootAsync, manually instantiate\n * and bootstrap it (e.g. by importing a module that injects StdioService) or add\n * an explicit provider that sets options.transport before use.\n */\n static forRootAsync(options: McpModuleAsyncOptions): DynamicModule {\n const moduleId = `mcp-module-${instanceIdCounter++}`;\n const asyncProviders = this.createAsyncProviders(options);\n const baseProviders: Provider[] = [\n {\n provide: 'MCP_MODULE_ID',\n useValue: moduleId,\n },\n McpRegistryService,\n McpExecutorService,\n SsePingService,\n McpSseService,\n McpStreamableHttpService,\n StdioService,\n ];\n\n return {\n module: McpModule,\n imports: options.imports ?? [],\n // No automatic controllers in async mode\n controllers: [],\n providers: [\n ...asyncProviders,\n ...baseProviders,\n ...(options.extraProviders ?? []),\n ],\n exports: [McpRegistryService, McpSseService, McpStreamableHttpService],\n };\n }\n\n private static createAsyncProviders(\n options: McpModuleAsyncOptions,\n ): Provider[] {\n if (options.useFactory) {\n return [\n {\n provide: 'MCP_OPTIONS',\n useFactory: async (...args: any[]) => {\n const resolved: McpAsyncOptions = await options.useFactory!(\n ...args,\n );\n return this.mergeAndNormalizeAsyncOptions(resolved);\n },\n inject: options.inject ?? [],\n },\n ];\n }\n\n // useClass / useExisting path\n const inject: any[] = [];\n let optionsFactoryProvider: Provider | undefined;\n\n if (options.useExisting || options.useClass) {\n const useExisting = options.useExisting || options.useClass!;\n inject.push(useExisting);\n if (options.useClass) {\n optionsFactoryProvider = {\n provide: options.useClass,\n useClass: options.useClass,\n } as Provider;\n }\n\n return [\n ...(optionsFactoryProvider ? [optionsFactoryProvider] : []),\n {\n provide: 'MCP_OPTIONS',\n useFactory: async (factory: McpOptionsFactory) => {\n const resolved = await factory.createMcpOptions();\n return this.mergeAndNormalizeAsyncOptions(resolved);\n },\n inject,\n },\n ];\n }\n\n throw new Error('Invalid McpModuleAsyncOptions configuration.');\n }\n\n private static mergeAndNormalizeAsyncOptions(\n resolved: McpAsyncOptions,\n ): McpOptions {\n const defaultOptions: Partial<McpOptions> = {\n sseEndpoint: 'sse',\n messagesEndpoint: 'messages',\n mcpEndpoint: 'mcp',\n guards: [],\n decorators: [],\n streamableHttp: {\n enableJsonResponse: true,\n sessionIdGenerator: undefined,\n statelessMode: true,\n },\n sse: {\n pingEnabled: true,\n pingIntervalMs: 30000,\n },\n };\n // Note: transport intentionally omitted\n const merged = { ...defaultOptions, ...resolved } as McpOptions;\n merged.sseEndpoint = normalizeEndpoint(merged.sseEndpoint);\n merged.messagesEndpoint = normalizeEndpoint(merged.messagesEndpoint);\n merged.mcpEndpoint = normalizeEndpoint(merged.mcpEndpoint);\n return merged;\n }\n\n private static createControllersFromOptions(\n options: McpOptions,\n ): Type<any>[] {\n const sseEndpoint = options.sseEndpoint ?? 'sse';\n const messagesEndpoint = options.messagesEndpoint ?? 'messages';\n const mcpEndpoint = options.mcpEndpoint ?? 'mcp';\n const guards = options.guards ?? [];\n const transports = Array.isArray(options.transport)\n ? options.transport\n : [options.transport ?? McpTransportType.SSE];\n const controllers: Type<any>[] = [];\n const decorators = options.decorators ?? [];\n const apiPrefix = options.apiPrefix ?? '';\n\n if (transports.includes(McpTransportType.SSE)) {\n const sseController = createSseController(\n sseEndpoint,\n messagesEndpoint,\n apiPrefix,\n guards,\n decorators,\n );\n controllers.push(sseController);\n }\n\n if (transports.includes(McpTransportType.STREAMABLE_HTTP)) {\n const streamableHttpController = createStreamableHttpController(\n mcpEndpoint,\n apiPrefix,\n guards,\n decorators,\n );\n controllers.push(streamableHttpController);\n }\n\n if (transports.includes(McpTransportType.STDIO)) {\n // STDIO transport is handled by injectable StdioService, no controller\n }\n\n return controllers;\n }\n\n private static createProvidersFromOptions(\n options: McpOptions,\n moduleId: string,\n ): Provider[] {\n const providers: Provider[] = [\n {\n provide: 'MCP_OPTIONS',\n useValue: options,\n },\n {\n provide: 'MCP_MODULE_ID',\n useValue: moduleId,\n },\n McpRegistryService,\n McpExecutorService,\n SsePingService,\n McpSseService,\n McpStreamableHttpService,\n StdioService,\n ];\n\n return providers;\n }\n}\n"]}
1
+ {"version":3,"file":"mcp.module.js","sourceRoot":"","sources":["../../src/mcp/mcp.module.ts"],"names":[],"mappings":"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","sourcesContent":["import { DynamicModule, Module, Provider, Type } from '@nestjs/common';\nimport { DiscoveryModule } from '@nestjs/core';\nimport { McpTransportType } from './interfaces';\nimport type {\n McpOptions,\n McpModuleAsyncOptions,\n McpOptionsFactory,\n McpAsyncOptions,\n} from './interfaces';\nimport { McpExecutorService } from './services/mcp-executor.service';\nimport { McpRegistryService } from './services/mcp-registry.service';\nimport { McpSseService } from './services/mcp-sse.service';\nimport { McpStreamableHttpService } from './services/mcp-streamable-http.service';\nimport { SsePingService } from './services/sse-ping.service';\nimport { createSseController } from './transport/sse.controller.factory';\nimport { StdioService } from './transport/stdio.service';\nimport { createStreamableHttpController } from './transport/streamable-http.controller.factory';\nimport { normalizeEndpoint } from './utils/normalize-endpoint';\n\nlet instanceIdCounter = 0;\n\n@Module({\n imports: [DiscoveryModule],\n providers: [McpRegistryService, McpExecutorService],\n})\nexport class McpModule {\n /**\n * To avoid import circular dependency issues, we use a marker property.\n */\n readonly __isMcpModule = true;\n\n static forRoot(options: McpOptions): DynamicModule {\n const defaultOptions: Partial<McpOptions> = {\n transport: [\n McpTransportType.SSE,\n McpTransportType.STREAMABLE_HTTP,\n McpTransportType.STDIO,\n ],\n sseEndpoint: 'sse',\n messagesEndpoint: 'messages',\n mcpEndpoint: 'mcp',\n guards: [],\n decorators: [],\n streamableHttp: {\n enableJsonResponse: true,\n sessionIdGenerator: undefined,\n statelessMode: true,\n },\n sse: {\n pingEnabled: true,\n pingIntervalMs: 30000,\n },\n };\n const mergedOptions = { ...defaultOptions, ...options } as McpOptions;\n mergedOptions.sseEndpoint = normalizeEndpoint(mergedOptions.sseEndpoint);\n mergedOptions.messagesEndpoint = normalizeEndpoint(\n mergedOptions.messagesEndpoint,\n );\n mergedOptions.mcpEndpoint = normalizeEndpoint(mergedOptions.mcpEndpoint);\n\n const moduleId = `mcp-module-${instanceIdCounter++}`;\n const providers = this.createProvidersFromOptions(mergedOptions, moduleId);\n const controllers = this.createControllersFromOptions(mergedOptions);\n return {\n module: McpModule,\n controllers,\n providers,\n exports: [McpRegistryService, McpSseService, McpStreamableHttpService],\n };\n }\n\n /**\n * Asynchronous variant of forRoot. Controllers are NOT auto-registered here because\n * they must be declared synchronously at module definition time. This keeps the\n * API explicit: when using forRootAsync, you are responsible for creating and\n * registering any transport controllers (e.g. via createSseController / createStreamableHttpController).\n *\n * The exposed async options intentionally omit the `transport` property. Transport\n * selection only influences automatic controller creation (which does not occur here)\n * and STDIO auto-start. If you need STDIO with forRootAsync, manually instantiate\n * and bootstrap it (e.g. by importing a module that injects StdioService) or add\n * an explicit provider that sets options.transport before use.\n */\n static forRootAsync(options: McpModuleAsyncOptions): DynamicModule {\n const moduleId = `mcp-module-${instanceIdCounter++}`;\n const asyncProviders = this.createAsyncProviders(options);\n const baseProviders: Provider[] = [\n {\n provide: 'MCP_MODULE_ID',\n useValue: moduleId,\n },\n McpRegistryService,\n McpExecutorService,\n SsePingService,\n McpSseService,\n McpStreamableHttpService,\n StdioService,\n ];\n\n return {\n module: McpModule,\n imports: options.imports ?? [],\n // No automatic controllers in async mode\n controllers: [],\n providers: [\n ...asyncProviders,\n ...baseProviders,\n ...(options.extraProviders ?? []),\n ],\n exports: [McpRegistryService, McpSseService, McpStreamableHttpService],\n };\n }\n\n private static createAsyncProviders(\n options: McpModuleAsyncOptions,\n ): Provider[] {\n if (options.useFactory) {\n return [\n {\n provide: 'MCP_OPTIONS',\n useFactory: async (...args: unknown[]) => {\n const resolved: McpAsyncOptions = await options.useFactory!(\n ...args,\n );\n return this.mergeAndNormalizeAsyncOptions(resolved);\n },\n inject: options.inject ?? [],\n },\n ];\n }\n\n // useClass / useExisting path\n const inject: any[] = [];\n let optionsFactoryProvider: Provider | undefined;\n\n if (options.useExisting || options.useClass) {\n const useExisting = options.useExisting || options.useClass!;\n inject.push(useExisting);\n if (options.useClass) {\n optionsFactoryProvider = {\n provide: options.useClass,\n useClass: options.useClass,\n } as Provider;\n }\n\n return [\n ...(optionsFactoryProvider ? [optionsFactoryProvider] : []),\n {\n provide: 'MCP_OPTIONS',\n useFactory: async (factory: McpOptionsFactory) => {\n const resolved = await factory.createMcpOptions();\n return this.mergeAndNormalizeAsyncOptions(resolved);\n },\n inject,\n },\n ];\n }\n\n throw new Error('Invalid McpModuleAsyncOptions configuration.');\n }\n\n private static mergeAndNormalizeAsyncOptions(\n resolved: McpAsyncOptions,\n ): McpOptions {\n const defaultOptions: Partial<McpOptions> = {\n sseEndpoint: 'sse',\n messagesEndpoint: 'messages',\n mcpEndpoint: 'mcp',\n guards: [],\n decorators: [],\n streamableHttp: {\n enableJsonResponse: true,\n sessionIdGenerator: undefined,\n statelessMode: true,\n },\n sse: {\n pingEnabled: true,\n pingIntervalMs: 30000,\n },\n };\n // Note: transport intentionally omitted\n const merged = { ...defaultOptions, ...resolved } as McpOptions;\n merged.sseEndpoint = normalizeEndpoint(merged.sseEndpoint);\n merged.messagesEndpoint = normalizeEndpoint(merged.messagesEndpoint);\n merged.mcpEndpoint = normalizeEndpoint(merged.mcpEndpoint);\n return merged;\n }\n\n private static createControllersFromOptions(\n options: McpOptions,\n ): Type<any>[] {\n const sseEndpoint = options.sseEndpoint ?? 'sse';\n const messagesEndpoint = options.messagesEndpoint ?? 'messages';\n const mcpEndpoint = options.mcpEndpoint ?? 'mcp';\n const guards = options.guards ?? [];\n const transports = Array.isArray(options.transport)\n ? options.transport\n : [options.transport ?? McpTransportType.SSE];\n const controllers: Type<any>[] = [];\n const decorators = options.decorators ?? [];\n const apiPrefix = options.apiPrefix ?? '';\n\n if (transports.includes(McpTransportType.SSE)) {\n const sseController = createSseController(\n sseEndpoint,\n messagesEndpoint,\n apiPrefix,\n guards,\n decorators,\n );\n controllers.push(sseController);\n }\n\n if (transports.includes(McpTransportType.STREAMABLE_HTTP)) {\n const streamableHttpController = createStreamableHttpController(\n mcpEndpoint,\n apiPrefix,\n guards,\n decorators,\n );\n controllers.push(streamableHttpController);\n }\n\n if (transports.includes(McpTransportType.STDIO)) {\n // STDIO transport is handled by injectable StdioService, no controller\n }\n\n return controllers;\n }\n\n private static createProvidersFromOptions(\n options: McpOptions,\n moduleId: string,\n ): Provider[] {\n const providers: Provider[] = [\n {\n provide: 'MCP_OPTIONS',\n useValue: options,\n },\n {\n provide: 'MCP_MODULE_ID',\n useValue: moduleId,\n },\n McpRegistryService,\n McpExecutorService,\n SsePingService,\n McpSseService,\n McpStreamableHttpService,\n StdioService,\n ];\n\n return providers;\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { ApplicationConfig, ModuleRef } from '@nestjs/core';
2
- import type { McpOptions } from '../interfaces';
2
+ import { McpOptions } from '../interfaces';
3
3
  import { McpRegistryService } from './mcp-registry.service';
4
4
  import { SsePingService } from './sse-ping.service';
5
5
  export declare class McpSseService {
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-sse.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp-sse.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD,qBACa,aAAa;IAWC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IACrD,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IACL,OAAO,CAAC,QAAQ,CAAC,WAAW;IAftD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IAKzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyC;IAEpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;gBAGjB,OAAO,EAAE,UAAU,EACjB,WAAW,EAAE,MAAM,EAC5C,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,kBAAkB,EACR,WAAW,EAAE,cAAc;IAMtE,UAAU;IAWJ,mBAAmB,CACvB,MAAM,EAAE,GAAG,EACX,MAAM,EAAE,GAAG,EACX,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAkDV,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;CA6B3E"}
1
+ {"version":3,"file":"mcp-sse.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp-sse.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD,qBACa,aAAa;IAWC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IACrD,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IACL,OAAO,CAAC,QAAQ,CAAC,WAAW;IAftD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IAKzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyC;IAEpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;gBAGjB,OAAO,EAAE,UAAU,EACjB,WAAW,EAAE,MAAM,EAC5C,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,kBAAkB,EACR,WAAW,EAAE,cAAc;IAMtE,UAAU;IAWJ,mBAAmB,CACvB,MAAM,EAAE,GAAG,EACX,MAAM,EAAE,GAAG,EACX,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAkDV,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;CA6B3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-sse.service.js","sourceRoot":"","sources":["../../../src/mcp/services/mcp-sse.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAA4D;AAC5D,uCAA8E;AAC9E,oEAAoE;AACpE,oEAA6E;AAC7E,wEAAqE;AAErE,iEAA4D;AAC5D,iEAA4D;AAC5D,yDAAoD;AACpD,oEAAgE;AAChE,0CAAiD;AAG1C,IAAM,aAAa,qBAAnB,MAAM,aAAa;IAUxB,YACyB,OAAoC,EAClC,WAAoC,EAC5C,iBAAoC,EACpC,SAAoB,EACpB,YAAgC,EACzB,WAA4C;QAL5B,YAAO,GAAP,OAAO,CAAY;QACjB,gBAAW,GAAX,WAAW,CAAQ;QAC5C,sBAAiB,GAAjB,iBAAiB,CAAmB;QACpC,cAAS,GAAT,SAAS,CAAW;QACpB,iBAAY,GAAZ,YAAY,CAAoB;QACR,gBAAW,GAAX,WAAW,CAAgB;QAfrD,WAAM,GAAG,IAAI,eAAM,CAAC,eAAa,CAAC,IAAI,CAAC,CAAC;QAKxC,eAAU,GAAG,IAAI,GAAG,EAA8B,CAAC;QAEnD,eAAU,GAAG,IAAI,GAAG,EAAqB,CAAC;IASxD,CAAC;IAKJ,UAAU;QAER,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;YACzB,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW;YAC1C,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,cAAc;SACjD,CAAC,CAAC;IACL,CAAC;IAKD,KAAK,CAAC,mBAAmB,CACvB,MAAW,EACX,MAAW,EACX,gBAAwB,EACxB,SAAiB;QAEjB,MAAM,OAAO,GAAG,6BAAkB,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAG1C,MAAM,SAAS,GAAG,IAAI,2BAAkB,CACtC,IAAA,sCAAiB,EACf,GAAG,SAAS,IAAI,IAAI,CAAC,iBAAiB,CAAC,eAAe,EAAE,IAAI,gBAAgB,EAAE,CAC/E,EACD,GAAG,CAAC,GAAG,CACR,CAAC;QACF,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;QAGtC,MAAM,YAAY,GAAG,IAAA,2CAAoB,EACvC,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,OAAO,CACb,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,YAAY,CAAC,CAAC;QAG3D,MAAM,SAAS,GAAG,IAAI,kBAAS,CAC7B,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAC1D;YACE,YAAY;YACZ,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE;SAC9C,CACF,CAAC;QAGF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAG1C,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QAE/D,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;YAEvB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAClC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAClC,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC,CAAC;QAEF,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IAKD,KAAK,CAAC,aAAa,CAAC,MAAW,EAAE,MAAW,EAAE,IAAa;QACzD,MAAM,OAAO,GAAG,6BAAkB,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,SAAmB,CAAC;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEjD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAClE,CAAC;QAGD,MAAM,SAAS,GAAG,uBAAgB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAC3C,yCAAkB,EAClB,SAAS,CACV,CAAC;QAGF,QAAQ,CAAC,uBAAuB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAGjD,MAAM,SAAS,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5D,CAAC;CACF,CAAA;AArHY,sCAAa;wBAAb,aAAa;IADzB,IAAA,mBAAU,GAAE;IAYR,WAAA,IAAA,eAAM,EAAC,aAAa,CAAC,CAAA;IACrB,WAAA,IAAA,eAAM,EAAC,eAAe,CAAC,CAAA;IAIvB,WAAA,IAAA,eAAM,EAAC,iCAAc,CAAC,CAAA;qDAHa,wBAAiB;QACzB,gBAAS;QACN,yCAAkB;QACK,iCAAc;GAhB3D,aAAa,CAqHzB","sourcesContent":["import { Inject, Injectable, Logger } from '@nestjs/common';\nimport { ApplicationConfig, ContextIdFactory, ModuleRef } from '@nestjs/core';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';\nimport { buildMcpCapabilities } from '../utils/capabilities-builder';\nimport type { McpOptions } from '../interfaces';\nimport { McpExecutorService } from './mcp-executor.service';\nimport { McpRegistryService } from './mcp-registry.service';\nimport { SsePingService } from './sse-ping.service';\nimport { normalizeEndpoint } from '../utils/normalize-endpoint';\nimport { HttpAdapterFactory } from '../adapters';\n\n@Injectable()\nexport class McpSseService {\n private readonly logger = new Logger(McpSseService.name);\n\n // Note: Currently, storing transports and servers makes it a requirement to have sticky sessions.\n\n // Map to store active transports by session ID\n private readonly transports = new Map<string, SSEServerTransport>();\n // Map to store MCP server instances by session ID\n private readonly mcpServers = new Map<string, McpServer>();\n\n constructor(\n @Inject('MCP_OPTIONS') private readonly options: McpOptions,\n @Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,\n private readonly applicationConfig: ApplicationConfig,\n private readonly moduleRef: ModuleRef,\n private readonly toolRegistry: McpRegistryService,\n @Inject(SsePingService) private readonly pingService: SsePingService,\n ) {}\n\n /**\n * Initialize the SSE service and configure ping service\n */\n initialize() {\n // Configure ping service with options\n this.pingService.configure({\n pingEnabled: this.options.sse?.pingEnabled, // Enable by default\n pingIntervalMs: this.options.sse?.pingIntervalMs,\n });\n }\n\n /**\n * Create and manage SSE connection\n */\n async createSseConnection(\n rawReq: any,\n rawRes: any,\n messagesEndpoint: string,\n apiPrefix: string,\n ): Promise<void> {\n const adapter = HttpAdapterFactory.getAdapter(rawReq, rawRes);\n const res = adapter.adaptResponse(rawRes);\n\n // Create a new SSE transport instance\n const transport = new SSEServerTransport(\n normalizeEndpoint(\n `${apiPrefix}/${this.applicationConfig.getGlobalPrefix()}/${messagesEndpoint}`,\n ),\n res.raw,\n );\n const sessionId = transport.sessionId;\n\n // Create a new MCP server instance with dynamic capabilities\n const capabilities = buildMcpCapabilities(\n this.mcpModuleId,\n this.toolRegistry,\n this.options,\n );\n this.logger.debug('Built MCP capabilities:', capabilities);\n\n // Create a new MCP server for this session with dynamic capabilities\n const mcpServer = new McpServer(\n { name: this.options.name, version: this.options.version },\n {\n capabilities,\n instructions: this.options.instructions || '',\n },\n );\n\n // Store the transport and server for this session\n this.transports.set(sessionId, transport);\n this.mcpServers.set(sessionId, mcpServer);\n\n // Register the connection with the ping service\n this.pingService.registerConnection(sessionId, transport, res);\n\n transport.onclose = () => {\n // Clean up when the connection closes\n this.transports.delete(sessionId);\n this.mcpServers.delete(sessionId);\n this.pingService.removeConnection(sessionId);\n };\n\n await mcpServer.connect(transport);\n }\n\n /**\n * Handle message processing for SSE\n */\n async handleMessage(rawReq: any, rawRes: any, body: unknown): Promise<any> {\n const adapter = HttpAdapterFactory.getAdapter(rawReq, rawRes);\n const req = adapter.adaptRequest(rawReq);\n const res = adapter.adaptResponse(rawRes);\n const sessionId = req.query.sessionId as string;\n const transport = this.transports.get(sessionId);\n\n if (!transport) {\n return res.status(404).send('Session not found');\n }\n\n const mcpServer = this.mcpServers.get(sessionId);\n if (!mcpServer) {\n return res.status(404).send('MCP server not found for session');\n }\n\n // Resolve the request-scoped tool executor service\n const contextId = ContextIdFactory.getByRequest(req);\n const executor = await this.moduleRef.resolve(\n McpExecutorService,\n contextId,\n );\n\n // Register request handlers with the user context from this specific request\n executor.registerRequestHandlers(mcpServer, req);\n\n // Process the message\n await transport.handlePostMessage(req.raw, res.raw, body);\n }\n}\n"]}
1
+ {"version":3,"file":"mcp-sse.service.js","sourceRoot":"","sources":["../../../src/mcp/services/mcp-sse.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable, Logger } from '@nestjs/common';\nimport { ApplicationConfig, ContextIdFactory, ModuleRef } from '@nestjs/core';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';\nimport { buildMcpCapabilities } from '../utils/capabilities-builder';\nimport { McpOptions } from '../interfaces';\nimport { McpExecutorService } from './mcp-executor.service';\nimport { McpRegistryService } from './mcp-registry.service';\nimport { SsePingService } from './sse-ping.service';\nimport { normalizeEndpoint } from '../utils/normalize-endpoint';\nimport { HttpAdapterFactory } from '../adapters';\n\n@Injectable()\nexport class McpSseService {\n private readonly logger = new Logger(McpSseService.name);\n\n // Note: Currently, storing transports and servers makes it a requirement to have sticky sessions.\n\n // Map to store active transports by session ID\n private readonly transports = new Map<string, SSEServerTransport>();\n // Map to store MCP server instances by session ID\n private readonly mcpServers = new Map<string, McpServer>();\n\n constructor(\n @Inject('MCP_OPTIONS') private readonly options: McpOptions,\n @Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,\n private readonly applicationConfig: ApplicationConfig,\n private readonly moduleRef: ModuleRef,\n private readonly toolRegistry: McpRegistryService,\n @Inject(SsePingService) private readonly pingService: SsePingService,\n ) {}\n\n /**\n * Initialize the SSE service and configure ping service\n */\n initialize() {\n // Configure ping service with options\n this.pingService.configure({\n pingEnabled: this.options.sse?.pingEnabled, // Enable by default\n pingIntervalMs: this.options.sse?.pingIntervalMs,\n });\n }\n\n /**\n * Create and manage SSE connection\n */\n async createSseConnection(\n rawReq: any,\n rawRes: any,\n messagesEndpoint: string,\n apiPrefix: string,\n ): Promise<void> {\n const adapter = HttpAdapterFactory.getAdapter(rawReq, rawRes);\n const res = adapter.adaptResponse(rawRes);\n\n // Create a new SSE transport instance\n const transport = new SSEServerTransport(\n normalizeEndpoint(\n `${apiPrefix}/${this.applicationConfig.getGlobalPrefix()}/${messagesEndpoint}`,\n ),\n res.raw,\n );\n const sessionId = transport.sessionId;\n\n // Create a new MCP server instance with dynamic capabilities\n const capabilities = buildMcpCapabilities(\n this.mcpModuleId,\n this.toolRegistry,\n this.options,\n );\n this.logger.debug('Built MCP capabilities:', capabilities);\n\n // Create a new MCP server for this session with dynamic capabilities\n const mcpServer = new McpServer(\n { name: this.options.name, version: this.options.version },\n {\n capabilities,\n instructions: this.options.instructions || '',\n },\n );\n\n // Store the transport and server for this session\n this.transports.set(sessionId, transport);\n this.mcpServers.set(sessionId, mcpServer);\n\n // Register the connection with the ping service\n this.pingService.registerConnection(sessionId, transport, res);\n\n transport.onclose = () => {\n // Clean up when the connection closes\n this.transports.delete(sessionId);\n this.mcpServers.delete(sessionId);\n this.pingService.removeConnection(sessionId);\n };\n\n await mcpServer.connect(transport);\n }\n\n /**\n * Handle message processing for SSE\n */\n async handleMessage(rawReq: any, rawRes: any, body: unknown): Promise<any> {\n const adapter = HttpAdapterFactory.getAdapter(rawReq, rawRes);\n const req = adapter.adaptRequest(rawReq);\n const res = adapter.adaptResponse(rawRes);\n const sessionId = req.query.sessionId as string;\n const transport = this.transports.get(sessionId);\n\n if (!transport) {\n return res.status(404).send('Session not found');\n }\n\n const mcpServer = this.mcpServers.get(sessionId);\n if (!mcpServer) {\n return res.status(404).send('MCP server not found for session');\n }\n\n // Resolve the request-scoped tool executor service\n const contextId = ContextIdFactory.getByRequest(req);\n const executor = await this.moduleRef.resolve(\n McpExecutorService,\n contextId,\n );\n\n // Register request handlers with the user context from this specific request\n executor.registerRequestHandlers(mcpServer, req);\n\n // Process the message\n await transport.handlePostMessage(req.raw, res.raw, body);\n }\n}\n"]}
@@ -2,7 +2,7 @@ import { ModuleRef } from '@nestjs/core';
2
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
4
4
  import { HttpRequest, HttpResponse } from '../interfaces/http-adapter.interface';
5
- import type { McpOptions } from '../interfaces';
5
+ import { McpOptions } from '../interfaces';
6
6
  import { McpRegistryService } from './mcp-registry.service';
7
7
  export declare class McpStreamableHttpService {
8
8
  private readonly options;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-streamable-http.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp-streamable-http.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAEnG,OAAO,EACL,WAAW,EACX,YAAY,EACb,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,qBACa,wBAAwB;IASV,OAAO,CAAC,QAAQ,CAAC,OAAO;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAX/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6C;IACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAEpB;IACP,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;IACrE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;gBAGA,OAAO,EAAE,UAAU,EACjB,WAAW,EAAE,MAAM,EAC5C,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,kBAAkB;IAS7C,qBAAqB,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC;QAChD,MAAM,EAAE,SAAS,CAAC;QAClB,SAAS,EAAE,6BAA6B,CAAC;KAC1C,CAAC;IA6CI,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCnE,sBAAsB,CAC1B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,IAAI,CAAC;IAqCV,qBAAqB,CACzB,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,IAAI,CAAC;IAwHV,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCnD,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAkC5D,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAmB3C,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAOxC"}
1
+ {"version":3,"file":"mcp-streamable-http.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp-streamable-http.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAEnG,OAAO,EACL,WAAW,EACX,YAAY,EACb,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,qBACa,wBAAwB;IASV,OAAO,CAAC,QAAQ,CAAC,OAAO;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAX/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6C;IACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAEpB;IACP,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;IACrE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;gBAGA,OAAO,EAAE,UAAU,EACjB,WAAW,EAAE,MAAM,EAC5C,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,kBAAkB;IAS7C,qBAAqB,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC;QAChD,MAAM,EAAE,SAAS,CAAC;QAClB,SAAS,EAAE,6BAA6B,CAAC;KAC1C,CAAC;IA6CI,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCnE,sBAAsB,CAC1B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,IAAI,CAAC;IAqCV,qBAAqB,CACzB,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,IAAI,CAAC;IAwHV,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCnD,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAkC5D,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAmB3C,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAOxC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-streamable-http.service.js","sourceRoot":"","sources":["../../../src/mcp/services/mcp-streamable-http.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable, Logger } from '@nestjs/common';\nimport { ContextIdFactory, ModuleRef } from '@nestjs/core';\nimport { randomUUID } from 'crypto';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { HttpAdapterFactory } from '../adapters/http-adapter.factory';\nimport {\n HttpRequest,\n HttpResponse,\n} from '../interfaces/http-adapter.interface';\nimport type { McpOptions } from '../interfaces';\nimport { McpExecutorService } from './mcp-executor.service';\nimport { McpRegistryService } from './mcp-registry.service';\nimport { buildMcpCapabilities } from '../utils/capabilities-builder';\n\n@Injectable()\nexport class McpStreamableHttpService {\n private readonly logger = new Logger(McpStreamableHttpService.name);\n private readonly transports: {\n [sessionId: string]: StreamableHTTPServerTransport;\n } = {};\n private readonly mcpServers: { [sessionId: string]: McpServer } = {};\n private readonly isStatelessMode: boolean;\n\n constructor(\n @Inject('MCP_OPTIONS') private readonly options: McpOptions,\n @Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,\n private readonly moduleRef: ModuleRef,\n private readonly toolRegistry: McpRegistryService,\n ) {\n // Determine if we're in stateless mode\n this.isStatelessMode = !!options.streamableHttp?.statelessMode;\n }\n\n /**\n * Create a new MCP server instance for stateless requests\n */\n async createStatelessServer(rawReq: any): Promise<{\n server: McpServer;\n transport: StreamableHTTPServerTransport;\n }> {\n // Create a new transport for this request\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n enableJsonResponse:\n this.options.streamableHttp?.enableJsonResponse || false,\n });\n\n // Create a new MCP server instance with dynamic capabilities\n const capabilities = buildMcpCapabilities(\n this.mcpModuleId,\n this.toolRegistry,\n this.options,\n );\n this.logger.debug('Built MCP capabilities:', capabilities);\n\n const server = new McpServer(\n { name: this.options.name, version: this.options.version },\n {\n capabilities: capabilities,\n instructions: this.options.instructions || '',\n },\n );\n\n // Connect the transport to the MCP server first\n await server.connect(transport);\n\n // Now resolve the request-scoped tool executor service\n const contextId = ContextIdFactory.getByRequest(rawReq);\n const executor = await this.moduleRef.resolve(\n McpExecutorService,\n contextId,\n { strict: true },\n );\n\n // Register request handlers after connection\n this.logger.debug('Registering request handlers for stateless MCP server');\n executor.registerRequestHandlers(server, rawReq);\n\n return { server, transport };\n }\n\n /**\n * Handle POST requests\n */\n async handlePostRequest(req: any, res: any, body: unknown): Promise<void> {\n this.logger.debug('Received MCP request:', body);\n\n // Get the appropriate HTTP adapter for the request/response\n const adapter = HttpAdapterFactory.getAdapter(req, res);\n const adaptedReq = adapter.adaptRequest(req);\n const adaptedRes = adapter.adaptResponse(res);\n\n try {\n if (this.isStatelessMode) {\n return this.handleStatelessRequest(adaptedReq, adaptedRes, body);\n } else {\n return this.handleStatefulRequest(adaptedReq, adaptedRes, body);\n }\n } catch (error) {\n this.logger.error('Error handling MCP request:', error);\n if (!adaptedRes.headersSent) {\n adaptedRes.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n\n /**\n * Handle requests in stateless mode\n */\n async handleStatelessRequest(\n req: any,\n res: HttpResponse,\n body: unknown,\n ): Promise<void> {\n this.logger.debug(\n `Handling stateless MCP request at ${req.url} with body: ${JSON.stringify(\n body,\n )}`,\n );\n\n let server: McpServer | null = null;\n let transport: StreamableHTTPServerTransport | null = null;\n\n try {\n // Create a new server and transport for each request\n const stateless = await this.createStatelessServer(req);\n server = stateless.server;\n transport = stateless.transport;\n\n // Handle the request\n await transport.handleRequest(req.raw, res.raw, body);\n\n // Clean up when the response closes\n res.on?.('close', () => {\n this.logger.debug('Stateless request closed, cleaning up');\n void transport?.close();\n void server?.close();\n });\n } catch (error) {\n this.logger.error('Error in stateless request handling:', error);\n // Clean up on error\n void transport?.close();\n void server?.close();\n throw error;\n }\n }\n\n /**\n * Handle requests in stateful mode\n */\n async handleStatefulRequest(\n req: HttpRequest,\n res: HttpResponse,\n body: unknown,\n ): Promise<void> {\n this.logger.debug(\n `Handling stateful MCP request at ${req.url} with body: ${JSON.stringify(\n body,\n )}`,\n );\n // Check for existing session ID\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n let transport: StreamableHTTPServerTransport;\n\n if (sessionId && this.transports[sessionId]) {\n // Reuse existing transport\n transport = this.transports[sessionId];\n } else if (!sessionId && this.isInitializeRequest(body)) {\n // New initialization request\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator:\n this.options.streamableHttp?.sessionIdGenerator ||\n (() => randomUUID()),\n enableJsonResponse:\n this.options.streamableHttp?.enableJsonResponse || false,\n onsessioninitialized: (sessionId: string) => {\n this.logger.debug(`Session initialized: ${sessionId}`);\n this.transports[sessionId] = transport;\n },\n });\n\n // Create a new MCP server for this session with dynamic capabilities\n const capabilities = buildMcpCapabilities(\n this.mcpModuleId,\n this.toolRegistry,\n this.options,\n );\n this.logger.debug('Built MCP capabilities:', capabilities);\n\n const mcpServer = new McpServer(\n { name: this.options.name, version: this.options.version },\n {\n capabilities,\n instructions: this.options.instructions || '',\n },\n );\n\n // Connect the transport to the MCP server BEFORE handling the request\n await mcpServer.connect(transport);\n\n // Handle the initialization request\n await transport.handleRequest(req.raw, res.raw, body);\n\n // Store the transport and server by session ID for future requests\n if (transport.sessionId) {\n this.transports[transport.sessionId] = transport;\n this.mcpServers[transport.sessionId] = mcpServer;\n\n // Set up cleanup when connection closes\n transport.onclose = () => {\n this.cleanupSession(transport.sessionId!);\n };\n }\n\n this.logger.log(\n `Initialized new session with ID: ${transport.sessionId}`,\n );\n return;\n } else if (sessionId && !this.transports[sessionId]) {\n // Provided session ID but no matching session exists\n res.status(404).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Session not found',\n },\n id: null,\n });\n return;\n } else {\n // Invalid request - no session ID or not initialization request\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: No valid session ID provided',\n },\n id: null,\n });\n return;\n }\n\n // For subsequent requests to an existing session\n const mcpServer = this.mcpServers[sessionId];\n if (!mcpServer) {\n res.status(404).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Session not found',\n },\n id: null,\n });\n return;\n }\n\n // Resolve the request-scoped tool executor service\n const contextId = ContextIdFactory.getByRequest(req);\n const executor = await this.moduleRef.resolve(\n McpExecutorService,\n contextId,\n { strict: true },\n );\n\n // Register request handlers with the user context from this specific request\n executor.registerRequestHandlers(mcpServer, req);\n\n // Handle the request with existing transport\n await transport.handleRequest(req.raw, res.raw, body);\n }\n\n /**\n * Handle GET requests for SSE streams\n */\n async handleGetRequest(req: any, res: any): Promise<void> {\n // Get the appropriate HTTP adapter for the request/response\n const adapter = HttpAdapterFactory.getAdapter(req, res);\n const adaptedReq = adapter.adaptRequest(req);\n const adaptedRes = adapter.adaptResponse(res);\n\n if (this.isStatelessMode) {\n adaptedRes.status(405).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Method not allowed in stateless mode',\n },\n id: null,\n });\n return;\n }\n\n const sessionId = adaptedReq.headers['mcp-session-id'] as\n | string\n | undefined;\n\n if (!sessionId || !this.transports[sessionId]) {\n adaptedRes.status(400).send('Invalid or missing session ID');\n return;\n }\n\n this.logger.debug(`Establishing SSE stream for session ${sessionId}`);\n const transport = this.transports[sessionId];\n await transport.handleRequest(adaptedReq.raw, adaptedRes.raw);\n }\n\n /**\n * Handle DELETE requests for terminating sessions\n */\n async handleDeleteRequest(req: any, res: any): Promise<void> {\n // Get the appropriate HTTP adapter for the request/response\n const adapter = HttpAdapterFactory.getAdapter(req, res);\n const adaptedReq = adapter.adaptRequest(req);\n const adaptedRes = adapter.adaptResponse(res);\n\n if (this.isStatelessMode) {\n adaptedRes.status(405).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Method not allowed in stateless mode',\n },\n id: null,\n });\n return;\n }\n\n const sessionId = adaptedReq.headers['mcp-session-id'] as\n | string\n | undefined;\n\n if (!sessionId || !this.transports[sessionId]) {\n adaptedRes.status(400).send('Invalid or missing session ID');\n return;\n }\n\n this.logger.debug(`Terminating session ${sessionId}`);\n const transport = this.transports[sessionId];\n await transport.handleRequest(adaptedReq.raw, adaptedRes.raw);\n this.cleanupSession(sessionId);\n }\n\n // Helper function to detect initialize requests\n isInitializeRequest(body: unknown): boolean {\n if (Array.isArray(body)) {\n return body.some(\n (msg) =>\n typeof msg === 'object' &&\n msg !== null &&\n 'method' in msg &&\n msg.method === 'initialize',\n );\n }\n return (\n typeof body === 'object' &&\n body !== null &&\n 'method' in body &&\n body.method === 'initialize'\n );\n }\n\n // Clean up session resources\n cleanupSession(sessionId: string): void {\n if (sessionId) {\n this.logger.debug(`Cleaning up session: ${sessionId}`);\n delete this.transports[sessionId];\n delete this.mcpServers[sessionId];\n }\n }\n}\n"]}
1
+ {"version":3,"file":"mcp-streamable-http.service.js","sourceRoot":"","sources":["../../../src/mcp/services/mcp-streamable-http.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAA4D;AAC5D,uCAA2D;AAC3D,mCAAoC;AACpC,oEAAoE;AACpE,0FAAmG;AACnG,2EAAsE;AAMtE,iEAA4D;AAC5D,iEAA4D;AAC5D,wEAAqE;AAG9D,IAAM,wBAAwB,gCAA9B,MAAM,wBAAwB;IAQnC,YACyB,OAAoC,EAClC,WAAoC,EAC5C,SAAoB,EACpB,YAAgC;QAHT,YAAO,GAAP,OAAO,CAAY;QACjB,gBAAW,GAAX,WAAW,CAAQ;QAC5C,cAAS,GAAT,SAAS,CAAW;QACpB,iBAAY,GAAZ,YAAY,CAAoB;QAXlC,WAAM,GAAG,IAAI,eAAM,CAAC,0BAAwB,CAAC,IAAI,CAAC,CAAC;QACnD,eAAU,GAEvB,EAAE,CAAC;QACU,eAAU,GAAuC,EAAE,CAAC;QAUnE,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,aAAa,CAAC;IACjE,CAAC;IAKD,KAAK,CAAC,qBAAqB,CAAC,MAAW;QAKrC,MAAM,SAAS,GAAG,IAAI,iDAA6B,CAAC;YAClD,kBAAkB,EAAE,SAAS;YAC7B,kBAAkB,EAChB,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,kBAAkB,IAAI,KAAK;SAC3D,CAAC,CAAC;QAGH,MAAM,YAAY,GAAG,IAAA,2CAAoB,EACvC,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,OAAO,CACb,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,YAAY,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,IAAI,kBAAS,CAC1B,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAC1D;YACE,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE;SAC9C,CACF,CAAC;QAGF,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAGhC,MAAM,SAAS,GAAG,uBAAgB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAC3C,yCAAkB,EAClB,SAAS,EACT,EAAE,MAAM,EAAE,IAAI,EAAE,CACjB,CAAC;QAGF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,QAAQ,CAAC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAEjD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;IAKD,KAAK,CAAC,iBAAiB,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAa;QACvD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,IAAI,CAAC,CAAC;QAGjD,MAAM,OAAO,GAAG,yCAAkB,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxD,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAE9C,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;YACnE,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,CAAC,qBAAqB,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACxD,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;gBAC5B,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC1B,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE;wBACL,IAAI,EAAE,CAAC,KAAK;wBACZ,OAAO,EAAE,uBAAuB;qBACjC;oBACD,EAAE,EAAE,IAAI;iBACT,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAKD,KAAK,CAAC,sBAAsB,CAC1B,GAAQ,EACR,GAAiB,EACjB,IAAa;QAEb,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,qCAAqC,GAAG,CAAC,GAAG,eAAe,IAAI,CAAC,SAAS,CACvE,IAAI,CACL,EAAE,CACJ,CAAC;QAEF,IAAI,MAAM,GAAqB,IAAI,CAAC;QACpC,IAAI,SAAS,GAAyC,IAAI,CAAC;QAE3D,IAAI,CAAC;YAEH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;YACxD,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;YAC1B,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;YAGhC,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAGtD,GAAG,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACrB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;gBAC3D,KAAK,SAAS,EAAE,KAAK,EAAE,CAAC;gBACxB,KAAK,MAAM,EAAE,KAAK,EAAE,CAAC;YACvB,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;YAEjE,KAAK,SAAS,EAAE,KAAK,EAAE,CAAC;YACxB,KAAK,MAAM,EAAE,KAAK,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAKD,KAAK,CAAC,qBAAqB,CACzB,GAAgB,EAChB,GAAiB,EACjB,IAAa;QAEb,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,oCAAoC,GAAG,CAAC,GAAG,eAAe,IAAI,CAAC,SAAS,CACtE,IAAI,CACL,EAAE,CACJ,CAAC;QAEF,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;QACtE,IAAI,SAAwC,CAAC;QAE7C,IAAI,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAE5C,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACzC,CAAC;aAAM,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;YAExD,SAAS,GAAG,IAAI,iDAA6B,CAAC;gBAC5C,kBAAkB,EAChB,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,kBAAkB;oBAC/C,CAAC,GAAG,EAAE,CAAC,IAAA,mBAAU,GAAE,CAAC;gBACtB,kBAAkB,EAChB,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,kBAAkB,IAAI,KAAK;gBAC1D,oBAAoB,EAAE,CAAC,SAAiB,EAAE,EAAE;oBAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,SAAS,EAAE,CAAC,CAAC;oBACvD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;gBACzC,CAAC;aACF,CAAC,CAAC;YAGH,MAAM,YAAY,GAAG,IAAA,2CAAoB,EACvC,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,OAAO,CACb,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,YAAY,CAAC,CAAC;YAE3D,MAAM,SAAS,GAAG,IAAI,kBAAS,CAC7B,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAC1D;gBACE,YAAY;gBACZ,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE;aAC9C,CACF,CAAC;YAGF,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAGnC,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAGtD,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;gBACxB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;gBACjD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;gBAGjD,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;oBACvB,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,SAAU,CAAC,CAAC;gBAC5C,CAAC,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,oCAAoC,SAAS,CAAC,SAAS,EAAE,CAC1D,CAAC;YACF,OAAO;QACT,CAAC;aAAM,IAAI,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAEpD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE;oBACL,IAAI,EAAE,CAAC,KAAK;oBACZ,OAAO,EAAE,mBAAmB;iBAC7B;gBACD,EAAE,EAAE,IAAI;aACT,CAAC,CAAC;YACH,OAAO;QACT,CAAC;aAAM,CAAC;YAEN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE;oBACL,IAAI,EAAE,CAAC,KAAK;oBACZ,OAAO,EAAE,2CAA2C;iBACrD;gBACD,EAAE,EAAE,IAAI;aACT,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAGD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE;oBACL,IAAI,EAAE,CAAC,KAAK;oBACZ,OAAO,EAAE,mBAAmB;iBAC7B;gBACD,EAAE,EAAE,IAAI;aACT,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAGD,MAAM,SAAS,GAAG,uBAAgB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAC3C,yCAAkB,EAClB,SAAS,EACT,EAAE,MAAM,EAAE,IAAI,EAAE,CACjB,CAAC;QAGF,QAAQ,CAAC,uBAAuB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAGjD,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;IAKD,KAAK,CAAC,gBAAgB,CAAC,GAAQ,EAAE,GAAQ;QAEvC,MAAM,OAAO,GAAG,yCAAkB,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxD,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAE9C,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE;oBACL,IAAI,EAAE,CAAC,KAAK;oBACZ,OAAO,EAAE,sCAAsC;iBAChD;gBACD,EAAE,EAAE,IAAI;aACT,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,gBAAgB,CAExC,CAAC;QAEd,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9C,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,SAAS,EAAE,CAAC,CAAC;QACtE,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7C,MAAM,SAAS,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;IAChE,CAAC;IAKD,KAAK,CAAC,mBAAmB,CAAC,GAAQ,EAAE,GAAQ;QAE1C,MAAM,OAAO,GAAG,yCAAkB,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxD,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAE9C,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE;oBACL,IAAI,EAAE,CAAC,KAAK;oBACZ,OAAO,EAAE,sCAAsC;iBAChD;gBACD,EAAE,EAAE,IAAI;aACT,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,gBAAgB,CAExC,CAAC;QAEd,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9C,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,SAAS,EAAE,CAAC,CAAC;QACtD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7C,MAAM,SAAS,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;QAC9D,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAGD,mBAAmB,CAAC,IAAa;QAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,IAAI,CACd,CAAC,GAAG,EAAE,EAAE,CACN,OAAO,GAAG,KAAK,QAAQ;gBACvB,GAAG,KAAK,IAAI;gBACZ,QAAQ,IAAI,GAAG;gBACf,GAAG,CAAC,MAAM,KAAK,YAAY,CAC9B,CAAC;QACJ,CAAC;QACD,OAAO,CACL,OAAO,IAAI,KAAK,QAAQ;YACxB,IAAI,KAAK,IAAI;YACb,QAAQ,IAAI,IAAI;YAChB,IAAI,CAAC,MAAM,KAAK,YAAY,CAC7B,CAAC;IACJ,CAAC;IAGD,cAAc,CAAC,SAAiB;QAC9B,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,SAAS,EAAE,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAClC,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;CACF,CAAA;AAzWY,4DAAwB;mCAAxB,wBAAwB;IADpC,IAAA,mBAAU,GAAE;IAUR,WAAA,IAAA,eAAM,EAAC,aAAa,CAAC,CAAA;IACrB,WAAA,IAAA,eAAM,EAAC,eAAe,CAAC,CAAA;qDACI,gBAAS;QACN,yCAAkB;GAZxC,wBAAwB,CAyWpC","sourcesContent":["import { Inject, Injectable, Logger } from '@nestjs/common';\nimport { ContextIdFactory, ModuleRef } from '@nestjs/core';\nimport { randomUUID } from 'crypto';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { HttpAdapterFactory } from '../adapters/http-adapter.factory';\nimport {\n HttpRequest,\n HttpResponse,\n} from '../interfaces/http-adapter.interface';\nimport { McpOptions } from '../interfaces';\nimport { McpExecutorService } from './mcp-executor.service';\nimport { McpRegistryService } from './mcp-registry.service';\nimport { buildMcpCapabilities } from '../utils/capabilities-builder';\n\n@Injectable()\nexport class McpStreamableHttpService {\n private readonly logger = new Logger(McpStreamableHttpService.name);\n private readonly transports: {\n [sessionId: string]: StreamableHTTPServerTransport;\n } = {};\n private readonly mcpServers: { [sessionId: string]: McpServer } = {};\n private readonly isStatelessMode: boolean;\n\n constructor(\n @Inject('MCP_OPTIONS') private readonly options: McpOptions,\n @Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,\n private readonly moduleRef: ModuleRef,\n private readonly toolRegistry: McpRegistryService,\n ) {\n // Determine if we're in stateless mode\n this.isStatelessMode = !!options.streamableHttp?.statelessMode;\n }\n\n /**\n * Create a new MCP server instance for stateless requests\n */\n async createStatelessServer(rawReq: any): Promise<{\n server: McpServer;\n transport: StreamableHTTPServerTransport;\n }> {\n // Create a new transport for this request\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n enableJsonResponse:\n this.options.streamableHttp?.enableJsonResponse || false,\n });\n\n // Create a new MCP server instance with dynamic capabilities\n const capabilities = buildMcpCapabilities(\n this.mcpModuleId,\n this.toolRegistry,\n this.options,\n );\n this.logger.debug('Built MCP capabilities:', capabilities);\n\n const server = new McpServer(\n { name: this.options.name, version: this.options.version },\n {\n capabilities: capabilities,\n instructions: this.options.instructions || '',\n },\n );\n\n // Connect the transport to the MCP server first\n await server.connect(transport);\n\n // Now resolve the request-scoped tool executor service\n const contextId = ContextIdFactory.getByRequest(rawReq);\n const executor = await this.moduleRef.resolve(\n McpExecutorService,\n contextId,\n { strict: true },\n );\n\n // Register request handlers after connection\n this.logger.debug('Registering request handlers for stateless MCP server');\n executor.registerRequestHandlers(server, rawReq);\n\n return { server, transport };\n }\n\n /**\n * Handle POST requests\n */\n async handlePostRequest(req: any, res: any, body: unknown): Promise<void> {\n this.logger.debug('Received MCP request:', body);\n\n // Get the appropriate HTTP adapter for the request/response\n const adapter = HttpAdapterFactory.getAdapter(req, res);\n const adaptedReq = adapter.adaptRequest(req);\n const adaptedRes = adapter.adaptResponse(res);\n\n try {\n if (this.isStatelessMode) {\n return this.handleStatelessRequest(adaptedReq, adaptedRes, body);\n } else {\n return this.handleStatefulRequest(adaptedReq, adaptedRes, body);\n }\n } catch (error) {\n this.logger.error('Error handling MCP request:', error);\n if (!adaptedRes.headersSent) {\n adaptedRes.status(500).json({\n jsonrpc: '2.0',\n error: {\n code: -32603,\n message: 'Internal server error',\n },\n id: null,\n });\n }\n }\n }\n\n /**\n * Handle requests in stateless mode\n */\n async handleStatelessRequest(\n req: any,\n res: HttpResponse,\n body: unknown,\n ): Promise<void> {\n this.logger.debug(\n `Handling stateless MCP request at ${req.url} with body: ${JSON.stringify(\n body,\n )}`,\n );\n\n let server: McpServer | null = null;\n let transport: StreamableHTTPServerTransport | null = null;\n\n try {\n // Create a new server and transport for each request\n const stateless = await this.createStatelessServer(req);\n server = stateless.server;\n transport = stateless.transport;\n\n // Handle the request\n await transport.handleRequest(req.raw, res.raw, body);\n\n // Clean up when the response closes\n res.on?.('close', () => {\n this.logger.debug('Stateless request closed, cleaning up');\n void transport?.close();\n void server?.close();\n });\n } catch (error) {\n this.logger.error('Error in stateless request handling:', error);\n // Clean up on error\n void transport?.close();\n void server?.close();\n throw error;\n }\n }\n\n /**\n * Handle requests in stateful mode\n */\n async handleStatefulRequest(\n req: HttpRequest,\n res: HttpResponse,\n body: unknown,\n ): Promise<void> {\n this.logger.debug(\n `Handling stateful MCP request at ${req.url} with body: ${JSON.stringify(\n body,\n )}`,\n );\n // Check for existing session ID\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n let transport: StreamableHTTPServerTransport;\n\n if (sessionId && this.transports[sessionId]) {\n // Reuse existing transport\n transport = this.transports[sessionId];\n } else if (!sessionId && this.isInitializeRequest(body)) {\n // New initialization request\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator:\n this.options.streamableHttp?.sessionIdGenerator ||\n (() => randomUUID()),\n enableJsonResponse:\n this.options.streamableHttp?.enableJsonResponse || false,\n onsessioninitialized: (sessionId: string) => {\n this.logger.debug(`Session initialized: ${sessionId}`);\n this.transports[sessionId] = transport;\n },\n });\n\n // Create a new MCP server for this session with dynamic capabilities\n const capabilities = buildMcpCapabilities(\n this.mcpModuleId,\n this.toolRegistry,\n this.options,\n );\n this.logger.debug('Built MCP capabilities:', capabilities);\n\n const mcpServer = new McpServer(\n { name: this.options.name, version: this.options.version },\n {\n capabilities,\n instructions: this.options.instructions || '',\n },\n );\n\n // Connect the transport to the MCP server BEFORE handling the request\n await mcpServer.connect(transport);\n\n // Handle the initialization request\n await transport.handleRequest(req.raw, res.raw, body);\n\n // Store the transport and server by session ID for future requests\n if (transport.sessionId) {\n this.transports[transport.sessionId] = transport;\n this.mcpServers[transport.sessionId] = mcpServer;\n\n // Set up cleanup when connection closes\n transport.onclose = () => {\n this.cleanupSession(transport.sessionId!);\n };\n }\n\n this.logger.log(\n `Initialized new session with ID: ${transport.sessionId}`,\n );\n return;\n } else if (sessionId && !this.transports[sessionId]) {\n // Provided session ID but no matching session exists\n res.status(404).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Session not found',\n },\n id: null,\n });\n return;\n } else {\n // Invalid request - no session ID or not initialization request\n res.status(400).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Bad Request: No valid session ID provided',\n },\n id: null,\n });\n return;\n }\n\n // For subsequent requests to an existing session\n const mcpServer = this.mcpServers[sessionId];\n if (!mcpServer) {\n res.status(404).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Session not found',\n },\n id: null,\n });\n return;\n }\n\n // Resolve the request-scoped tool executor service\n const contextId = ContextIdFactory.getByRequest(req);\n const executor = await this.moduleRef.resolve(\n McpExecutorService,\n contextId,\n { strict: true },\n );\n\n // Register request handlers with the user context from this specific request\n executor.registerRequestHandlers(mcpServer, req);\n\n // Handle the request with existing transport\n await transport.handleRequest(req.raw, res.raw, body);\n }\n\n /**\n * Handle GET requests for SSE streams\n */\n async handleGetRequest(req: any, res: any): Promise<void> {\n // Get the appropriate HTTP adapter for the request/response\n const adapter = HttpAdapterFactory.getAdapter(req, res);\n const adaptedReq = adapter.adaptRequest(req);\n const adaptedRes = adapter.adaptResponse(res);\n\n if (this.isStatelessMode) {\n adaptedRes.status(405).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Method not allowed in stateless mode',\n },\n id: null,\n });\n return;\n }\n\n const sessionId = adaptedReq.headers['mcp-session-id'] as\n | string\n | undefined;\n\n if (!sessionId || !this.transports[sessionId]) {\n adaptedRes.status(400).send('Invalid or missing session ID');\n return;\n }\n\n this.logger.debug(`Establishing SSE stream for session ${sessionId}`);\n const transport = this.transports[sessionId];\n await transport.handleRequest(adaptedReq.raw, adaptedRes.raw);\n }\n\n /**\n * Handle DELETE requests for terminating sessions\n */\n async handleDeleteRequest(req: any, res: any): Promise<void> {\n // Get the appropriate HTTP adapter for the request/response\n const adapter = HttpAdapterFactory.getAdapter(req, res);\n const adaptedReq = adapter.adaptRequest(req);\n const adaptedRes = adapter.adaptResponse(res);\n\n if (this.isStatelessMode) {\n adaptedRes.status(405).json({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message: 'Method not allowed in stateless mode',\n },\n id: null,\n });\n return;\n }\n\n const sessionId = adaptedReq.headers['mcp-session-id'] as\n | string\n | undefined;\n\n if (!sessionId || !this.transports[sessionId]) {\n adaptedRes.status(400).send('Invalid or missing session ID');\n return;\n }\n\n this.logger.debug(`Terminating session ${sessionId}`);\n const transport = this.transports[sessionId];\n await transport.handleRequest(adaptedReq.raw, adaptedRes.raw);\n this.cleanupSession(sessionId);\n }\n\n // Helper function to detect initialize requests\n isInitializeRequest(body: unknown): boolean {\n if (Array.isArray(body)) {\n return body.some(\n (msg) =>\n typeof msg === 'object' &&\n msg !== null &&\n 'method' in msg &&\n msg.method === 'initialize',\n );\n }\n return (\n typeof body === 'object' &&\n body !== null &&\n 'method' in body &&\n body.method === 'initialize'\n );\n }\n\n // Clean up session resources\n cleanupSession(sessionId: string): void {\n if (sessionId) {\n this.logger.debug(`Cleaning up session: ${sessionId}`);\n delete this.transports[sessionId];\n delete this.mcpServers[sessionId];\n }\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { CanActivate, Logger, Type } from '@nestjs/common';
2
- import type { McpOptions } from '../interfaces';
2
+ import { McpOptions } from '../interfaces';
3
3
  import { McpSseService } from '../services/mcp-sse.service';
4
4
  export declare function createSseController(sseEndpoint: string, messagesEndpoint: string, apiPrefix: string, guards?: Type<CanActivate>[], decorators?: ClassDecorator[]): {
5
5
  new (options: McpOptions, mcpSseService: McpSseService): {
@@ -1 +1 @@
1
- {"version":3,"file":"sse.controller.factory.d.ts","sourceRoot":"","sources":["../../../src/mcp/transport/sse.controller.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAIX,MAAM,EAKN,IAAI,EAIL,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAM5D,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,IAAI,CAAC,WAAW,CAAC,EAAO,EAChC,UAAU,GAAE,cAAc,EAAO;kBAUmB,UAAU,iBAC3B,aAAa;;0BADI,UAAU;gCAC3B,aAAa;;oBAerB,GAAG,UAAiB,GAAG;yBAe/B,GAAG,UACH,GAAG,QACJ,OAAO,GACpB,OAAO,CAAC,IAAI,CAAC;;EAMnB"}
1
+ {"version":3,"file":"sse.controller.factory.d.ts","sourceRoot":"","sources":["../../../src/mcp/transport/sse.controller.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAIX,MAAM,EAKN,IAAI,EAIL,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAM5D,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,IAAI,CAAC,WAAW,CAAC,EAAO,EAChC,UAAU,GAAE,cAAc,EAAO;kBAUmB,UAAU,iBAC3B,aAAa;;0BADI,UAAU;gCAC3B,aAAa;;oBAerB,GAAG,UAAiB,GAAG;yBAe/B,GAAG,UACH,GAAG,QACJ,OAAO,GACpB,OAAO,CAAC,IAAI,CAAC;;EAMnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"sse.controller.factory.js","sourceRoot":"","sources":["../../../src/mcp/transport/sse.controller.factory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAwBA,kDAuDC;AA/ED,2CAewB;AAGxB,iEAA4D;AAC5D,oEAAgE;AAKhE,SAAgB,mBAAmB,CACjC,WAAmB,EACnB,gBAAwB,EACxB,SAAiB,EACjB,SAA8B,EAAE,EAChC,aAA+B,EAAE;;IAEjC,IAIM,aAAa,qBAJnB,MAIM,aAAa;QAGjB,YACyB,OAAmC,EAC1C,aAA4B;YADL,YAAO,GAAP,OAAO,CAAY;YAC1C,kBAAa,GAAb,aAAa,CAAe;YAJrC,WAAM,GAAG,IAAI,eAAM,CAAC,eAAa,CAAC,IAAI,CAAC,CAAC;QAK9C,CAAC;QAKJ,YAAY;YACV,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;QAClC,CAAC;QAOK,AAAN,KAAK,CAAC,GAAG,CAAQ,MAAW,EAAS,MAAW;YAC9C,OAAO,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAC3C,MAAM,EACN,MAAM,EACN,gBAAgB,EAChB,SAAS,CACV,CAAC;QACJ,CAAC;QAOK,AAAN,KAAK,CAAC,QAAQ,CACL,MAAW,EACX,MAAW,EACV,IAAa;YAErB,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/D,CAAC;KACF,CAAA;IArBO;QAFL,IAAA,YAAG,EAAC,IAAA,sCAAiB,EAAC,GAAG,SAAS,IAAI,WAAW,EAAE,CAAC,CAAC;QACrD,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC;QACV,WAAA,IAAA,YAAG,GAAE,CAAA;QAAe,WAAA,IAAA,YAAG,GAAE,CAAA;;;;4CAOnC;IAOK;QAFL,IAAA,aAAI,EAAC,IAAA,sCAAiB,EAAC,GAAG,SAAS,IAAI,gBAAgB,EAAE,CAAC,CAAC;QAC3D,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC;QAElB,WAAA,IAAA,YAAG,GAAE,CAAA;QACL,WAAA,IAAA,YAAG,GAAE,CAAA;QACL,WAAA,IAAA,aAAI,GAAE,CAAA;;;;iDAGR;IAxCG,aAAa;QAJlB,IAAA,mBAAU,EAAC;YACV,OAAO,EAAE,wBAAe;SACzB,CAAC;QACD,IAAA,wBAAe,EAAC,GAAG,UAAU,CAAC;QAK1B,WAAA,IAAA,eAAM,EAAC,aAAa,CAAC,CAAA;iDACS,+BAAa;OAL1C,aAAa,CAyClB;IAED,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import {\n Body,\n CanActivate,\n Controller,\n Get,\n Inject,\n Logger,\n OnModuleInit,\n Post,\n Req,\n Res,\n Type,\n UseGuards,\n VERSION_NEUTRAL,\n applyDecorators,\n} from '@nestjs/common';\n\nimport type { McpOptions } from '../interfaces';\nimport { McpSseService } from '../services/mcp-sse.service';\nimport { normalizeEndpoint } from '../utils/normalize-endpoint';\n\n/**\n * Creates a controller for handling SSE connections and tool executions\n */\nexport function createSseController(\n sseEndpoint: string,\n messagesEndpoint: string,\n apiPrefix: string,\n guards: Type<CanActivate>[] = [],\n decorators: ClassDecorator[] = [],\n) {\n @Controller({\n version: VERSION_NEUTRAL,\n })\n @applyDecorators(...decorators)\n class SseController implements OnModuleInit {\n readonly logger = new Logger(SseController.name);\n\n constructor(\n @Inject('MCP_OPTIONS') public readonly options: McpOptions,\n public readonly mcpSseService: McpSseService,\n ) {}\n\n /**\n * Initialize the controller and configure SSE service\n */\n onModuleInit() {\n this.mcpSseService.initialize();\n }\n\n /**\n * SSE connection endpoint\n */\n @Get(normalizeEndpoint(`${apiPrefix}/${sseEndpoint}`))\n @UseGuards(...guards)\n async sse(@Req() rawReq: any, @Res() rawRes: any) {\n return this.mcpSseService.createSseConnection(\n rawReq,\n rawRes,\n messagesEndpoint,\n apiPrefix,\n );\n }\n\n /**\n * Tool execution endpoint - protected by the provided guards\n */\n @Post(normalizeEndpoint(`${apiPrefix}/${messagesEndpoint}`))\n @UseGuards(...guards)\n async messages(\n @Req() rawReq: any,\n @Res() rawRes: any,\n @Body() body: unknown,\n ): Promise<void> {\n await this.mcpSseService.handleMessage(rawReq, rawRes, body);\n }\n }\n\n return SseController;\n}\n"]}
1
+ {"version":3,"file":"sse.controller.factory.js","sourceRoot":"","sources":["../../../src/mcp/transport/sse.controller.factory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAwBA,kDAuDC;AA/ED,2CAewB;AAGxB,iEAA4D;AAC5D,oEAAgE;AAKhE,SAAgB,mBAAmB,CACjC,WAAmB,EACnB,gBAAwB,EACxB,SAAiB,EACjB,SAA8B,EAAE,EAChC,aAA+B,EAAE;;IAEjC,IAIM,aAAa,qBAJnB,MAIM,aAAa;QAGjB,YACyB,OAAmC,EAC1C,aAA4B;YADL,YAAO,GAAP,OAAO,CAAY;YAC1C,kBAAa,GAAb,aAAa,CAAe;YAJrC,WAAM,GAAG,IAAI,eAAM,CAAC,eAAa,CAAC,IAAI,CAAC,CAAC;QAK9C,CAAC;QAKJ,YAAY;YACV,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;QAClC,CAAC;QAOK,AAAN,KAAK,CAAC,GAAG,CAAQ,MAAW,EAAS,MAAW;YAC9C,OAAO,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAC3C,MAAM,EACN,MAAM,EACN,gBAAgB,EAChB,SAAS,CACV,CAAC;QACJ,CAAC;QAOK,AAAN,KAAK,CAAC,QAAQ,CACL,MAAW,EACX,MAAW,EACV,IAAa;YAErB,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/D,CAAC;KACF,CAAA;IArBO;QAFL,IAAA,YAAG,EAAC,IAAA,sCAAiB,EAAC,GAAG,SAAS,IAAI,WAAW,EAAE,CAAC,CAAC;QACrD,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC;QACV,WAAA,IAAA,YAAG,GAAE,CAAA;QAAe,WAAA,IAAA,YAAG,GAAE,CAAA;;;;4CAOnC;IAOK;QAFL,IAAA,aAAI,EAAC,IAAA,sCAAiB,EAAC,GAAG,SAAS,IAAI,gBAAgB,EAAE,CAAC,CAAC;QAC3D,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC;QAElB,WAAA,IAAA,YAAG,GAAE,CAAA;QACL,WAAA,IAAA,YAAG,GAAE,CAAA;QACL,WAAA,IAAA,aAAI,GAAE,CAAA;;;;iDAGR;IAxCG,aAAa;QAJlB,IAAA,mBAAU,EAAC;YACV,OAAO,EAAE,wBAAe;SACzB,CAAC;QACD,IAAA,wBAAe,EAAC,GAAG,UAAU,CAAC;QAK1B,WAAA,IAAA,eAAM,EAAC,aAAa,CAAC,CAAA;iDACS,+BAAa;OAL1C,aAAa,CAyClB;IAED,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import {\n Body,\n CanActivate,\n Controller,\n Get,\n Inject,\n Logger,\n OnModuleInit,\n Post,\n Req,\n Res,\n Type,\n UseGuards,\n VERSION_NEUTRAL,\n applyDecorators,\n} from '@nestjs/common';\n\nimport { McpOptions } from '../interfaces';\nimport { McpSseService } from '../services/mcp-sse.service';\nimport { normalizeEndpoint } from '../utils/normalize-endpoint';\n\n/**\n * Creates a controller for handling SSE connections and tool executions\n */\nexport function createSseController(\n sseEndpoint: string,\n messagesEndpoint: string,\n apiPrefix: string,\n guards: Type<CanActivate>[] = [],\n decorators: ClassDecorator[] = [],\n) {\n @Controller({\n version: VERSION_NEUTRAL,\n })\n @applyDecorators(...decorators)\n class SseController implements OnModuleInit {\n readonly logger = new Logger(SseController.name);\n\n constructor(\n @Inject('MCP_OPTIONS') public readonly options: McpOptions,\n public readonly mcpSseService: McpSseService,\n ) {}\n\n /**\n * Initialize the controller and configure SSE service\n */\n onModuleInit() {\n this.mcpSseService.initialize();\n }\n\n /**\n * SSE connection endpoint\n */\n @Get(normalizeEndpoint(`${apiPrefix}/${sseEndpoint}`))\n @UseGuards(...guards)\n async sse(@Req() rawReq: any, @Res() rawRes: any) {\n return this.mcpSseService.createSseConnection(\n rawReq,\n rawRes,\n messagesEndpoint,\n apiPrefix,\n );\n }\n\n /**\n * Tool execution endpoint - protected by the provided guards\n */\n @Post(normalizeEndpoint(`${apiPrefix}/${messagesEndpoint}`))\n @UseGuards(...guards)\n async messages(\n @Req() rawReq: any,\n @Res() rawRes: any,\n @Body() body: unknown,\n ): Promise<void> {\n await this.mcpSseService.handleMessage(rawReq, rawRes, body);\n }\n }\n\n return SseController;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { OnApplicationBootstrap } from '@nestjs/common';
2
2
  import { ModuleRef } from '@nestjs/core';
3
- import type { McpOptions } from '../interfaces';
3
+ import { McpOptions } from '../interfaces';
4
4
  import { McpRegistryService } from '../services/mcp-registry.service';
5
5
  export declare class StdioService implements OnApplicationBootstrap {
6
6
  private readonly options;
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/transport/stdio.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,sBAAsB,EACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAGtE,qBACa,YAAa,YAAW,sBAAsB;IAIhC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAN/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;gBAGd,OAAO,EAAE,UAAU,EACjB,WAAW,EAAE,MAAM,EAC5C,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,kBAAkB;IAG7C,sBAAsB;CAsC7B"}
1
+ {"version":3,"file":"stdio.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/transport/stdio.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,sBAAsB,EACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAoB,MAAM,eAAe,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAGtE,qBACa,YAAa,YAAW,sBAAsB;IAIhC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAN/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;gBAGd,OAAO,EAAE,UAAU,EACjB,WAAW,EAAE,MAAM,EAC5C,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,kBAAkB;IAG7C,sBAAsB;CAsC7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.service.js","sourceRoot":"","sources":["../../../src/mcp/transport/stdio.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oEAAoE;AACpE,wEAAiF;AACjF,2CAKwB;AACxB,uCAA2D;AAC3D,8CAAiD;AAEjD,2EAAsE;AACtE,2EAAsE;AACtE,wEAAqE;AAG9D,IAAM,YAAY,oBAAlB,MAAM,YAAY;IAGvB,YACyB,OAAoC,EAClC,WAAoC,EAC5C,SAAoB,EACpB,YAAgC;QAHT,YAAO,GAAP,OAAO,CAAY;QACjB,gBAAW,GAAX,WAAW,CAAQ;QAC5C,cAAS,GAAT,SAAS,CAAW;QACpB,iBAAY,GAAZ,YAAY,CAAoB;QANlC,WAAM,GAAG,IAAI,eAAM,CAAC,cAAY,CAAC,IAAI,CAAC,CAAC;IAOrD,CAAC;IAEJ,KAAK,CAAC,sBAAsB;QAC1B,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,6BAAgB,CAAC,KAAK,EAAE,CAAC;YACtD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAG9C,MAAM,YAAY,GAAG,IAAA,2CAAoB,EACvC,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,OAAO,CACb,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,YAAY,CAAC,CAAC;QAG3D,MAAM,SAAS,GAAG,IAAI,kBAAS,CAC7B,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAC1D;YACE,YAAY;YACZ,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE;SAC9C,CACF,CAAC;QAEF,MAAM,SAAS,GAAG,uBAAgB,CAAC,MAAM,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAC3C,yCAAkB,EAClB,SAAS,EACT,EAAE,MAAM,EAAE,KAAK,EAAE,CAClB,CAAC;QAGF,QAAQ,CAAC,uBAAuB,CAAC,SAAS,EAAE,EAAS,CAAC,CAAC;QAEvD,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;QAC7C,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEnC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACrC,CAAC;CACF,CAAA;AAhDY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,eAAM,EAAC,aAAa,CAAC,CAAA;IACrB,WAAA,IAAA,eAAM,EAAC,eAAe,CAAC,CAAA;qDACI,gBAAS;QACN,yCAAkB;GAPxC,YAAY,CAgDxB","sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n Inject,\n Injectable,\n Logger,\n OnApplicationBootstrap,\n} from '@nestjs/common';\nimport { ContextIdFactory, ModuleRef } from '@nestjs/core';\nimport { McpTransportType } from '../interfaces';\nimport type { McpOptions } from '../interfaces';\nimport { McpExecutorService } from '../services/mcp-executor.service';\nimport { McpRegistryService } from '../services/mcp-registry.service';\nimport { buildMcpCapabilities } from '../utils/capabilities-builder';\n\n@Injectable()\nexport class StdioService implements OnApplicationBootstrap {\n private readonly logger = new Logger(StdioService.name);\n\n constructor(\n @Inject('MCP_OPTIONS') private readonly options: McpOptions,\n @Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,\n private readonly moduleRef: ModuleRef,\n private readonly toolRegistry: McpRegistryService,\n ) {}\n\n async onApplicationBootstrap() {\n if (this.options.transport !== McpTransportType.STDIO) {\n return;\n }\n this.logger.log('Bootstrapping MCP STDIO...');\n\n // Create a new MCP server instance with dynamic capabilities\n const capabilities = buildMcpCapabilities(\n this.mcpModuleId,\n this.toolRegistry,\n this.options,\n );\n this.logger.debug('Built MCP capabilities:', capabilities);\n\n // Create MCP server with dynamic capabilities\n const mcpServer = new McpServer(\n { name: this.options.name, version: this.options.version },\n {\n capabilities,\n instructions: this.options.instructions || '',\n },\n );\n\n const contextId = ContextIdFactory.create();\n const executor = await this.moduleRef.resolve(\n McpExecutorService,\n contextId,\n { strict: false },\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n executor.registerRequestHandlers(mcpServer, {} as any);\n\n const transport = new StdioServerTransport();\n await mcpServer.connect(transport);\n\n this.logger.log('MCP STDIO ready');\n }\n}\n"]}
1
+ {"version":3,"file":"stdio.service.js","sourceRoot":"","sources":["../../../src/mcp/transport/stdio.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oEAAoE;AACpE,wEAAiF;AACjF,2CAKwB;AACxB,uCAA2D;AAC3D,8CAA6D;AAC7D,2EAAsE;AACtE,2EAAsE;AACtE,wEAAqE;AAG9D,IAAM,YAAY,oBAAlB,MAAM,YAAY;IAGvB,YACyB,OAAoC,EAClC,WAAoC,EAC5C,SAAoB,EACpB,YAAgC;QAHT,YAAO,GAAP,OAAO,CAAY;QACjB,gBAAW,GAAX,WAAW,CAAQ;QAC5C,cAAS,GAAT,SAAS,CAAW;QACpB,iBAAY,GAAZ,YAAY,CAAoB;QANlC,WAAM,GAAG,IAAI,eAAM,CAAC,cAAY,CAAC,IAAI,CAAC,CAAC;IAOrD,CAAC;IAEJ,KAAK,CAAC,sBAAsB;QAC1B,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,6BAAgB,CAAC,KAAK,EAAE,CAAC;YACtD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAG9C,MAAM,YAAY,GAAG,IAAA,2CAAoB,EACvC,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,OAAO,CACb,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,YAAY,CAAC,CAAC;QAG3D,MAAM,SAAS,GAAG,IAAI,kBAAS,CAC7B,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAC1D;YACE,YAAY;YACZ,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE;SAC9C,CACF,CAAC;QAEF,MAAM,SAAS,GAAG,uBAAgB,CAAC,MAAM,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAC3C,yCAAkB,EAClB,SAAS,EACT,EAAE,MAAM,EAAE,KAAK,EAAE,CAClB,CAAC;QAGF,QAAQ,CAAC,uBAAuB,CAAC,SAAS,EAAE,EAAS,CAAC,CAAC;QAEvD,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;QAC7C,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEnC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACrC,CAAC;CACF,CAAA;AAhDY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,eAAM,EAAC,aAAa,CAAC,CAAA;IACrB,WAAA,IAAA,eAAM,EAAC,eAAe,CAAC,CAAA;qDACI,gBAAS;QACN,yCAAkB;GAPxC,YAAY,CAgDxB","sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n Inject,\n Injectable,\n Logger,\n OnApplicationBootstrap,\n} from '@nestjs/common';\nimport { ContextIdFactory, ModuleRef } from '@nestjs/core';\nimport { McpOptions, McpTransportType } from '../interfaces';\nimport { McpExecutorService } from '../services/mcp-executor.service';\nimport { McpRegistryService } from '../services/mcp-registry.service';\nimport { buildMcpCapabilities } from '../utils/capabilities-builder';\n\n@Injectable()\nexport class StdioService implements OnApplicationBootstrap {\n private readonly logger = new Logger(StdioService.name);\n\n constructor(\n @Inject('MCP_OPTIONS') private readonly options: McpOptions,\n @Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,\n private readonly moduleRef: ModuleRef,\n private readonly toolRegistry: McpRegistryService,\n ) {}\n\n async onApplicationBootstrap() {\n if (this.options.transport !== McpTransportType.STDIO) {\n return;\n }\n this.logger.log('Bootstrapping MCP STDIO...');\n\n // Create a new MCP server instance with dynamic capabilities\n const capabilities = buildMcpCapabilities(\n this.mcpModuleId,\n this.toolRegistry,\n this.options,\n );\n this.logger.debug('Built MCP capabilities:', capabilities);\n\n // Create MCP server with dynamic capabilities\n const mcpServer = new McpServer(\n { name: this.options.name, version: this.options.version },\n {\n capabilities,\n instructions: this.options.instructions || '',\n },\n );\n\n const contextId = ContextIdFactory.create();\n const executor = await this.moduleRef.resolve(\n McpExecutorService,\n contextId,\n { strict: false },\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n executor.registerRequestHandlers(mcpServer, {} as any);\n\n const transport = new StdioServerTransport();\n await mcpServer.connect(transport);\n\n this.logger.log('MCP STDIO ready');\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { CanActivate, Logger, Type } from '@nestjs/common';
2
- import type { McpOptions } from '../interfaces';
2
+ import { McpOptions } from '../interfaces';
3
3
  import { McpStreamableHttpService } from '../services/mcp-streamable-http.service';
4
4
  export declare function createStreamableHttpController(endpoint: string, apiPrefix: string, guards?: Type<CanActivate>[], decorators?: ClassDecorator[]): {
5
5
  new (options: McpOptions, mcpStreamableHttpService: McpStreamableHttpService): {
@@ -1 +1 @@
1
- {"version":3,"file":"streamable-http.controller.factory.d.ts","sourceRoot":"","sources":["../../../src/mcp/transport/streamable-http.controller.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAKX,MAAM,EAIN,IAAI,EAGL,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AAMnF,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,IAAI,CAAC,WAAW,CAAC,EAAO,EAChC,UAAU,GAAE,cAAc,EAAO;kBAQmB,UAAU,4BAChB,wBAAwB;;0BADlB,UAAU;2CAChB,wBAAwB;+BAStD,GAAG,OACH,GAAG,QACD,OAAO,GACpB,OAAO,CAAC,IAAI,CAAC;8BASmB,GAAG,OAAc,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;iCASjC,GAAG,OAAc,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;;EAM7E"}
1
+ {"version":3,"file":"streamable-http.controller.factory.d.ts","sourceRoot":"","sources":["../../../src/mcp/transport/streamable-http.controller.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAKX,MAAM,EAIN,IAAI,EAGL,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AAMnF,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,IAAI,CAAC,WAAW,CAAC,EAAO,EAChC,UAAU,GAAE,cAAc,EAAO;kBAQmB,UAAU,4BAChB,wBAAwB;;0BADlB,UAAU;2CAChB,wBAAwB;+BAStD,GAAG,OACH,GAAG,QACD,OAAO,GACpB,OAAO,CAAC,IAAI,CAAC;8BASmB,GAAG,OAAc,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;iCASjC,GAAG,OAAc,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;;EAM7E"}
@@ -1 +1 @@
1
- {"version":3,"file":"streamable-http.controller.factory.js","sourceRoot":"","sources":["../../../src/mcp/transport/streamable-http.controller.factory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAuBA,wEAiDC;AAxED,2CAcwB;AAGxB,yFAAmF;AACnF,oEAAgE;AAKhE,SAAgB,8BAA8B,CAC5C,QAAgB,EAChB,SAAiB,EACjB,SAA8B,EAAE,EAChC,aAA+B,EAAE;;IAEjC,IAEM,wBAAwB,gCAF9B,MAEM,wBAAwB;QAG5B,YACyB,OAAmC,EAC1C,wBAAkD;YAD3B,YAAO,GAAP,OAAO,CAAY;YAC1C,6BAAwB,GAAxB,wBAAwB,CAA0B;YAJpD,WAAM,GAAG,IAAI,eAAM,CAAC,0BAAwB,CAAC,IAAI,CAAC,CAAC;QAKhE,CAAC;QAOE,AAAN,KAAK,CAAC,iBAAiB,CACd,GAAQ,EACR,GAAQ,EACP,IAAa;YAErB,MAAM,IAAI,CAAC,wBAAwB,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACxE,CAAC;QAOK,AAAN,KAAK,CAAC,gBAAgB,CAAQ,GAAQ,EAAS,GAAQ;YACrD,MAAM,IAAI,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjE,CAAC;QAOK,AAAN,KAAK,CAAC,mBAAmB,CAAQ,GAAQ,EAAS,GAAQ;YACxD,MAAM,IAAI,CAAC,wBAAwB,CAAC,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACpE,CAAC;KACF,CAAA;IAzBO;QAFL,IAAA,aAAI,EAAC,GAAG,IAAA,sCAAiB,EAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,EAAE,CAAC;QACxD,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC;QAElB,WAAA,IAAA,YAAG,GAAE,CAAA;QACL,WAAA,IAAA,YAAG,GAAE,CAAA;QACL,WAAA,IAAA,aAAI,GAAE,CAAA;;;;qEAGR;IAOK;QAFL,IAAA,YAAG,EAAC,GAAG,IAAA,sCAAiB,EAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,EAAE,CAAC;QACvD,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC;QACG,WAAA,IAAA,YAAG,GAAE,CAAA;QAAY,WAAA,IAAA,YAAG,GAAE,CAAA;;;;oEAE7C;IAOK;QAFL,IAAA,eAAM,EAAC,GAAG,IAAA,sCAAiB,EAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,EAAE,CAAC;QAC1D,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC;QACM,WAAA,IAAA,YAAG,GAAE,CAAA;QAAY,WAAA,IAAA,YAAG,GAAE,CAAA;;;;uEAEhD;IArCG,wBAAwB;QAF7B,IAAA,mBAAU,GAAE;QACZ,IAAA,wBAAe,EAAC,GAAG,UAAU,CAAC;QAK1B,WAAA,IAAA,eAAM,EAAC,aAAa,CAAC,CAAA;iDACoB,sDAAwB;OALhE,wBAAwB,CAsC7B;IAED,OAAO,wBAAwB,CAAC;AAClC,CAAC","sourcesContent":["import {\n Body,\n CanActivate,\n Controller,\n Delete,\n Get,\n Inject,\n Logger,\n Post,\n Req,\n Res,\n Type,\n UseGuards,\n applyDecorators,\n} from '@nestjs/common';\n\nimport type { McpOptions } from '../interfaces';\nimport { McpStreamableHttpService } from '../services/mcp-streamable-http.service';\nimport { normalizeEndpoint } from '../utils/normalize-endpoint';\n\n/**\n * Creates a controller for handling Streamable HTTP connections and tool executions\n */\nexport function createStreamableHttpController(\n endpoint: string,\n apiPrefix: string,\n guards: Type<CanActivate>[] = [],\n decorators: ClassDecorator[] = [],\n) {\n @Controller()\n @applyDecorators(...decorators)\n class StreamableHttpController {\n public readonly logger = new Logger(StreamableHttpController.name);\n\n constructor(\n @Inject('MCP_OPTIONS') public readonly options: McpOptions,\n public readonly mcpStreamableHttpService: McpStreamableHttpService,\n ) {}\n\n /**\n * Main HTTP endpoint for both initialization and subsequent requests\n */\n @Post(`${normalizeEndpoint(`${apiPrefix}/${endpoint}`)}`)\n @UseGuards(...guards)\n async handlePostRequest(\n @Req() req: any,\n @Res() res: any,\n @Body() body: unknown,\n ): Promise<void> {\n await this.mcpStreamableHttpService.handlePostRequest(req, res, body);\n }\n\n /**\n * GET endpoint for SSE streams - not supported in stateless mode\n */\n @Get(`${normalizeEndpoint(`${apiPrefix}/${endpoint}`)}`)\n @UseGuards(...guards)\n async handleGetRequest(@Req() req: any, @Res() res: any): Promise<void> {\n await this.mcpStreamableHttpService.handleGetRequest(req, res);\n }\n\n /**\n * DELETE endpoint for terminating sessions - not supported in stateless mode\n */\n @Delete(`${normalizeEndpoint(`${apiPrefix}/${endpoint}`)}`)\n @UseGuards(...guards)\n async handleDeleteRequest(@Req() req: any, @Res() res: any): Promise<void> {\n await this.mcpStreamableHttpService.handleDeleteRequest(req, res);\n }\n }\n\n return StreamableHttpController;\n}\n"]}
1
+ {"version":3,"file":"streamable-http.controller.factory.js","sourceRoot":"","sources":["../../../src/mcp/transport/streamable-http.controller.factory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAuBA,wEAiDC;AAxED,2CAcwB;AAGxB,yFAAmF;AACnF,oEAAgE;AAKhE,SAAgB,8BAA8B,CAC5C,QAAgB,EAChB,SAAiB,EACjB,SAA8B,EAAE,EAChC,aAA+B,EAAE;;IAEjC,IAEM,wBAAwB,gCAF9B,MAEM,wBAAwB;QAG5B,YACyB,OAAmC,EAC1C,wBAAkD;YAD3B,YAAO,GAAP,OAAO,CAAY;YAC1C,6BAAwB,GAAxB,wBAAwB,CAA0B;YAJpD,WAAM,GAAG,IAAI,eAAM,CAAC,0BAAwB,CAAC,IAAI,CAAC,CAAC;QAKhE,CAAC;QAOE,AAAN,KAAK,CAAC,iBAAiB,CACd,GAAQ,EACR,GAAQ,EACP,IAAa;YAErB,MAAM,IAAI,CAAC,wBAAwB,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACxE,CAAC;QAOK,AAAN,KAAK,CAAC,gBAAgB,CAAQ,GAAQ,EAAS,GAAQ;YACrD,MAAM,IAAI,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjE,CAAC;QAOK,AAAN,KAAK,CAAC,mBAAmB,CAAQ,GAAQ,EAAS,GAAQ;YACxD,MAAM,IAAI,CAAC,wBAAwB,CAAC,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACpE,CAAC;KACF,CAAA;IAzBO;QAFL,IAAA,aAAI,EAAC,GAAG,IAAA,sCAAiB,EAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,EAAE,CAAC;QACxD,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC;QAElB,WAAA,IAAA,YAAG,GAAE,CAAA;QACL,WAAA,IAAA,YAAG,GAAE,CAAA;QACL,WAAA,IAAA,aAAI,GAAE,CAAA;;;;qEAGR;IAOK;QAFL,IAAA,YAAG,EAAC,GAAG,IAAA,sCAAiB,EAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,EAAE,CAAC;QACvD,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC;QACG,WAAA,IAAA,YAAG,GAAE,CAAA;QAAY,WAAA,IAAA,YAAG,GAAE,CAAA;;;;oEAE7C;IAOK;QAFL,IAAA,eAAM,EAAC,GAAG,IAAA,sCAAiB,EAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,EAAE,CAAC;QAC1D,IAAA,kBAAS,EAAC,GAAG,MAAM,CAAC;QACM,WAAA,IAAA,YAAG,GAAE,CAAA;QAAY,WAAA,IAAA,YAAG,GAAE,CAAA;;;;uEAEhD;IArCG,wBAAwB;QAF7B,IAAA,mBAAU,GAAE;QACZ,IAAA,wBAAe,EAAC,GAAG,UAAU,CAAC;QAK1B,WAAA,IAAA,eAAM,EAAC,aAAa,CAAC,CAAA;iDACoB,sDAAwB;OALhE,wBAAwB,CAsC7B;IAED,OAAO,wBAAwB,CAAC;AAClC,CAAC","sourcesContent":["import {\n Body,\n CanActivate,\n Controller,\n Delete,\n Get,\n Inject,\n Logger,\n Post,\n Req,\n Res,\n Type,\n UseGuards,\n applyDecorators,\n} from '@nestjs/common';\n\nimport { McpOptions } from '../interfaces';\nimport { McpStreamableHttpService } from '../services/mcp-streamable-http.service';\nimport { normalizeEndpoint } from '../utils/normalize-endpoint';\n\n/**\n * Creates a controller for handling Streamable HTTP connections and tool executions\n */\nexport function createStreamableHttpController(\n endpoint: string,\n apiPrefix: string,\n guards: Type<CanActivate>[] = [],\n decorators: ClassDecorator[] = [],\n) {\n @Controller()\n @applyDecorators(...decorators)\n class StreamableHttpController {\n public readonly logger = new Logger(StreamableHttpController.name);\n\n constructor(\n @Inject('MCP_OPTIONS') public readonly options: McpOptions,\n public readonly mcpStreamableHttpService: McpStreamableHttpService,\n ) {}\n\n /**\n * Main HTTP endpoint for both initialization and subsequent requests\n */\n @Post(`${normalizeEndpoint(`${apiPrefix}/${endpoint}`)}`)\n @UseGuards(...guards)\n async handlePostRequest(\n @Req() req: any,\n @Res() res: any,\n @Body() body: unknown,\n ): Promise<void> {\n await this.mcpStreamableHttpService.handlePostRequest(req, res, body);\n }\n\n /**\n * GET endpoint for SSE streams - not supported in stateless mode\n */\n @Get(`${normalizeEndpoint(`${apiPrefix}/${endpoint}`)}`)\n @UseGuards(...guards)\n async handleGetRequest(@Req() req: any, @Res() res: any): Promise<void> {\n await this.mcpStreamableHttpService.handleGetRequest(req, res);\n }\n\n /**\n * DELETE endpoint for terminating sessions - not supported in stateless mode\n */\n @Delete(`${normalizeEndpoint(`${apiPrefix}/${endpoint}`)}`)\n @UseGuards(...guards)\n async handleDeleteRequest(@Req() req: any, @Res() res: any): Promise<void> {\n await this.mcpStreamableHttpService.handleDeleteRequest(req, res);\n }\n }\n\n return StreamableHttpController;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { ServerCapabilities } from '@modelcontextprotocol/sdk/types.js';
2
2
  import { McpRegistryService } from '../services/mcp-registry.service';
3
- import type { McpOptions } from '../interfaces';
3
+ import { McpOptions } from '../interfaces';
4
4
  export declare function buildMcpCapabilities(mcpModuleId: string, registry: McpRegistryService, options: McpOptions): ServerCapabilities;
5
5
  //# sourceMappingURL=capabilities-builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities-builder.d.ts","sourceRoot":"","sources":["../../../src/mcp/utils/capabilities-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAMhD,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,UAAU,GAClB,kBAAkB,CA8BpB"}
1
+ {"version":3,"file":"capabilities-builder.d.ts","sourceRoot":"","sources":["../../../src/mcp/utils/capabilities-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAM3C,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,UAAU,GAClB,kBAAkB,CA8BpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities-builder.js","sourceRoot":"","sources":["../../../src/mcp/utils/capabilities-builder.ts"],"names":[],"mappings":";;AAQA,oDAkCC;AAlCD,SAAgB,oBAAoB,CAClC,WAAmB,EACnB,QAA4B,EAC5B,OAAmB;IAGnB,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;IAEpD,MAAM,YAAY,GAAuB,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAGjE,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,IAAI;YACzC,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IAED,IACE,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC;QAC7C,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EACrD,CAAC;QACD,YAAY,CAAC,SAAS,GAAG,YAAY,CAAC,SAAS,IAAI;YACjD,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IAGD,IAAI,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,YAAY,CAAC,OAAO,GAAG,YAAY,CAAC,OAAO,IAAI;YAC7C,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import { ServerCapabilities } from '@modelcontextprotocol/sdk/types.js';\nimport { McpRegistryService } from '../services/mcp-registry.service';\nimport type { McpOptions } from '../interfaces';\n\n/**\n * Utility function to build MCP server capabilities dynamically based on\n * discovered tools, resources, and prompts\n */\nexport function buildMcpCapabilities(\n mcpModuleId: string,\n registry: McpRegistryService,\n options: McpOptions,\n): ServerCapabilities {\n // Start with user-provided capabilities or empty object\n const baseCapabilities = options.capabilities || {};\n\n const capabilities: ServerCapabilities = { ...baseCapabilities };\n\n // Add tools capability if tools are discovered\n if (registry.getTools(mcpModuleId).length > 0) {\n capabilities.tools = capabilities.tools || {\n listChanged: true,\n };\n }\n\n if (\n registry.getResources(mcpModuleId).length > 0 ||\n registry.getResourceTemplates(mcpModuleId).length > 0\n ) {\n capabilities.resources = capabilities.resources || {\n listChanged: true,\n };\n }\n\n // Add prompts capability if prompts are discovered\n if (registry.getPrompts(mcpModuleId).length > 0) {\n capabilities.prompts = capabilities.prompts || {\n listChanged: true,\n };\n }\n\n return capabilities;\n}\n"]}
1
+ {"version":3,"file":"capabilities-builder.js","sourceRoot":"","sources":["../../../src/mcp/utils/capabilities-builder.ts"],"names":[],"mappings":";;AAQA,oDAkCC;AAlCD,SAAgB,oBAAoB,CAClC,WAAmB,EACnB,QAA4B,EAC5B,OAAmB;IAGnB,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;IAEpD,MAAM,YAAY,GAAuB,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAGjE,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,IAAI;YACzC,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IAED,IACE,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC;QAC7C,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EACrD,CAAC;QACD,YAAY,CAAC,SAAS,GAAG,YAAY,CAAC,SAAS,IAAI;YACjD,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IAGD,IAAI,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,YAAY,CAAC,OAAO,GAAG,YAAY,CAAC,OAAO,IAAI;YAC7C,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import { ServerCapabilities } from '@modelcontextprotocol/sdk/types.js';\nimport { McpRegistryService } from '../services/mcp-registry.service';\nimport { McpOptions } from '../interfaces';\n\n/**\n * Utility function to build MCP server capabilities dynamically based on\n * discovered tools, resources, and prompts\n */\nexport function buildMcpCapabilities(\n mcpModuleId: string,\n registry: McpRegistryService,\n options: McpOptions,\n): ServerCapabilities {\n // Start with user-provided capabilities or empty object\n const baseCapabilities = options.capabilities || {};\n\n const capabilities: ServerCapabilities = { ...baseCapabilities };\n\n // Add tools capability if tools are discovered\n if (registry.getTools(mcpModuleId).length > 0) {\n capabilities.tools = capabilities.tools || {\n listChanged: true,\n };\n }\n\n if (\n registry.getResources(mcpModuleId).length > 0 ||\n registry.getResourceTemplates(mcpModuleId).length > 0\n ) {\n capabilities.resources = capabilities.resources || {\n listChanged: true,\n };\n }\n\n // Add prompts capability if prompts are discovered\n if (registry.getPrompts(mcpModuleId).length > 0) {\n capabilities.prompts = capabilities.prompts || {\n listChanged: true,\n };\n }\n\n return capabilities;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rekog/mcp-nest",
3
- "version": "1.8.1-alpha.4",
3
+ "version": "1.8.1",
4
4
  "description": "NestJS module for creating Model Context Protocol (MCP) servers",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",
@@ -7,7 +7,7 @@ import {
7
7
  } from '@nestjs/common';
8
8
  import { Request } from 'express';
9
9
  import { JwtPayload, JwtTokenService } from '../services/jwt-token.service';
10
- import type { IOAuthStore } from '../stores/oauth-store.interface';
10
+ import { IOAuthStore } from '../stores/oauth-store.interface';
11
11
 
12
12
  export interface AuthenticatedRequest extends Request {
13
13
  user: JwtPayload;
@@ -26,7 +26,7 @@ import {
26
26
  import { ClientService } from './services/client.service';
27
27
  import { JwtTokenService, TokenPair } from './services/jwt-token.service';
28
28
  import { STRATEGY_NAME } from './services/oauth-strategy.service';
29
- import type { IOAuthStore } from './stores/oauth-store.interface';
29
+ import { IOAuthStore } from './stores/oauth-store.interface';
30
30
 
31
31
  interface OAuthCallbackRequest extends ExpressRequest {
32
32
  user?: {
@@ -1,5 +1,5 @@
1
1
  import { TypeOrmModuleOptions } from '@nestjs/typeorm';
2
- import type { IOAuthStore } from '../stores/oauth-store.interface';
2
+ import { IOAuthStore } from '../stores/oauth-store.interface';
3
3
 
4
4
  export interface OAuthProviderConfig {
5
5
  name: string;
@@ -1,7 +1,7 @@
1
1
  import { BadRequestException, Injectable, Inject } from '@nestjs/common';
2
- import type { IOAuthStore } from '../stores/oauth-store.interface';
3
2
  import {
4
3
  ClientRegistrationDto,
4
+ IOAuthStore,
5
5
  OAuthClient,
6
6
  } from '../stores/oauth-store.interface';
7
7
  import { randomBytes } from 'crypto';
@@ -4,8 +4,11 @@ import {
4
4
  OAuthSession,
5
5
  OAuthUserProfile,
6
6
  } from '../providers/oauth-provider.interface';
7
- import { AuthorizationCode, OAuthClient } from './oauth-store.interface';
8
- import type { IOAuthStore } from './oauth-store.interface';
7
+ import {
8
+ AuthorizationCode,
9
+ IOAuthStore,
10
+ OAuthClient,
11
+ } from './oauth-store.interface';
9
12
 
10
13
  // In-memory storage (in production, use a database)
11
14
  @Injectable()
@@ -13,8 +13,11 @@ import {
13
13
  OAuthSession,
14
14
  OAuthUserProfile,
15
15
  } from '../../providers/oauth-provider.interface';
16
- import { AuthorizationCode, OAuthClient } from '../oauth-store.interface';
17
- import type { IOAuthStore } from '../oauth-store.interface';
16
+ import {
17
+ AuthorizationCode,
18
+ IOAuthStore,
19
+ OAuthClient,
20
+ } from '../oauth-store.interface';
18
21
 
19
22
  @Injectable()
20
23
  export class TypeOrmStore implements IOAuthStore {
@@ -118,7 +118,7 @@ export class McpModule {
118
118
  return [
119
119
  {
120
120
  provide: 'MCP_OPTIONS',
121
- useFactory: async (...args: any[]) => {
121
+ useFactory: async (...args: unknown[]) => {
122
122
  const resolved: McpAsyncOptions = await options.useFactory!(
123
123
  ...args,
124
124
  );
@@ -3,7 +3,7 @@ import { ApplicationConfig, ContextIdFactory, ModuleRef } from '@nestjs/core';
3
3
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
4
  import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
5
5
  import { buildMcpCapabilities } from '../utils/capabilities-builder';
6
- import type { McpOptions } from '../interfaces';
6
+ import { McpOptions } from '../interfaces';
7
7
  import { McpExecutorService } from './mcp-executor.service';
8
8
  import { McpRegistryService } from './mcp-registry.service';
9
9
  import { SsePingService } from './sse-ping.service';
@@ -8,7 +8,7 @@ import {
8
8
  HttpRequest,
9
9
  HttpResponse,
10
10
  } from '../interfaces/http-adapter.interface';
11
- import type { McpOptions } from '../interfaces';
11
+ import { McpOptions } from '../interfaces';
12
12
  import { McpExecutorService } from './mcp-executor.service';
13
13
  import { McpRegistryService } from './mcp-registry.service';
14
14
  import { buildMcpCapabilities } from '../utils/capabilities-builder';
@@ -15,7 +15,7 @@ import {
15
15
  applyDecorators,
16
16
  } from '@nestjs/common';
17
17
 
18
- import type { McpOptions } from '../interfaces';
18
+ import { McpOptions } from '../interfaces';
19
19
  import { McpSseService } from '../services/mcp-sse.service';
20
20
  import { normalizeEndpoint } from '../utils/normalize-endpoint';
21
21
 
@@ -7,8 +7,7 @@ import {
7
7
  OnApplicationBootstrap,
8
8
  } from '@nestjs/common';
9
9
  import { ContextIdFactory, ModuleRef } from '@nestjs/core';
10
- import { McpTransportType } from '../interfaces';
11
- import type { McpOptions } from '../interfaces';
10
+ import { McpOptions, McpTransportType } from '../interfaces';
12
11
  import { McpExecutorService } from '../services/mcp-executor.service';
13
12
  import { McpRegistryService } from '../services/mcp-registry.service';
14
13
  import { buildMcpCapabilities } from '../utils/capabilities-builder';
@@ -14,7 +14,7 @@ import {
14
14
  applyDecorators,
15
15
  } from '@nestjs/common';
16
16
 
17
- import type { McpOptions } from '../interfaces';
17
+ import { McpOptions } from '../interfaces';
18
18
  import { McpStreamableHttpService } from '../services/mcp-streamable-http.service';
19
19
  import { normalizeEndpoint } from '../utils/normalize-endpoint';
20
20
 
@@ -1,6 +1,6 @@
1
1
  import { ServerCapabilities } from '@modelcontextprotocol/sdk/types.js';
2
2
  import { McpRegistryService } from '../services/mcp-registry.service';
3
- import type { McpOptions } from '../interfaces';
3
+ import { McpOptions } from '../interfaces';
4
4
 
5
5
  /**
6
6
  * Utility function to build MCP server capabilities dynamically based on