Install
$ agentstack add mcp-adrian-d-hidalgo-nestjs-mcp-server ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
MCP Server NestJS Module Library
[](https://www.npmjs.com/package/@nestjs-mcp/server) [](https://github.com/semantic-release/semantic-release) [](https://www.npmjs.com/package/@nestjs-mcp/server) [](https://github.com/adrian-d-hidalgo/nestjs-mcp-server/actions/workflows/ci.yml) [](https://codecov.io/gh/adrian-d-hidalgo/nestjs-mcp-server) [](https://snyk.io/test/github/adrian-d-hidalgo/nestjs-mcp-server) [](./LICENSE) [](./CONTRIBUTING.md) [](CODEOFCONDUCT.md)
Overview
NestJS MCP Server is a modular library for building Model Context Protocol (MCP) servers using NestJS. It provides decorators, modules, and integration patterns to expose MCP resources, tools, and prompts in a scalable, maintainable way. This project is a wrapper for the official @modelcontextprotocol/sdk and is always kept compatible with its types and specification.
Table of Contents
- [Installation](#installation)
- [Quickstart](#quickstart)
- [What is MCP?](#what-is-mcp)
- [Core Concepts](#core-concepts)
- [Server](#server)
- [Resource](#resource)
- [Tool](#tool)
- [Prompt](#prompt)
- [Module API](#module-api)
- [
McpModule.forRoot](#mcpmoduleforroot) - [
McpModule.forRootAsync](#mcpmoduleforrootasync) - [
McpModule.forFeature](#mcpmoduleforfeature) - [Module Usage](#module-usage)
- [1. Global Registration with
McpModule.forRoot](#1-global-registration-with-mcpmoduleforroot) - [2. Feature Module Registration with
McpModule.forFeature](#2-feature-module-registration-with-mcpmoduleforfeature) - [Capabilities](#capabilities)
- [Resolver Decorator](#resolver-decorator)
- [Prompt Decorator](#prompt-decorator)
- [Resource Decorator](#resource-decorator)
- [Tool Decorator](#tool-decorator)
- [Tool Annotations](#tool-annotations)
- [ToolOptions Variants](#tooloptions-variants)
- [RequestHandlerExtra Argument](#requesthandlerextra-argument)
- [Guards](#guards)
- [Global-level guards](#global-level-guards)
- [Resolver-level guards](#resolver-level-guards)
- [Method-level guards](#method-level-guards)
- [Guard Example](#guard-example)
- [MCP Execution Context](#mcp-execution-context)
- [Guards with Dependency Injection](#guards-with-dependency-injection)
- [Session Management](#session-management)
- [Session Management Options](#session-management-options)
- [Transport Options](#transport-options)
- [Inspector Playground](#inspector-playground)
- [Examples](#examples)
- [Changelog](#changelog)
- [License](#license)
- [Contributions](#contributions)
Installation
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
Quickstart
Register the MCP module in your NestJS app and expose a simple tool:
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 {}
What is MCP?
The Model Context Protocol (MCP) is an open protocol for connecting LLMs to external data, tools, and prompts. MCP servers expose resources (data), tools (actions), and prompts (conversational flows) in a standardized way, enabling seamless integration with LLM-powered clients.
- See the Anthropic announcement for more background.
Core Concepts
Server
The MCP Server is the main entry point for exposing capabilities to LLMs. It manages the registration and discovery of resources, tools, and prompts.
Resource
A Resource represents structured data or documents that can be queried or retrieved by LLMs. Resources are typically read-only and are identified by a unique URI.
- Learn more: MCP Resources documentation
Tool
A Tool is an action or function that can be invoked by LLMs. Tools may have side effects and can accept parameters to perform computations or trigger operations.
- Learn more: MCP Tools documentation
Prompt
A Prompt defines a conversational flow, template, or interaction pattern for LLMs. Prompts help guide the model's behavior in specific scenarios.
- Learn more: MCP Prompts documentation
> See the [Capabilities](#capabilities) section for implementation details and code examples.
Module API
McpModule.forRoot
Registers the MCP Server globally in your NestJS application.
Parameters:
options: McpModuleOptions— Main server configuration object:name: string: The name of your MCP server.version: string: The version of your MCP server.instructions?: string: Optional description of the MCP server for the client.capabilities?: Record: Optional additional capabilities metadata.providers?: Provider[]: Optional array of NestJS providers to include in the module.imports?: any[]: Optional array of NestJS modules to import.logging?: McpLoggingOptions: Optional logging configuration:enabled?: boolean(default:true): Enable/disable logging.level?: 'error' | 'warn' | 'log' | 'debug' | 'verbose'(default:'verbose'): Set the logging level.transports?: McpModuleTransportOptions: Optional transport configuration (see [Transport Options](#transport-options)).protocolOptions?: Record: Optional parameters passed directly to the underlying@modelcontextprotocol/sdkserver instance.
Returns:
- A dynamic NestJS module with all MCP providers registered.
Example:
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
Registers the MCP Server globally using asynchronous options, useful for integrating with configuration modules like @nestjs/config.
> Note: > > - The imports array should include any modules that provide dependencies required by your useFactory (e.g., ConfigModule if you inject ConfigService). > - Use forRootAsync only once in your root module (AppModule). > - See McpModuleAsyncOptions for all available options.
Parameters:
options: McpModuleAsyncOptions— Asynchronous configuration object:imports?: any[]: Optional modules to import before the factory runs.useFactory: (...args: any[]) => Promise | McpModuleOptions: A factory function that returns theMcpModuleOptions.inject?: any[]: Optional providers to inject into theuseFactory.
Returns:
- A dynamic NestJS module.
Example (with ConfigModule):
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
Registers additional MCP resources, tools, or prompts within a feature module. Use this to organize large servers into multiple modules. Resolvers containing MCP capabilities must be included in the providers array of the feature module.
Parameters:
options?: McpFeatureOptions(Currently unused, reserved for future enhancements).
Returns:
- A dynamic module.
Example:
// 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 {}
Module Usage
This library provides two main ways to register MCP capabilities in your NestJS application:
1. Global Registration with McpModule.forRoot
Use McpModule.forRoot in your root application module to configure and register the MCP server globally. This is required for every MCP server application.
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. Feature Module Registration with McpModule.forFeature
Use McpModule.forFeature in feature modules to register additional resolvers, tools, or resources. This is useful for organizing large servers into multiple modules.
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 {}
- Use
forRootorforRootAsynconly once in your root module (AppModule). - Use
forFeaturein any feature module where you define MCP capabilities (@Resolverclasses). - Ensure all Resolvers are listed in the
providersarray of their respective modules.
Capabilities
This library provides a set of decorators to define MCP capabilities and apply cross-cutting concerns such as guards. Decorators can be used at both the Resolver (class) level and the method level.
Resolver Decorator
A Resolver is a class that groups related MCP capabilities. All MCP capability methods (@Prompt, @Resource, @Tool) must belong to a class decorated with @Resolver.
- No
@Injectable()Needed: Resolver classes are automatically treated as providers by the MCP module and do not require the@Injectable()decorator. - Dependency Injection: Standard NestJS dependency injection works within Resolver constructors.
- Namespacing: You can optionally provide a string argument to
@Resolver('my_namespace')to namespace the capabilities within that resolver. - Guards: Guards can be applied at the class level using
@UseGuards().
Example:
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...*/) {
/* ... */
}
}
You can also apply guards at the resolver level:
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
}
Prompt Decorator
Decorate methods within a Resolver class to expose them as MCP Prompts. Accepts options compatible with server.prompt() from @modelcontextprotocol/sdk. The name should use 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.' }] };
}
}
Resource Decorator
Decorate methods within a Resolver class to expose them as MCP Resources. Accepts options compatible with server.resource() from @modelcontextprotocol/sdk. The name should use 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(
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [adrian-d-hidalgo](https://github.com/adrian-d-hidalgo)
- **Source:** [adrian-d-hidalgo/nestjs-mcp-server](https://github.com/adrian-d-hidalgo/nestjs-mcp-server)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.