Token导航 LogoToken导航TokenDH.com
Nestjs MCP Server logo
AI代理stdio官方级别未说明来源级核验

Nestjs MCP Server

MCP Server

@modelcontextprotocol/inspector

一个用于构建Model Context Protocol (MCP)服务器的NestJS模块库,提供装饰器、模块和集成模式,以可扩展和可维护的方式暴露MCP资源、工具和提示。

工具数

0

提示词数

0

GitHub Stars

34

资源数

0
工具管理TypeScript模型集成

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

adrian-d-hidalgo

提供方

adrian-d-hidalgo

最后核验

2026/5/17 20:23

运行时

Node.js

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

npx @modelcontextprotocol/inspector

详细介绍

MCP服务器NestJS模块库

](https://www.npmjs.com/package/@nestjs-mcp/server) ![Semantic Release](https://github.com/semantic-release/semantic-release) ](https://www.npmjs.com/package/@nestjs-mcp/server) ![CI Pipeline](https://github.com/adrian-d-hidalgo/nestjs-mcp-server/actions/workflows/ci.yml) ![codecov](https://codecov.io/gh/adrian-d-hidalgo/nestjs-mcp-server) ![Known Vulnerabilities](https://snyk.io/test/github/adrian-d-hidalgo/nestjs-mcp-server) ![MIT License](./LICENSE) ![PRs Welcome](./CONTRIBUTING.md) ![Contributor Covenant](CODE_OF_CONDUCT.md)

______________________________________________________________________

概述

______________________________________________________________________

目录

- 服务器 - 资源 - 工具 - 提示

- McpModule.forRoot - McpModule.forRootAsync - McpModule.forFeature

- 1.全球注册 McpModule.forRoot - 2.功能模块注册 McpModule.forFeature

- 解析器装饰器 - 快速装饰师 - 资源装饰师 - 工具装饰器 - 工具注释 - 工具选项变体 - RequestHandler额外参数

- 全球级警卫 - 分解器液位保护装置 - 方法级别防护 - 警卫示例 - MCP执行上下文 - 依赖注入防护

- 会话管理选项

______________________________________________________________________

安装

npm install @nestjs-mcp/server @modelcontextprotocol/sdk zod
# or
yarn add @nestjs-mcp/server @modelcontextprotocol/sdk zod
# or
pnpm add @nestjs-mcp/server @modelcontextprotocol/sdk zod

______________________________________________________________________

快速入门

在NestJS应用程序中注册MCP模块,并公开一个简单的工具:

import { Module } from '@nestjs/common';

import { CallToolResult } from '@modelcontextprotocol/sdk/types';

import { Resolver, Tool, McpModule } from '@nestjs-mcp/server';

@Resolver()
export class HealthResolver {
  /**
   * Simple health check tool
   */
  @Tool({ name: 'server_health_check' })
  healthCheck(): CallToolResult {
    return {
      content: [
        {
          type: 'text',
          text: 'Server is operational. All systems running normally.',
        },
      ],
    };
  }
}

@Module({
  imports: [
    McpModule.forRoot({
      name: 'My MCP Server',
      version: '1.0.0',
    }),
  ],
  providers: [HealthResolver],
})
export class AppModule {}

______________________________________________________________________

什么是MCP?

模型上下文协议(MCP) 是一种用于将LLM连接到外部数据、工具和提示的开放协议。MCP服务器以标准化的方式公开资源(数据)、工具(操作)和提示(会话流),实现与LLM驱动的客户端的无缝集成。

______________________________________________________________________

核心概念

服务器

MCP服务器是向LLM公开功能的主要入口点。它管理资源、工具和提示的注册和发现。

资源

资源表示LLM可以查询或检索的结构化数据或文档。资源通常是只读的,由唯一的URI标识。

工具

工具是LLM可以调用的动作或函数。工具可能有副作用,可以接受参数来执行计算或触发操作。

提示

Prompt为LLM定义会话流、模板或交互模式。提示有助于指导模型在特定场景中的行为。

能力 实现细节和代码示例部分。

______________________________________________________________________

模块API

McpModule.forRoot

在NestJS应用程序中全局注册MCP服务器。

参数:

  • options: McpModuleOptions --主服务器配置对象:

- name: string:您的MCP服务器的名称。 - version: string:MCP服务器的版本。 - instructions?: string:客户端MCP服务器的可选描述。 - capabilities?: Record:可选的附加功能元数据。 - providers?: Provider[]:要包含在模块中的NestJS提供程序的可选数组。 - imports?: any[]:要导入的NestJS模块的可选数组。 - logging?: McpLoggingOptions:可选日志记录配置: - enabled?: boolean (默认值: true):启用/禁用日志记录。 - level?: 'error' | 'warn' | 'log' | 'debug' | 'verbose' (默认值: 'verbose'):设置日志记录级别。 - transports?: McpModuleTransportOptions:可选传输配置(请参见 运输选项). - protocolOptions?: Record:直接传递给底层的可选参数 @modelcontextprotocol/sdk 服务器实例。

退货:

  • 一个动态NestJS模块,已注册所有MCP提供商。

例子:

import { Module } from '@nestjs/common';
import { McpModule } from '@nestjs-mcp/server';

@Module({
  imports: [
    McpModule.forRoot({
      name: 'My Server',
      version: '1.0.0',
      instructions: 'A server providing utility tools and data.',
      logging: { level: 'log' },
      transports: { sse: { enabled: false } }, // Disable SSE transport
      // ...other MCP options
    }),
  ],
})
export class AppModule {}

McpModule.forRootAsync

使用异步选项全局注册MCP服务器,这对于与配置模块集成非常有用,例如 @nestjs/config.

注: - 这 imports 数组应包括提供所需依赖项的任何模块 useFactory (例如。, ConfigModule 如果你注射 ConfigService). - 使用 forRootAsync 在根模块中只有一次(AppModule). - 看 McpModuleAsyncOptions 所有可用选项。

参数:

  • options: McpModuleAsyncOptions --异步配置对象:

- imports?: any[]:在工厂运行之前导入的可选模块。 - useFactory: (...args: any[]) => Promise | McpModuleOptions:一个返回 McpModuleOptions. - inject?: any[]:可供选择的注射提供者 useFactory.

退货:

  • 一个动态的NestJS模块。

示例(使用ConfigMgr):

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { McpModule } from '@nestjs-mcp/server';

@Module({
  imports: [
    ConfigModule.forRoot(), // Make sure ConfigModule is imported
    McpModule.forRootAsync({
      imports: [ConfigModule], // Import ConfigModule here too
      useFactory: (configService: ConfigService) => ({
        name: configService.get('MCP_SERVER_NAME', 'Default Server'),
        version: configService.get('MCP_SERVER_VERSION', '1.0.0'),
        instructions: configService.get('MCP_SERVER_DESC'),
        logging: {
          level: configService.get('MCP_LOG_LEVEL', 'verbose'),
        },
        // ... other options from configService
      }),
      inject: [ConfigService], // Inject ConfigService into the factory
    }),
  ],
})
export class AppModule {}

McpModule.forFeature

在功能模块中注册其他MCP资源、工具或提示。使用此功能将大型服务器组织成多个模块。包含MCP功能的解析器必须包含在 providers 特征模块的数组。

参数:

  • options?: McpFeatureOptions (目前未使用,保留用于未来的增强功能)。

退货:

  • 一个动态模块。

例子:

// src/status/status.resolver.ts
import { Resolver, Tool } from '@nestjs-mcp/server';
import { CallToolResult } from '@modelcontextprotocol/sdk/types';

@Resolver('status')
export class StatusResolver {
  @Tool({ name: 'health_check' })
  healthCheck(): CallToolResult {
    return { content: [{ type: 'text', text: 'OK' }] };
  }
}

// src/status/status.module.ts
import { Module } from '@nestjs/common';
import { McpModule } from '@nestjs-mcp/server';
import { StatusResolver } from './status.resolver';

@Module({
  imports: [McpModule.forFeature()], // Import forFeature here
  providers: [StatusResolver], // Register your resolver
})
export class StatusModule {}

______________________________________________________________________

模块使用

此库提供了在NestJS应用程序中注册MCP功能的两种主要方法:

1.全球注册 McpModule.forRoot

使用 McpModule.forRoot 在根应用程序模块中,全局配置和注册MCP服务器。这是每个MCP服务器应用程序所必需的。

import { Module } from '@nestjs/common';
import { McpModule } from '@nestjs-mcp/server';
import { PromptsResolver } from './prompts.resolver';

@Module({
  imports: [
    McpModule.forRoot({
      name: 'My MCP Server',
      version: '1.0.0',
      // ...other MCP options
    }),
  ],
  providers: [PromptsResolver],
})
export class AppModule {}

2.功能模块注册 McpModule.forFeature

使用 McpModule.forFeature 在功能模块中注册其他解析器、工具或资源。这对于将大型服务器组织成多个模块非常有用。

import { Module } from '@nestjs/common';
import { McpModule } from '@nestjs-mcp/server';

import { ToolsResolver } from './tools.resolver';

@Module({
  imports: [McpModule.forFeature()],
  providers: [ToolsResolver],
})
export class ToolsModule {}
  • 使用 forRootforRootAsync 仅一次 在根模块中(AppModule).
  • 使用 forFeature 在定义MCP功能的任何功能模块中(@Resolver 班级)。
  • 确保所有解析程序都列在 providers 它们各自模块的阵列。

______________________________________________________________________

能力

该库提供了一组装饰器来定义MCP功能并应用交叉关注点,如防护。装饰器可以在解析器(类)级别和方法级别使用。

解析器装饰器

解析器是一个对相关MCP功能进行分组的类。 全部 MCP能力方法(@Prompt, @Resource, @Tool) 必须 属于装饰有 @Resolver.

  • @Injectable() 需要: MCP模块会自动将解析器类视为提供者 不要 要求 @Injectable() 装饰师。
  • 依赖注入: 标准NestJS依赖注入在解析器构造函数中工作。
  • 命名空间 : 您可以选择为以下对象提供字符串参数 @Resolver('my_namespace') 为该解析器中的功能命名。
  • 警卫: 防护装置可以在班级级别使用 @UseGuards().

例子:

import { Resolver, Prompt, Resource, Tool } from '@nestjs-mcp/server';
// Import any services you need to inject
import { SomeService } from '../some.service';

@Resolver('workspace') // No @Injectable()
export class MyResolver {
  // Inject dependencies as usual
  constructor(private readonly someService: SomeService) {}

  @Prompt({ name: 'greet_user' }) // Capabilities must be inside a Resolver
  greetPrompt(/*...args...*/) {
    const greeting = this.someService.getGreeting();
    /* ... */
  }

  @Resource({ name: 'user_profile', uri: 'user://{id}' })
  getUserResource(/*...args...*/) {
    /* ... */
  }

  @Tool({ name: 'calculate_sum' })
  sumTool(/*...args...*/) {
    /* ... */
  }
}

您还可以在解析器级别应用防护:

import { UseGuards, Resolver } from '@nestjs-mcp/server';
import { MyGuard } from './guards/my.guard';

@UseGuards(MyGuard) // Applied to all capabilities in this Resolver
@Resolver('secure') // No @Injectable()
export class SecureResolver {
  // All capabilities in this resolver will use MyGuard
}

快速装饰师

装饰Resolver类中的方法,将其作为MCP Prompts公开。接受与兼容的选项 server.prompt()@modelcontextprotocol/sdk. name 应该使用 snake_case.

import { Prompt, Resolver } from '@nestjs-mcp/server';
import { RequestHandlerExtra } from '@nestjs-mcp/server'; // Import type for extra info
import { z } from 'zod'; // Example if using Zod schema

// Optional: Define schema if needed
// const SummaryArgs = z.object({ topic: z.string() });

@Resolver('prompts') // Must be in a Resolver class
export class MyPrompts {
  @Prompt({
    name: 'generate_summary',
    description: 'Generates a summary for the given text.',
    // argsSchema: SummaryArgs
  })
  generateSummaryPrompt(
    // params: z.infer, // Arguments based on argsSchema (if defined)
    extra: RequestHandlerExtra, // Contains sessionId and other metadata
  ) {
    console.log(`Generating summary for session: ${extra.sessionId}`);
    /* ... return CallPromptResult ... */
    return { content: [{ type: 'text', text: 'Summary generated.' }] };
  }
}

资源装饰师

装饰Resolver类中的方法,将其作为MCP资源公开。接受与兼容的选项 server.resource()@modelcontextprotocol/sdk. name 应该使用 snake_case.

import { Resource, Resolver } from '@nestjs-mcp/server';
import { RequestHandlerExtra } from '@nestjs-mcp/server'; // Import type for extra info
import { URL } from 'url'; // Type for URI resource
import { z } from 'zod'; // Example if using Zod template

// Optional: Define template schema if needed
// const DocQueryTemplate = z.object({ query: z.string() });

@Resolver('data') // Must be in a Resolver class
export class MyResources {
  @Resource({
    name: 'user_profile',
    uri: 'user://profiles/{userId}',
    // metadata: { description: '...' } // Optional
  })
  getUserProfile(
    uri: URL, // First argument is the parsed URI
    // metadata: Record // Second argument if is defined
    extra: RequestHandlerExtra, // Contains sessionId and other metadata
  ) {
    const userId = uri.pathname.split('/').pop(); // Example: Extract ID from URI
    console.log(`Fetching profile for ${userId}, session: ${extra.sessionId}`);
    /* ... return CallResourceResult ... */
    return { content: [{ type: 'text', text: `Profile data for ${userId}` }] };
  }

  @Resource({
    name: 'document_list',
    template: { type: 'string', description: 'Document content query' }, // Simple template example
    // metadata: { list: true } // Optional
  })
  findDocuments(
    uri: URL, // First arg based on simple template type
    variables: Record, // Second arg is path params (if any)
    extra: RequestHandlerExtra, // Contains sessionId and other metadata
  ) {
    console.log(
      `Finding documents matching '${query}', session: ${extra.sessionId}`,
    );
    /* ... return CallResourceResult ... */
    return { content: [{ type: 'text', text: 'List of documents.' }] };
  }
}

工具装饰器

装饰Resolver类中的方法,将其作为MCP工具公开。接受与兼容的选项 server.tool()@modelcontextprotocol/sdk. name 应该使用 snake_case.

import { Tool, Resolver } from '@nestjs-mcp/server';
import { RequestHandlerExtra } from '@nestjs-mcp/server';
import { z } from 'zod';
import { CallToolResult } from '@modelcontextprotocol/sdk/types';

@Resolver('user_tools')
export class UserToolsResolver {
  @Tool({
    name: 'delete_user',
    description: 'Deletes a user by ID',
    paramsSchema: { userId: z.string() },
    annotations: { destructiveHint: true, readOnlyHint: false },
  })
  deleteUser(
    { userId }: { userId: string },
    extra: RequestHandlerExtra,
  ): CallToolResult {
    // ...logic...
    return { content: [{ type: 'text', text: `User ${userId} deleted.` }] };
  }
}

工具注释

annotations 字段允许您提供有关工具行为的协议级提示,例如它是破坏性的、只读的、幂等的,还是具有其他特殊属性。客户端、UI或协议本身可以使用这些提示来显示警告、优化调用或执行策略。

常用注释键:

  • destructiveHint (boolean):表示工具执行破坏性操作(例如,删除数据)。
  • readOnlyHint (boolean):表示该工具不修改任何数据。
  • idempotentHint (boolean):表示该工具可以安全地多次调用,效果相同。
  • openWorldHint (boolean):表示该工具可能在当前系统之外产生副作用。

例子:

@Tool({
  name: 'reset_password',
  paramsSchema: { userId: z.string() },
  annotations: { destructiveHint: true, idempotentHint: false }
})
resetPassword({ userId }: { userId: string }): CallToolResult {
  // ...
}

工具选项变体

变量必填字段
ToolBaseOptions名称
ToolWithDescriptionOptions名称、描述
工具带参数或注释选项名称、参数模式或注释
工具带参数或注释和描述选项名称、参数模式或注释、描述
工具带参数和注释选项名称、参数模式、注释
工具带参数和注释和描述选项名称、参数模式、注释、描述
  • paramsSchemaparamsSchemaOrAnnotations 可以是用于输入验证的Zod模式。
  • annotations 是具有如上所述的协议级提示的对象。

RequestHandler额外参数

所有MCP能力方法(@Prompt, @Resource, @Tool)总是收到a RequestHandlerExtra object作为最后一个参数。此对象从以下对象扩展了原始类型 @modelcontextprotocol/sdk 并提供关于当前MCP请求的基本上下文。

SDK中的属性:

  • signalAbortSignal 用于在请求被取消时进行通信
  • authInfo:有关已验证访问令牌的可选信息
  • sessionId:传输中的会话ID(如果可用)
  • sendNotification:发送与当前请求相关的通知的函数
  • sendRequest:发送与当前请求相关的请求的函数

扩展属性:

  • headers:来自原始请求的HTTP标头(由@nestjs-mcp/server添加)

使用示例:

import { Tool, Resolver, SessionManager } from '@nestjs-mcp/server';
import { RequestHandlerExtra } from '@nestjs-mcp/server';
import { CallToolResult } from '@modelcontextprotocol/sdk/types';

@Resolver('auth')
export class AuthResolver {
  @Tool({
    name: 'authenticate_user',
    description: 'Authenticates a user with credentials',
    // ...other options
  })
  authenticateUser(
    params: { username: string; password: string },
    extra: RequestHandlerExtra, // Always the last parameter
  ): CallToolResult {
    // Access the session ID
    console.log(`Request received in session: ${extra.sessionId}`);

    // Access request headers (extended property)
    const authHeader = extra.headers.authorization;
    const userAgent = extra.headers['user-agent'];
    console.log(`Request from: ${userAgent}`);

    // Check if request was cancelled
    if (extra.signal.aborted) {
      return {
        content: [{ type: 'text', text: 'Request was cancelled' }],
      };
    }

    // Implement authentication logic
    return {
      content: [{ type: 'text', text: 'Authentication successful' }],
    };
  }
}

重要提示:

  • extra 始终是任何方法中的最后一个参数 @Resource, @Prompt,或 @Tool
  • headers 属性是@nestjs-mcp/server添加的一个扩展,用于直接访问HTTP标头

______________________________________________________________________

守卫

对解析器、单个方法或全局应用一个或多个保护。警卫必须执行NestJS CanActivate 界面。

全球级警卫

这种方法使用标准的NestJS全局防护系统(APP_GUARD).全球警卫将保护 全部 NestJS路由,包括MCP传输端点(如 /mcp/sse).在任何MCP特定逻辑运行之前,将此用于广泛的身份验证或检查。

// src/guards/global-auth.guard.ts
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Request } from 'express';

