import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { McpModule } from '@nestjs-mcp/server'; import { TASKSTREAM_API_URL, TaskStreamApi } from './api/taskstream-api'; import { HealthController } from './health.controller'; import { McpHostsMiddleware } from './mcp-hosts.middleware'; import { BacklogResolver } from './tools/backlog.resolver'; import { IssuesResolver } from './tools/issues.resolver'; import { NotificationsResolver } from './tools/notifications.resolver'; import { ProjectsResolver } from './tools/projects.resolver'; import { ReleasesResolver } from './tools/releases.resolver'; import { SprintsResolver } from './tools/sprints.resolver'; import { UsersResolver } from './tools/users.resolver'; const INSTRUCTIONS = `TaskStream: issue tracker (projects, tickets, epics, sprints, QA, releases). Projects and tickets go by key (WEB, WEB-12). Statuses, ticket types and areas are per project: read their ids with get_project before creating, updating or moving tickets, and use a ticket's allowedTransitions (get_issue) to move it. Sprints and releases go by id (list_sprints, list_releases); the backlog is search_issues with noSprint and sort RANK. Tools act as the user whose Pireon token the client sends; without one, only public projects can be read.`; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), McpModule.forRootAsync({ inject: [ConfigService], useFactory: (config: ConfigService) => ({ name: 'taskstream', version: '1.0.0', instructions: INSTRUCTIONS, // The library logs every tool on every request (it builds a server per call): // only warnings and errors unless asked for more. logging: { level: config.get('MCP_LOG_LEVEL', 'warn') }, }), }), ], controllers: [HealthController], providers: [ { provide: TASKSTREAM_API_URL, inject: [ConfigService], // Origin of the API (its routes already start with /api). useFactory: (config: ConfigService) => config .get('TASKSTREAM_API_URL', 'http://localhost:3000') .replace(/\/+$/, ''), }, TaskStreamApi, ProjectsResolver, IssuesResolver, BacklogResolver, SprintsResolver, ReleasesResolver, NotificationsResolver, UsersResolver, ], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer): void { consumer.apply(McpHostsMiddleware).forRoutes('mcp'); } }