NestJS MCP Server Module

NestJS MCP Server Module

site icon
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 and resource 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

安装教程

  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 {}
  1. 定义工具和资源
// 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'] });

许可证

该项目遵循 MIT 开源许可条款,请参阅 MIT 了解完整条款。