npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@millionfor/nestjs-mcp-server

v1.0.0-alpha.3

Published

A mcp service encapsulation based on nestjs framework

Readme

nestjs-mcp-server

A mcp service encapsulation based on nestjs framework

Install

# npm
npm install @millionfor/nestjs-mcp-server @modelcontextprotocol/sdk zod

# yarn
yarn add @millionfor/nestjs-mcp-server @modelcontextprotocol/sdk zod

# pnpm
pnpm add @millionfor/nestjs-mcp-server @modelcontextprotocol/sdk zod

Usage

1. Import module

Import McpModule in your module

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

@Module({
  imports: [
    McpModule.register({
      controllerBaseUrl: "api/mcp",
      mcpServerConfigs: [
        {
          serverId: "my-mcp-server",
          serverInfo: {
            name: "my-mcp-server",
            version: "1.0.0",
          },
        },
      ],
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

In addition, you can also import modules through forRoot and forFeature, the differences are as follows:

  • forRoot: Usually registered in the root module
  • forFeature: Share Service instance with forRoot registered module
  • register: Register once and do not share with any module

2. Operation McpServer

After creating MCP Server, you can obtain the official sdk's native MCP Server instance through the getServer method. This instance has no encapsulation and is completely native.

For example, you can register a tool

import { Controller } from "@nestjs/common";
import { McpServerService } from "@millionfor/nestjs-mcp-server";
import { z } from "zod";

@Controller()
export class AppController {
  constructor(private readonly mcpServerService: McpServerService) {
    this.mcpServerService.getServer("server-id")?.tool(
      "get-current-time",
      {
        format: z
          .enum(["iso", "locale", "unix"])
          .optional()
          .default("iso")
          .describe("时间格式: iso, locale, 或 unix"),
      },
      async ({ format }: { format: "iso" | "locale" | "unix" }) => {
        const now = new Date();
        let timeValue: string | number;

        switch (format) {
          case "iso":
            timeValue = now.toISOString();
            break;
          case "locale":
            timeValue = now.toLocaleString();
            break;
          case "unix":
            timeValue = now.getTime();
            break;
          default:
            timeValue = now.toISOString();
        }

        return {
          content: [{ type: "text", text: String(timeValue) }],
        };
      }
    );
  }
}

3. Manually register the server instance

The above example directly passes in mcpServerConfigs in McpModule.register, which creates an MCP Server when the module is initialized.

Of course this is not necessary. You can manually register the MCP Server in the Controller or Service without passing in mcpServerConfigs:

import { Controller } from "@nestjs/common";
import { McpServerService } from "@millionfor/nestjs-mcp-server";
import { z } from "zod";

@Controller()
export class AppController {
  constructor(private readonly mcpServerService: McpServerService) {
    // 手动注册一个MCP Server实例
    this.mcpServerService.registerServer({
      serverId: "another-server",
      serverInfo: {
        name: "another-mcp-server",
        version: "1.0.0",
      },
    });
  }
}

Server access endpoint

After registering the module, the following endpoints are automatically created:

  • SSE connection endpoint: /{controllerBaseUrl}/{serverId}/sse
  • Message processing endpoint: /{controllerBaseUrl}/{serverId}/messages

For example, if you use controllerBaseUrl: 'api/mcp' and serverId: 'my-mcp-server', the access URL is:

  • http://localhost:3000/api/mcp/my-mcp-server/sse - for SSE connections
  • http://localhost:3000/api/mcp/my-mcp-server/messages - for message processing

API

McpModule.register

  • controllerBaseUrl: Basic URL path for MCP Controller
  • sseEndpoint: SSE connection endpoint name, default is sse
  • messagesEndpoint: Message processing endpoint name, default is messages
  • mcpServerConfigs:
  • serverId: McpServer id, use id to manage multiple instances
  • serverInfo: As the first parameter, pass it directly into the native MCP TS-SDK McpServer class
  • serverOptions: As the second parameter, pass it directly into the native MCP TS-SDK McpServer class

forRoot same as register, forFeature only receives mcpServerConfigs

McpServerService

McpModule export service to manage multiple McpServer instances.

You can inject it into your Controller or Service using the following methods:

registerServer

  • Function: Register a McpServer instance
  • Parameters: mcpServerConfigs same as McpModule.forRoot
  • Return value: Registered McpServer instance

getServer

  • Function: Get the specified McpServer instance
  • Parameters: serverId
  • Return value: McpServer instance

getServerIds

  • Function: Get all registered McpServer instance ids
  • Return value: string[] All registered McpServer instance id arrays

hasServer

  • Function: determine whether the specified McpServer instance has been registered
  • Parameters: serverId
  • Return value: boolean

connect

  • Function: Connecting McpServer to the transport layer generally does not need to be used unless you want to manually manage the connection.
  • Parameters:
  • serverId
  • transport, Transport instance
  • Return value: void

McpTransportService

McpModule export service to manage multiple SSEServerTransport instances.

It is usually not necessary to use unless you want to manually manage the connection.

The following only lists the possible methods. For more methods, please refer to the source code.

getTransport

  • Function: Get a specific transmission connection
  • Parameters: serverId, sessionId
  • Return value: SSEServerTransport instance

getActiveSessionIds

  • Function: Get all active session IDs of McpServer
  • Parameters: serverId
  • Return value: string[] All active session ID array

Advanced Configuration

Custom endpoint name

You can customize the SSE and message endpoint names when module registration:

McpModule.register({
  controllerBaseUrl: "api/mcp",
  sseEndpoint: "connect", // Default is 'sse'
  messagesEndpoint: "rpc", // Default is 'messages'
  mcpServerConfigs: [
    /* ... */
  ],
});

License

MIT