nestjs-mcp
v1.0.6
Published
Automatic MCP server generation for NestJS applications
Maintainers
Readme
@nestjs-mcp/server
Automatic generation of an MCP (Model Context Protocol) server for NestJS applications, enabling Claude Desktop to manage your application without creating a separate admin panel.
🚀 Features
- 🎯 Automatic Scanning - Detects all controllers with the
@UseMCP()decorator - 📝 Schema Generation - Automatically generates JSON Schema from DTO classes
- 🔒 Support for Guards and Interceptors - Full integration with the NestJS pipeline
- 🔄 Data Transformation - Configurable transformers for input/output data
- 📊 Validation - Automatic validation based on class-validator
- 🛠️ CLI Tools - Commands for configuration generation and testing
- 📦 TypeScript - Full typing and IntelliSense support
📦 Installation
npm install @nestjs-mcp/server
# or
yarn add @nestjs-mcp/server🔧 Quick Start
1. Import the Module
import { Module } from '@nestjs/common';
import { MCPModule } from '@nestjs-mcp/server';
@Module({
imports: [
MCPModule.register({
name: 'My NestJS App',
version: '1.0.0',
autoScan: true,
enableLogging: true,
}),
],
})
export class AppModule {}2. Decorate Controllers
import { Controller, Get, Post, Body } from '@nestjs/common';
import { UseMCP } from '@nestjs-mcp/server';
@Controller('users')
@UseMCP({
name: 'user-management',
description: 'System user management',
})
export class UserController {
@Get()
async getUsers() {
return this.userService.findAll();
}
@Post()
async createUser(@Body() dto: CreateUserDto) {
return this.userService.create(dto);
}
}3. Generate Configuration for Claude Desktop
npx nestjs-mcp generate-config4. Connect via Claude Desktop
Copy the generated configuration to Claude Desktop settings and restart the application.
📚 Detailed Documentation
@UseMCP() Decorator
@UseMCP({
// Resource name for MCP (defaults to controller name)
name?: string;
// Description for Claude
description?: string;
// Methods to export (defaults to all public methods)
methods?: string[];
// Data transformers
transformers?: {
input?: (data: any) => any;
output?: (data: any) => any;
};
// Enable DTO validation (default: true)
validation?: boolean;
// Required permissions
permissions?: string[];
// Controller grouping
group?: string;
// Tags for categorization
tags?: string[];
// Conditional registration
condition?: () => boolean;
})Method Configuration
import { MCPMethod, SkipMCP } from '@nestjs-mcp/server';
@Controller('products')
@UseMCP()
export class ProductController {
// Customize individual method
@Get(':id')
@MCPMethod({
name: 'get_product_details',
description: 'Retrieve detailed product information',
})
async getProduct(@Param('id') id: string) {
// ...
}
// Exclude method from MCP
@Post('internal')
@SkipMCP()
async internalMethod() {
// ...
}
}Advanced Configuration
MCPModule.register({
port: 3001,
name: 'E-Commerce API',
version: '2.0.0',
// Controller auto-scanning
autoScan: true,
includePatterns: ['**/*.controller.ts'],
excludePatterns: ['**/*.spec.ts', '**/internal/**'],
// Logging
enableLogging: true,
// CORS settings
cors: {
origin: ['http://localhost:*'],
methods: ['GET', 'POST'],
credentials: true,
},
// Authentication
auth: {
enabled: true,
validateToken: async (token: string) => {
// Your token validation logic
return isValidToken(token);
},
},
// Rate limiting
rateLimit: {
windowMs: 60000, // 1 minute
max: 100, // Maximum requests
},
})Grouping and Organization
// Grouping related controllers
@Controller('users')
@UseMCP({
group: 'user-management',
tags: ['admin', 'users'],
})
export class UserController {}
@Controller('roles')
@UseMCP({
group: 'user-management',
tags: ['admin', 'roles'],
})
export class RoleController {}Data Transformation
@Controller('reports')
@UseMCP({
transformers: {
// Input data transformation
input: (data) => ({
...data,
requestedAt: new Date(),
}),
// Output data transformation
output: (result) => ({
data: result,
timestamp: new Date().toISOString(),
version: '1.0',
}),
},
})
export class ReportController {}🛠️ CLI Commands
Configuration Generation
npx nestjs-mcp generate-config [options]
Options:
-o, --output <path> Path to output file (default: claude_desktop_config.json)
-e, --env <json> Environment variables in JSON format
-a, --args <json> Additional arguments in JSON formatController Validation
npx nestjs-mcp validate [options]
Options:
-v, --verbose Show detailed output
-c, --controllers <names> Check specific controllers (comma-separated)Connection Testing
npx nestjs-mcp test [options]
Options:
-p, --port <port> MCP server port (default: 3001)🎯 Usage Examples
Basic CRUD Controller
@Controller('products')
@UseMCP({
description: 'Product catalog management',
})
export class ProductController {
constructor(private productService: ProductService) {}
@Get()
async findAll(@Query() query: FilterProductDto) {
return this.productService.findAll(query);
}
@Get(':id')
async findOne(@Param('id') id: string) {
return this.productService.findOne(id);
}
@Post()
async create(@Body() dto: CreateProductDto) {
return this.productService.create(dto);
}
@Put(':id')
async update(@Param('id') id: string, @Body() dto: UpdateProductDto) {
return this.productService.update(id, dto);
}
@Delete(':id')
async remove(@Param('id') id: string) {
return this.productService.remove(id);
}
}Controller with Guards and Interceptors
@Controller('admin')
@UseMCP({
permissions: ['admin'],
})
@UseGuards(AuthGuard, RoleGuard)
@UseInterceptors(LoggingInterceptor)
export class AdminController {
@Post('users/ban')
@MCPMethod({
description: 'Ban a user',
transformOutput: (result) => ({
success: true,
userId: result.id,
bannedAt: new Date().toISOString(),
}),
})
async banUser(@Body() dto: BanUserDto) {
return this.adminService.banUser(dto.userId, dto.reason);
}
}Async Configuration
@Module({
imports: [
MCPModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
name: configService.get('APP_NAME'),
version: configService.get('APP_VERSION'),
port: configService.get('MCP_PORT'),
auth: {
enabled: true,
validateToken: async (token) => {
// Validation via external service
return authService.validateToken(token);
},
},
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}🔍 Debugging and Monitoring
Enabling Detailed Logging
MCPModule.register({
enableLogging: true,
// Optionally configure Winston logger
})Viewing Registered Tools
@Injectable()
export class MCPDebugService {
constructor(private mcpServer: MCPServer) {}
getRegisteredTools() {
return this.mcpServer.getTools();
}
}🚨 Error Handling
The library automatically handles errors and returns them in a structured format:
@Post()
async createUser(@Body() dto: CreateUserDto) {
try {
return await this.userService.create(dto);
} catch (error) {
// Errors are automatically formatted for Claude
throw new BadRequestException('User already exists');
}
}🔒 Security
- Token authentication support
- Integration with NestJS Guards
- Rate limiting to prevent overload
- Validation of all input data
- CORS support
📝 License
MIT
🤝 Contributing
We welcome contributions to the project! Please review CONTRIBUTING.md for details.
🐛 Bug Reports
If you find a bug, please create an issue on GitHub.
