Content
# nest-mcp-sse
This is a dynamic module for quickly developing SSE (Server-Sent Events) transport type McpServer under NestJS projects. With this module, you won't have to worry about connection transport, lifecycle management, McpServer instantiation, and other trivial matters, allowing you to focus on the development of the MCP tool.
**This module does not over-encapsulate** 🥳
It only manages MCP Server instances and SSE transport, without wrapping any methods of the native MCP Server, keeping the learning curve as low as possible.
## Features
- Quickly create MCP servers in NestJS applications
- Support for managing multiple MCP Server instances
- Automatically handle SSE connection lifecycle
## Installation
```bash
# npm
npm install nest-mcp-sse @modelcontextprotocol/sdk zod
# yarn
yarn add nest-mcp-sse @modelcontextprotocol/sdk zod
# pnpm
pnpm add nest-mcp-sse @modelcontextprotocol/sdk zod
```
## Usage
### 1. Import the Module
Import `McpModule` in your module
```typescript
import { Module } from "@nestjs/common";
import { McpModule } from "nest-mcp-sse";
@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 {}
```
Additionally, you can import the module using `forRoot` and `forFeature`, with the following distinctions:
- forRoot: Typically registered in the root module
- forFeature: Shares Service instances with modules registered via forRoot
- register: Registers once without sharing with any modules
### 2. Operate McpServer
After creating the MCP Server, you can obtain the native MCP Server instance using the `getServer` method. This instance is not wrapped and is completely native.
For example, you can register a tool
```ts
import { Controller } from "@nestjs/common";
import { McpServerService } from "nest-mcp-sse";
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("Time format: iso, locale, or 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 Server Instances
In the example above, `mcpServerConfigs` was passed directly in `McpModule.register`, which creates the MCP Server during module initialization.
Of course, this is not necessary; you can choose not to pass `mcpServerConfigs` and manually register the MCP Server in a Controller or Service:
```typescript
import { Controller } from "@nestjs/common";
import { McpServerService } from "nest-mcp-sse";
import { z } from "zod";
@Controller()
export class AppController {
constructor(private readonly mcpServerService: McpServerService) {
// Manually register an MCP Server instance
this.mcpServerService.registerServer({
serverId: "another-server",
serverInfo: {
name: "another-mcp-server",
version: "1.0.0",
},
});
}
}
```
## Server Access Endpoints
After registering the module, the following endpoints will be automatically created:
- **SSE Connection Endpoint**: `/{controllerBaseUrl}/{serverId}/sse`
- **Message Handling Endpoint**: `/{controllerBaseUrl}/{serverId}/messages`
For example, if you use `controllerBaseUrl: 'api/mcp'` and `serverId: 'my-mcp-server'`, the access URLs will be:
- `http://localhost:3000/api/mcp/my-mcp-server/sse` - for SSE connection
- `http://localhost:3000/api/mcp/my-mcp-server/messages` - for message handling
## API
### McpModule.register
- **controllerBaseUrl**: The base URL path for the MCP Controller
- **sseEndpoint**: The name of the SSE connection endpoint, default is `sse`
- **messagesEndpoint**: The name of the message handling endpoint, default is `messages`
- **mcpServerConfigs**:
- serverId: The id of the McpServer, used to manage multiple instances
- serverInfo: Passed as the first parameter, directly input the native [MCP TS-SDK's McpServer class](https://github.com/modelcontextprotocol/typescript-sdk)
- serverOptions: Passed as the second parameter, directly input the native [MCP TS-SDK's McpServer class](https://github.com/modelcontextprotocol/typescript-sdk)
`forRoot` is the same as `register`, while `forFeature` only accepts `mcpServerConfigs`.
### McpServerService
The Service exported by McpModule, used to manage multiple McpServer instances.
You can inject it into your Controller or Service and use the following methods:
#### registerServer
- Purpose: Register an McpServer instance
- Parameters: Same as `mcpServerConfigs` in `McpModule.forRoot`
- Return Value: The registered McpServer instance
#### getServer
- Purpose: Get a specified McpServer instance
- Parameters: serverId
- Return Value: McpServer instance
#### getServerIds
- Purpose: Get all registered McpServer instance ids
- Return Value: `string[]` Array of all registered McpServer instance ids
#### hasServer
- Purpose: Determine if a specified McpServer instance has been registered
- Parameters: serverId
- Return Value: boolean
#### connect
- Purpose: Connect McpServer to the transport layer, generally not needed unless you want to manage connections manually.
- Parameters:
- serverId
- transport, Transport instance
- Return Value: void
### McpTransportService
The Service exported by McpModule, used to manage multiple SSEServerTransport instances.
Generally not needed unless you want to manage connections manually.
The following methods may be used; for more methods, please refer to the source code.
#### getTransport
- Purpose: Get a specific transport connection
- Parameters: serverId, sessionId
- Return Value: SSEServerTransport instance
#### getActiveSessionIds
- Purpose: Get all active session IDs of the McpServer
- Parameters: serverId
- Return Value: `string[]` Array of all active session IDs
## Advanced Configuration
### Custom Endpoint Names
You can customize the SSE and message endpoint names when registering the module:
```typescript
McpModule.register({
controllerBaseUrl: "api/mcp",
sseEndpoint: "connect", // default is 'sse'
messagesEndpoint: "rpc", // default is 'messages'
mcpServerConfigs: [
/* ... */
],
});
```
## Example Code
You can clone this repository and run the example code by following these steps:
```bash
pnpm install
cd example
pnpm install
pnpm start
```
Connection Info
You Might Also Like
MarkItDown MCP
Converting files and office documents to Markdown.
Time
Obtaining current time information and converting time between different...
Filesystem
Model Context Protocol Servers
Sequential Thinking
Offers a structured approach to dynamic and reflective problem-solving,...
Git
Model Context Protocol Servers
Context 7
Context7 MCP Server -- Up-to-date code documentation for LLMs and AI code editors