@Injectable()
export class GlobalAuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    const apiKey = request.headers['x-api-key'];
    // Example: Check for a valid API key
    return !!apiKey && apiKey === 'EXPECTED_KEY';
  }
}

在主模块中全局注册警卫:

// src/app.module.ts
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { McpModule } from '@nestjs-mcp/server';
import { GlobalAuthGuard } from './guards/global-auth.guard';

@Module({
  imports: [McpModule.forRoot(/*...*/)],
  providers: [
    {
      provide: APP_GUARD,
      useClass: GlobalAuthGuard,
    },
  ],
})
export class AppModule {}

分解器液位保护装置

这是此库的自定义功能。使用 @UseGuards() 装饰师(出口自 @nestjs-mcp/server)在Resolver类上。所有MCP方法(@Prompt, @Resource, @Tool) 在该特定解析器内 将受到这些警卫的保护。使用此功能为一组相关功能强制执行逻辑(例如角色检查)。

import { UseGuards, Resolver, Prompt } from '@nestjs-mcp/server';
import { RoleGuard } from './guards/role.guard';

@UseGuards(RoleGuard)
@Resolver('admin')
export class AdminResolver {
  @Prompt({ name: 'admin_action' })
  adminAction(/*...*/) {
    /* ... */
  }
  // ... other admin capabilities
}

