app.module.tsβ’2.65 kB
import { Module } from '@nestjs/common'
import { randomUUID } from 'crypto'
import { ConfigModule } from '@nestjs/config'
import {
McpModule,
McpTransportType,
McpAuthModule,
GoogleOAuthProvider,
McpAuthJwtGuard,
} from '@rekog/mcp-nest'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { TimezoneModule } from '../timezone/timezone.module'
import { McpToolsModule } from '../mcp-tools/mcp-tools.module'
import { McpAuthGuardModule } from '../mcp-auth/mcp-auth-guard.module'
import { EmailAllowlistGuard } from '../mcp-auth/email-allowlist.guard'
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
// MCP Auth Guard Module (provides EmailAllowlistGuard globally)
McpAuthGuardModule,
// MCP Authentication Module (only protects MCP endpoints)
McpAuthModule.forRoot({
provider: GoogleOAuthProvider,
// Provide test defaults if env vars are not set (for unit/e2e tests)
clientId: process.env.MCP_AUTH_CLIENT_ID || 'test-client-id',
clientSecret: process.env.MCP_AUTH_CLIENT_SECRET || 'test-client-secret',
jwtSecret: process.env.MCP_AUTH_JWT_SECRET || process.env.JWT_SECRET || 'test-jwt-secret',
serverUrl:
process.env.MCP_AUTH_SERVER_URL || process.env.SERVER_URL || 'http://localhost:3000',
jwtAccessTokenExpiresIn: process.env.JWT_EXPIRES_IN || '3600s',
enableRefreshTokens: false,
storeConfiguration: {
type: 'memory', // Use in-memory store for simplicity
},
apiPrefix: '/auth/mcp',
}),
TimezoneModule.forRoot(),
McpToolsModule,
McpModule.forRoot({
name: 'timezone-mcp-server',
version: '1.0.0',
capabilities: {
tools: {},
prompts: {},
},
// We can't use the ConfigModule here. We would have
// to use forRootAsync, but the `transport` option
// seems to be explicitely excluded from that in
// the @rekog/mcp-nest source code.
transport:
process.env.MCP_TRANSPORT === 'stdio'
? McpTransportType.STDIO
: McpTransportType.STREAMABLE_HTTP,
mcpEndpoint: '/mcp',
streamableHttp: {
enableJsonResponse: false,
sessionIdGenerator: () => randomUUID(),
},
// Apply JWT auth guard first, then email allowlist guard to MCP endpoints
// McpAuthJwtGuard validates JWT and populates request.user
// EmailAllowlistGuard validates the email from request.user
guards: [McpAuthJwtGuard, EmailAllowlistGuard],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}