@nestjs-mcp/server 0.1.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/.copilotignore +38 -0
  2. package/.devcontainer/Dockerfile.dev +28 -0
  3. package/.devcontainer/devcontainer.json +56 -0
  4. package/.devcontainer/docker-compose.yml +15 -0
  5. package/.dockerignore +37 -0
  6. package/.github/codeql-config.yml +4 -0
  7. package/.github/copilot-instructions.md +138 -0
  8. package/.github/prompts/memory.prompt.md +120 -0
  9. package/.github/workflows/auto-tag-release.yml +84 -0
  10. package/.github/workflows/codeql-analysis.yml +56 -0
  11. package/.github/workflows/npm-publish.yml +58 -0
  12. package/.github/workflows/pr-branch-validation.yml +78 -0
  13. package/.github/workflows/run-tests.yml +41 -0
  14. package/.github/workflows/sync-main-to-develop.yml +53 -0
  15. package/.handbook/GIT_GUIDELINES.md +250 -0
  16. package/.handbook/PACKAGE_VERSIONING.md +140 -0
  17. package/.handbook/STACK.md +75 -0
  18. package/.prettierrc +4 -0
  19. package/.vscode/extensions.json +44 -0
  20. package/.vscode/settings.json +40 -0
  21. package/CONTRIBUTING.md +261 -0
  22. package/LICENSE +21 -0
  23. package/README.md +490 -0
  24. package/dist/examples/async-import/app.module.d.ts +2 -0
  25. package/dist/examples/async-import/app.module.js +33 -0
  26. package/dist/examples/async-import/app.module.js.map +1 -0
  27. package/dist/examples/async-import/main.d.ts +1 -0
  28. package/dist/examples/async-import/main.js +17 -0
  29. package/dist/examples/async-import/main.js.map +1 -0
  30. package/dist/examples/guards/app.module.d.ts +6 -0
  31. package/dist/examples/guards/app.module.js +48 -0
  32. package/dist/examples/guards/app.module.js.map +1 -0
  33. package/dist/examples/guards/guards.resolver.d.ts +13 -0
  34. package/dist/examples/guards/guards.resolver.js +61 -0
  35. package/dist/examples/guards/guards.resolver.js.map +1 -0
  36. package/dist/examples/guards/main.d.ts +1 -0
  37. package/dist/examples/guards/main.js +11 -0
  38. package/dist/examples/guards/main.js.map +1 -0
  39. package/dist/examples/mixed/app.module.d.ts +2 -0
  40. package/dist/examples/mixed/app.module.js +31 -0
  41. package/dist/examples/mixed/app.module.js.map +1 -0
  42. package/dist/examples/mixed/main.d.ts +1 -0
  43. package/dist/examples/mixed/main.js +11 -0
  44. package/dist/examples/mixed/main.js.map +1 -0
  45. package/dist/examples/mixed/mixed.resolver.d.ts +6 -0
  46. package/dist/examples/mixed/mixed.resolver.js +78 -0
  47. package/dist/examples/mixed/mixed.resolver.js.map +1 -0
  48. package/dist/examples/prompts/app.module.d.ts +2 -0
  49. package/dist/examples/prompts/app.module.js +31 -0
  50. package/dist/examples/prompts/app.module.js.map +1 -0
  51. package/dist/examples/prompts/main.d.ts +1 -0
  52. package/dist/examples/prompts/main.js +11 -0
  53. package/dist/examples/prompts/main.js.map +1 -0
  54. package/dist/examples/prompts/prompts.resolver.d.ts +14 -0
  55. package/dist/examples/prompts/prompts.resolver.js +165 -0
  56. package/dist/examples/prompts/prompts.resolver.js.map +1 -0
  57. package/dist/examples/resources/app.module.d.ts +2 -0
  58. package/dist/examples/resources/app.module.js +31 -0
  59. package/dist/examples/resources/app.module.js.map +1 -0
  60. package/dist/examples/resources/main.d.ts +1 -0
  61. package/dist/examples/resources/main.js +11 -0
  62. package/dist/examples/resources/main.js.map +1 -0
  63. package/dist/examples/resources/resources.resolver.d.ts +12 -0
  64. package/dist/examples/resources/resources.resolver.js +114 -0
  65. package/dist/examples/resources/resources.resolver.js.map +1 -0
  66. package/dist/examples/tools/app.module.d.ts +2 -0
  67. package/dist/examples/tools/app.module.js +31 -0
  68. package/dist/examples/tools/app.module.js.map +1 -0
  69. package/dist/examples/tools/main.d.ts +1 -0
  70. package/dist/examples/tools/main.js +11 -0
  71. package/dist/examples/tools/main.js.map +1 -0
  72. package/dist/examples/tools/tools.resolver.d.ts +23 -0
  73. package/dist/examples/tools/tools.resolver.js +175 -0
  74. package/dist/examples/tools/tools.resolver.js.map +1 -0
  75. package/dist/src/controllers/sse/index.d.ts +2 -0
  76. package/dist/src/controllers/sse/index.js +19 -0
  77. package/dist/src/controllers/sse/index.js.map +1 -0
  78. package/dist/src/controllers/sse/sse.controller.d.ts +8 -0
  79. package/dist/src/controllers/sse/sse.controller.js +51 -0
  80. package/dist/src/controllers/sse/sse.controller.js.map +1 -0
  81. package/dist/src/controllers/sse/sse.service.d.ts +16 -0
  82. package/dist/src/controllers/sse/sse.service.js +78 -0
  83. package/dist/src/controllers/sse/sse.service.js.map +1 -0
  84. package/dist/src/controllers/streamable/index.d.ts +2 -0
  85. package/dist/src/controllers/streamable/index.js +19 -0
  86. package/dist/src/controllers/streamable/index.js.map +1 -0
  87. package/dist/src/controllers/streamable/streamable.controller.d.ts +9 -0
  88. package/dist/src/controllers/streamable/streamable.controller.js +62 -0
  89. package/dist/src/controllers/streamable/streamable.controller.js.map +1 -0
  90. package/dist/src/controllers/streamable/streamable.service.d.ts +24 -0
  91. package/dist/src/controllers/streamable/streamable.service.js +117 -0
  92. package/dist/src/controllers/streamable/streamable.service.js.map +1 -0
  93. package/dist/src/decorators/capabilities.constants.d.ts +4 -0
  94. package/dist/src/decorators/capabilities.constants.js +8 -0
  95. package/dist/src/decorators/capabilities.constants.js.map +1 -0
  96. package/dist/src/decorators/capabilities.decorators.d.ts +8 -0
  97. package/dist/src/decorators/capabilities.decorators.js +49 -0
  98. package/dist/src/decorators/capabilities.decorators.js.map +1 -0
  99. package/dist/src/decorators/index.d.ts +2 -0
  100. package/dist/src/decorators/index.js +19 -0
  101. package/dist/src/decorators/index.js.map +1 -0
  102. package/dist/src/index.d.ts +4 -0
  103. package/dist/src/index.js +21 -0
  104. package/dist/src/index.js.map +1 -0
  105. package/dist/src/interfaces/capabilities.interface.d.ts +52 -0
  106. package/dist/src/interfaces/capabilities.interface.js +3 -0
  107. package/dist/src/interfaces/capabilities.interface.js.map +1 -0
  108. package/dist/src/interfaces/guards.interface.d.ts +4 -0
  109. package/dist/src/interfaces/guards.interface.js +3 -0
  110. package/dist/src/interfaces/guards.interface.js.map +1 -0
  111. package/dist/src/interfaces/index.d.ts +2 -0
  112. package/dist/src/interfaces/index.js +19 -0
  113. package/dist/src/interfaces/index.js.map +1 -0
  114. package/dist/src/interfaces/mcp-server-options.interface.d.ts +42 -0
  115. package/dist/src/interfaces/mcp-server-options.interface.js +3 -0
  116. package/dist/src/interfaces/mcp-server-options.interface.js.map +1 -0
  117. package/dist/src/mcp.module.d.ts +13 -0
  118. package/dist/src/mcp.module.js +176 -0
  119. package/dist/src/mcp.module.js.map +1 -0
  120. package/dist/src/registry/discovery.service.d.ts +16 -0
  121. package/dist/src/registry/discovery.service.js +85 -0
  122. package/dist/src/registry/discovery.service.js.map +1 -0
  123. package/dist/src/registry/index.d.ts +2 -0
  124. package/dist/src/registry/index.js +19 -0
  125. package/dist/src/registry/index.js.map +1 -0
  126. package/dist/src/registry/logger.service.d.ts +16 -0
  127. package/dist/src/registry/logger.service.js +97 -0
  128. package/dist/src/registry/logger.service.js.map +1 -0
  129. package/dist/src/registry/registry.service.d.ts +14 -0
  130. package/dist/src/registry/registry.service.js +165 -0
  131. package/dist/src/registry/registry.service.js.map +1 -0
  132. package/dist/tsconfig.build.tsbuildinfo +1 -0
  133. package/eslint.config.mjs +40 -0
  134. package/examples/README.md +56 -0
  135. package/examples/async-import/app.module.ts +22 -0
  136. package/examples/async-import/main.ts +15 -0
  137. package/examples/guards/app.module.ts +44 -0
  138. package/examples/guards/guards.resolver.ts +52 -0
  139. package/examples/guards/main.ts +11 -0
  140. package/examples/mixed/app.module.ts +20 -0
  141. package/examples/mixed/main.ts +11 -0
  142. package/examples/mixed/mixed.resolver.ts +56 -0
  143. package/examples/prompts/app.module.ts +20 -0
  144. package/examples/prompts/main.ts +11 -0
  145. package/examples/prompts/prompts.resolver.ts +184 -0
  146. package/examples/resources/app.module.ts +19 -0
  147. package/examples/resources/main.ts +11 -0
  148. package/examples/resources/resources.resolver.ts +123 -0
  149. package/examples/tools/app.module.ts +20 -0
  150. package/examples/tools/main.ts +11 -0
  151. package/examples/tools/tools.resolver.ts +205 -0
  152. package/nest-cli.json +8 -0
  153. package/package.json +106 -0
  154. package/scripts/npm-publish.js +301 -0
  155. package/src/controllers/sse/index.ts +2 -0
  156. package/src/controllers/sse/sse.controller.ts +19 -0
  157. package/src/controllers/sse/sse.service.ts +90 -0
  158. package/src/controllers/streamable/index.ts +2 -0
  159. package/src/controllers/streamable/streamable.controller.ts +24 -0
  160. package/src/controllers/streamable/streamable.service.ts +168 -0
  161. package/src/decorators/capabilities.constants.ts +7 -0
  162. package/src/decorators/capabilities.decorators.ts +150 -0
  163. package/src/decorators/index.ts +2 -0
  164. package/src/index.ts +11 -0
  165. package/src/interfaces/capabilities.interface.ts +95 -0
  166. package/src/interfaces/guards.interface.ts +13 -0
  167. package/src/interfaces/index.ts +2 -0
  168. package/src/interfaces/mcp-server-options.interface.ts +105 -0
  169. package/src/mcp.module.ts +233 -0
  170. package/src/mcp.service.spec.ts +28 -0
  171. package/src/registry/discovery.service.ts +116 -0
  172. package/src/registry/index.ts +2 -0
  173. package/src/registry/logger.service.ts +143 -0
  174. package/src/registry/registry.service.ts +281 -0
  175. package/test/base.e2e-spec.ts +74 -0
  176. package/test/jest-e2e.json +9 -0
  177. package/tsconfig.build.json +4 -0
  178. package/tsconfig.json +23 -0