方法级别防护

这是此库的自定义功能。方法级别防护使用 @UseGuards() 直接在MCP能力方法上进行装饰(@Prompt, @Resource, @Tool).只有装饰的方法会受到这些警卫的保护。使用此功能对特定功能进行细粒度访问控制。

import { UseGuards, Resolver, Prompt, Tool } from '@nestjs-mcp/server';
import { SpecificCheckGuard } from './guards/specific-check.guard';

@Resolver('mixed')
export class MixedResolver {
  @Prompt({ name: 'public_prompt' })
  publicPrompt() {
    /* Publicly accessible */
  }

  @UseGuards(SpecificCheckGuard)
  @Tool({ name: 'protected_tool' })
  protectedTool(/*...*/) {
    /* Requires SpecificCheckGuard to pass */
  }
}

重要提示: 解析器和方法级别保护 仅对MCP功能调用运行,不适用于由全局警卫处理的初始连接建立。他们使用习俗 McpExecutionContext.

警卫示例

解析器或方法级别保护的防护:

// src/guards/my-mcp.guard.ts
import { CanActivate, Injectable } from '@nestjs/common';
import { McpExecutionContext, SessionManager } from '@nestjs-mcp/server';

@Injectable()
export class MyMcpGuard implements CanActivate {
  constructor(private readonly sessionManager: SessionManager) {}

