================================================================================ MCP MODULE - COMPLETE FILES LISTING ================================================================================ PROJECT: GoodGo Platform MODULE: Model Context Protocol (MCP) Integration LOCATION: apps/api/src/modules/mcp/ DATE: April 11, 2026 ================================================================================ 1. SOURCE FILES ================================================================================ ๐Ÿ“„ File 1: apps/api/src/modules/mcp/index.ts โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” Type: Module Export/Index Lines: 1 Purpose: Main module entry point Exports: { McpIntegrationModule } Content: โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ export { McpIntegrationModule } from './mcp.module'; Status: โœ… Simple re-export, well-formed ๐Ÿ“„ File 2: apps/api/src/modules/mcp/mcp.module.ts โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” Type: NestJS Module Configuration Lines: 22 Purpose: Bootstrap MCP integration module with dependencies Key Features: โ€ข @Module decorator with imports, controllers โ€ข Implements OnModuleInit lifecycle hook โ€ข Configures McpCoreModule.forRoot() with settings โ€ข Sets up service integration (Typesense, Auth, MCP Registry) โ€ข Logs initialized servers on startup Decorator: @Module({ imports: [SearchModule, AuthModule, McpCoreModule.forRoot({...})], controllers: [McpTransportController], }) Class: McpIntegrationModule implements OnModuleInit Injected Dependencies: 1. typesenseClient: TypesenseClientService (from SearchModule) 2. mcpRegistry: McpRegistryService (from @goodgo/mcp-servers) 3. logger: LoggerService (from SharedModule) Lifecycle Hook: async onModuleInit(): Promise - Sets Typesense client on registry - Re-initializes MCP servers - Logs server names on startup Status: โš ๏ธ Partially tested (initialization logic not covered) ๐Ÿ“„ File 3: apps/api/src/modules/mcp/presentation/mcp-transport.controller.ts โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” Type: NestJS HTTP Controller Lines: 102 Purpose: HTTP transport layer for MCP Server-Sent Events (SSE) connections Decorators Applied: @ApiTags('mcp') - Swagger grouping @ApiBearerAuth('JWT') - API doc @Controller('mcp') - Route prefix @UseGuards(JwtAuthGuard) - Auth guard (all endpoints) Private Properties: transports: Map โ†’ Active session tracking by sessionId Constructor: McpTransportController(registry: McpRegistryService) Endpoints (3): 1๏ธโƒฃ GET /mcp/servers โ”œโ”€โ”€ Decorator: @Get('servers') โ”œโ”€โ”€ Throttle: 30 requests per 60,000ms โ”œโ”€โ”€ Auth: JwtAuthGuard โœ… โ”œโ”€โ”€ Returns: { servers: string[] } โ”œโ”€โ”€ HTTP Status: 200 OK, 401 Unauthorized โ””โ”€โ”€ Logic: Returns server.names from registry 2๏ธโƒฃ GET /mcp/:serverName/sse โ”œโ”€โ”€ Decorator: @Get(':serverName/sse') โ”œโ”€โ”€ Throttle: 5 requests per 60,000ms โšก (STRICTER) โ”œโ”€โ”€ Params: serverName (string) โ”œโ”€โ”€ Auth: JwtAuthGuard โœ…, CurrentUser decorator โ”œโ”€โ”€ Returns: SSE stream (response.write) โ”œโ”€โ”€ HTTP Status: 200 (stream), 404 (not found), 401 (unauthorized) โ””โ”€โ”€ Logic: 1. Verify server exists (throw NOT_FOUND if not) 2. Create SSEServerTransport instance 3. Store in Map[sessionId] 4. Attach close listener for cleanup 5. Connect transport to server 3๏ธโƒฃ POST /mcp/:serverName/messages โ”œโ”€โ”€ Decorator: @Post(':serverName/messages') โ”œโ”€โ”€ Throttle: 30 requests per 60,000ms โ”œโ”€โ”€ Params: serverName (string) โ”œโ”€โ”€ Query: sessionId (required) โ”œโ”€โ”€ Auth: JwtAuthGuard โœ…, CurrentUser decorator โ”œโ”€โ”€ Returns: Delegate response to transport โ”œโ”€โ”€ HTTP Status: 200 OK, 400 (missing sessionId), 404 (not found), 401 (unauthorized) โ””โ”€โ”€ Logic: 1. Extract sessionId from query 2. Validate sessionId present (throw BAD_REQUEST if not) 3. Look up transport (throw NOT_FOUND if expired) 4. Delegate to transport.handlePostMessage() Status: โœ… Well tested (see spec file) ================================================================================ 2. TEST FILES ================================================================================ ๐Ÿงช File 4: apps/api/src/modules/mcp/presentation/__tests__/mcp-transport.controller.spec.ts โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” Type: Unit Test Suite Lines: 174 Testing Framework: Vitest Subject: McpTransportController Test Coverage: 11 tests in 4 describe blocks DESCRIBE BLOCK 1: security decorators (4 tests) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โœ… Test 1: has JwtAuthGuard applied at controller level Method: Reflect.getMetadata('__guards__', McpTransportController) Checks: guards exist and contain JwtAuthGuard โœ… Test 2: has Throttle metadata on listServers endpoint Metadata: THROTTLER:LIMITdefault Expected: 30 โœ… Test 3: has Throttle metadata on handleSse endpoint with low limit Metadata: THROTTLER:LIMITdefault on handleSse Expected: 5 (stricter limit) โœ… Test 4: has Throttle metadata on handleMessage endpoint Metadata: THROTTLER:LIMITdefault Expected: 30 DESCRIBE BLOCK 2: listServers (2 tests) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โœ… Test 1: returns list of server names from registry Setup: mockRegistry.getServerNames.mockReturnValue(['search', 'listings']) Action: controller.listServers() Assert: result.servers equals ['search', 'listings'] Verify: getServerNames called once โœ… Test 2: returns empty array when no servers registered Setup: mockRegistry.getServerNames.mockReturnValue([]) Action: controller.listServers() Assert: result.servers equals [] DESCRIBE BLOCK 3: handleSse (3 tests) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โœ… Test 1: throws NOT_FOUND when server does not exist Setup: mockRegistry.getServer.mockReturnValue(null) Action: controller.handleSse('nonexistent', mockUser, req, res) Assert: Throws HttpException Status: HttpStatus.NOT_FOUND Message: Contains 'nonexistent' โœ… Test 2: creates transport and connects to server Setup: mockServer.connect mock resolved Action: controller.handleSse('search', mockUser, req, res) Verify: - getServer called with 'search' - connect called once - req.on called with 'close' event โœ… Test 3: cleans up transport on connection close Setup: handleSse called successfully Action: Simulate connection close by calling closeHandler Assert: Subsequent handleMessage fails with NOT_FOUND (proves transport was deleted from Map) DESCRIBE BLOCK 4: handleMessage (2 tests) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โœ… Test 1: throws BAD_REQUEST when sessionId query parameter is missing Setup: mockReq.query = {} Action: controller.handleMessage('search', mockUser, req, res) Assert: Throws HttpException Status: HttpStatus.BAD_REQUEST โœ… Test 2: throws NOT_FOUND when session does not exist Setup: mockReq.query = { sessionId: 'nonexistent-session' } Action: controller.handleMessage('search', mockUser, req, res) Assert: Throws HttpException Status: HttpStatus.NOT_FOUND Mocking Strategies Used: 1. vi.mock() - Module mocking (SSEServerTransport) 2. vi.fn() - Function mocks (service methods) 3. mockReturnValue() - Sync returns 4. mockResolvedValue() - Async returns 5. Manual mock objects - req/res simulation 6. Reflect.getMetadata() - Decorator inspection Status: โœ… Comprehensive test coverage ================================================================================ 3. ARCHITECTURE & DDD LAYERS ================================================================================ Current Status: SIMPLIFIED ARCHITECTURE (Presentation-only) โœ… IMPLEMENTED LAYERS: Presentation Layer โ”œโ”€โ”€ Controllers โ”‚ โ””โ”€โ”€ mcp-transport.controller.ts (102 lines) โ”‚ โ”œโ”€โ”€ 3 HTTP endpoints โ”‚ โ”œโ”€โ”€ JWT auth protection โ”‚ โ”œโ”€โ”€ Rate limiting (throttle) โ”‚ โ””โ”€โ”€ SSE session management โ”‚ โ””โ”€โ”€ Tests โ””โ”€โ”€ __tests__/mcp-transport.controller.spec.ts (174 lines) โ”œโ”€โ”€ 11 tests โ”œโ”€โ”€ 4 describe blocks โ””โ”€โ”€ Comprehensive coverage โŒ MISSING LAYERS: Domain Layer (NO FILES) โ”œโ”€โ”€ No entities/ โ”œโ”€โ”€ No value-objects/ โ”œโ”€โ”€ No domain-events/ โ””โ”€โ”€ No repositories/ interfaces Application Layer (NO FILES) โ”œโ”€โ”€ No handlers/ (CQRS) โ”œโ”€โ”€ No commands/ โ”œโ”€โ”€ No queries/ โ””โ”€โ”€ No DTOs/ Infrastructure Layer (NO FILES) โ”œโ”€โ”€ No repositories/ (implementations) โ”œโ”€โ”€ No services/ โ””โ”€โ”€ No external-adapters/ Architecture Notes: โ€ข Acts as integration wrapper โ€ข Delegates to @goodgo/mcp-servers library โ€ข Simple HTTP-to-SSE bridge โ€ข In-memory session tracking (Map) โ€ข No persistence or business logic ================================================================================ 4. DEPENDENCIES & IMPORTS ================================================================================ External Dependencies: โ€ข @goodgo/mcp-servers (SSEServerTransport, McpRegistryService) โ€ข @nestjs/common (Controller, decorators, etc.) โ€ข @nestjs/swagger (API documentation) โ€ข @nestjs/throttler (Rate limiting) Internal Dependencies: โ€ข @modules/auth (JwtAuthGuard, CurrentUser) โ€ข @modules/search (TypesenseClientService) โ€ข @modules/shared (LoggerService) Direct Imports in Module: import { McpTransportController } from './presentation/mcp-transport.controller'; import { SearchModule, AuthModule } from other modules; ================================================================================ 5. KEY STATISTICS ================================================================================ File Count: โ€ข Total Source Files: 4 โ€ข Test Files: 1 โ€ข Lines of Code: 125 (implementation only) โ€ข Lines of Tests: 174 โ€ข Test/Code Ratio: 1.39:1 Test Coverage: โ€ข Controller Methods Tested: 3/3 (100%) โ€ข Endpoints Tested: 3/3 (100%) โ€ข Security Decorators Tested: โœ… โ€ข Error Cases Tested: โœ… โ€ข Happy Path Cases: โœ… โ€ข Module Initialization: โš ๏ธ (Partial) Classes & Handlers: โ€ข Controllers: 1 (McpTransportController) โ€ข Modules: 1 (McpIntegrationModule) โ€ข Handlers: 0 (Not using CQRS) โ€ข Entities: 0 (Not implemented) โ€ข Services: 0 (Delegated to library) ================================================================================ 6. TESTING PATTERNS & CONVENTIONS ================================================================================ Framework: Vitest Config: apps/api/vitest.config.ts โ€ข globals: true (vi, describe, it, expect available globally) โ€ข environment: 'node' โ€ข pattern: src/**/*.spec.ts Common Patterns in Codebase: Pattern A: Simple Handler Testing (Auth module) โ”œโ”€โ”€ Minimal mocking โ”œโ”€โ”€ Command objects for input โ””โ”€โ”€ Focused assertions Pattern B: Complex Handler Testing (Payments module) โ”œโ”€โ”€ Multiple dependency mocks โ”œโ”€โ”€ Business rule testing โ”œโ”€โ”€ Event bus verification โ””โ”€โ”€ Error scenario coverage Pattern C: Domain Entity Testing (Payments module) โ”œโ”€โ”€ Explicit vitest imports โ”œโ”€โ”€ Entity state transitions โ”œโ”€โ”€ Domain event verification โ”œโ”€โ”€ Value object testing โ””โ”€โ”€ Helper factory functions Pattern D: Infrastructure Service Testing (Zalopay service) โ”œโ”€โ”€ External service simulation โ”œโ”€โ”€ Crypto/security testing โ”œโ”€โ”€ Complex test data builders โ””โ”€โ”€ Edge case coverage ================================================================================ 7. RECOMMENDED TEST COMMANDS ================================================================================ Run all MCP tests: $ pnpm test -- src/modules/mcp Run specific test file: $ pnpm test -- src/modules/mcp/presentation/__tests__/mcp-transport.controller.spec.ts Run with watch mode: $ pnpm test -- --watch src/modules/mcp Run with coverage: $ pnpm test -- --coverage src/modules/mcp Run all tests (project-wide): $ pnpm test ================================================================================ SUMMARY ================================================================================ The MCP module is a SIMPLIFIED integration layer that: โœ… Exposes 3 HTTP endpoints for MCP server access โœ… Handles SSE connection lifecycle โœ… Provides rate limiting and JWT authentication โœ… Well-tested at controller level (174 lines of tests) Areas for Improvement: โš ๏ธ Module initialization not tested โš ๏ธ No domain layer implementation โš ๏ธ No application handlers (CQRS) โš ๏ธ No infrastructure adapters The module follows project conventions: โœ… Vitest for testing โœ… vi.fn() for mocking โœ… Decorator verification with Reflect API โœ… Organized __tests__/ subdirectory For additional test examples: โ€ข Auth module: apps/api/src/modules/auth/application/__tests__/ โ€ข Payments module: apps/api/src/modules/payments/ โ€ข Search module: apps/api/src/modules/search/ ================================================================================ Generated: April 11, 2026 ================================================================================