Add it to Claude Code
claude mcp add mcp-nestjs -- node dist/main.jsMake your agent remember this setup
mcp-nestjs's config, env vars, and the gotchas you hit — recalled in every future Claude Code, Cursor, and Codex session.
npx conare@latestFree · one command · indexes the sessions already on disk. Set up in the browser instead →
What it does
- Decorator-driven registration of tools, resources, and prompts
- Automatic discovery of decorated methods in providers and controllers
- Support for multiple transports including SSE, Streamable HTTP, and Stdio
- Built-in interactive playground UI for testing tools
- Schema adapter support for Zod, Joi, and class-validator
Try it
Original README from zahidhasanaunto/mcp-nestjs
mcp-nestjs
NestJS module for building Model Context Protocol (MCP) servers. Expose your NestJS services as MCP tools, resources, and prompts using decorators — with auto-discovery, multiple transports, and a built-in playground UI.
Features
- Decorator-driven —
@McpTool(),@McpResource(),@McpPrompt(),@McpGuard(),@McpToolGroup() - Auto-discovery — decorated methods on any provider or controller are registered automatically
- Schema adapters — auto-detect Zod, Joi, class-validator, or inline schemas (zero config)
- Multiple transports — SSE, Streamable HTTP, and Stdio (JSON-RPC 2.0)
- Built-in playground — interactive UI at
/mcp-playgroundto browse and test tools - Guards — per-tool or per-class authorization
- Session management — configurable timeout, cleanup, and max sessions
- No SDK dependency — custom JSON-RPC 2.0 implementation
Installation
npm install mcp-nestjs
Peer dependencies (your NestJS app already has these):
npm install @nestjs/common @nestjs/core reflect-metadata rxjs
Optional schema libraries (auto-detected):
npm install zod # for Zod schemas
npm install joi # for Joi schemas
npm install class-validator class-transformer # for DTO schemas
Quick Start
// app.module.ts
import { Module } from '@nestjs/common';
import { McpModule } from 'mcp-nestjs';
import { GreetingService } from './greeting.service';
@Module({
imports: [
McpModule.forRoot({
name: 'my-mcp-server',
version: '1.0.0',
transports: { sse: { enabled: true } },
playground: true,
}),
],
providers: [GreetingService],
})
export class AppModule {}
// greeting.service.ts
import { Injectable } from '@nestjs/common';
import { McpTool } from 'mcp-nestjs';
@Injectable()
export class GreetingService {
@McpTool({
description: 'Say hello to someone',
schema: {
name: { type: 'string', description: 'Name to greet' },
},
})
async greet(args: { name: string }) {
return { message: `Hello, ${args.name}!` };
}
}
Start your app and visit http://localhost:3000/mcp-playground.
Module Configuration
`McpModule.forRoot(options)`
McpModule.forRoot({
name: 'my-server', // Server name (required)
version: '1.0.0', // Server version (required)
transports: {
sse: { enabled: true, path: '/sse' }, // SSE transport
http: { enabled: true, path: '/mcp' }, // Streamable HTTP transport
stdio: { enabled: false }, // Stdio transport
},
session: {
timeout: 30 * 60 * 1000, // Session timeout (default: 30min)
cleanupInterval: 5 * 60 * 1000, // Cleanup interval (default: 5min)
maxSessions: 1000, // Max concurrent sessions
},
playground: true, // Enable playground UI
tools: [], // Manual tool registrations
guards: [], // Global guards
})
`McpModule.forRootAsync(options)`
McpModule.forRootAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
name: config.get('MCP_SERVER_NAME'),
version: config.get('MCP_VERSION'),
transports: { sse: { enabled: true } },
playground: true,
}),
inject: [ConfigService],
})
`McpModule.forFeature(providers)`
Register additional providers in feature modules:
McpModule.forFeature([MyFeatureService])
Decorators
`@McpTool(options)` — Method Decorator
Marks a method as an MCP tool.
@McpTool({
name?: string, // Override tool name (default: [group_]methodName)
description: string, // Required description
schema?: ZodType | JoiSchema | Record<string, InlinePropertyDef>, // Input schema
transform?: 'auto' | 'raw' | ((result) => ToolResult), // Response mode
excludeProperties?: string[], // Hide fields from schema
requiredProperties?: string[], // Override required fields
})
Schema options:
// Inline (always available)
@McpTool({
description: 'Search users',
schema: {
query: { type: 'string', description: 'Search term' },
limit: { type: 'number', default: 10, required: false },
role: { type: 'string', enum: ['admin', 'user'] },
tags: { type: 'array', items: { type: 'string' }, required: false },
},
})
// Zod (if installed)
import { z } from 'zod';
@McpTool({
description: 'Create user',
schema: z.object({
name: z.string(),
email: z.string(),
role: z.enum(['admin', 'user']).optional(),
}),
})
// Joi (if installed)
import Joi from 'joi';
@McpTool({
description: 'Create user',
schema: Joi.object({
name: Joi.string().required(),
email: Joi.string().required(),
}),
})
Transform modes: