{"_id":"@alexahdp/nestjs-mcp-server","name":"@alexahdp/nestjs-mcp-server","dist-tags":{"latest":"0.3.0"},"versions":{"0.3.0":{"name":"@alexahdp/nestjs-mcp-server","version":"0.3.0","description":"Modular library for building scalable MCP servers with NestJS, providing decorators and integration patterns as a wrapper for the official MCP TypeScript SDK.","author":{"name":"Adrián Darío Hidalgo Flores, Aleksandr Pezikov"},"license":"MIT","engines":{"node":">=22","pnpm":">=10"},"publishConfig":{"access":"public"},"main":"dist/index.js","types":"dist/index.d.ts","repository":{"type":"git","url":"git+https://github.com/alexahdp/nestjs-mcp-server.git"},"bugs":{"url":"https://github.com/alexahdp/nestjs-mcp-server/issues"},"keywords":["decorators","integration","large-language-models","llm","mcp","model-context-protocol","module","nestjs","npm","pnpm","sdk","server","typescript","yarn"],"scripts":{"build":"nest build","prepare":"is-ci || husky","format":"prettier --write \"src/**/*.ts\" \"test/**/*.ts\"","start:example":"npx -y ts-node-dev --respawn examples/$EXAMPLE/main.ts","start:inspector":"npx -y @modelcontextprotocol/inspector","lint":"eslint \"{src,test,examples}/**/*.ts\" --fix","typecheck":"tsc --noEmit","test":"jest","test:watch":"jest --watch","test:cov":"jest --coverage","test:debug":"node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand","test:e2e":"jest --config ./test/jest-e2e.json","test:publish":"node scripts/test-npm-publish.js","npm:publish":"node scripts/npm-publish.js"},"peerDependencies":{"@nestjs/common":"^11.0.1","@nestjs/core":"^11.0.1","@nestjs/platform-express":"^11.0.1","reflect-metadata":"^0.2.2","rxjs":"^7.8.1"},"dependencies":{"@modelcontextprotocol/sdk":"^1.11.1","zod":"^3.24.4"},"devDependencies":{"@commitlint/cli":"^19.8.1","@commitlint/config-conventional":"^19.8.1","@commitlint/types":"^19.8.1","@eslint/eslintrc":"^3.2.0","@eslint/js":"^9.18.0","@nestjs/cli":"^11.0.0","@nestjs/config":"^4.0.2","@nestjs/schematics":"^11.0.0","@nestjs/testing":"^11.0.1","@swc/cli":"^0.6.0","@swc/core":"^1.10.7","@types/express":"^5.0.0","@types/jest":"^29.5.14","@types/node":"^22.10.7","@types/supertest":"^6.0.2","eslint":"^9.18.0","eslint-config-prettier":"^10.0.1","eslint-plugin-prettier":"^5.2.2","globals":"^16.0.0","husky":"^9.1.7","is-ci":"^4.1.0","jest":"^29.7.0","prettier":"^3.4.2","source-map-support":"^0.5.21","supertest":"^7.0.0","ts-jest":"^29.2.5","ts-loader":"^9.5.2","ts-node":"^10.9.2","tsconfig-paths":"^4.2.0","typescript":"^5.7.3","typescript-eslint":"^8.20.0"},"jest":{"moduleFileExtensions":["js","json","ts"],"rootDir":"src","testRegex":".*\\.spec\\.ts$","transform":{"^.+\\.(t|j)s$":"ts-jest"},"collectCoverageFrom":["**/*.(t|j)s"],"coverageDirectory":"../coverage","testEnvironment":"node","coverageThreshold":{"global":{"statements":50,"branches":25,"functions":40,"lines":50}},"coveragePathIgnorePatterns":["/index\\.ts$","\\.interface\\.ts$","\\.types\\.ts$"]},"_id":"@alexahdp/nestjs-mcp-server@0.3.0","gitHead":"2d40bc4cbfdd09df6781584f8588428213010e93","homepage":"https://github.com/alexahdp/nestjs-mcp-server#readme","_nodeVersion":"22.13.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-2uZcS1hICfgW3zpb0nTXVnBWkEnqeD0OWeia72fJ799+5owZ9aHGvtz4IY60GRAHJ6IPAnDHcwqvJuEmJNeG4Q==","shasum":"e81507785121df4c203aa8841e0136a3f7baf51b","tarball":"https://registry.npmjs.org/@alexahdp/nestjs-mcp-server/-/nestjs-mcp-server-0.3.0.tgz","fileCount":80,"unpackedSize":467364,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCm1f0NJtYGMMhKq39ob88jo5oV14eTi7Uj4JA2zJ3bwwIhAOJb8+BkOWVxM/79UOFWKJgclJg/okA/AN6qZOGP1GbS"}]},"_npmUser":{"name":"alexahdp","email":"alexahdp@gmail.com"},"directories":{},"maintainers":[{"name":"alexahdp","email":"alexahdp@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nestjs-mcp-server_0.3.0_1761605640372_0.6264451430623525"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-27T22:54:00.258Z","0.3.0":"2025-10-27T22:54:00.574Z","modified":"2025-10-27T22:54:00.845Z"},"maintainers":[{"name":"alexahdp","email":"alexahdp@gmail.com"}],"description":"Modular library for building scalable MCP servers with NestJS, providing decorators and integration patterns as a wrapper for the official MCP TypeScript SDK.","homepage":"https://github.com/alexahdp/nestjs-mcp-server#readme","keywords":["decorators","integration","large-language-models","llm","mcp","model-context-protocol","module","nestjs","npm","pnpm","sdk","server","typescript","yarn"],"repository":{"type":"git","url":"git+https://github.com/alexahdp/nestjs-mcp-server.git"},"author":{"name":"Adrián Darío Hidalgo Flores, Aleksandr Pezikov"},"bugs":{"url":"https://github.com/alexahdp/nestjs-mcp-server/issues"},"license":"MIT","readme":"# MCP Server NestJS Module Library <!-- omit in toc -->\n\nThis repository is a fork of https://github.com/adrian-d-hidalgo/nestjs-mcp-server.\nChanges in this fork:\n\n- multi-instance support - removed session-manager and sessions\n- removed sse transport\n\n[![NPM Version](https://img.shields.io/npm/v/@nestjs-mcp/server)](https://www.npmjs.com/package/@nestjs-mcp/server)\n[![Semantic Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![Downloads](https://img.shields.io/npm/dm/@nestjs-mcp/server)](https://www.npmjs.com/package/@nestjs-mcp/server)\n[![CI Pipeline](https://github.com/adrian-d-hidalgo/nestjs-mcp-server/actions/workflows/run-tests.yml/badge.svg)](https://github.com/adrian-d-hidalgo/nestjs-mcp-server/actions/workflows/run-tests.yml)\n[![codecov](https://codecov.io/gh/adrian-d-hidalgo/nestjs-mcp-server/graph/badge.svg?token=5E228VKY5K)](https://codecov.io/gh/adrian-d-hidalgo/nestjs-mcp-server)\n[![Known Vulnerabilities](https://snyk.io/test/github/adrian-d-hidalgo/nestjs-mcp-server/badge.svg)](https://snyk.io/test/github/adrian-d-hidalgo/nestjs-mcp-server)\n[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](./CONTRIBUTING.md)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)\n\n---\n\n## Overview <!-- omit in toc -->\n\n**NestJS MCP Server** is a modular library for building [Model Context Protocol (MCP)](https://github.com/modelcontextprotocol/typescript-sdk/tree/server) servers using [NestJS](https://nestjs.com/). 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`](https://github.com/modelcontextprotocol/typescript-sdk/tree/server) and is always kept compatible with its types and specification.\n\n---\n\n## Table of Contents <!-- omit in toc -->\n\n- [Overview](#overview)\n- [Installation](#installation)\n- [Quickstart](#quickstart)\n- [What is MCP?](#what-is-mcp)\n- [Core Concepts](#core-concepts)\n  - [Server](#server)\n  - [Resource](#resource)\n  - [Tool](#tool)\n  - [Prompt](#prompt)\n- [Module API](#module-api)\n  - [forRoot](#mcpmoduleforroot)\n  - [forRootAsync](#mcpmoduleforrootasync)\n  - [forFeature](#mcpmoduleforfeature)\n- [Module Usage](#module-usage)\n  - [1. Global Registration with `McpModule.forRoot`](#1-global-registration-with-mcpmoduleforroot)\n  - [2. Feature Module Registration with `McpModule.forFeature`](#2-feature-module-registration-with-mcpmoduleforfeature)\n- [Capabilities](#capabilities)\n  - [Resolver Decorator](#resolver-decorator)\n  - [Prompt Decorator](#prompt-decorator)\n  - [Resource Decorator](#resource-decorator)\n  - [Tool Decorator](#tool-decorator)\n  - [RequestHandlerExtra Parameter](#requesthandlerextra-argument)\n- [Guards](#guards)\n  - [Global-level guards](#global-level-guards)\n  - [Resolver-level guards](#resolver-level-guards)\n  - [Method-level guards](#method-level-guards)\n  - [Guard Example](#guard-example)\n  - [MCP Execution Context](#mcp-execution-context)\n- [Stateless Architecture](#stateless-architecture)\n- [Transport Options](#transport-options)\n- [Inspector Playground](#inspector-playground)\n- [Examples](#examples)\n- [Changelog](#changelog)\n- [License](#license)\n- [Contributions](#contributions)\n\n---\n\n## Installation\n\n```sh\nnpm install @nestjs-mcp/server @modelcontextprotocol/sdk zod\n# or\nyarn add @nestjs-mcp/server @modelcontextprotocol/sdk zod\n# or\npnpm add @nestjs-mcp/server @modelcontextprotocol/sdk zod\n```\n\n---\n\n## Quickstart\n\nRegister the MCP module in your NestJS app and expose a simple tool:\n\n```ts\nimport { Module } from '@nestjs/common';\n\nimport { CallToolResult } from '@modelcontextprotocol/sdk/types';\n\nimport { Resolver, Tool, McpModule } from '@nestjs-mcp/server';\n\n@Resolver()\nexport class HealthResolver {\n  /**\n   * Simple health check tool\n   */\n  @Tool({ name: 'server_health_check' })\n  healthCheck(): CallToolResult {\n    return {\n      content: [\n        {\n          type: 'text',\n          text: 'Server is operational. All systems running normally.',\n        },\n      ],\n    };\n  }\n}\n\n@Module({\n  imports: [\n    McpModule.forRoot({\n      name: 'My MCP Server',\n      version: '1.0.0',\n    }),\n  ],\n  providers: [HealthResolver],\n})\nexport class AppModule {}\n```\n\n---\n\n## What is MCP?\n\nThe **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.\n\n- See the [Anthropic announcement](https://www.anthropic.com/news/model-context-protocol) for more background.\n\n---\n\n## Core Concepts\n\n### Server\n\nThe MCP Server is the main entry point for exposing capabilities to LLMs. It manages the registration and discovery of resources, tools, and prompts.\n\n### Resource\n\nA 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.\n\n- Learn more: [MCP Resources documentation](https://modelcontextprotocol.io/docs/concepts/resources)\n\n### Tool\n\nA 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.\n\n- Learn more: [MCP Tools documentation](https://modelcontextprotocol.io/docs/concepts/tools)\n\n### Prompt\n\nA Prompt defines a conversational flow, template, or interaction pattern for LLMs. Prompts help guide the model's behavior in specific scenarios.\n\n- Learn more: [MCP Prompts documentation](https://modelcontextprotocol.io/docs/concepts/prompts)\n\n> **See the [Capabilities](#capabilities) section for implementation details and code examples.**\n\n---\n\n## Module API\n\n### `McpModule.forRoot`\n\nRegisters the MCP Server globally in your NestJS application.\n\n**Parameters:**\n\n- `options: McpModuleOptions` — Main server configuration object:\n  - `name: string`: The name of your MCP server.\n  - `version: string`: The version of your MCP server.\n  - `instructions?: string`: Optional description of the MCP server for the client.\n  - `capabilities?: Record<string, unknown>`: Optional additional capabilities metadata.\n  - `providers?: Provider[]`: Optional array of NestJS providers to include in the module.\n  - `imports?: any[]`: Optional array of NestJS modules to import.\n  - `logging?: McpLoggingOptions`: Optional logging configuration:\n    - `enabled?: boolean` (default: `true`): Enable/disable logging.\n    - `level?: 'error' | 'warn' | 'log' | 'debug' | 'verbose'` (default: `'verbose'`): Set the logging level.\n  - `transports?: McpModuleTransportOptions`: Optional transport configuration (see [Transport Options](#transport-options)).\n  - `protocolOptions?: Record<string, unknown>`: Optional parameters passed directly to the underlying `@modelcontextprotocol/sdk` server instance.\n\n**Returns:**\n\n- A dynamic NestJS module with all MCP providers registered.\n\n**Example:**\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { McpModule } from '@nestjs-mcp/server';\n\n@Module({\n  imports: [\n    McpModule.forRoot({\n      name: 'My Server',\n      version: '1.0.0',\n      instructions: 'A server providing utility tools and data.',\n      logging: { level: 'log' },\n      // ...other MCP options\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n### `McpModule.forRootAsync`\n\nRegisters the MCP Server globally using asynchronous options, useful for integrating with configuration modules like `@nestjs/config`.\n\n> **Note:**\n>\n> - The `imports` array should include any modules that provide dependencies required by your `useFactory` (e.g., `ConfigModule` if you inject `ConfigService`).\n> - Use `forRootAsync` only once in your root module (`AppModule`).\n> - See `McpModuleAsyncOptions` for all available options.\n\n**Parameters:**\n\n- `options: McpModuleAsyncOptions` — Asynchronous configuration object:\n  - `imports?: any[]`: Optional modules to import before the factory runs.\n  - `useFactory: (...args: any[]) => Promise<McpModuleOptions> | McpModuleOptions`: A factory function that returns the `McpModuleOptions`.\n  - `inject?: any[]`: Optional providers to inject into the `useFactory`.\n\n**Returns:**\n\n- A dynamic NestJS module.\n\n**Example (with ConfigModule):**\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { ConfigModule, ConfigService } from '@nestjs/config';\nimport { McpModule } from '@nestjs-mcp/server';\n\n@Module({\n  imports: [\n    ConfigModule.forRoot(), // Make sure ConfigModule is imported\n    McpModule.forRootAsync({\n      imports: [ConfigModule], // Import ConfigModule here too\n      useFactory: (configService: ConfigService) => ({\n        name: configService.get<string>('MCP_SERVER_NAME', 'Default Server'),\n        version: configService.get<string>('MCP_SERVER_VERSION', '1.0.0'),\n        instructions: configService.get<string>('MCP_SERVER_DESC'),\n        logging: {\n          level: configService.get('MCP_LOG_LEVEL', 'verbose'),\n        },\n        // ... other options from configService\n      }),\n      inject: [ConfigService], // Inject ConfigService into the factory\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n### `McpModule.forFeature`\n\nRegisters 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.\n\n**Parameters:**\n\n- `options?: McpFeatureOptions` (Currently unused, reserved for future enhancements).\n\n**Returns:**\n\n- A dynamic module.\n\n**Example:**\n\n```ts\n// src/status/status.resolver.ts\nimport { Resolver, Tool } from '@nestjs-mcp/server';\nimport { CallToolResult } from '@modelcontextprotocol/sdk/types';\n\n@Resolver('status')\nexport class StatusResolver {\n  @Tool({ name: 'health_check' })\n  healthCheck(): CallToolResult {\n    return { content: [{ type: 'text', text: 'OK' }] };\n  }\n}\n\n// src/status/status.module.ts\nimport { Module } from '@nestjs/common';\nimport { McpModule } from '@nestjs-mcp/server';\nimport { StatusResolver } from './status.resolver';\n\n@Module({\n  imports: [McpModule.forFeature()], // Import forFeature here\n  providers: [StatusResolver], // Register your resolver\n})\nexport class StatusModule {}\n```\n\n---\n\n## Module Usage\n\nThis library provides two main ways to register MCP capabilities in your NestJS application:\n\n### 1. Global Registration with `McpModule.forRoot`\n\nUse `McpModule.forRoot` in your root application module to configure and register the MCP server globally. This is required for every MCP server application.\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { McpModule } from '@nestjs-mcp/server';\nimport { PromptsResolver } from './prompts.resolver';\n\n@Module({\n  imports: [\n    McpModule.forRoot({\n      name: 'My MCP Server',\n      version: '1.0.0',\n      // ...other MCP options\n    }),\n  ],\n  providers: [PromptsResolver],\n})\nexport class AppModule {}\n```\n\n### 2. Feature Module Registration with `McpModule.forFeature`\n\nUse `McpModule.forFeature` in feature modules to register additional resolvers, tools, or resources. This is useful for organizing large servers into multiple modules.\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { McpModule } from '@nestjs-mcp/server';\n\nimport { ToolsResolver } from './tools.resolver';\n\n@Module({\n  imports: [McpModule.forFeature()],\n  providers: [ToolsResolver],\n})\nexport class ToolsModule {}\n```\n\n- Use `forRoot` or `forRootAsync` **only once** in your root module (`AppModule`).\n- Use `forFeature` in any feature module where you define MCP capabilities (`@Resolver` classes).\n- Ensure all Resolvers are listed in the `providers` array of their respective modules.\n\n---\n\n## Capabilities\n\nThis 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.\n\n### Resolver Decorator\n\nA Resolver is a class that groups related MCP capabilities. **All** MCP capability methods (`@Prompt`, `@Resource`, `@Tool`) **must** belong to a class decorated with `@Resolver`.\n\n- **No `@Injectable()` Needed:** Resolver classes are automatically treated as providers by the MCP module and **do not** require the `@Injectable()` decorator.\n- **Dependency Injection:** Standard NestJS dependency injection works within Resolver constructors.\n- **Namespacing:** You can optionally provide a string argument to `@Resolver('my_namespace')` to namespace the capabilities within that resolver.\n- **Guards:** Guards can be applied at the class level using `@UseGuards()`.\n\n**Example:**\n\n```ts\nimport { Resolver, Prompt, Resource, Tool } from '@nestjs-mcp/server';\n// Import any services you need to inject\nimport { SomeService } from '../some.service';\n\n@Resolver('workspace') // No @Injectable()\nexport class MyResolver {\n  // Inject dependencies as usual\n  constructor(private readonly someService: SomeService) {}\n\n  @Prompt({ name: 'greet_user' }) // Capabilities must be inside a Resolver\n  greetPrompt(/*...args...*/) {\n    const greeting = this.someService.getGreeting();\n    /* ... */\n  }\n\n  @Resource({ name: 'user_profile', uri: 'user://{id}' })\n  getUserResource(/*...args...*/) {\n    /* ... */\n  }\n\n  @Tool({ name: 'calculate_sum' })\n  sumTool(/*...args...*/) {\n    /* ... */\n  }\n}\n```\n\nYou can also apply guards at the resolver level:\n\n```ts\nimport { UseGuards, Resolver } from '@nestjs-mcp/server';\nimport { MyGuard } from './guards/my.guard';\n\n@UseGuards(MyGuard) // Applied to all capabilities in this Resolver\n@Resolver('secure') // No @Injectable()\nexport class SecureResolver {\n  // All capabilities in this resolver will use MyGuard\n}\n```\n\n### Prompt Decorator\n\nDecorate 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`.**\n\n```ts\nimport { Prompt, Resolver } from '@nestjs-mcp/server';\nimport { RequestHandlerExtra } from '@nestjs-mcp/server'; // Import type for extra info\nimport { z } from 'zod'; // Example if using Zod schema\n\n// Optional: Define schema if needed\n// const SummaryArgs = z.object({ topic: z.string() });\n\n@Resolver('prompts') // Must be in a Resolver class\nexport class MyPrompts {\n  @Prompt({\n    name: 'generate_summary',\n    description: 'Generates a summary for the given text.',\n    // argsSchema: SummaryArgs\n  })\n  generateSummaryPrompt(\n    // params: z.infer<typeof SummaryArgs>, // Arguments based on argsSchema (if defined)\n    extra: RequestHandlerExtra, // Contains sessionId and other metadata\n  ) {\n    console.log(`Generating summary for session: ${extra.sessionId}`);\n    /* ... return CallPromptResult ... */\n    return { content: [{ type: 'text', text: 'Summary generated.' }] };\n  }\n}\n```\n\n### Resource Decorator\n\nDecorate 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`.**\n\n```ts\nimport { Resource, Resolver } from '@nestjs-mcp/server';\nimport { RequestHandlerExtra } from '@nestjs-mcp/server'; // Import type for extra info\nimport { URL } from 'url'; // Type for URI resource\nimport { z } from 'zod'; // Example if using Zod template\n\n// Optional: Define template schema if needed\n// const DocQueryTemplate = z.object({ query: z.string() });\n\n@Resolver('data') // Must be in a Resolver class\nexport class MyResources {\n  @Resource({\n    name: 'user_profile',\n    uri: 'user://profiles/{userId}',\n    // metadata: { description: '...' } // Optional\n  })\n  getUserProfile(\n    uri: URL, // First argument is the parsed URI\n    // metadata: Record<string, any> // Second argument if is defined\n    extra: RequestHandlerExtra, // Contains sessionId and other metadata\n  ) {\n    const userId = uri.pathname.split('/').pop(); // Example: Extract ID from URI\n    console.log(`Fetching profile for ${userId}, session: ${extra.sessionId}`);\n    /* ... return CallResourceResult ... */\n    return { content: [{ type: 'text', text: `Profile data for ${userId}` }] };\n  }\n\n  @Resource({\n    name: 'document_list',\n    template: { type: 'string', description: 'Document content query' }, // Simple template example\n    // metadata: { list: true } // Optional\n  })\n  findDocuments(\n    uri: URL, // First arg based on simple template type\n    variables: Record<string, string>, // Second arg is path params (if any)\n    extra: RequestHandlerExtra, // Contains sessionId and other metadata\n  ) {\n    console.log(\n      `Finding documents matching '${query}', session: ${extra.sessionId}`,\n    );\n    /* ... return CallResourceResult ... */\n    return { content: [{ type: 'text', text: 'List of documents.' }] };\n  }\n}\n```\n\n### Tool Decorator\n\nDecorate methods within a Resolver class to expose them as MCP Tools. Accepts options compatible with `server.tool()` from `@modelcontextprotocol/sdk`. **The `name` should use `snake_case`.**\n\n```ts\nimport { Tool, Resolver } from '@nestjs-mcp/server';\nimport { RequestHandlerExtra } from '@nestjs-mcp/server';\nimport { z } from 'zod';\nimport { CallToolResult } from '@modelcontextprotocol/sdk/types';\n\n@Resolver('user_tools')\nexport class UserToolsResolver {\n  @Tool({\n    name: 'delete_user',\n    description: 'Deletes a user by ID',\n    paramsSchema: { userId: z.string() },\n    annotations: { destructiveHint: true, readOnlyHint: false },\n  })\n  deleteUser(\n    { userId }: { userId: string },\n    extra: RequestHandlerExtra,\n  ): CallToolResult {\n    // ...logic...\n    return { content: [{ type: 'text', text: `User ${userId} deleted.` }] };\n  }\n}\n```\n\n#### Tool Annotations\n\nThe `annotations` field allows you to provide protocol-level hints about the tool's behavior, such as whether it is destructive, read-only, idempotent, or has other special properties. These hints can be used by clients, UIs, or the protocol itself to display warnings, optimize calls, or enforce policies.\n\n**Common annotation keys:**\n\n- `destructiveHint` (boolean): Indicates the tool performs a destructive action (e.g., deletes data).\n- `readOnlyHint` (boolean): Indicates the tool does not modify any data.\n- `idempotentHint` (boolean): Indicates the tool can be safely called multiple times with the same effect.\n- `openWorldHint` (boolean): Indicates the tool may have side effects outside the current system.\n\n**Example:**\n\n```ts\n@Tool({\n  name: 'reset_password',\n  paramsSchema: { userId: z.string() },\n  annotations: { destructiveHint: true, idempotentHint: false }\n})\nresetPassword({ userId }: { userId: string }): CallToolResult {\n  // ...\n}\n```\n\n#### ToolOptions Variants\n\n| Variant                                          | Required Fields                              |\n| ------------------------------------------------ | -------------------------------------------- |\n| ToolBaseOptions                                  | name                                         |\n| ToolWithDescriptionOptions                       | name, description                            |\n| ToolWithParamOrAnnotationsOptions                | name, paramsSchemaOrAnnotations              |\n| ToolWithParamOrAnnotationsAndDescriptionOptions  | name, paramsSchemaOrAnnotations, description |\n| ToolWithParamAndAnnotationsOptions               | name, paramsSchema, annotations              |\n| ToolWithParamAndAnnotationsAndDescriptionOptions | name, paramsSchema, annotations, description |\n\n- `paramsSchema` and `paramsSchemaOrAnnotations` can be a Zod schema for input validation.\n- `annotations` is an object with protocol-level hints as described above.\n\n### RequestHandlerExtra Argument\n\nAll MCP capability methods (`@Prompt`, `@Resource`, `@Tool`) always receive a `RequestHandlerExtra` object as their last parameter. This object extends the original type from `@modelcontextprotocol/sdk` and provides essential context about the current MCP request.\n\n**Properties from SDK:**\n\n- `signal`: An `AbortSignal` used to communicate if the request was cancelled\n- `authInfo`: Optional information about a validated access token\n- `sessionId`: The session ID from the transport, if available (may be undefined in stateless mode)\n- `sendNotification`: Function to send a notification related to the current request\n- `sendRequest`: Function to send a request related to the current request\n\n**Extended Properties:**\n\n- `request`: Express Request object providing access to headers, body, query params, IP, etc. (added by @nestjs-mcp/server)\n\n**Usage Example:**\n\n```ts\nimport { Tool, Resolver } from '@nestjs-mcp/server';\nimport { RequestHandlerExtra } from '@nestjs-mcp/server';\nimport { CallToolResult } from '@modelcontextprotocol/sdk/types';\n\n@Resolver('auth')\nexport class AuthResolver {\n  @Tool({\n    name: 'authenticate_user',\n    description: 'Authenticates a user with credentials',\n    // ...other options\n  })\n  authenticateUser(\n    params: { username: string; password: string },\n    extra: RequestHandlerExtra, // Always the last parameter\n  ): CallToolResult {\n    // Access request headers\n    const authHeader = extra.request.headers.authorization;\n    const userAgent = extra.request.headers['user-agent'];\n    const clientIp = extra.request.ip;\n\n    console.log(`Request from: ${userAgent} (${clientIp})`);\n\n    // Access request body\n    const requestBody = extra.request.body;\n\n    // Check if request was cancelled\n    if (extra.signal.aborted) {\n      return {\n        content: [{ type: 'text', text: 'Request was cancelled' }],\n      };\n    }\n\n    // Implement authentication logic\n    return {\n      content: [{ type: 'text', text: 'Authentication successful' }],\n    };\n  }\n}\n```\n\n**Available Request Properties:**\n\nThe `extra.request` object is a standard Express Request with access to:\n\n- `headers` - HTTP headers\n- `body` - Request body (parsed by body-parser middleware)\n- `query` - Query string parameters\n- `params` - Route parameters\n- `ip` - Client IP address\n- `method` - HTTP method (GET, POST, etc.)\n- `url` - Request URL\n- `cookies` - Cookies (if cookie-parser middleware is used)\n- And all other Express Request properties\n\n**Important Notes:**\n\n- `extra` is always the last parameter in any method decorated with `@Resource`, `@Prompt`, or `@Tool`\n- The `request` property provides direct access to the Express Request object\n\n---\n\n## Guards\n\nApply one or more guards to a Resolver, to individual methods, or globally. Guards must implement the NestJS `CanActivate` interface.\n\n### Global-level guards\n\nThis approach uses the standard NestJS global guard system (`APP_GUARD`). A global guard will protect **all** NestJS routes, including the MCP transport endpoint (`/mcp`). Use this for broad authentication or checks that apply before any MCP-specific logic runs.\n\n```ts\n// src/guards/global-auth.guard.ts\nimport { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';\nimport { Request } from 'express';\n\n@Injectable()\nexport class GlobalAuthGuard implements CanActivate {\n  canActivate(context: ExecutionContext): boolean {\n    const request = context.switchToHttp().getRequest<Request>();\n    const apiKey = request.headers['x-api-key'];\n    // Example: Check for a valid API key\n    return !!apiKey && apiKey === 'EXPECTED_KEY';\n  }\n}\n```\n\nRegister the guard globally in your main module:\n\n```ts\n// src/app.module.ts\nimport { Module } from '@nestjs/common';\nimport { APP_GUARD } from '@nestjs/core';\nimport { McpModule } from '@nestjs-mcp/server';\nimport { GlobalAuthGuard } from './guards/global-auth.guard';\n\n@Module({\n  imports: [McpModule.forRoot(/*...*/)],\n  providers: [\n    {\n      provide: APP_GUARD,\n      useClass: GlobalAuthGuard,\n    },\n  ],\n})\nexport class AppModule {}\n```\n\n### Resolver-level guards\n\nThis is a custom feature of this library. Resolver-level guards are applied using the `@UseGuards()` decorator (exported from `@nestjs-mcp/server`) on a Resolver class. All MCP methods (`@Prompt`, `@Resource`, `@Tool`) **within that specific resolver** will be protected by these guards. Use this to enforce logic (e.g., role checks) for a group of related capabilities.\n\n```ts\nimport { UseGuards, Resolver, Prompt } from '@nestjs-mcp/server';\nimport { RoleGuard } from './guards/role.guard';\n\n@UseGuards(RoleGuard)\n@Resolver('admin')\nexport class AdminResolver {\n  @Prompt({ name: 'admin_action' })\n  adminAction(/*...*/) {\n    /* ... */\n  }\n  // ... other admin capabilities\n}\n```\n\n### Method-level guards\n\nThis is a custom feature of this library. Method-level guards are applied using the `@UseGuards()` decorator directly on an MCP capability method (`@Prompt`, `@Resource`, `@Tool`). Only the decorated method will be protected by these guards. Use this for fine-grained access control on specific capabilities.\n\n```ts\nimport { UseGuards, Resolver, Prompt, Tool } from '@nestjs-mcp/server';\nimport { SpecificCheckGuard } from './guards/specific-check.guard';\n\n@Resolver('mixed')\nexport class MixedResolver {\n  @Prompt({ name: 'public_prompt' })\n  publicPrompt() {\n    /* Publicly accessible */\n  }\n\n  @UseGuards(SpecificCheckGuard)\n  @Tool({ name: 'protected_tool' })\n  protectedTool(/*...*/) {\n    /* Requires SpecificCheckGuard to pass */\n  }\n}\n```\n\n**Important:** Resolver and Method-level guards **only run for MCP capability invocations**, not for the initial connection establishment handled by global guards. They use the custom `McpExecutionContext`.\n\n### Guard Example\n\nA guard for Resolver or Method-level protection:\n\n```ts\n// src/guards/my-mcp.guard.ts\nimport { CanActivate, Injectable } from '@nestjs/common';\nimport { McpExecutionContext } from '@nestjs-mcp/server';\n\n@Injectable()\nexport class MyMcpGuard implements CanActivate {\n  canActivate(context: McpExecutionContext): boolean {\n    const sessionId = context.getSessionId();\n    const handlerArgs = context.getArgs();\n    const request = context.switchToHttp().getRequest();\n    const userAgent = request?.headers['user-agent'];\n\n    console.log(`Guard activated for session ${sessionId} from ${userAgent}`);\n    console.log('Handler args:', handlerArgs);\n\n    return true;\n  }\n}\n```\n\n### MCP Execution Context\n\nWhen implementing **Resolver-level** or **Method-level** guards using `@UseGuards()` from this library, your `canActivate` method receives an `McpExecutionContext` instance. This context provides access to MCP-specific information:\n\n```typescript\nimport { CanActivate, Injectable } from '@nestjs/common';\nimport { McpExecutionContext } from '@nestjs-mcp/server';\nimport { Request } from 'express';\n\n@Injectable()\nexport class McpAuthGuard implements CanActivate {\n  canActivate(context: McpExecutionContext): boolean {\n    const sessionId = context.getSessionId();\n    const handlerArgs = context.getArgs<any>();\n    const request = context.switchToHttp().getRequest<Request>();\n\n    console.log('MCP Handler Arguments:', handlerArgs);\n    console.log('Session ID:', sessionId);\n\n    const authHeader = request.headers.authorization;\n    if (!authHeader || !authHeader.startsWith('Bearer ')) {\n      console.log('Guard Denied: Missing or invalid Bearer token.');\n      return false;\n    }\n\n    const token = authHeader.split(' ')[1];\n    const isValidToken = token === 'VALID_TOKEN';\n\n    if (isValidToken) {\n      console.log(`Guard Passed for session ${sessionId} with token.`);\n      return true;\n    } else {\n      console.log(`Guard Denied: Invalid token for session ${sessionId}.`);\n      return false;\n    }\n  }\n}\n```\n\n**Key points for `McpExecutionContext`:**\n\n- `getSessionId()`: Retrieves the unique ID for the current MCP session (may be undefined in stateless mode)\n- `getArgs()`: Provides the arguments passed to the MCP handler method (`@Tool`, `@Prompt`, `@Resource`)\n- `switchToHttp().getRequest()`: Returns the Express Request object with access to headers, body, query params, etc.\n- `switchToHttp().getResponse()` / `switchToHttp().getNext()`: These will throw errors as the Response object is not directly available in this context\n\n---\n\n## Stateless Architecture\n\nThis library implements a **stateless** approach following the recommended \"Without Session Management\" pattern from `@modelcontextprotocol/sdk`. Each request is handled independently without maintaining session state between requests.\n\n### How It Works\n\n1. **Request Flow:**\n\n   - Client sends POST request to `/mcp`\n   - Server creates a new transport for each request with `sessionIdGenerator: undefined`\n   - Request is processed and transport is closed when response completes\n\n2. **Request Context:**\n   - The original Express Request is made available via `AsyncLocalStorage`\n   - Guards and handlers can access request data through `extra.request`\n   - No session state is maintained between requests\n\n### Benefits\n\n- **Simpler Architecture**: No session state to manage\n- **Better Scalability**: Each request is independent\n- **SDK Compliance**: Follows recommended approach from `@modelcontextprotocol/sdk`\n- **Reduced Memory Usage**: No session storage overhead\n- **Easier Debugging**: No cross-request state issues\n\n### Accessing Request Data\n\nAll MCP handlers receive the Express Request object in the `extra` parameter:\n\n```typescript\n@Tool({ name: 'my_tool' })\nmyTool(params: any, extra: RequestHandlerExtra): CallToolResult {\n  // Access headers\n  const authHeader = extra.request.headers.authorization;\n\n  // Access body\n  const body = extra.request.body;\n\n  // Access IP\n  const clientIp = extra.request.ip;\n\n  // ... use request data\n}\n```\n\nGuards can also access the request through the execution context:\n\n```typescript\n@Injectable()\nexport class MyGuard implements CanActivate {\n  canActivate(context: McpExecutionContext): boolean {\n    const request = context.switchToHttp().getRequest<Request>();\n    const apiKey = request.headers['x-api-key'];\n    return !!apiKey;\n  }\n}\n```\n\n---\n\n## Transport Options\n\nThe MCP server communicates over HTTP using the Streamable transport mechanism. This transport uses standard HTTP POST requests and responses, suitable for most request/response interactions.\n\n**Configuration:**\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { McpModule } from '@nestjs-mcp/server';\n\n@Module({\n  imports: [\n    McpModule.forRoot({\n      name: 'My Server',\n      version: '1.0.0',\n      transports: {\n        streamable: { enabled: true }, // Streamable is enabled by default\n      },\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n**Default Configuration:**\n\nIf the `transports` option is omitted, the streamable transport (`/mcp` endpoint) is enabled by default.\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { McpModule } from '@nestjs-mcp/server';\n\n@Module({\n  imports: [\n    McpModule.forRoot({\n      name: 'My Server',\n      version: '1.0.0',\n      // Streamable transport is enabled by default\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\nThe server will be accessible at the `/mcp` endpoint for all MCP client requests.\n\n---\n\n## Inspector Playground\n\nUse the Inspector Playground to interactively test and debug your MCP server endpoints in a browser UI. This tool, powered by [`@modelcontextprotocol/inspector`](https://www.npmjs.com/package/@modelcontextprotocol/inspector), allows you to:\n\n- Explore available resources, tools, and prompts\n- Invoke endpoints and view responses in real time\n- Validate your server implementation against the MCP specification\n\nTo launch the Inspector Playground (make sure your NestJS MCP server is running):\n\n```sh\nnpx @modelcontextprotocol/inspector\n```\n\nIt will typically connect to `http://localhost:3000` by default, or you can specify a different target URL.\n\n---\n\n## Examples\n\nThe [`examples/`](./examples/) directory contains ready-to-use scenarios demonstrating how to register and expose MCP capabilities.\n\nEach example is self-contained and follows best practices. For advanced usage, see the code and documentation in each example.\n\n---\n\n## Changelog\n\nSee [CHANGELOG.md](./CHANGELOG.md) for release notes.\n\n---\n\n## License\n\nMIT — see [LICENSE](./LICENSE) for details.\n\n---\n\n## Contributions\n\nContributions are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines, reporting issues, and pull request rules.\n\nBefore contributing, please read our [Code of Conduct](./CODE_OF_CONDUCT.md) to understand the expectations for behavior in our community.\n","readmeFilename":"README.md","_rev":"1-eb70728358e85d1e131f8299f79506a2"}