  canActivate(context: McpExecutionContext): boolean {
    const sessionId = context.getSessionId();
    if (!sessionId) return false;

    const handlerArgs = context.getArgs();

    const session = this.sessionManager.getSession(sessionId);
    const request = session?.request;
    const userAgent = request?.headers['user-agent'];

    console.log(`Guard activated for session ${sessionId} from ${userAgent}`);
    console.log('Handler args:', handlerArgs);

    return true;
  }
}

MCP执行上下文

实施时 解析器级别方法级别 警卫使用 @UseGuards() 从这个图书馆,你的 canActivate 方法接收 McpExecutionContext 例子此上下文提供了对MCP特定信息的访问:

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { McpExecutionContext, SessionManager } from '@nestjs-mcp/server';
import { Request } from 'express';

@Injectable()
export class McpAuthGuard implements CanActivate {
  constructor(private readonly sessionManager: SessionManager) {}

  canActivate(context: McpExecutionContext): boolean {
    const sessionId = context.getSessionId();
    if (!sessionId) {
      console.error('Guard Error: MCP Session ID not found in context.');
      return false;
    }

    const handlerArgs = context.getArgs();
    console.log('MCP Handler Arguments:', handlerArgs);

    const session = this.sessionManager.getSession(sessionId);
    if (!session) {
      console.error(`Guard Error: Session not found for ID: ${sessionId}`);
      return false;
    }
    const request = session.request as Request;

    const authHeader = request.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      console.log('Guard Denied: Missing or invalid Bearer token.');
      return false;
    }
    const token = authHeader.split(' ')[1];
    const isValidToken = token === 'VALID_TOKEN';