package/README.md ADDED
@@ -0,0 +1,490 @@
1
+ # MCP Server NestJS Module Library <!-- omit in toc -->
2
+
3
+ [![NPM Version](https://img.shields.io/npm/v/@your-org/nestjs-mcp-server)](https://www.npmjs.com/package/@nestjs-mcp/server)
4
+ [![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
5
+
6
+ ---
7
+
8
+ ## Overview <!-- omit in toc -->
9
+
10
+ **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.
11
+
12
+ ---
13
+
14
+ ## Table of Contents <!-- omit in toc -->
15
+
16
+ - [Overview](#overview)
17
+ - [Installation](#installation)
18
+ - [Quickstart](#quickstart)
19
+ - [What is MCP?](#what-is-mcp)
20
+ - [Core Concepts](#core-concepts)
21
+ - [Server](#server)
22
+ - [Resource](#resource)
23
+ - [Tool](#tool)
24
+ - [Prompt](#prompt)
25
+ - [Module API](#module-api)
26
+ - [forRoot](#mcpmoduleforroot)
27
+ - [forFeature](#mcpmoduleforfeature)
28
+ - [Resolver](#resolver)
29
+ - [Capabilities](#capabilities)
30
+ - [@Resolver](#resolver-decorator)
31
+ - [@Prompt](#prompt-decorator)
32
+ - [@Resource](#resource-decorator)
33
+ - [@Tool](#tool-decorator)
34
+ - [Guards](#guards)
35
+ - [Global-level guards:](#global-guard-guards)
36
+ - [Resolver-level guards:](#resolver-level-guards)
37
+ - [Method-level guards:](#method-level-guards)
38
+ - [Guard Example](#guard-example)
39
+ - [Inspector Playground](#inspector-playground)
40
+ - [Examples](#examples)
41
+ - [Changelog](#changelog)
42
+ - [License](#license)
43
+ - [Contributions](#contributions)
44
+
45
+ ---
46
+
47
+ ## Installation
48
+
49
+ ```sh
50
+ pnpm add @your-org/nestjs-mcp-server @modelcontextprotocol/sdk
51
+ # or
52
+ npm install @your-org/nestjs-mcp-server @modelcontextprotocol/sdk
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Quickstart
58
+
59
+ Register the MCP module in your NestJS app and expose a simple tool:
60
+
61
+ ```ts
62
+ import { Module } from '@nestjs/common';
63
+ import { Injectable } from '@nestjs/common';
64
+
65
+ import { CallToolResult } from '@modelcontextprotocol/sdk/types';
66
+
67
+ import { Tool } from '@nestjs-mcp/server';
68
+
69
+ @Injectable()
70
+ export class AppService {
71
+ /**
72
+ * Simple health check tool
73
+ */
74
+ @Tool({ name: 'server_health_check' })
75
+ healthCheck(): CallToolResult {
76
+ return {
77
+ content: [
78
+ {
79
+ type: 'text',
80
+ text: 'Server is operational. All systems running normally.',
81
+ },
82
+ ],
83
+ };
84
+ }
85
+ }
86
+
87
+ @Module({
88
+ imports: [
89
+ McpModule.forRoot({
90
+ name: 'My MCP Server',
91
+ version: '1.0.0',
92
+ }),
93
+ ],
94
+ providers: [AppService],
95
+ })
96
+ export class AppModule {}
97
+ ```
98
+
99
+ ---
100
+
101
+ ## What is MCP?
102
+
103
+ 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.
104
+
105
+ - See the [Anthropic announcement](https://www.anthropic.com/news/model-context-protocol) for more background.
106
+
107
+ ---
108
+
109
+ ## Core Concepts
110
+
111
+ ### Server
112
+
113
+ The MCP Server is the main entry point for exposing capabilities to LLMs. It manages the registration and discovery of resources, tools, and prompts.
114
+
115
+ ### Resource
116
+
117
+ 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.
118
+
119
+ - Learn more: [MCP Resources documentation](https://modelcontextprotocol.io/docs/concepts/resources)
120
+
121
+ ### Tool
122
+
123
+ 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.
124
+
125
+ - Learn more: [MCP Tools documentation](https://modelcontextprotocol.io/docs/concepts/tools)
126
+
127
+ ### Prompt
128
+
129
+ A Prompt defines a conversational flow, template, or interaction pattern for LLMs. Prompts help guide the model’s behavior in specific scenarios.
130
+
131
+ - Learn more: [MCP Prompts documentation](https://modelcontextprotocol.io/docs/concepts/prompts)
132
+
133
+ > **See the [Capabilities](#capabilities) section for implementation details and code examples.**
134
+
135
+ ---
136
+
137
+ ## Module API
138
+
139
+ ### `McpModule.forRoot`
140
+
141
+ Registers the MCP Server globally in your NestJS application. Accepts an options object compatible with the MCP Server specification from `@modelcontextprotocol/sdk`.
142
+
143
+ **Parameters:**
144
+
145
+ - `options: McpServerOptions` — Main server configuration (name, version, description, etc.)
146
+
147
+ **Returns:**
148
+
149
+ - A dynamic NestJS module with all MCP providers registered
150
+
151
+ **Example:**
152
+
153
+ ```ts
154
+ import { McpModule } from '@nestjs-mcp/server';
155
+
156
+ @Module({
157
+ imports: [
158
+ McpModule.forRoot({
159
+ name: 'My Server',
160
+ version: '1.0.0',
161
+ // ...other MCP options
162
+ }),
163
+ ],
164
+ })
165
+ export class AppModule {}
166
+ ```
167
+
168
+ ### `McpModule.forFeature`
169
+
170
+ Registers additional MCP resources, tools, or prompts in a feature module. Use this to organize large servers into multiple modules.
171
+
172
+ **Parameters:**
173
+
174
+ - `providers: Provider[]` — Array of NestJS providers (resources, tools, prompts)
175
+
176
+ **Returns:**
177
+
178
+ - A dynamic module with the specified providers
179
+
180
+ **Example:**
181
+
182
+ ```ts
183
+ import { McpModule } from '@nestjs-mcp/server';
184
+
185
+ @Module({
186
+ imports: [McpModule.forFeature()],
187
+ providers: [
188
+ /*Your Providers with Mcp Capabilities*/
189
+ ],
190
+ })
191
+ export class StatusModule {}
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Module Usage
197
+
198
+ This library provides two main ways to register MCP capabilities in your NestJS application:
199
+
200
+ ### 1. Global Registration with `McpModule.forRoot`
201
+
202
+ Use `McpModule.forRoot` in your root application module to configure and register the MCP server globally. This is required for every MCP server application.
203
+
204
+ ```ts
205
+ import { Module } from '@nestjs/common';
206
+ import { McpModule } from '@nestjs-mcp/server';
207
+ import { PromptsResolver } from './prompts.resolver';
208
+
209
+ @Module({
210
+ imports: [
211
+ McpModule.forRoot({
212
+ name: 'My MCP Server',
213
+ version: '1.0.0',
214
+ // ...other MCP options
215
+ }),
216
+ ],
217
+ providers: [PromptsResolver],
218
+ })
219
+ export class AppModule {}
220
+ ```
221
+
222
+ ### 2. Feature Module Registration with `McpModule.forFeature`
223
+
224
+ Use `McpModule.forFeature` in feature modules to register additional resolvers, tools, or resources. This is useful for organizing large servers into multiple modules.
225
+
226
+ ```ts
227
+ import { Module } from '@nestjs/common';
228
+ import { McpModule } from '@nestjs-mcp/server';
229
+
230
+ import { ToolsResolver } from './tools.resolver';
231
+
232
+ @Module({
233
+ imports: [McpModule.forFeature()],
234
+ providers: [ToolsResolver],
235
+ })
236
+ export class ToolsModule {}
237
+ ```
238
+
239
+ - Use `forRoot` only once in your root module.
240
+ - Use `forFeature` as many times as needed in feature modules.
241
+ - All resolvers, tools, and resources must be registered as providers.
242
+
243
+ ---
244
+
245
+ ## Capabilities
246
+
247
+ 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.
248
+
249
+ ### Resolver Decorator
250
+
251
+ A Resolver is a class that groups related MCP capabilities (such as prompts, resources, and tools) and provides a workspace context for them. Use the `@Resolver` decorator to mark a class as a resolver. Dependency injection is supported, and you can apply guards or other cross-cutting concerns at the class level.
252
+
253
+ **Example:**
254
+
255
+ ```ts
256
+ import { Resolver, Prompt, Resource, Tool } from '@nestjs-mcp/server';
257
+
258
+ @Resolver('workspace')
259
+ export class MyResolver {
260
+ @Prompt({ name: 'greet' })
261
+ greetPrompt() {
262
+ /* ... */
263
+ }
264
+
265
+ @Resource({ name: 'user', uri: 'user://{id}' })
266
+ getUserResource() {
267
+ /* ... */
268
+ }
269
+
270
+ @Tool({ name: 'sum' })
271
+ sumTool() {
272
+ /* ... */
273
+ }
274
+ }
275
+ ```
276
+
277
+ You can also apply guards at the resolver level:
278
+
279
+ ```ts
280
+ import { UseGuards, Resolver } from '@nestjs-mcp/server';
281
+ import { MyGuard } from './guards/my.guard';
282
+
283
+ @UseGuards(MyGuard)
284
+ @Resolver('secure')
285
+ export class SecureResolver {
286
+ // ...
287
+ }
288
+ ```
289
+
290
+ ### Prompt Decorator
291
+
292
+ Decorate methods within a Resolver to expose them as MCP Prompts.
293
+
294
+ ```ts
295
+ import { Prompt } from '@nestjs-mcp/server';
296
+
297
+ @Resolver('workspace')
298
+ export class MyResolver {
299
+ @Prompt({ name: 'greet' })
300
+ greetPrompt() {
301
+ /* ... */
302
+ }
303
+ }
304
+ ```
305
+
306
+ ### Resource Decorator
307
+
308
+ Decorate methods within a Resolver to expose them as MCP Resources.
309
+
310
+ ```ts
311
+ import { Resource } from '@nestjs-mcp/server';
312
+
313
+ @Resolver('workspace')
314
+ export class MyResolver {
315
+ @Resource({ name: 'user', uri: 'user://{id}' })
316
+ getUserResource() {
317
+ /* ... */
318
+ }
319
+ }
320
+ ```
321
+
322
+ ### Tool Decorator
323
+
324
+ Decorate methods within a Resolver to expose them as MCP Tools.
325
+
326
+ ```ts
327
+ import { Tool } from '@nestjs-mcp/server';
328
+
329
+ @Resolver('workspace')
330
+ export class MyResolver {
331
+ @Tool({ name: 'sum' })
332
+ sumTool() {
333
+ /* ... */
334
+ }
335
+ }
336
+ ```
337
+
338
+ ---
339
+
340
+ ## Guards
341
+
342
+ Apply one or more guards to a Resolver, to individual methods, or globally. Guards must implement the NestJS `CanActivate` interface.
343
+
344
+ ### Global-level guards:
345
+
346
+ This approach uses the standard NestJS global guard system. A global guard will protect all entry points of your MCP server by running before any connection is handled. Use this for authentication, API key checks, or any logic that should apply to every connection.
347
+
348
+ ```ts
349
+ // src/guards/global-auth.guard.ts
350
+ import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
351
+
352
+ @Injectable()
353
+ export class GlobalAuthGuard implements CanActivate {
354
+ canActivate(context: ExecutionContext): boolean {
355
+ // Example: Allow all requests (replace with real logic)
356
+ // You can access request info via context.switchToHttp().getRequest() if needed
357
+ return true;
358
+ }
359
+ }
360
+ ```
361
+
362
+ Register the guard globally in your main module:
363
+
364
+ ```ts
365
+ import { Module } from '@nestjs/common';
366
+ import { APP_GUARD } from '@nestjs/core';
367
+ import { McpModule } from '@nestjs-mcp/server';
368
+ import { GlobalAuthGuard } from './guards/global-auth.guard';
369
+ import { PromptsResolver } from './prompts.resolver';
370
+
371
+ @Module({
372
+ imports: [
373
+ McpModule.forRoot({
374
+ name: 'My MCP Server',
375
+ version: '1.0.0',
376
+ }),
377
+ ],
378
+ providers: [
379
+ PromptsResolver,
380
+ {
381
+ provide: APP_GUARD,
382
+ useClass: GlobalAuthGuard,
383
+ },
384
+ ],
385
+ })
386
+ export class AppModule {}
387
+ ```
388
+
389
+ **Key points:**
390
+
391
+ - The guard will run for every request handled by your NestJS application, including all MCP endpoints.
392
+ - You can implement any logic in canActivate, such as checking headers, tokens, or user roles.
393
+ - This approach is fully compatible with NestJS and your MCP Server module.
394
+
395
+ ### Resolver-level guards:
396
+
397
+ This is a custom feature of this library. Resolver-level guards are applied using the `@UseGuards` decorator on a Resolver class. All MCP methods (`@Prompt`, `@Resource`, `@Tool`) in the resolver will be protected by these guards. Use this to enforce logic (e.g., role checks) for a specific group of capabilities.
398
+
399
+ ```ts
400
+ import { UseGuards, Resolver, Prompt } from '@nestjs-mcp/server';
401
+ import { MyGuard } from './guards/my.guard';
402
+
403
+ @UseGuards(MyGuard)
404
+ @Resolver('secure')
405
+ export class SecureResolver {
406
+ @Prompt({ name: 'securePrompt' })
407
+ securePrompt() {
408
+ /* ... */
409
+ }
410
+ }
411
+ ```
412
+
413
+ ### Method-level guards:
414
+
415
+ This is a custom feature of this library. Method-level guards are applied using the `@UseGuards` decorator directly on a method. Only the decorated MCP method will be protected by these guards. Use this for fine-grained access control on specific capabilities.
416
+
417
+ ```ts
418
+ import { UseGuards, Resolver, Prompt } from '@nestjs-mcp/server';
419
+ import { MyGuard } from './guards/my.guard';
420
+
421
+ @Resolver('mixed')
422
+ export class MixedResolver {
423
+ @Prompt({ name: 'publicPrompt' })
424
+ publicPrompt() {
425
+ /* ... */
426
+ }
427
+
428
+ @UseGuards(MyGuard)
429
+ @Prompt({ name: 'protectedPrompt' })
430
+ protectedPrompt() {
431
+ /* ... */
432
+ }
433
+ }
434
+ ```
435
+
436
+ ### Guard Example
437
+
438
+ ```ts
439
+ import { CanActivate } from '@nestjs/common';
440
+ import { McpExecutionContext } from '@nestjs-mcp/server';
441
+
442
+ export class MyGuard implements CanActivate {
443
+ canActivate(context: McpExecutionContext): boolean {
444
+ // Custom logic: allow or deny
445
+ return true;
446
+ }
447
+ }
448
+ ```
449
+
450
+ ---
451
+
452
+ ## Inspector Playground
453
+
454
+ Use 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:
455
+
456
+ - Explore available resources, tools, and prompts
457
+ - Invoke endpoints and view responses in real time
458
+ - Validate your server implementation against the MCP specification
459
+
460
+ To launch the Inspector Playground:
461
+
462
+ ```sh
463
+ npx @modelcontextprotocol/inspector
464
+ ```
465
+
466
+ ---
467
+
468
+ ## Examples
469
+
470
+ The [`examples/`](./examples/) directory contains ready-to-use scenarios demonstrating how to register and expose MCP capabilities
471
+
472
+ Each example is self-contained and follows best practices. For advanced usage, see the code and documentation in each example.
473
+
474
+ ---
475
+
476
+ ## Changelog
477
+
478
+ See [CHANGELOG.md](./CHANGELOG.md) for release notes.
479
+
480
+ ---
481
+
482
+ ## License
483
+
484
+ MIT — see [LICENSE](./LICENSE) for details.
485
+
486
+ ---
487
+
488
+ ## Contributions
489
+
490
+ Contributions are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines, reporting issues, and pull request rules.
@@ -0,0 +1,2 @@
1
+ export declare class AppModule {
2
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AppModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const config_1 = require("@nestjs/config");
12
+ const mcp_module_1 = require("../../src/mcp.module");
13
+ let AppModule = class AppModule {
14
+ };
15
+ exports.AppModule = AppModule;
16
+ exports.AppModule = AppModule = __decorate([
17
+ (0, common_1.Module)({
18
+ imports: [
19
+ mcp_module_1.McpModule.forRootAsync({
20
+ imports: [config_1.ConfigModule.forRoot()],
21
+ useFactory: (configService) => ({
22
+ name: 'tools',
23
+ version: '1.0.0',
24
+ logging: {
25
+ enabled: configService.get('MCP_LOGGING_ENABLED'),
26
+ level: configService.get('MCP_LOGGING_LEVEL'),
27
+ },
28
+ }),
29
+ }),
30
+ ],
31
+ })
32
+ ], AppModule);
33
+ //# sourceMappingURL=app.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../../../examples/async-import/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AAExC,2CAA6D;AAE7D,qDAAiD;AAiB1C,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IAfrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,sBAAS,CAAC,YAAY,CAAC;gBACrB,OAAO,EAAE,CAAC,qBAAY,CAAC,OAAO,EAAE,CAAC;gBACjC,UAAU,EAAE,CAAC,aAA4B,EAAE,EAAE,CAAC,CAAC;oBAC7C,IAAI,EAAE,OAAO;oBACb,OAAO,EAAE,OAAO;oBAChB,OAAO,EAAE;wBACP,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,qBAAqB,CAAC;wBACjD,KAAK,EAAE,aAAa,CAAC,GAAG,CAAC,mBAAmB,CAAC;qBAC9C;iBACF,CAAC;aACH,CAAC;SACH;KACF,CAAC;GACW,SAAS,CAAG"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@nestjs/core");
4
+ const app_module_1 = require("./app.module");
5
+ async function bootstrap() {
6
+ try {
7
+ const app = await core_1.NestFactory.create(app_module_1.AppModule);
8
+ await app.listen(3000);
9
+ console.log('Async-import example server running on http://localhost:3000');
10
+ }
11
+ catch (error) {
12
+ console.error('Failed to start server:', error);
13
+ process.exit(1);
14
+ }
15
+ }
16
+ void bootstrap();
17
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../examples/async-import/main.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,6CAAyC;AAEzC,KAAK,UAAU,SAAS;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,CAAC,CAAC;QAChD,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,SAAS,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ export declare class GlobalLogGuard implements CanActivate {
3
+ canActivate(_context: ExecutionContext): boolean;
4
+ }
5
+ export declare class AppModule {
6
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AppModule = exports.GlobalLogGuard = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const mcp_module_1 = require("../../src/mcp.module");
12
+ const core_1 = require("@nestjs/core");
13
+ const guards_resolver_1 = require("./guards.resolver");
14
+ let GlobalLogGuard = class GlobalLogGuard {
15
+ canActivate(_context) {
16
+ console.log('[GlobalLogGuard] Global guard executed');
17
+ return true;
18
+ }
19
+ };
20
+ exports.GlobalLogGuard = GlobalLogGuard;
21
+ exports.GlobalLogGuard = GlobalLogGuard = __decorate([
22
+ (0, common_1.Injectable)()
23
+ ], GlobalLogGuard);
24
+ let AppModule = class AppModule {
25
+ };
26
+ exports.AppModule = AppModule;
27
+ exports.AppModule = AppModule = __decorate([
28
+ (0, common_1.Module)({
29
+ imports: [
30
+ mcp_module_1.McpModule.forRoot({
31
+ name: 'tools',
32
+ version: '1.0.0',
33
+ logging: {
34
+ enabled: true,
35
+ level: 'verbose',
36
+ },
37
+ }),
38
+ ],
39
+ providers: [
40
+ {
41
+ provide: core_1.APP_GUARD,
42
+ useClass: GlobalLogGuard,
43
+ },
44
+ guards_resolver_1.GuardsResolver,
45
+ ],
46
+ })
47
+ ], AppModule);
48
+ //# sourceMappingURL=app.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../../../examples/guards/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAKwB;AAExB,qDAAiD;AAEjD,uCAAyC;AACzC,uDAAmD;AAI5C,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,WAAW,CAAC,QAA0B;QAIpC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AARY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;GACA,cAAc,CAQ1B;AAqBM,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IAnBrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,sBAAS,CAAC,OAAO,CAAC;gBAChB,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,OAAO;gBAChB,OAAO,EAAE;oBACP,OAAO,EAAE,IAAI;oBACb,KAAK,EAAE,SAAS;iBACjB;aACF,CAAC;SACH;QACD,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,gBAAS;gBAClB,QAAQ,EAAE,cAAc;aACzB;YACD,gCAAc;SACf;KACF,CAAC;GACW,SAAS,CAAG"}
@@ -0,0 +1,13 @@
1
+ import { CanActivate } from '@nestjs/common';
2
+ import { McpExecutionContext } from '../../src';
3
+ import { CallToolResult, GetPromptResult } from '@modelcontextprotocol/sdk/types';
4
+ export declare class ResolverLogGuard implements CanActivate {
5
+ canActivate(_context: McpExecutionContext): boolean;
6
+ }
7
+ export declare class MethodLogGuard implements CanActivate {
8
+ canActivate(_context: McpExecutionContext): boolean;
9
+ }
10
+ export declare class GuardsResolver {
11
+ logPrompt(): GetPromptResult;
12
+ logTool(): CallToolResult;
13
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.GuardsResolver = exports.MethodLogGuard = exports.ResolverLogGuard = void 0;
13
+ const src_1 = require("../../src");
14
+ class ResolverLogGuard {
15
+ canActivate(_context) {
16
+ console.log('[ResolverLogGuard] Resolver-level guard executed');
17
+ return true;
18
+ }
19
+ }
20
+ exports.ResolverLogGuard = ResolverLogGuard;
21
+ class MethodLogGuard {
22
+ canActivate(_context) {
23
+ console.log('[MethodLogGuard] Method-level guard executed');
24
+ return true;
25
+ }
26
+ }
27
+ exports.MethodLogGuard = MethodLogGuard;
28
+ let GuardsResolver = class GuardsResolver {
29
+ logPrompt() {
30
+ return {
31
+ messages: [
32
+ {
33
+ role: 'assistant',
34
+ content: { type: 'text', text: 'Prompt executed' },
35
+ },
36
+ ],
37
+ };
38
+ }
39
+ logTool() {
40
+ return { content: [{ type: 'text', text: 'Tool executed' }] };
41
+ }
42
+ };
43
+ exports.GuardsResolver = GuardsResolver;
44
+ __decorate([
45
+ (0, src_1.Prompt)({ name: 'logPrompt' }),
46
+ __metadata("design:type", Function),
47
+ __metadata("design:paramtypes", []),
48
+ __metadata("design:returntype", Object)
49
+ ], GuardsResolver.prototype, "logPrompt", null);
50
+ __decorate([
51
+ (0, src_1.UseGuards)(MethodLogGuard),
52
+ (0, src_1.Tool)({ name: 'logTool' }),
53
+ __metadata("design:type", Function),
54
+ __metadata("design:paramtypes", []),
55
+ __metadata("design:returntype", Object)
56
+ ], GuardsResolver.prototype, "logTool", null);
57
+ exports.GuardsResolver = GuardsResolver = __decorate([
58
+ (0, src_1.UseGuards)(ResolverLogGuard),
59
+ (0, src_1.Resolver)('guards')
60
+ ], GuardsResolver);
61
+ //# sourceMappingURL=guards.resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.resolver.js","sourceRoot":"","sources":["../../../examples/guards/guards.resolver.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,mCAMmB;AAQnB,MAAa,gBAAgB;IAC3B,WAAW,CAAC,QAA6B;QACvC,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AALD,4CAKC;AAGD,MAAa,cAAc;IACzB,WAAW,CAAC,QAA6B;QACvC,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AALD,wCAKC;AAIM,IAAM,cAAc,GAApB,MAAM,cAAc;IAEzB,SAAS;QACP,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE;iBACnD;aACF;SACF,CAAC;IACJ,CAAC;IAID,OAAO;QACL,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;IAChE,CAAC;CACF,CAAA;AAlBY,wCAAc;AAEzB;IADC,IAAA,YAAM,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;;;;+CAU7B;AAID;IAFC,IAAA,eAAS,EAAC,cAAc,CAAC;IACzB,IAAA,UAAI,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;;;6CAGzB;yBAjBU,cAAc;IAF1B,IAAA,eAAS,EAAC,gBAAgB,CAAC;IAC3B,IAAA,cAAQ,EAAC,QAAQ,CAAC;GACN,cAAc,CAkB1B"}