
NestJS MCP Server Module

2025.04.13
0
TypeScript实时通信工具执行资源管理开发效率
NestJS MCP Server Module 是一个基于 NestJS 的模块,用于创建支持 Server-Sent Events (SSE) 传输的 MCP (Model Context Protocol) 服务器。该模块提供了工具和资源的自动发现与注册、基于 Zod 的请求验证、进度通知以及基于守卫的身份验证等功能。
View on GitHub
Overview
基本能力
产品定位
NestJS MCP Server Module 是一个用于构建 MCP 服务器的 NestJS 模块,支持 SSE 传输,适用于需要实时通信和工具执行的场景。
核心功能
- 🚀 SSE Transport for streaming and tool execution
- 🔍 Automatic
tool
andresource
discovery and registration - 💯 Zod-based request validation
- 📊 Progress notifications
- 🔒 Guard-based authentication
适用场景
- 需要实时通信的应用
- 需要工具执行和资源管理的系统
- 需要进度通知和请求验证的服务
工具列表
GreetingTool
: 提供问候语生成和模拟长时间操作的功能Resource
: 提供资源管理和 URI 绑定的功能
常见问题解答
- 如何保护 MCP 端点?
使用 NestJS Guards 实现身份验证,并在
McpModule.forRoot
配置中应用这些守卫。
使用教程
使用依赖
npm install @rekog/mcp-nest @modelcontextprotocol/sdk zod
安装教程
- 导入模块
// 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 {}
- 定义工具和资源
// greeting.tool.ts
import { Injectable } from '@nestjs/common';
import { Tool, 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) {
const greeting = `Hello, ${name}!`;
const totalSteps = 5;
for (let i = 0; i < totalSteps; i++) {
await new Promise((resolve) => setTimeout(resolve, 500));
// 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',
},
],
};
}
}
调试方式
- 访问
GET /sse
端点进行 SSE 连接测试 - 访问
POST /messages
端点进行工具执行测试
API Endpoints
GET /sse
: SSE connection endpoint (Protected by guards if configured)POST /messages
: Tool execution endpoint (Protected by guards if configured)
Tips
It's possible to use the module with global prefix, but the recommended way is to exclude those endpoints with:
app.setGlobalPrefix('/api', { exclude: ['sse', 'messages'] });