    if (isValidToken) {
      console.log(`Guard Passed for session ${sessionId} with token.`);
      return true;
    } else {
      console.log(`Guard Denied: Invalid token for session ${sessionId}.`);
      return false;
    }
  }
}

关键点 McpExecutionContext:

  • getSessionId():检索当前MCP会话的唯一ID。 关键 用于将保护检查与存储的会话状态相关联 SessionManager.
  • 论点(handlerArgs):提供专门传递给MCP处理程序方法的参数(@Tool, @Prompt, @Resource)被调用。这些参数的结构取决于能力类型及其定义(例如。, params 对于工具, query/params 资源)。您可以通过以下方式访问这些 context.getArgs(),但要注意基于能力的实际结构。
  • 请求数据:使用 SessionManager 注入到你的警卫中以获取会话详细信息(包括原始信息) Request)基于 sessionId 从上下文中获得。
  • switchToHttp().getResponse() / switchToHttp().getNext():这些将抛出错误,因为Response对象在此上下文中不直接可用或不相关。

使用 SessionManager 注入到你的警卫中以获取会话详细信息(包括原始信息) Request)基于 sessionId 从上下文中获得。

依赖注入防护

守卫可以注入NestJS提供程序,如 SessionManager.使用 @Injectable() 并将该警卫注册为提供者:

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private readonly sessionManager: SessionManager) {}

  canActivate(context: McpExecutionContext): boolean {
    const session = this.sessionManager.getSession(context.getSessionId());
    return !!session?.request.headers.authorization;
  }
}

