### Run Example Servers (Manual Setup) Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/CONTRIBUTING.md Start one of the example MCP servers locally. The server will be accessible at http://localhost:3000. ```sh pnpm start:resources # or pnpm start:tools # or pnpm start:prompts ``` -------------------------------- ### Single Module Setup Example Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/mcpmodule.md An example demonstrating the setup for a monolithic application where `McpModule.forRoot` is used within the main `AppModule`. ```typescript @Module({ imports: [ McpModule.forRoot({ name: 'Monolithic Server', version: '1.0.0', }), ], providers: [MyResolver], }) export class AppModule {} ``` -------------------------------- ### Run Example Server with pnpm Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/examples/README.md Command to run a specific example server by setting the EXAMPLE environment variable. Ensure you have pnpm installed. ```sh EXAMPLE= pnpm start:example ``` -------------------------------- ### Install Dependencies (Manual Setup) Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/CONTRIBUTING.md Install project dependencies using PNPM or NPM after cloning the repository. Ensure Node.js v24+ and PNPM are installed. ```sh pnpm install # or npm install ``` -------------------------------- ### Multi-Module Setup Example Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/mcpmodule.md Illustrates a multi-module setup where `McpModule.forRoot` is used in the root `AppModule` and `McpModule.forFeature` is used in feature modules like `ToolsModule`. ```typescript // app.module.ts @Module({ imports: [ McpModule.forRoot({ name: 'Server', version: '1.0.0' }), ToolsModule, ResourcesModule, ], }) export class AppModule {} // tools.module.ts @Module({ imports: [McpModule.forFeature()], providers: [ToolsResolver], }) export class ToolsModule {} ``` -------------------------------- ### Example: Getting a Resource via cURL Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md This example shows how to retrieve a resource, such as configuration details, using a cURL command. It specifies the resource URI in the JSON-RPC parameters. ```bash curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -H "mcp-session-id: session-123" \ -d '{ "jsonrpc": "2.0", "id": 2, "method": "resources/read", "params": { "uri": "app://config" } }' ``` -------------------------------- ### Complete McpModuleOptions Example Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/types.md An example demonstrating how to configure McpModuleOptions. This includes setting the server name, version, instructions, logging level, session timeouts, and transport configurations. ```typescript const options: McpModuleOptions = { name: 'My MCP Server', version: '2.0.1', instructions: 'This server provides user management tools and data resources', logging: { enabled: true, level: 'debug' }, session: { sessionTimeoutMs: 1800000, cleanupIntervalMs: 300000, maxConcurrentSessions: 1000, }, transports: { streamable: { enabled: true }, sse: { enabled: false }, }, }; ``` -------------------------------- ### Run Mixed Example with cross-env on Windows Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/examples/README.md Command for Windows users to run the 'mixed' example using 'cross-env' to set environment variables with pnpm. ```sh npx cross-env EXAMPLE=mixed pnpm start:example ``` -------------------------------- ### Start MCP Inspector Playground Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/examples/README.md Command to launch the MCP Inspector Playground for interactive testing and debugging of MCP server examples. Requires pnpm. ```sh pnpm start:inspector ``` -------------------------------- ### McpModule Async Configuration Example Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/types.md An example demonstrating how to configure McpModule asynchronously using `useFactory`, `imports`, and `inject`. This pattern is useful for loading configuration from external sources. ```typescript const asyncOptions: McpModuleAsyncOptions = { imports: [ConfigModule], inject: [ConfigService], useFactory: async (config: ConfigService) => ({ name: config.get('MCP_NAME'), version: config.get('MCP_VERSION'), }), }; ``` -------------------------------- ### Module Initialization Error: Missing MCP_VERSION Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/error-handling-patterns.md Shows how an error thrown during McpModule asynchronous setup fails application bootstrap. This ensures required configuration is present before the server starts. ```typescript import { Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { McpModule } from '@nestjs-mcp/server'; @Module({ imports: [ McpModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config: ConfigService) => { const version = config.get('MCP_VERSION'); if (!version) { throw new Error('MCP_VERSION environment variable is required'); } return { name: config.get('MCP_NAME'), version: version, }; }, }), ], }) export class AppModule {} ``` -------------------------------- ### Get Prompt Request Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Example JSON-RPC request to retrieve a specific prompt ('code_review') with arguments for language and code length. ```typescript { "jsonrpc": "2.0", "id": 4, "method": "prompts/get", "params": { "name": "code_review", "arguments": { "language": "typescript", "codeLength": "medium" } } } ``` -------------------------------- ### Run Mixed Example with pnpm Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/examples/README.md Specific command to run the 'mixed' example, demonstrating multiple MCP capabilities in one server. Uses pnpm for execution. ```sh EXAMPLE=mixed pnpm start:example ``` -------------------------------- ### Example: Executing a Prompt via cURL Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md This example demonstrates how to execute a prompt, such as generating a summary, using a cURL command. The prompt name and any necessary arguments are included in the JSON-RPC payload. ```bash curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -H "mcp-session-id: session-123" \ -d '{ "jsonrpc": "2.0", "id": 3, "method": "prompts/get", "params": { "name": "summarize", "arguments": { "topic": "machine learning" } } }' ``` -------------------------------- ### Get Prompt Response Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Example JSON-RPC response containing a user message for a code review prompt. ```typescript { "jsonrpc": "2.0", "id": 4, "result": { "messages": [ { "role": "user", "content": { "type": "text", "text": "Review this TypeScript code for quality and best practices..." } } ] } } ``` -------------------------------- ### Example Response: Get Resource Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md The response for a resource retrieval request includes the resource's URI, MIME type, and content. This structure allows clients to access and interpret the requested data. ```json { "jsonrpc": "2.0", "id": 2, "result": { "contents": [ { "uri": "app://config", "mimeType": "application/json", "text": "{\"version\": \"1.0.0\"}" } ] } } ``` -------------------------------- ### Application Bootstrap Failure Handling Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/error-handling-patterns.md Example of catching errors during application bootstrap. This ensures graceful shutdown and provides informative logging if the server fails to start. ```typescript import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { try { const app = await NestFactory.create(AppModule); await app.listen(3000); } catch (error) { console.error('Failed to start MCP server:', error); process.exit(1); } } bootstrap(); ``` -------------------------------- ### Install NestJS MCP Server Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/README.md Install the necessary packages for the NestJS MCP Server, including the SDK and Zod for validation. ```sh 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 ``` -------------------------------- ### Example .env File for McpModule Configuration Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/configuration.md This is an example `.env` file that can be used with the `@nestjs/config` package to configure the `McpModule`. Ensure these variables match the keys used in the `useFactory` function. ```env MCP_SERVER_NAME=My MCP Server MCP_SERVER_VERSION=1.0.0 MCP_SERVER_INSTRUCTIONS=This server provides user management tools MCP_LOGGING_ENABLED=true MCP_LOG_LEVEL=verbose MCP_SESSION_TIMEOUT=1800000 MCP_CLEANUP_INTERVAL=300000 MCP_MAX_SESSIONS=1000 MCP_STREAMABLE_ENABLED=true MCP_SSE_ENABLED=false ``` -------------------------------- ### Bootstrap and Start NestJS Server Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/quick-start.md Create the main entry point for your NestJS application. This file bootstraps the application using NestFactory and starts the HTTP server, listening on port 3000. It also logs a message to the console indicating the server is running. ```typescript import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3000); console.log('MCP Server running on http://localhost:3000'); } bootstrap(); ``` -------------------------------- ### Run the NestJS MCP Server Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/quick-start.md Start the NestJS MCP server using npm run start or by directly executing the main TypeScript file with ts-node. Ensure your project is set up with a start script in package.json. ```bash npm run start # or ts-node src/main.ts ``` -------------------------------- ### Minimal Production Server Configuration Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/configuration.md Use this snippet for a basic production server setup. It requires only the name and version. ```typescript McpModule.forRoot({ name: 'Production MCP', version: '1.0.0', }) ``` -------------------------------- ### Example: Calling a Tool via cURL Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md This example demonstrates how to call the 'add_numbers' tool using a cURL command. It includes the necessary headers for content type and session ID, along with the JSON-RPC request payload. ```bash curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -H "mcp-session-id: session-123" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "add_numbers", "arguments": { "a": 5, "b": 3 } } }' ``` -------------------------------- ### Start MCP Inspector Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/quick-start.md Run the MCP Inspector to manage your server. Visit the provided URL to connect. ```bash npx @modelcontextprotocol/inspector ``` -------------------------------- ### SSE Response Example Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/transports.md Example of Server-Sent Events stream format for MCP messages. ```text data: {"jsonrpc":"2.0","id":1,"result":{...}} data: {"jsonrpc":"2.0","method":"notifications/message","params":{...}} ``` -------------------------------- ### List Resource Templates Request Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Example JSON-RPC request to list available resource templates. ```typescript { "jsonrpc": "2.0", "id": 3, "method": "resources/templates/list", "params": {} } ``` -------------------------------- ### Clone Repository Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/CONTRIBUTING.md Clone the project repository locally to begin development. This is the first step for both DevContainer and manual setup. ```sh git clone https://github.com/adrian-d-hidalgo/nestjs-mcp-server.git cd nestjs-mcp-server ``` -------------------------------- ### List Resource Templates Response Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Example JSON-RPC response listing resource templates, including their names, descriptions, and URI templates. ```typescript { "jsonrpc": "2.0", "id": 3, "result": { "templates": [ { "name": "user_profile", "description": "User profile resource", "uriTemplate": "user://profiles/{id}" } ] } } ``` -------------------------------- ### TypeScript Client Example for Streamable Transport Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/transports.md Example of how to use the fetch API in TypeScript to interact with the Streamable transport endpoint. It demonstrates sending a tool call and retrieving the session ID from response headers. ```typescript // TypeScript example using fetch async function callMcpTool(toolName: string, args: any) { const response = await fetch('http://localhost:3000/mcp', { method: 'POST', headers: { 'Content-Type': 'application/json', 'mcp-session-id': 'my-session-123', }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: toolName, arguments: args, }, }), }); const sessionId = response.headers.get('mcp-session-id'); const result = await response.json(); return result; } ``` -------------------------------- ### Direct Dependencies Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/index.md Lists the direct dependencies of the project, including the MCP SDK and Zod for validation. These are installed automatically when the package is added. ```json { "@modelcontextprotocol/sdk": "^1.29.0", "zod": "^4.4.3" } ``` -------------------------------- ### Example Response: Tool Call Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md This is the expected JSON response after successfully calling a tool. It contains the 'jsonrpc' version, the request 'id', and the 'result' of the operation. ```json { "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "5 + 3 = 8" } ] } } ``` -------------------------------- ### Minimal NestJS MCP Server Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/index.md Sets up a basic NestJS MCP server with a single 'ping' tool. Ensure `@nestjs-mcp/server` is installed. ```typescript import { Module } from '@nestjs/common'; import { McpModule, Resolver, Tool, RequestHandlerExtra } from '@nestjs-mcp/server'; import { CallToolResult } from '@modelcontextprotocol/sdk/types'; @Resolver() export class HealthResolver { @Tool({ name: 'ping' }) ping(extra: RequestHandlerExtra): CallToolResult { return { content: [{ type: 'text', text: 'pong' }] }; } } @Module({ imports: [McpModule.forRoot({ name: 'Server', version: '1.0.0' })], providers: [HealthResolver], }) export class AppModule {} ``` -------------------------------- ### Read Resource by URI Response Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Example JSON-RPC response containing user profile data retrieved by URI. ```typescript { "jsonrpc": "2.0", "id": 2, "result": { "contents": [ { "uri": "user://profiles/alice", "mimeType": "application/json", "text": "{\"id\":\"alice\",\"name\":\"Alice\",\"email\":\"alice@example.com\"}" } ] } } ``` -------------------------------- ### Example Response: Execute Prompt Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md The response to a prompt execution request contains the generated messages. This structure facilitates the display of conversational or generated content to the user. ```json { "jsonrpc": "2.0", "id": 3, "result": { "messages": [ { "role": "user", "content": { "type": "text", "text": "Please summarize the key points about \"machine learning\"" } } ] } } ``` -------------------------------- ### Example McpModuleTransportOptions Configuration Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/types.md Demonstrates how to configure McpModuleTransportOptions to enable streamable HTTP transport and disable the legacy SSE transport. This is useful for setting up specific communication channels. ```typescript const transports: McpModuleTransportOptions = { streamable: { enabled: true }, sse: { enabled: false }, // Disable legacy SSE }; ``` -------------------------------- ### Resolver-Level Guards Example Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/guards-and-context.md Applies guards to all capabilities within a resolver. Ensure the guard implements CanActivate and uses McpExecutionContext. ```typescript import { UseGuards, Resolver, Tool } from '@nestjs-mcp/server'; import { CanActivate, Injectable } from '@nestjs/common'; import { McpExecutionContext } from '@nestjs-mcp/server'; @Injectable() export class AdminGuard implements CanActivate { canActivate(context: McpExecutionContext): boolean { const sessionId = context.getSessionId(); // Check if session user is admin return true; } } @UseGuards(AdminGuard) @Resolver('admin') export class AdminResolver { @Tool({ name: 'delete_user' }) deleteUser(params: any, extra: any) { // Protected by AdminGuard } @Prompt({ name: 'admin_prompt' }) adminPrompt(extra: any) { // Also protected by AdminGuard } } ``` -------------------------------- ### Get Handler Arguments for Prompts Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/guards-and-context.md Demonstrates retrieving arguments for a 'prompt' type handler using McpExecutionContext. It logs the prompt arguments. ```typescript import { PromptHandlerArgs } from '@nestjs-mcp/server'; canActivate(context: McpExecutionContext): boolean { const args = context.getArgs(); if (args.type === 'prompt') { console.log('Prompt args:', args.args); } return true; } ``` -------------------------------- ### Usage Example for RequestHandlerExtra Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/types.md Demonstrates how to use the RequestHandlerExtra type to access headers and session information within a tool resolver. ```typescript import { Tool, Resolver, RequestHandlerExtra } from '@nestjs-mcp/server'; import { CallToolResult } from '@modelcontextprotocol/sdk/types'; @Resolver('tools') export class MyResolver { @Tool({ name: 'get_header' }) getHeader(extra: RequestHandlerExtra): CallToolResult { const authHeader = extra.headers.authorization; const sessionId = extra.sessionId; return { content: [ { type: 'text', text: `Session: ${sessionId}, Auth: ${authHeader ? 'present' : 'missing'}`, }, ], }; } } ``` -------------------------------- ### Get Handler Arguments for Resources Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/guards-and-context.md Illustrates retrieving arguments for 'resource:uri' and 'resource:template' types using McpExecutionContext. It logs the URI or template variables. ```typescript import { ResourceUriHandlerArgs, ResourceTemplateHandlerArgs } from '@nestjs-mcp/server'; canActivate(context: McpExecutionContext): boolean { const args = context.getArgs(); if (args.type === 'resource:uri') { console.log('Resource URI:', args.uri); } else if (args.type === 'resource:template') { console.log('Template variables:', args.variables); } return true; } ``` -------------------------------- ### Tool Annotations Example Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/README.md The 'annotations' field provides protocol-level hints about a tool's behavior, such as whether it is destructive, read-only, or idempotent. These hints can be used by clients or the protocol itself. ```typescript @Tool({ name: 'reset_password', paramsSchema: { userId: z.string() }, annotations: { destructiveHint: true, idempotentHint: false } }) resetPassword({ userId }: { userId: string }): CallToolResult { // ... } ``` -------------------------------- ### Type Narrowing Example for McpHandlerArgs Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/types.md Demonstrates how to use a switch statement on the 'type' property to safely narrow down the specific McpHandlerArgs type and access its properties. ```typescript function handleArgs(args: McpHandlerArgs) { switch (args.type) { case 'tool': console.log('Tool params:', args.params); break; case 'prompt': console.log('Prompt args:', args.args); break; case 'resource:uri': console.log('Resource URI:', args.uri); break; case 'resource:template': console.log('Resource template variables:', args.variables); break; } } ``` -------------------------------- ### Configure MCP Server Transports Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/README.md Configure which transport mechanisms are enabled globally using the `transports` option in `McpModule.forRoot`. This example explicitly enables streamable and disables SSE. ```typescript 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 {} ``` -------------------------------- ### Quickstart: Register MCP Module and Expose Tool Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/README.md Register the MCP module globally using `McpModule.forRoot` and define a simple health check tool using the `@Tool` decorator. Ensure necessary types are imported. ```typescript 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 {} ``` -------------------------------- ### Streamable Transport Response Body Example Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/transports.md Example of a JSON-RPC 2.0 response body from the Streamable transport, containing tool output. ```json { "jsonrpc": "2.0", "id": 1, "result": { "content": [{ "type": "text", "text": "Tool output" }] } } ``` -------------------------------- ### Streamable Transport Request Body Example Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/transports.md Example of a JSON-RPC 2.0 request body for the Streamable transport, used for calling tools. ```json { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "my_tool", "arguments": { "param": "value" } } } ``` -------------------------------- ### Get Handler Method from McpExecutionContext Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/guards-and-context.md Illustrates how to get the specific handler method being executed. This is helpful for logging the invoked method's name. ```typescript canActivate(context: McpExecutionContext): boolean { const handler = context.getHandler(); console.log(`Method: ${handler.name}`); // e.g., 'deleteUser' return true; } ``` -------------------------------- ### Configure Server with Environment Variables Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/quick-start.md Use ConfigModule and McpModule.forRootAsync to load server configuration from environment variables. ```typescript import { ConfigModule, ConfigService } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), McpModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config: ConfigService) => ({ name: config.get('MCP_SERVER_NAME'), version: config.get('MCP_SERVER_VERSION'), logging: { level: config.get('MCP_LOG_LEVEL', 'verbose') }, session: { sessionTimeoutMs: config.get('MCP_SESSION_TIMEOUT', 1800000), }, transports: { streamable: { enabled: config.get('MCP_STREAMABLE_ENABLED', true), }, sse: { enabled: config.get('MCP_SSE_ENABLED', true) }, }, }), }), ], }) export class AppModule {} ``` -------------------------------- ### Install NestJS MCP Server Dependencies Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/quick-start.md Install the necessary packages for the NestJS MCP server using npm, yarn, or pnpm. Ensure you have Node.js 24+ and NestJS 11.1.18+. ```bash 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 ``` -------------------------------- ### McpModuleAsyncOptions Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/types.md Configuration options for asynchronously initializing the McpModule. This includes specifying modules to import, a factory function to create the configuration, and tokens to inject into the factory. ```APIDOC ## McpModuleAsyncOptions Configuration for `McpModule.forRootAsync()`. ### Properties | Property | Type | Required | Description | |----------|------|----------|-------------| | imports | `any[]` | no | Modules to import before factory executes | | useFactory | `(...args) => Promise | McpModuleOptions` | yes | Factory function returning configuration | | inject | `any[]` | no | Tokens to inject into useFactory | ### Example ```typescript const asyncOptions: McpModuleAsyncOptions = { imports: [ConfigModule], inject: [ConfigService], useFactory: async (config: ConfigService) => ({ name: config.get('MCP_NAME'), version: config.get('MCP_VERSION'), }), }; ``` ``` -------------------------------- ### Enterprise Deployment Configuration with Async Factory Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/configuration.md Configure an enterprise deployment using an asynchronous factory, injecting configuration values from `ConfigModule`. This example customizes session, logging, and transport settings, including a custom session ID generator. ```typescript McpModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config: ConfigService) => ({ name: config.get('MCP_NAME'), version: config.get('MCP_VERSION'), instructions: config.get('MCP_INSTRUCTIONS'), logging: { enabled: config.get('LOG_ENABLED', true), level: config.get('LOG_LEVEL', 'warn'), // Minimal logging }, session: { sessionTimeoutMs: 3600000, // 1 hour cleanupIntervalMs: 600000, // 10 minutes maxConcurrentSessions: 10000, }, transports: { streamable: { enabled: true, options: { sessionIdGenerator: () => v4(), // UUID generator }, }, sse: { enabled: false }, // Only use Streamable }, }), }) ``` -------------------------------- ### Call Tool: Delete User Response Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Example JSON-RPC response indicating successful deletion of a user. ```typescript { "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "User user-123 deleted successfully" } ] } } ``` -------------------------------- ### Return Different Content Types Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/quick-start.md Demonstrates how to return different content types, such as text and images, from a tool. ```typescript import { CallToolResult, Tool } from '@nestjs/cqrs'; @Tool({ name: 'get_document' }) getDocument(params: any, extra: any): CallToolResult { return { content: [ { type: 'text', text: 'File content', }, { type: 'image', mimeType: 'image/png', data: 'base64-encoded-data', }, ], }; } ``` -------------------------------- ### Read Resource by URI Request Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Example JSON-RPC request to read a user profile resource using its URI. ```typescript { "jsonrpc": "2.0", "id": 2, "method": "resources/read", "params": { "uri": "user://profiles/alice" } } ``` -------------------------------- ### Generate SSH Key for Signing Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/CONTRIBUTING.md Use this command to generate a new SSH key pair for signing commits. Ensure you replace 'your_email@example.com' with your actual email address. ```sh ssh-keygen -t ed25519 -C "your_email@example.com" ``` -------------------------------- ### Configure MCP Server Session Management Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/README.md Configure session timeouts, cleanup intervals, and resource limits using the `session` option in `McpModule.forRoot`. This example sets custom values for session timeout, cleanup interval, and maximum concurrent sessions. ```typescript 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 {} ``` -------------------------------- ### Get McpExecutionContext Type Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/guards-and-context.md Demonstrates how to retrieve the type of the MCP execution context. This method always returns 'mcp'. ```typescript canActivate(context: McpExecutionContext): boolean { const type = context.getType(); // Always 'mcp' return type === 'mcp'; } ``` -------------------------------- ### Call Tool: Delete User Request Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Example JSON-RPC request to call the 'delete_user' tool with a specific user ID. ```typescript { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "delete_user", "arguments": { "userId": "user-123" } } } ``` -------------------------------- ### Method-Level Guards Example Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/guards-and-context.md Applies guards to individual capabilities within a resolver. This allows for fine-grained control over specific operations. ```typescript import { UseGuards, Resolver, Tool } from '@nestjs-mcp/server'; import { CanActivate, Injectable } from '@nestjs/common'; import { McpExecutionContext } from '@nestjs-mcp/server'; @Injectable() export class DestructiveGuard implements CanActivate { canActivate(context: McpExecutionContext): boolean { const request = context.getRequest(); const hasConfirmation = request.headers['x-confirm-destructive']; return !!hasConfirmation; } } @Resolver('user') export class UserResolver { @Tool({ name: 'list_users' }) listUsers(extra: any) { // No guard - publicly accessible } @UseGuards(DestructiveGuard) @Tool({ name: 'delete_all_users' }) deleteAllUsers(extra: any) { // Only accessible with confirmation } } ``` -------------------------------- ### Authentication Errors with Guards Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/error-handling-patterns.md Throw errors in guards to deny access when authentication fails. This example checks for a missing or invalid token. ```typescript @Injectable() export class TokenGuard implements CanActivate { canActivate(context: McpExecutionContext): boolean { const request = context.getRequest(); const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new Error('Missing authentication token'); } if (!this.validateToken(token)) { throw new Error('Invalid or expired token'); } return true; } private validateToken(token: string): boolean { // Validation logic return true; } } ``` -------------------------------- ### Using MCP_PROMPT Decorator Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/metadata-constants.md Marks a method as an MCP Prompt and demonstrates retrieving its name and arguments schema metadata. ```typescript import { MCP_PROMPT } from '@nestjs-mcp/server'; @Prompt({ name: 'my_prompt', argsSchema: MySchema, }) myPromptMethod() {} // Retrieve metadata const metadata = Reflect.getMetadata(MCP_PROMPT, MyResolver.prototype.myPromptMethod); console.log(metadata.name); // 'my_prompt' ``` -------------------------------- ### Use Dependency Injection for Database Access Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/quick-start.md Illustrates using dependency injection to provide a `DatabaseService` to a `DatabaseResolver` for accessing user data. ```typescript import { Injectable } from '@nestjs/common'; import { Resolver, Tool } from '@nestjs/cqrs'; @Injectable() export class DatabaseService { getUser(id: string) { // Implementation } } @Resolver('database') export class DatabaseResolver { constructor(private readonly db: DatabaseService) {} @Tool({ name: 'get_user' }) getUser(params: { id: string }, extra: any) { const user = this.db.getUser(params.id); return { content: [{ type: 'text', text: JSON.stringify(user) }], }; } } ``` -------------------------------- ### Call Tool: Delete User Error Response Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Example JSON-RPC error response when access is denied for a delete user operation. ```typescript { "jsonrpc": "2.0", "id": 1, "error": { "code": -32000, "message": "Access denied by guard on deleteUser" } } ``` -------------------------------- ### Test Server with cURL (Basic) Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/quick-start.md Use cURL to send a POST request to the MCP endpoint for basic tool calls. ```bash curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "greet", "arguments": { "name": "Alice" } } }' ``` -------------------------------- ### Applying Guards to a Resolver Class Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/decorators.md Use @UseGuards on a resolver class to protect all its methods. The example shows a custom AdminGuard being applied. ```typescript import { UseGuards, Resolver, Tool } from '@nestjs-mcp/server'; import { CanActivate } from '@nestjs/common'; import { McpExecutionContext } from '@nestjs-mcp/server'; export class AdminGuard implements CanActivate { canActivate(context: McpExecutionContext): boolean { const sessionId = context.getSessionId(); // Check if user is admin return true; } } @UseGuards(AdminGuard) @Resolver('admin') export class AdminResolver { @Tool({ name: 'delete_user' }) deleteUser(params: any, extra: any) { // All methods in this resolver are protected by AdminGuard } } ``` -------------------------------- ### Register MCP Server with forRoot Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/README.md Use McpModule.forRoot to register the MCP Server globally with synchronous configuration. Ensure all necessary options like name, version, and logging are provided. ```typescript 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 {} ``` -------------------------------- ### Using MCP_RESOURCE Decorator Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/metadata-constants.md Marks a method as an MCP Resource and shows how to retrieve its name and URI metadata. ```typescript import { MCP_RESOURCE } from '@nestjs-mcp/server'; @Resource({ name: 'config', uri: 'app://config', }) getConfig() {} // Retrieve metadata const metadata = Reflect.getMetadata(MCP_RESOURCE, MyResolver.prototype.getConfig); console.log(metadata.name); // 'config' console.log(metadata.uri); // 'app://config' ``` -------------------------------- ### Prompts Get Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Retrieves prompt messages based on a name and optional arguments. Useful for generating content like code reviews. ```APIDOC ## Prompts Get ### Description Retrieves prompt messages based on a name and optional arguments. Useful for generating content like code reviews. ### Method POST ### Endpoint /prompts/get ### Request Body - **jsonrpc** (string) - Required - JSON-RPC protocol version. - **id** (number) - Required - Unique identifier for the request. - **method** (string) - Required - The method name, "prompts/get". - **params** (object) - Required - Parameters for retrieving the prompt. - **name** (string) - Required - The name of the prompt to retrieve. - **arguments** (object) - Optional - Arguments to customize the prompt. - **language** (string) - Optional - The programming language for code-related prompts. - **codeLength** (string) - Optional - The desired length of code output. ### Request Example ```json { "jsonrpc": "2.0", "id": 4, "method": "prompts/get", "params": { "name": "code_review", "arguments": { "language": "typescript", "codeLength": "medium" } } } ``` ### Response #### Success Response - **jsonrpc** (string) - JSON-RPC protocol version. - **id** (number) - Unique identifier for the response. - **result** (object) - The result containing prompt messages. - **messages** (array) - An array of message objects. - **role** (string) - The role of the message sender (e.g., "user"). - **content** (object) - The content of the message. - **type** (string) - The type of content (e.g., "text"). - **text** (string) - The message text. #### Response Example ```json { "jsonrpc": "2.0", "id": 4, "result": { "messages": [ { "role": "user", "content": { "type": "text", "text": "Review this TypeScript code for quality and best practices..." } } ] } } ``` ``` -------------------------------- ### Lint and Test Project Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/CONTRIBUTING.md Run linting and tests to ensure code quality and compatibility before submitting a pull request. These commands should be executed after making changes. ```sh pnpm lint pnpm test ``` -------------------------------- ### Global Registration with McpModule.forRoot Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/README.md Use `McpModule.forRoot` in your root application module to configure and register the MCP server globally. This is required for every MCP server application. ```typescript 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 {} ``` -------------------------------- ### Get Handler Arguments for Tools Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/guards-and-context.md Shows how to retrieve arguments for a 'tool' type handler using McpExecutionContext. It logs the tool parameters. ```typescript import { ToolHandlerArgs } from '@nestjs-mcp/server'; canActivate(context: McpExecutionContext): boolean { const args = context.getArgs(); if (args.type === 'tool') { console.log('Tool params:', args.params); } return true; } ``` -------------------------------- ### Get Active Session Count Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/services.md Retrieves the number of currently active MCP sessions. This is useful for monitoring and managing server load. ```typescript const count = sessionManager.getActiveSessionCount(); console.log(`Active sessions: ${count}`); ``` -------------------------------- ### Monitor Active Sessions Source: https://github.com/adrian-d-hidalgo/nestjs-mcp-server/blob/main/_autodocs/api-endpoints.md Retrieve the count of active sessions by making a GET request to the /admin/sessions endpoint. Requires an admin token for authorization. ```bash # Get active session count via SessionManager curl -X GET http://localhost:3000/admin/sessions \ -H "Authorization: Bearer admin-token" ```