NestJS MCP 서버 모듈

MCP(Model Context Protocol)를 사용하여 NestJS 애플리케이션에서 AI를 위한 도구, 리소스 및 프롬프트를 손쉽게 노출할 수 있는 NestJS 모듈입니다.
@rekog/mcp-nest 사용하면 NestJS에서 익숙한 방식으로 도구, 리소스, 프롬프트를 정의하고 종속성 주입의 모든 기능을 활용하여 기존 코드베이스를 활용하여 복잡한 엔터프라이즈급 MCP 서버를 구축할 수 있습니다.
특징
🚀 모든 전송 유형 지원:
스트리밍 가능한 HTTP
HTTP+SSE
스튜디오
🔍 자동 tool , resource , prompt 검색 및 등록
💯 Zod 기반 도구 호출 검증
📊 진행 상황 알림
🔒 가드 기반 인증
🌐 MCP 리소스(도구, 리소스, 프롬프트) 내 HTTP 요청 정보에 대한 액세스
Related MCP server: SSE MCP Server
설치
지엑스피1
빠른 시작
1. 모듈 가져오기
// app.module.ts
import { Module } from '@nestjs/common';
import { McpModule } from '@rekog/mcp-nest';
import { GreetingTool } from './greeting.tool';
@Module({
imports: [
McpModule.forRoot({
name: 'my-mcp-server',
version: '1.0.0',
}),
],
providers: [GreetingTool],
})
export class AppModule {}
2. 도구 및 리소스 정의
// greeting.tool.ts
import type { Request } from 'express';
import { Injectable } from '@nestjs/common';
import { Tool, Resource, Context } from '@rekog/mcp-nest';
import { z } from 'zod';
import { Progress } from '@modelcontextprotocol/sdk/types';
@Injectable()
export class GreetingTool {
constructor() {}
@Tool({
name: 'hello-world',
description:
'Returns a greeting and simulates a long operation with progress updates',
parameters: z.object({
name: z.string().default('World'),
}),
})
async sayHello({ name }, context: Context, request: Request) {
const userAgent = request.get('user-agent') || 'Unknown';
const greeting = `Hello, ${name}! Your user agent is: ${userAgent}`;
const totalSteps = 5;
for (let i = 0; i < totalSteps; i++) {
await new Promise((resolve) => setTimeout(resolve, 100));
// Send a progress update.
await context.reportProgress({
progress: (i + 1) * 20,
total: 100,
} as Progress);
}
return {
content: [{ type: 'text', text: greeting }],
};
}
@Resource({
uri: 'mcp://hello-world/{userName}',
name: 'Hello World',
description: 'A simple greeting resource',
mimeType: 'text/plain',
})
// Different from the SDK, we put the parameters and URI in the same object.
async getCurrentSchema({ uri, userName }) {
return {
content: [
{
uri,
text: `User is ${userName}`,
mimeType: 'text/plain',
},
],
};
}
}
완료되었습니다!
TIP
위 예제는 MCP 도구 내에서 HTTPRequest 헤더에 액세스하는 방법을 보여줍니다. 이는 사용자 식별, 클라이언트별 로직 추가 및 기타 여러 사용 사례에 유용합니다. 더 많은 예제는 인증 테스트를 참조하세요.
STDIO 빠른 시작
가장 큰 차이점은 모듈을 가져올 때 transport 옵션을 제공해야 한다는 것입니다.
McpModule.forRoot({
name: 'playground-stdio-server',
version: '0.0.1',
transport: McpTransportType.STDIO,
});
나머지는 동일하며, 평소처럼 도구, 리소스, 프롬프트를 정의할 수 있습니다. STDIO 전송을 사용하는 독립형 NestJS 애플리케이션의 예는 다음과 같습니다.
async function bootstrap() {
const app = await NestFactory.createApplicationContext(AppModule, {
logger: false,
});
return app.close();
}
void bootstrap();
다음으로, MCP Stdio 클라이언트와 함께 MCP 서버를 사용할 수 있습니다( 예 참조 ). 또는 프로젝트를 빌드한 후 다음 MCP 클라이언트 구성과 함께 사용할 수 있습니다.
{
"mcpServers": {
"greeting": {
"command": "node",
"args": [
"<path to dist js file>",
]
}
}
}
API 엔드포인트
HTTP+SSE 전송은 두 개의 엔드포인트를 노출합니다.
스트리밍 가능한 HTTP 전송은 다음 엔드포인트를 노출합니다.
POST /mcp : 모든 MCP 작업(도구 실행, 리소스 액세스 등)의 주요 엔드포인트입니다. 상태 저장 모드에서는 세션을 생성하고 유지합니다.
GET /mcp : 실시간 업데이트 및 진행 상황 알림을 위한 서버 전송 이벤트(SSE) 스트림을 설정합니다. 상태 저장 모드에서만 사용 가능합니다.
DELETE /mcp : MCP 세션을 종료합니다. 상태 저장 모드에서만 사용 가능합니다.
팁
글로벌 접두사를 사용하여 모듈을 사용할 수 있지만 권장되는 방법은 다음을 사용하여 해당 엔드포인트를 제외하는 것입니다.
app.setGlobalPrefix('/api', { exclude: ['sse', 'messages', 'mcp'] });
입증
표준 NestJS Guards를 사용하여 MCP 엔드포인트를 보호할 수 있습니다.
1. 가드 생성
CanActivate 인터페이스를 구현합니다. 가드는 요청 검증(예: JWT, API 키 확인)을 처리하고, 선택적으로 사용자 정보를 요청 객체에 첨부해야 합니다.
특별한 것은 없습니다. 자세한 내용은 NestJS 문서를 확인하세요.
2. 가드를 적용하세요
가드를 McpModule.forRoot 구성으로 전달하세요. 가드는 /sse 및 /messages 엔드포인트 모두에 적용됩니다.
// app.module.ts
import { Module } from '@nestjs/common';
import { McpModule } from '@rekog/mcp-nest';
import { GreetingTool } from './greeting.tool';
import { AuthGuard } from './auth.guard';
@Module({
imports: [
McpModule.forRoot({
name: 'my-mcp-server',
version: '1.0.0',
guards: [AuthGuard], // Apply the guard here
}),
],
providers: [GreetingTool, AuthGuard], // Ensure the Guard is also provided
})
export class AppModule {}
이게 전부입니다! 나머지는 NestJS Guards와 동일합니다.
운동장
playground 디렉터리에는 MCP 및 @rekog/mcp-nest 기능을 빠르게 테스트할 수 있는 예제가 포함되어 있습니다. 자세한 내용은 playground/README.md 를 참조하세요.
구성
McpModule.forRoot() 메서드는 McpOptions 객체를 사용하여 서버를 구성합니다. 사용 가능한 옵션은 다음과 같습니다.
옵션 | 설명 | 기본 |
name
| 필수. MCP 서버 이름입니다. | - |
version
| 필수. MCP 서버의 버전입니다. | - |
capabilities
| 광고를 위한 선택적 MCP 서버 기능입니다. @modelcontextprotocol/sdk를 참조하세요. | undefined
|
instructions
| 클라이언트가 서버와 상호 작용하는 방법에 대한 선택적 지침입니다. | undefined
|
transport
| 활성화할 전송 유형을 지정합니다. | [McpTransportType.SSE, McpTransportType.STREAMABLE_HTTP, McpTransportType.STDIO]
|
sseEndpoint
| SSE 연결에 대한 종료점 경로( SSE
전송과 함께 사용됨). | 'sse'
|
messagesEndpoint
| 메시지를 전송하기 위한 엔드포인트 경로( SSE
전송과 함께 사용). | 'messages'
|
mcpEndpoint
| MCP 작업을 위한 기본 엔드포인트 경로( STREAMABLE_HTTP
전송과 함께 사용됨). | 'mcp'
|
globalApiPrefix
| 모든 MCP 엔드포인트에 대한 글로벌 접두사입니다. 기존 애플리케이션에 통합할 때 유용합니다. | ''
|
guards
| 인증/권한 부여를 위해 MCP 엔드포인트에 적용할 NestJS Guard 배열입니다. | []
|
decorators
| 생성된 MCP 컨트롤러에 적용할 NestJS 클래스 데코레이터의 배열입니다. | []
|
sse
| SSE
전송에 특화된 구성입니다. | { pingEnabled: true, pingIntervalMs: 30000 }
|
sse.pingEnabled
| 연결을 유지하기 위해 주기적 SSE ping 메시지를 활성화할지 여부입니다. | true
|
sse.pingIntervalMs
| SSE ping 메시지를 보내는 간격(밀리초)입니다. | 30000
|
streamableHttp
| STREAMABLE_HTTP
전송에 특화된 구성입니다. | { enableJsonResponse: true, sessionIdGenerator: undefined, statelessMode: true }
|
streamableHttp.enableJsonResponse
| true
인 경우 /mcp
엔드포인트가 스트리밍이 아닌 요청(예: listTools
)에 대한 JSON 응답을 반환할 수 있습니다. | true
|
streamableHttp.sessionIdGenerator
| 상태 저장 모드에서 실행할 때 고유한 세션 ID를 생성하는 함수입니다. statelessMode
가 false
인 경우 필수입니다. | undefined
|
streamableHttp.statelessMode
| true
이면 STREAMABLE_HTTP
전송은 상태 비저장(세션 없음)으로 작동합니다. false
이면 상태 저장( sessionIdGenerator
가 필요합니다. | true
|