@Module({
  imports: [McpModule.forRoot({ name: 'my-server', version: '1.0.0' })],
  providers: [AuthGuard, MyResolver],
})
export class AppModule {}
警卫没有 @Injectable() 仍然有效,但不会收到注入的依赖项。

______________________________________________________________________

会话管理

这个图书馆包括 SessionManager 负责跟踪活动MCP会话的服务。每个传入的MCP连接都会建立一个会话,由一个唯一的 sessionIdThe SessionManager 通常存储相关的初始值 Request 每个会话的对象。

为什么它很重要?

  • 访问请求数据: 由于MCP操作(工具调用、提示执行)可能独立于初始HTTP连接(特别是使用SSE等流式传输)发生 SessionManager 提供了一种检索原始文件的方法 Request 与特定内容相关的上下文 sessionId。这对于需要访问原始请求中的请求标头、参数或其他特定于连接的详细信息的防护或功能方法(在解析器中)至关重要。
  • 状态管理: 虽然目前专注于存储请求 SessionManager 如果您的应用程序需要,可以扩展以存储额外的会话特定状态。

用法示例(在解析器中):

解析程序可能需要访问原始请求,例如,获取用户信息或在初始连接期间在头中传递的API密钥。

import { Tool, Resolver, SessionManager } from '@nestjs-mcp/server';
import { RequestHandlerExtra } from '@nestjs-mcp/server'; // Provides sessionId
import { Request } from 'express';
import { CallToolResult } from '@modelcontextprotocol/sdk/types';
import { z } from 'zod';

const UserToolParams = z.object({
  user_id: z.string().optional(),
});

@Resolver('user_tools') // No @Injectable() needed
export class UserToolsResolver {
  // Inject SessionManager
  constructor(private readonly sessionManager: SessionManager) {}

  @Tool({
    name: 'get_user_agent',
    description:
      'Gets the user agent from the original request for the session.',
    paramSchema: UserToolParams,
  })
  getUserAgent(
    params: z.infer,
    extra: RequestHandlerExtra, // Get extra info, including sessionId
  ): CallToolResult {
    const sessionId = extra.sessionId;
    if (!sessionId) {
      return {
        content: [{ type: 'text', text: 'Error: Session ID missing.' }],
      };
    }

    // Use sessionId to get the session from the manager
    const session = this.sessionManager.getSession(sessionId);
    if (!session) {
      return {
        content: [
          {
            type: 'text',
            text: `Error: Session not found for ID: ${sessionId}`,
          },
        ],
      };
    }

    // Access the original request stored in the session
    const request = session.request as Request;
    const userAgent = request.headers['user-agent'] || 'Unknown';

    return {
      content: [
        { type: 'text', text: `Session ${sessionId} User Agent: ${userAgent}` },
      ],
    };
  }
}

在这个例子中:

  1. @Tool 方法接收 extra: RequestHandlerExtra,其中包含 sessionId.
  2. SessionManager 被注入 UserToolsResolver.
  3. sessionId 与一起使用 sessionManager.getSession() 以检索会话数据。
  4. 原版 request 从检索到的会话数据中访问对象。

SessionManager 当您使用时,会自动注册为提供商 McpModule.forRootMcpModule.forRootAsync 并且可以像任何其他NestJS提供者一样注入。

______________________________________________________________________

运输选项

MCP服务器可以通过不同的传输机制进行通信。此库包括对以下内容的内置支持:

  1. 可流式传输(/mcp 端点): 使用标准HTTP POST请求和响应的通用传输。适用于大多数请求/响应交互。默认情况下启用。
  2. SSE(服务器发送事件)(/sse 端点): 一种传输机制,允许服务器通过单个HTTP连接向客户端推送更新。适用于流式响应或长时间运行的操作。 注: 这被认为是一种传统的传输方式,但仍然支持兼容性。默认情况下启用。

您可以使用配置全局启用哪些传输 transports 选项在 McpModule.forRootMcpModule.forRootAsync.

配置:

import { Module } from '@nestjs/common';
import { McpModule } from '@nestjs-mcp/server';

@Module({
  imports: [
    McpModule.forRoot({
      name: 'My Server',
      version: '1.0.0',
      transports: {
        streamable: { enabled: true }, // Keep streamable enabled (default)
        sse: { enabled: false }, // Disable legacy SSE transport
      },
    }),
  ],
})
export class AppModule {}

默认配置:

如果 transports 选项被省略,两者 streamable (/mcp)以及 sse (/sse)默认情况下启用。

import { Module } from '@nestjs/common';
import { McpModule } from '@nestjs-mcp/server';

@Module({
  imports: [
    McpModule.forRoot({
      name: 'My Server',
      version: '1.0.0',
      // Both streamable and sse will be enabled
    }),
  ],
})
export class AppModule {}

禁用未使用的传输可以略微减少应用程序的表面积和资源使用。

______________________________________________________________________

会话管理选项

配置会话超时、清理间隔和资源限制,以针对生产工作负载优化服务器。

配置:

import { Module } from '@nestjs/common';
import { McpModule } from '@nestjs-mcp/server';

@Module({
  imports: [
    McpModule.forRoot({
      name: 'My Server',
      version: '1.0.0',
      session: {
        sessionTimeoutMs: 1800000, // 30 minutes (default)
        cleanupIntervalMs: 300000, // 5 minutes (default)
        maxConcurrentSessions: 1000, // Max sessions (default)
      },
    }),
  ],
})
export class AppModule {}

配置选项:

选项类型默认值描述
sessionTimeoutMsnumber1800000 (30分钟)会话清理前的最长不活动时间
cleanupIntervalMsnumber300000 (5分钟)清理作业执行频率
maxConcurrentSessionsnumber1000允许的最大并发会话数

工作原理:

  • 活动跟踪:每届会议 lastActivity 每次请求时都会更新时间戳
  • 清理工作:运行每 cleanupIntervalMs 关闭并删除非活动会话
  • 会话限制:当出现以下情况时,新连接被拒绝(503) maxConcurrentSessions 已达到

生产建议:

  • 高流量服务器:增加 maxConcurrentSessions (2000-5000)和减少 cleanupIntervalMs (2-3分钟)
  • 低内存环境:减少 maxConcurrentSessions (100-500)和 sessionTimeoutMs (10-15分钟)
  • 长时间运行的工作流程:增加 sessionTimeoutMs (60-90分钟)

环境变量示例:

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { McpModule } from '@nestjs-mcp/server';

@Module({
  imports: [
    ConfigModule.forRoot(),
    McpModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        name: 'My Server',
        version: '1.0.0',
        session: {
          sessionTimeoutMs: config.get('MCP_SESSION_TIMEOUT', 1800000),
          cleanupIntervalMs: config.get('MCP_CLEANUP_INTERVAL', 300000),
          maxConcurrentSessions: config.get('MCP_MAX_SESSIONS', 1000),
        },
      }),
    }),
  ],
})
export class AppModule {}

______________________________________________________________________

检查员游乐场

使用Inspector Playground在浏览器UI中交互式测试和调试MCP服务器端点。该工具由 @modelcontextprotocol/inspector,允许您:

  • 探索可用的资源、工具和提示
  • 实时调用端点并查看响应
  • 根据MCP规范验证服务器实现

要启动Inspector Playground(确保您的NestJS MCP服务器正在运行):

npx @modelcontextprotocol/inspector

它通常会连接到 http://localhost:3000 默认情况下,您也可以指定其他目标URL。

______________________________________________________________________

例子

examples/ 目录包含演示如何注册和公开MCP功能的现成场景。

每个示例都是自包含的,并遵循最佳实践。有关高级用法,请参阅每个示例中的代码和文档。

______________________________________________________________________

更新日志

更改日志.md 发布说明。

______________________________________________________________________

许可证

麻省理工学院——见 许可证 了解详情。

______________________________________________________________________

贡献

欢迎投稿!请参阅 贡献.md 用于指导方针、报告问题和拉取请求规则。

在投稿之前,请阅读我们的 行为准则 了解我们社区对行为的期望。

目录标签

目录标签

工具管理TypeScript模型集成NestJS本地部署MCP服务器模块库LLM集成

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

api-key

运行时(runtime,运行环境)

Node.js

来源包(packageName,安装包名)

@modelcontextprotocol/inspector

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdioapi-key部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP