@rekog/mcp-nest 1.9.4 → 1.9.6
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.
- package/README.md +5 -1
- package/dist/mcp/decorators/prompt.decorator.d.ts +1 -2
- package/dist/mcp/decorators/prompt.decorator.d.ts.map +1 -1
- package/dist/mcp/decorators/prompt.decorator.js.map +1 -1
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +2 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/interfaces/dynamic-prompt.interface.d.ts +11 -0
- package/dist/mcp/interfaces/dynamic-prompt.interface.d.ts.map +1 -0
- package/dist/mcp/interfaces/dynamic-prompt.interface.js +3 -0
- package/dist/mcp/interfaces/dynamic-prompt.interface.js.map +1 -0
- package/dist/mcp/interfaces/dynamic-resource.interface.d.ts +11 -0
- package/dist/mcp/interfaces/dynamic-resource.interface.d.ts.map +1 -0
- package/dist/mcp/interfaces/dynamic-resource.interface.js +3 -0
- package/dist/mcp/interfaces/dynamic-resource.interface.js.map +1 -0
- package/dist/mcp/interfaces/dynamic-tool.interface.js.map +1 -1
- package/dist/mcp/interfaces/index.d.ts +2 -0
- package/dist/mcp/interfaces/index.d.ts.map +1 -1
- package/dist/mcp/interfaces/index.js.map +1 -1
- package/dist/mcp/mcp.module.d.ts.map +1 -1
- package/dist/mcp/mcp.module.js +15 -11
- package/dist/mcp/mcp.module.js.map +1 -1
- package/dist/mcp/services/handlers/mcp-handler.base.d.ts +4 -4
- package/dist/mcp/services/handlers/mcp-handler.base.d.ts.map +1 -1
- package/dist/mcp/services/handlers/mcp-handler.base.js.map +1 -1
- package/dist/mcp/services/handlers/mcp-prompts.handler.d.ts +2 -2
- package/dist/mcp/services/handlers/mcp-prompts.handler.d.ts.map +1 -1
- package/dist/mcp/services/handlers/mcp-prompts.handler.js +13 -3
- package/dist/mcp/services/handlers/mcp-prompts.handler.js.map +1 -1
- package/dist/mcp/services/handlers/mcp-resources.handler.d.ts +2 -2
- package/dist/mcp/services/handlers/mcp-resources.handler.d.ts.map +1 -1
- package/dist/mcp/services/handlers/mcp-resources.handler.js +12 -2
- package/dist/mcp/services/handlers/mcp-resources.handler.js.map +1 -1
- package/dist/mcp/services/handlers/mcp-tools.handler.d.ts +2 -2
- package/dist/mcp/services/handlers/mcp-tools.handler.d.ts.map +1 -1
- package/dist/mcp/services/handlers/mcp-tools.handler.js +5 -5
- package/dist/mcp/services/handlers/mcp-tools.handler.js.map +1 -1
- package/dist/mcp/services/mcp-dynamic-registry.service.d.ts +26 -0
- package/dist/mcp/services/mcp-dynamic-registry.service.d.ts.map +1 -0
- package/dist/mcp/services/mcp-dynamic-registry.service.js +133 -0
- package/dist/mcp/services/mcp-dynamic-registry.service.js.map +1 -0
- package/dist/mcp/services/mcp-executor.service.d.ts +2 -2
- package/dist/mcp/services/mcp-executor.service.d.ts.map +1 -1
- package/dist/mcp/services/mcp-executor.service.js +2 -2
- package/dist/mcp/services/mcp-executor.service.js.map +1 -1
- package/dist/mcp/services/{mcp-registry.service.d.ts → mcp-registry-discovery.service.d.ts} +16 -15
- package/dist/mcp/services/mcp-registry-discovery.service.d.ts.map +1 -0
- package/dist/mcp/services/{mcp-registry.service.js → mcp-registry-discovery.service.js} +41 -25
- package/dist/mcp/services/mcp-registry-discovery.service.js.map +1 -0
- package/dist/mcp/services/mcp-sse.service.d.ts +2 -2
- package/dist/mcp/services/mcp-sse.service.d.ts.map +1 -1
- package/dist/mcp/services/mcp-sse.service.js +2 -2
- package/dist/mcp/services/mcp-sse.service.js.map +1 -1
- package/dist/mcp/services/mcp-streamable-http.service.d.ts +2 -2
- package/dist/mcp/services/mcp-streamable-http.service.d.ts.map +1 -1
- package/dist/mcp/services/mcp-streamable-http.service.js +2 -2
- package/dist/mcp/services/mcp-streamable-http.service.js.map +1 -1
- package/dist/mcp/services/tool-authorization.service.d.ts +4 -4
- package/dist/mcp/services/tool-authorization.service.d.ts.map +1 -1
- package/dist/mcp/services/tool-authorization.service.js.map +1 -1
- package/dist/mcp/transport/stdio.service.d.ts +2 -2
- package/dist/mcp/transport/stdio.service.d.ts.map +1 -1
- package/dist/mcp/transport/stdio.service.js +7 -7
- package/dist/mcp/transport/stdio.service.js.map +1 -1
- package/dist/mcp/utils/capabilities-builder.d.ts +2 -2
- package/dist/mcp/utils/capabilities-builder.d.ts.map +1 -1
- package/dist/mcp/utils/capabilities-builder.js.map +1 -1
- package/dist/mcp/utils/mcp-server.factory.d.ts +2 -2
- package/dist/mcp/utils/mcp-server.factory.d.ts.map +1 -1
- package/dist/mcp/utils/mcp-server.factory.js.map +1 -1
- package/package.json +9 -9
- package/src/mcp/decorators/prompt.decorator.ts +1 -1
- package/src/mcp/index.ts +2 -2
- package/src/mcp/interfaces/dynamic-prompt.interface.ts +20 -0
- package/src/mcp/interfaces/dynamic-resource.interface.ts +22 -0
- package/src/mcp/interfaces/dynamic-tool.interface.ts +2 -2
- package/src/mcp/interfaces/index.ts +10 -0
- package/src/mcp/mcp.module.ts +15 -11
- package/src/mcp/services/handlers/mcp-handler.base.ts +6 -3
- package/src/mcp/services/handlers/mcp-prompts.handler.ts +36 -4
- package/src/mcp/services/handlers/mcp-resources.handler.ts +24 -2
- package/src/mcp/services/handlers/mcp-tools.handler.ts +11 -8
- package/src/mcp/services/mcp-dynamic-registry.service.ts +236 -0
- package/src/mcp/services/mcp-executor.service.ts +2 -2
- package/src/mcp/services/{mcp-registry.service.spec.ts → mcp-registry-discovery.service.spec.ts} +18 -12
- package/src/mcp/services/{mcp-registry.service.ts → mcp-registry-discovery.service.ts} +77 -35
- package/src/mcp/services/mcp-sse.service.ts +2 -2
- package/src/mcp/services/mcp-streamable-http.service.ts +2 -2
- package/src/mcp/services/tool-authorization.service.ts +4 -4
- package/src/mcp/transport/stdio.service.ts +8 -8
- package/src/mcp/utils/capabilities-builder.ts +2 -2
- package/src/mcp/utils/mcp-server.factory.ts +2 -2
- package/dist/authz/services/jwt-token.service.spec.d.ts +0 -2
- package/dist/authz/services/jwt-token.service.spec.d.ts.map +0 -1
- package/dist/authz/services/jwt-token.service.spec.js +0 -86
- package/dist/authz/services/jwt-token.service.spec.js.map +0 -1
- package/dist/authz/stores/memory-store.service.spec.d.ts +0 -2
- package/dist/authz/stores/memory-store.service.spec.d.ts.map +0 -1
- package/dist/authz/stores/memory-store.service.spec.js +0 -382
- package/dist/authz/stores/memory-store.service.spec.js.map +0 -1
- package/dist/authz/stores/typeorm/typeorm-store.service.spec.d.ts +0 -2
- package/dist/authz/stores/typeorm/typeorm-store.service.spec.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/typeorm-store.service.spec.js +0 -340
- package/dist/authz/stores/typeorm/typeorm-store.service.spec.js.map +0 -1
- package/dist/mcp/services/mcp-registry.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-registry.service.js.map +0 -1
- package/dist/mcp/services/mcp-registry.service.spec.d.ts +0 -2
- package/dist/mcp/services/mcp-registry.service.spec.d.ts.map +0 -1
- package/dist/mcp/services/mcp-registry.service.spec.js +0 -245
- package/dist/mcp/services/mcp-registry.service.spec.js.map +0 -1
- package/dist/mcp/services/mcp-tool-builder.service.d.ts +0 -15
- package/dist/mcp/services/mcp-tool-builder.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-tool-builder.service.js +0 -70
- package/dist/mcp/services/mcp-tool-builder.service.js.map +0 -1
- package/dist/mcp/transport/custom-decorator.spec.d.ts +0 -2
- package/dist/mcp/transport/custom-decorator.spec.d.ts.map +0 -1
- package/dist/mcp/transport/custom-decorator.spec.js +0 -34
- package/dist/mcp/transport/custom-decorator.spec.js.map +0 -1
- package/dist/mcp/utils/mcp-logger.factory.spec.d.ts +0 -2
- package/dist/mcp/utils/mcp-logger.factory.spec.d.ts.map +0 -1
- package/dist/mcp/utils/mcp-logger.factory.spec.js +0 -150
- package/dist/mcp/utils/mcp-logger.factory.spec.js.map +0 -1
- package/dist/mcp/utils/normalize-endpoint.spec.d.ts +0 -2
- package/dist/mcp/utils/normalize-endpoint.spec.d.ts.map +0 -1
- package/dist/mcp/utils/normalize-endpoint.spec.js +0 -40
- package/dist/mcp/utils/normalize-endpoint.spec.js.map +0 -1
- package/src/mcp/services/mcp-tool-builder.service.ts +0 -151
package/README.md
CHANGED
|
@@ -34,6 +34,10 @@ With `@rekog/mcp-nest` you define tools, resources, and prompts in a way that's
|
|
|
34
34
|
**Are you interested to build ChatGPT widgets (with the OpenAI SDK) or MCP apps?**
|
|
35
35
|
Find out how to do that with `@rekog/MCP-Nest` in this repository [MCP-Nest-Samples](https://github.com/rinormaloku/MCP-Nest-Samples)
|
|
36
36
|
|
|
37
|
+
|
|
38
|
+
> [!TIP]
|
|
39
|
+
> You can easily learn about this package using the `chat` tab in [Context7](https://context7.com/rekog-labs/mcp-nest?tab=chat). Better yet, connect the [Context7 MCP server](https://github.com/upstash/context7#installation) to allow your AI agents to access the documentation and implement MCP-Nest for you.
|
|
40
|
+
|
|
37
41
|
## Installation
|
|
38
42
|
|
|
39
43
|
```bash
|
|
@@ -94,7 +98,7 @@ export class GreetingTool {
|
|
|
94
98
|
|
|
95
99
|
- **[Tools Guide](docs/tools.md)** - Define and expose NestJS methods as MCP tools
|
|
96
100
|
- **[Discovery and Registration of Tools](docs/tool-discovery-and-registration.md)** - Automatic discovery and manual registration of tools
|
|
97
|
-
- **[Dynamic
|
|
101
|
+
- **[Dynamic Capabilities Guide](docs/dynamic-capabilities.md)** - Register tools, resources, and prompts programmatically at runtime
|
|
98
102
|
- **[Resources Guide](docs/resources.md)** - Serve static and dynamic content
|
|
99
103
|
- **[Resource Templates Guide](docs/resource-templates.md)** - Create parameterized resources
|
|
100
104
|
- **[Prompts Guide](docs/prompts.md)** - Build reusable prompt templates
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ZodObject, ZodType } from 'zod';
|
|
2
|
-
type PromptArgsRawShape = {
|
|
2
|
+
export type PromptArgsRawShape = {
|
|
3
3
|
[k: string]: ZodType;
|
|
4
4
|
};
|
|
5
5
|
export interface PromptMetadata {
|
|
@@ -13,5 +13,4 @@ export interface PromptOptions {
|
|
|
13
13
|
parameters?: ZodObject<PromptArgsRawShape>;
|
|
14
14
|
}
|
|
15
15
|
export declare const Prompt: (options: PromptOptions) => import("@nestjs/common").CustomDecorator<string>;
|
|
16
|
-
export {};
|
|
17
16
|
//# sourceMappingURL=prompt.decorator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.decorator.d.ts","sourceRoot":"","sources":["../../../src/mcp/decorators/prompt.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEzC,
|
|
1
|
+
{"version":3,"file":"prompt.decorator.d.ts","sourceRoot":"","sources":["../../../src/mcp/decorators/prompt.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEzC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;CAC5C;AAED,eAAO,MAAM,MAAM,GAAI,SAAS,aAAa,qDAE5C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.decorator.js","sourceRoot":"","sources":["../../../src/mcp/decorators/prompt.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,2CAAsD;AAmB/C,MAAM,MAAM,GAAG,CAAC,OAAsB,EAAE,EAAE;IAC/C,OAAO,IAAA,oBAAW,EAAC,mCAAuB,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC,CAAC;AAFW,QAAA,MAAM,UAEjB","sourcesContent":["import { SetMetadata } from '@nestjs/common';\nimport { MCP_PROMPT_METADATA_KEY } from './constants';\nimport { ZodObject, ZodType } from 'zod';\n\
|
|
1
|
+
{"version":3,"file":"prompt.decorator.js","sourceRoot":"","sources":["../../../src/mcp/decorators/prompt.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,2CAAsD;AAmB/C,MAAM,MAAM,GAAG,CAAC,OAAsB,EAAE,EAAE;IAC/C,OAAO,IAAA,oBAAW,EAAC,mCAAuB,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC,CAAC;AAFW,QAAA,MAAM,UAEjB","sourcesContent":["import { SetMetadata } from '@nestjs/common';\nimport { MCP_PROMPT_METADATA_KEY } from './constants';\nimport { ZodObject, ZodType } from 'zod';\n\nexport type PromptArgsRawShape = {\n [k: string]: ZodType;\n};\n\nexport interface PromptMetadata {\n name: string;\n description: string;\n parameters?: ZodObject<PromptArgsRawShape>;\n}\n\nexport interface PromptOptions {\n name?: string;\n description: string;\n parameters?: ZodObject<PromptArgsRawShape>;\n}\n\nexport const Prompt = (options: PromptOptions) => {\n return SetMetadata(MCP_PROMPT_METADATA_KEY, options);\n};\n"]}
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * from './decorators';
|
|
2
2
|
export * from './interfaces';
|
|
3
3
|
export * from './mcp.module';
|
|
4
|
-
export * from './services/mcp-registry.service';
|
|
4
|
+
export * from './services/mcp-registry-discovery.service';
|
|
5
5
|
export * from './services/mcp-executor.service';
|
|
6
6
|
export * from './services/mcp-sse.service';
|
|
7
7
|
export * from './services/mcp-streamable-http.service';
|
|
8
|
-
export * from './services/mcp-
|
|
8
|
+
export * from './services/mcp-dynamic-registry.service';
|
|
9
9
|
export * from './constants/feature-registration.constants';
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/mcp/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,4CAA4C,CAAC"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -17,10 +17,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./decorators"), exports);
|
|
18
18
|
__exportStar(require("./interfaces"), exports);
|
|
19
19
|
__exportStar(require("./mcp.module"), exports);
|
|
20
|
-
__exportStar(require("./services/mcp-registry.service"), exports);
|
|
20
|
+
__exportStar(require("./services/mcp-registry-discovery.service"), exports);
|
|
21
21
|
__exportStar(require("./services/mcp-executor.service"), exports);
|
|
22
22
|
__exportStar(require("./services/mcp-sse.service"), exports);
|
|
23
23
|
__exportStar(require("./services/mcp-streamable-http.service"), exports);
|
|
24
|
-
__exportStar(require("./services/mcp-
|
|
24
|
+
__exportStar(require("./services/mcp-dynamic-registry.service"), exports);
|
|
25
25
|
__exportStar(require("./constants/feature-registration.constants"), exports);
|
|
26
26
|
//# sourceMappingURL=index.js.map
|
package/dist/mcp/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,+CAA6B;AAC7B,+CAA6B;AAC7B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,+CAA6B;AAC7B,+CAA6B;AAC7B,4EAA0D;AAC1D,kEAAgD;AAChD,6DAA2C;AAC3C,yEAAuD;AACvD,0EAAwD;AACxD,6EAA2D","sourcesContent":["export * from './decorators';\nexport * from './interfaces';\nexport * from './mcp.module';\nexport * from './services/mcp-registry-discovery.service';\nexport * from './services/mcp-executor.service';\nexport * from './services/mcp-sse.service';\nexport * from './services/mcp-streamable-http.service';\nexport * from './services/mcp-dynamic-registry.service';\nexport * from './constants/feature-registration.constants';\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ZodObject } from 'zod';
|
|
2
|
+
import { Context } from './mcp-tool.interface';
|
|
3
|
+
import type { PromptArgsRawShape } from '../decorators/prompt.decorator';
|
|
4
|
+
export type DynamicPromptHandler = (args: Record<string, string> | undefined, context: Context, request: any) => Promise<any> | any;
|
|
5
|
+
export interface DynamicPromptDefinition {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
parameters?: ZodObject<PromptArgsRawShape>;
|
|
9
|
+
handler: DynamicPromptHandler;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=dynamic-prompt.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-prompt.interface.d.ts","sourceRoot":"","sources":["../../../src/mcp/interfaces/dynamic-prompt.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EACxC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,GAAG,KACT,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAExB,MAAM,WAAW,uBAAuB;IAEtC,IAAI,EAAE,MAAM,CAAC;IAEb,WAAW,EAAE,MAAM,CAAC;IAEpB,UAAU,CAAC,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;IAE3C,OAAO,EAAE,oBAAoB,CAAC;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-prompt.interface.js","sourceRoot":"","sources":["../../../src/mcp/interfaces/dynamic-prompt.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { ZodObject } from 'zod';\nimport { Context } from './mcp-tool.interface';\nimport type { PromptArgsRawShape } from '../decorators/prompt.decorator';\n\nexport type DynamicPromptHandler = (\n args: Record<string, string> | undefined,\n context: Context,\n request: any,\n) => Promise<any> | any;\n\nexport interface DynamicPromptDefinition {\n /** Unique name for the prompt */\n name: string;\n /** Description shown to the LLM */\n description: string;\n /** Zod schema describing the prompt arguments */\n parameters?: ZodObject<PromptArgsRawShape>;\n /** Handler function that returns the prompt messages */\n handler: DynamicPromptHandler;\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Context } from './mcp-tool.interface';
|
|
2
|
+
export type DynamicResourceHandler = (params: Record<string, unknown>, context: Context, request: any) => Promise<any> | any;
|
|
3
|
+
export interface DynamicResourceDefinition {
|
|
4
|
+
uri: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
mimeType?: string;
|
|
8
|
+
_meta?: Record<string, any>;
|
|
9
|
+
handler: DynamicResourceHandler;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=dynamic-resource.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-resource.interface.d.ts","sourceRoot":"","sources":["../../../src/mcp/interfaces/dynamic-resource.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,MAAM,MAAM,sBAAsB,GAAG,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,GAAG,KACT,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAExB,MAAM,WAAW,yBAAyB;IAExC,GAAG,EAAE,MAAM,CAAC;IAEZ,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE5B,OAAO,EAAE,sBAAsB,CAAC;CACjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamic-resource.interface.js","sourceRoot":"","sources":["../../../src/mcp/interfaces/dynamic-resource.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { Context } from './mcp-tool.interface';\n\nexport type DynamicResourceHandler = (\n params: Record<string, unknown>,\n context: Context,\n request: any,\n) => Promise<any> | any;\n\nexport interface DynamicResourceDefinition {\n /** URI that uniquely identifies this resource */\n uri: string;\n /** Human-readable name (defaults to uri if omitted) */\n name?: string;\n /** Optional description shown to the LLM */\n description?: string;\n /** Optional MIME type of the resource content */\n mimeType?: string;\n /** Additional metadata */\n _meta?: Record<string, any>;\n /** Handler function that returns the resource content */\n handler: DynamicResourceHandler;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-tool.interface.js","sourceRoot":"","sources":["../../../src/mcp/interfaces/dynamic-tool.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { z } from 'zod';\nimport { Context } from './mcp-tool.interface';\nimport { ToolAnnotations } from '../decorators/tool.decorator';\n\n/**\n * Handler function signature for dynamically registered tools.\n * Receives the same arguments as decorator-based tools.\n */\nexport type DynamicToolHandler = (\n args: Record<string, unknown>,\n context: Context,\n request: any,\n) => Promise<any> | any;\n\n/**\n * Definition for a dynamically registered tool.\n * Use this with
|
|
1
|
+
{"version":3,"file":"dynamic-tool.interface.js","sourceRoot":"","sources":["../../../src/mcp/interfaces/dynamic-tool.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { z } from 'zod';\nimport { Context } from './mcp-tool.interface';\nimport { ToolAnnotations } from '../decorators/tool.decorator';\n\n/**\n * Handler function signature for dynamically registered tools.\n * Receives the same arguments as decorator-based tools.\n */\nexport type DynamicToolHandler = (\n args: Record<string, unknown>,\n context: Context,\n request: any,\n) => Promise<any> | any;\n\n/**\n * Definition for a dynamically registered tool.\n * Use this with McpRegistryService.registerTool() to register tools at runtime.\n *\n * @example\n * ```typescript\n * registry.registerTool({\n * name: 'search-knowledge',\n * description: 'Search the knowledge base',\n * parameters: z.object({ query: z.string() }),\n * handler: async (args, context) => {\n * const results = await searchService.search(args.query);\n * return { content: [{ type: 'text', text: JSON.stringify(results) }] };\n * },\n * });\n * ```\n */\nexport interface DynamicToolDefinition {\n /** Unique name for the tool */\n name: string;\n /** Description shown to the LLM */\n description: string;\n /** Zod schema for input validation */\n parameters?: z.ZodType;\n /** Zod schema for output validation */\n outputSchema?: z.ZodType;\n /** MCP tool annotations */\n annotations?: ToolAnnotations;\n /** Additional metadata */\n _meta?: Record<string, any>;\n /** Handler function that executes the tool */\n handler: DynamicToolHandler;\n /** Mark as public (accessible without authentication) */\n isPublic?: boolean;\n /** Required OAuth scopes */\n requiredScopes?: string[];\n /** Required user roles */\n requiredRoles?: string[];\n}\n"]}
|
|
@@ -3,4 +3,6 @@ export type { McpOptions, McpAsyncOptions, McpOptionsFactory, McpModuleAsyncOpti
|
|
|
3
3
|
export type { Literal, SerializableValue, McpRequestSchema, McpRequest, Context, } from './mcp-tool.interface';
|
|
4
4
|
export type { HttpRequest } from './http-adapter.interface';
|
|
5
5
|
export type { DynamicToolDefinition, DynamicToolHandler, } from './dynamic-tool.interface';
|
|
6
|
+
export type { DynamicResourceDefinition, DynamicResourceHandler, } from './dynamic-resource.interface';
|
|
7
|
+
export type { DynamicPromptDefinition, DynamicPromptHandler, } from './dynamic-prompt.interface';
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EACV,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,OAAO,GACR,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,YAAY,EACV,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EACV,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,OAAO,GACR,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,YAAY,EACV,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACV,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EACV,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/interfaces/index.ts"],"names":[],"mappings":";;;AAAA,iEAA2D;AAAlD,yHAAA,gBAAgB,OAAA","sourcesContent":["export { McpTransportType } from './mcp-options.interface';\nexport type {\n McpOptions,\n McpAsyncOptions,\n McpOptionsFactory,\n McpModuleAsyncOptions,\n} from './mcp-options.interface';\n\nexport type {\n Literal,\n SerializableValue,\n McpRequestSchema,\n McpRequest,\n Context,\n} from './mcp-tool.interface';\n\nexport type { HttpRequest } from './http-adapter.interface';\n\nexport type {\n DynamicToolDefinition,\n DynamicToolHandler,\n} from './dynamic-tool.interface';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/interfaces/index.ts"],"names":[],"mappings":";;;AAAA,iEAA2D;AAAlD,yHAAA,gBAAgB,OAAA","sourcesContent":["export { McpTransportType } from './mcp-options.interface';\nexport type {\n McpOptions,\n McpAsyncOptions,\n McpOptionsFactory,\n McpModuleAsyncOptions,\n} from './mcp-options.interface';\n\nexport type {\n Literal,\n SerializableValue,\n McpRequestSchema,\n McpRequest,\n Context,\n} from './mcp-tool.interface';\n\nexport type { HttpRequest } from './http-adapter.interface';\n\nexport type {\n DynamicToolDefinition,\n DynamicToolHandler,\n} from './dynamic-tool.interface';\n\nexport type {\n DynamicResourceDefinition,\n DynamicResourceHandler,\n} from './dynamic-resource.interface';\n\nexport type {\n DynamicPromptDefinition,\n DynamicPromptHandler,\n} from './dynamic-prompt.interface';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.module.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp.module.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EAIf,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EACV,UAAU,EACV,qBAAqB,EAGtB,MAAM,cAAc,CAAC;AAwBtB,qBACa,gBAAgB;CAAG;AAEhC,
|
|
1
|
+
{"version":3,"file":"mcp.module.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp.module.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EAIf,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EACV,UAAU,EACV,qBAAqB,EAGtB,MAAM,cAAc,CAAC;AAwBtB,qBACa,gBAAgB;CAAG;AAEhC,qBAQa,SAAS;IAIpB,QAAQ,CAAC,aAAa,QAAQ;IAgC9B,MAAM,CAAC,UAAU,CACf,SAAS,EAAE,cAAc,EAAE,EAC3B,UAAU,EAAE,MAAM,GACjB,aAAa;IAsBhB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,aAAa;IAyDlD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa;IAqClE,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAgDnC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IA2B5C,OAAO,CAAC,MAAM,CAAC,4BAA4B;IA4C3C,OAAO,CAAC,MAAM,CAAC,0BAA0B;CAyB1C"}
|
package/dist/mcp/mcp.module.js
CHANGED
|
@@ -12,12 +12,12 @@ const common_1 = require("@nestjs/common");
|
|
|
12
12
|
const core_1 = require("@nestjs/core");
|
|
13
13
|
const interfaces_1 = require("./interfaces");
|
|
14
14
|
const mcp_executor_service_1 = require("./services/mcp-executor.service");
|
|
15
|
-
const
|
|
15
|
+
const mcp_registry_discovery_service_1 = require("./services/mcp-registry-discovery.service");
|
|
16
16
|
const mcp_sse_service_1 = require("./services/mcp-sse.service");
|
|
17
17
|
const mcp_streamable_http_service_1 = require("./services/mcp-streamable-http.service");
|
|
18
18
|
const sse_ping_service_1 = require("./services/sse-ping.service");
|
|
19
19
|
const tool_authorization_service_1 = require("./services/tool-authorization.service");
|
|
20
|
-
const
|
|
20
|
+
const mcp_dynamic_registry_service_1 = require("./services/mcp-dynamic-registry.service");
|
|
21
21
|
const sse_controller_factory_1 = require("./transport/sse.controller.factory");
|
|
22
22
|
const stdio_service_1 = require("./transport/stdio.service");
|
|
23
23
|
const streamable_http_controller_factory_1 = require("./transport/streamable-http.controller.factory");
|
|
@@ -87,10 +87,10 @@ let McpModule = McpModule_1 = class McpModule {
|
|
|
87
87
|
controllers,
|
|
88
88
|
providers,
|
|
89
89
|
exports: [
|
|
90
|
-
|
|
90
|
+
mcp_registry_discovery_service_1.McpRegistryDiscoveryService,
|
|
91
91
|
mcp_sse_service_1.McpSseService,
|
|
92
92
|
mcp_streamable_http_service_1.McpStreamableHttpService,
|
|
93
|
-
|
|
93
|
+
mcp_dynamic_registry_service_1.McpRegistryService,
|
|
94
94
|
],
|
|
95
95
|
};
|
|
96
96
|
}
|
|
@@ -102,13 +102,13 @@ let McpModule = McpModule_1 = class McpModule {
|
|
|
102
102
|
provide: 'MCP_MODULE_ID',
|
|
103
103
|
useValue: moduleId,
|
|
104
104
|
},
|
|
105
|
-
|
|
105
|
+
mcp_registry_discovery_service_1.McpRegistryDiscoveryService,
|
|
106
106
|
mcp_executor_service_1.McpExecutorService,
|
|
107
107
|
tool_authorization_service_1.ToolAuthorizationService,
|
|
108
108
|
sse_ping_service_1.SsePingService,
|
|
109
109
|
mcp_sse_service_1.McpSseService,
|
|
110
110
|
mcp_streamable_http_service_1.McpStreamableHttpService,
|
|
111
|
-
|
|
111
|
+
mcp_dynamic_registry_service_1.McpRegistryService,
|
|
112
112
|
stdio_service_1.StdioService,
|
|
113
113
|
];
|
|
114
114
|
return {
|
|
@@ -121,10 +121,10 @@ let McpModule = McpModule_1 = class McpModule {
|
|
|
121
121
|
...(options.extraProviders ?? []),
|
|
122
122
|
],
|
|
123
123
|
exports: [
|
|
124
|
-
|
|
124
|
+
mcp_registry_discovery_service_1.McpRegistryDiscoveryService,
|
|
125
125
|
mcp_sse_service_1.McpSseService,
|
|
126
126
|
mcp_streamable_http_service_1.McpStreamableHttpService,
|
|
127
|
-
|
|
127
|
+
mcp_dynamic_registry_service_1.McpRegistryService,
|
|
128
128
|
],
|
|
129
129
|
};
|
|
130
130
|
}
|
|
@@ -222,13 +222,13 @@ let McpModule = McpModule_1 = class McpModule {
|
|
|
222
222
|
provide: 'MCP_MODULE_ID',
|
|
223
223
|
useValue: moduleId,
|
|
224
224
|
},
|
|
225
|
-
|
|
225
|
+
mcp_registry_discovery_service_1.McpRegistryDiscoveryService,
|
|
226
226
|
mcp_executor_service_1.McpExecutorService,
|
|
227
227
|
tool_authorization_service_1.ToolAuthorizationService,
|
|
228
228
|
sse_ping_service_1.SsePingService,
|
|
229
229
|
mcp_sse_service_1.McpSseService,
|
|
230
230
|
mcp_streamable_http_service_1.McpStreamableHttpService,
|
|
231
|
-
|
|
231
|
+
mcp_dynamic_registry_service_1.McpRegistryService,
|
|
232
232
|
stdio_service_1.StdioService,
|
|
233
233
|
];
|
|
234
234
|
return providers;
|
|
@@ -238,7 +238,11 @@ exports.McpModule = McpModule;
|
|
|
238
238
|
exports.McpModule = McpModule = McpModule_1 = __decorate([
|
|
239
239
|
(0, common_1.Module)({
|
|
240
240
|
imports: [core_1.DiscoveryModule],
|
|
241
|
-
providers: [
|
|
241
|
+
providers: [
|
|
242
|
+
mcp_registry_discovery_service_1.McpRegistryDiscoveryService,
|
|
243
|
+
mcp_executor_service_1.McpExecutorService,
|
|
244
|
+
tool_authorization_service_1.ToolAuthorizationService,
|
|
245
|
+
],
|
|
242
246
|
})
|
|
243
247
|
], McpModule);
|
|
244
248
|
//# sourceMappingURL=mcp.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.module.js","sourceRoot":"","sources":["../../src/mcp/mcp.module.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DynamicModule,\n InjectionToken,\n Module,\n Provider,\n Type,\n} from '@nestjs/common';\nimport { DiscoveryModule } from '@nestjs/core';\nimport { McpTransportType } from './interfaces';\nimport type {\n McpOptions,\n McpModuleAsyncOptions,\n McpOptionsFactory,\n McpAsyncOptions,\n} from './interfaces';\nimport { McpExecutorService } from './services/mcp-executor.service';\nimport { McpRegistryService } from './services/mcp-registry.service';\nimport { McpSseService } from './services/mcp-sse.service';\nimport { McpStreamableHttpService } from './services/mcp-streamable-http.service';\nimport { SsePingService } from './services/sse-ping.service';\nimport { ToolAuthorizationService } from './services/tool-authorization.service';\nimport { McpToolBuilder } from './services/mcp-tool-builder.service';\nimport { createSseController } from './transport/sse.controller.factory';\nimport { StdioService } from './transport/stdio.service';\nimport { createStreamableHttpController } from './transport/streamable-http.controller.factory';\nimport { normalizeEndpoint } from './utils/normalize-endpoint';\nimport {\n MCP_FEATURE_REGISTRATION,\n McpFeatureRegistration,\n} from './constants/feature-registration.constants';\n\nlet instanceIdCounter = 0;\nlet featureIdCounter = 0;\n\n/**\n * Lightweight module class used by McpModule.forFeature().\n * This is separate from McpModule to avoid circular dependency issues.\n */\n@Module({})\nexport class McpFeatureModule {}\n\n@Module({\n imports: [DiscoveryModule],\n providers: [McpRegistryService, McpExecutorService, ToolAuthorizationService],\n})\nexport class McpModule {\n /**\n * To avoid import circular dependency issues, we use a marker property.\n */\n readonly __isMcpModule = true;\n\n /**\n * Registers tool providers to be associated with a specific MCP server.\n *\n * Use this method to organize tools into separate feature modules while\n * associating them with a specific MCP server created by forRoot().\n *\n * @param providers - Array of provider classes that contain @Tool, @Resource, @ResourceTemplate, or @Prompt decorated methods\n * @param serverName - The name of the MCP server (as specified in forRoot options) to register these tools with\n * @returns A DynamicModule that can be imported into any module\n *\n * @example\n * ```typescript\n * // In feature.module.ts\n * @Module({\n * imports: [McpModule.forFeature([UserTools, OrderTools], 'my-server')],\n * providers: [UserTools, OrderTools, UserService, OrderService],\n * exports: [UserTools, OrderTools],\n * })\n * export class FeatureModule {}\n *\n * // In app.module.ts\n * @Module({\n * imports: [\n * McpModule.forRoot({ name: 'my-server', version: '1.0.0' }),\n * FeatureModule,\n * ],\n * })\n * export class AppModule {}\n * ```\n */\n static forFeature(\n providers: InjectionToken[],\n serverName: string,\n ): DynamicModule {\n const registration: McpFeatureRegistration = {\n serverName,\n providerTokens: providers,\n };\n\n // Use a unique token for each forFeature call to allow multiple registrations\n const registrationToken = `${MCP_FEATURE_REGISTRATION}_${featureIdCounter++}`;\n\n return {\n module: McpFeatureModule,\n providers: [\n {\n provide: registrationToken,\n useValue: registration,\n },\n ],\n exports: [registrationToken],\n global: true, // Make it global so the registration can be discovered from any module\n };\n }\n\n static forRoot(options: McpOptions): DynamicModule {\n const defaultOptions: Partial<McpOptions> = {\n transport: [\n McpTransportType.SSE,\n McpTransportType.STREAMABLE_HTTP,\n McpTransportType.STDIO,\n ],\n sseEndpoint: 'sse',\n messagesEndpoint: 'messages',\n mcpEndpoint: 'mcp',\n guards: [],\n decorators: [],\n streamableHttp: {\n enableJsonResponse: true,\n sessionIdGenerator: undefined,\n statelessMode: true,\n },\n sse: {\n pingEnabled: true,\n pingIntervalMs: 30000,\n },\n };\n const mergedOptions = { ...defaultOptions, ...options } as McpOptions;\n mergedOptions.sseEndpoint = normalizeEndpoint(mergedOptions.sseEndpoint);\n mergedOptions.messagesEndpoint = normalizeEndpoint(\n mergedOptions.messagesEndpoint,\n );\n mergedOptions.mcpEndpoint = normalizeEndpoint(mergedOptions.mcpEndpoint);\n\n const moduleId = `mcp-module-${instanceIdCounter++}`;\n const providers = this.createProvidersFromOptions(mergedOptions, moduleId);\n const controllers = this.createControllersFromOptions(mergedOptions);\n return {\n module: McpModule,\n controllers,\n providers,\n exports: [\n McpRegistryService,\n McpSseService,\n McpStreamableHttpService,\n McpToolBuilder,\n ],\n };\n }\n\n /**\n * Asynchronous variant of forRoot. Controllers are NOT auto-registered here because\n * they must be declared synchronously at module definition time. This keeps the\n * API explicit: when using forRootAsync, you are responsible for creating and\n * registering any transport controllers (e.g. via createSseController / createStreamableHttpController).\n *\n * The exposed async options intentionally omit the `transport` property. Transport\n * selection only influences automatic controller creation (which does not occur here)\n * and STDIO auto-start. If you need STDIO with forRootAsync, manually instantiate\n * and bootstrap it (e.g. by importing a module that injects StdioService) or add\n * an explicit provider that sets options.transport before use.\n */\n static forRootAsync(options: McpModuleAsyncOptions): DynamicModule {\n const moduleId = `mcp-module-${instanceIdCounter++}`;\n const asyncProviders = this.createAsyncProviders(options);\n const baseProviders: Provider[] = [\n {\n provide: 'MCP_MODULE_ID',\n useValue: moduleId,\n },\n McpRegistryService,\n McpExecutorService,\n ToolAuthorizationService,\n SsePingService,\n McpSseService,\n McpStreamableHttpService,\n McpToolBuilder,\n StdioService,\n ];\n\n return {\n module: McpModule,\n imports: options.imports ?? [],\n // No automatic controllers in async mode\n controllers: [],\n providers: [\n ...asyncProviders,\n ...baseProviders,\n ...(options.extraProviders ?? []),\n ],\n exports: [\n McpRegistryService,\n McpSseService,\n McpStreamableHttpService,\n McpToolBuilder,\n ],\n };\n }\n\n private static createAsyncProviders(\n options: McpModuleAsyncOptions,\n ): Provider[] {\n if (options.useFactory) {\n return [\n {\n provide: 'MCP_OPTIONS',\n useFactory: async (...args: unknown[]) => {\n const resolved: McpAsyncOptions = await options.useFactory!(\n ...args,\n );\n return this.mergeAndNormalizeAsyncOptions(resolved);\n },\n inject: options.inject ?? [],\n },\n ];\n }\n\n // useClass / useExisting path\n const inject: any[] = [];\n let optionsFactoryProvider: Provider | undefined;\n\n if (options.useExisting || options.useClass) {\n const useExisting = options.useExisting || options.useClass!;\n inject.push(useExisting);\n if (options.useClass) {\n optionsFactoryProvider = {\n provide: options.useClass,\n useClass: options.useClass,\n } as Provider;\n }\n\n return [\n ...(optionsFactoryProvider ? [optionsFactoryProvider] : []),\n {\n provide: 'MCP_OPTIONS',\n useFactory: async (factory: McpOptionsFactory) => {\n const resolved = await factory.createMcpOptions();\n return this.mergeAndNormalizeAsyncOptions(resolved);\n },\n inject,\n },\n ];\n }\n\n throw new Error('Invalid McpModuleAsyncOptions configuration.');\n }\n\n private static mergeAndNormalizeAsyncOptions(\n resolved: McpAsyncOptions,\n ): McpOptions {\n const defaultOptions: Partial<McpOptions> = {\n sseEndpoint: 'sse',\n messagesEndpoint: 'messages',\n mcpEndpoint: 'mcp',\n guards: [],\n decorators: [],\n streamableHttp: {\n enableJsonResponse: true,\n sessionIdGenerator: undefined,\n statelessMode: true,\n },\n sse: {\n pingEnabled: true,\n pingIntervalMs: 30000,\n },\n };\n // Note: transport intentionally omitted\n const merged = { ...defaultOptions, ...resolved } as McpOptions;\n merged.sseEndpoint = normalizeEndpoint(merged.sseEndpoint);\n merged.messagesEndpoint = normalizeEndpoint(merged.messagesEndpoint);\n merged.mcpEndpoint = normalizeEndpoint(merged.mcpEndpoint);\n return merged;\n }\n\n private static createControllersFromOptions(\n options: McpOptions,\n ): Type<any>[] {\n const sseEndpoint = options.sseEndpoint ?? 'sse';\n const messagesEndpoint = options.messagesEndpoint ?? 'messages';\n const mcpEndpoint = options.mcpEndpoint ?? 'mcp';\n const guards = options.guards ?? [];\n const transports = Array.isArray(options.transport)\n ? options.transport\n : [options.transport ?? McpTransportType.SSE];\n const controllers: Type<any>[] = [];\n const decorators = options.decorators ?? [];\n const apiPrefix = options.apiPrefix ?? '';\n\n if (transports.includes(McpTransportType.SSE)) {\n const sseController = createSseController(\n sseEndpoint,\n messagesEndpoint,\n apiPrefix,\n guards,\n decorators,\n options,\n );\n controllers.push(sseController);\n }\n\n if (transports.includes(McpTransportType.STREAMABLE_HTTP)) {\n const streamableHttpController = createStreamableHttpController(\n mcpEndpoint,\n apiPrefix,\n guards,\n decorators,\n options,\n );\n controllers.push(streamableHttpController);\n }\n\n if (transports.includes(McpTransportType.STDIO)) {\n // STDIO transport is handled by injectable StdioService, no controller\n }\n\n return controllers;\n }\n\n private static createProvidersFromOptions(\n options: McpOptions,\n moduleId: string,\n ): Provider[] {\n const providers: Provider[] = [\n {\n provide: 'MCP_OPTIONS',\n useValue: options,\n },\n {\n provide: 'MCP_MODULE_ID',\n useValue: moduleId,\n },\n McpRegistryService,\n McpExecutorService,\n ToolAuthorizationService,\n SsePingService,\n McpSseService,\n McpStreamableHttpService,\n McpToolBuilder,\n StdioService,\n ];\n\n return providers;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mcp.module.js","sourceRoot":"","sources":["../../src/mcp/mcp.module.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DynamicModule,\n InjectionToken,\n Module,\n Provider,\n Type,\n} from '@nestjs/common';\nimport { DiscoveryModule } from '@nestjs/core';\nimport { McpTransportType } from './interfaces';\nimport type {\n McpOptions,\n McpModuleAsyncOptions,\n McpOptionsFactory,\n McpAsyncOptions,\n} from './interfaces';\nimport { McpExecutorService } from './services/mcp-executor.service';\nimport { McpRegistryDiscoveryService } from './services/mcp-registry-discovery.service';\nimport { McpSseService } from './services/mcp-sse.service';\nimport { McpStreamableHttpService } from './services/mcp-streamable-http.service';\nimport { SsePingService } from './services/sse-ping.service';\nimport { ToolAuthorizationService } from './services/tool-authorization.service';\nimport { McpRegistryService } from './services/mcp-dynamic-registry.service';\nimport { createSseController } from './transport/sse.controller.factory';\nimport { StdioService } from './transport/stdio.service';\nimport { createStreamableHttpController } from './transport/streamable-http.controller.factory';\nimport { normalizeEndpoint } from './utils/normalize-endpoint';\nimport {\n MCP_FEATURE_REGISTRATION,\n McpFeatureRegistration,\n} from './constants/feature-registration.constants';\n\nlet instanceIdCounter = 0;\nlet featureIdCounter = 0;\n\n/**\n * Lightweight module class used by McpModule.forFeature().\n * This is separate from McpModule to avoid circular dependency issues.\n */\n@Module({})\nexport class McpFeatureModule {}\n\n@Module({\n imports: [DiscoveryModule],\n providers: [\n McpRegistryDiscoveryService,\n McpExecutorService,\n ToolAuthorizationService,\n ],\n})\nexport class McpModule {\n /**\n * To avoid import circular dependency issues, we use a marker property.\n */\n readonly __isMcpModule = true;\n\n /**\n * Registers tool providers to be associated with a specific MCP server.\n *\n * Use this method to organize tools into separate feature modules while\n * associating them with a specific MCP server created by forRoot().\n *\n * @param providers - Array of provider classes that contain @Tool, @Resource, @ResourceTemplate, or @Prompt decorated methods\n * @param serverName - The name of the MCP server (as specified in forRoot options) to register these tools with\n * @returns A DynamicModule that can be imported into any module\n *\n * @example\n * ```typescript\n * // In feature.module.ts\n * @Module({\n * imports: [McpModule.forFeature([UserTools, OrderTools], 'my-server')],\n * providers: [UserTools, OrderTools, UserService, OrderService],\n * exports: [UserTools, OrderTools],\n * })\n * export class FeatureModule {}\n *\n * // In app.module.ts\n * @Module({\n * imports: [\n * McpModule.forRoot({ name: 'my-server', version: '1.0.0' }),\n * FeatureModule,\n * ],\n * })\n * export class AppModule {}\n * ```\n */\n static forFeature(\n providers: InjectionToken[],\n serverName: string,\n ): DynamicModule {\n const registration: McpFeatureRegistration = {\n serverName,\n providerTokens: providers,\n };\n\n // Use a unique token for each forFeature call to allow multiple registrations\n const registrationToken = `${MCP_FEATURE_REGISTRATION}_${featureIdCounter++}`;\n\n return {\n module: McpFeatureModule,\n providers: [\n {\n provide: registrationToken,\n useValue: registration,\n },\n ],\n exports: [registrationToken],\n global: true, // Make it global so the registration can be discovered from any module\n };\n }\n\n static forRoot(options: McpOptions): DynamicModule {\n const defaultOptions: Partial<McpOptions> = {\n transport: [\n McpTransportType.SSE,\n McpTransportType.STREAMABLE_HTTP,\n McpTransportType.STDIO,\n ],\n sseEndpoint: 'sse',\n messagesEndpoint: 'messages',\n mcpEndpoint: 'mcp',\n guards: [],\n decorators: [],\n streamableHttp: {\n enableJsonResponse: true,\n sessionIdGenerator: undefined,\n statelessMode: true,\n },\n sse: {\n pingEnabled: true,\n pingIntervalMs: 30000,\n },\n };\n const mergedOptions = { ...defaultOptions, ...options } as McpOptions;\n mergedOptions.sseEndpoint = normalizeEndpoint(mergedOptions.sseEndpoint);\n mergedOptions.messagesEndpoint = normalizeEndpoint(\n mergedOptions.messagesEndpoint,\n );\n mergedOptions.mcpEndpoint = normalizeEndpoint(mergedOptions.mcpEndpoint);\n\n const moduleId = `mcp-module-${instanceIdCounter++}`;\n const providers = this.createProvidersFromOptions(mergedOptions, moduleId);\n const controllers = this.createControllersFromOptions(mergedOptions);\n return {\n module: McpModule,\n controllers,\n providers,\n exports: [\n McpRegistryDiscoveryService,\n McpSseService,\n McpStreamableHttpService,\n McpRegistryService,\n ],\n };\n }\n\n /**\n * Asynchronous variant of forRoot. Controllers are NOT auto-registered here because\n * they must be declared synchronously at module definition time. This keeps the\n * API explicit: when using forRootAsync, you are responsible for creating and\n * registering any transport controllers (e.g. via createSseController / createStreamableHttpController).\n *\n * The exposed async options intentionally omit the `transport` property. Transport\n * selection only influences automatic controller creation (which does not occur here)\n * and STDIO auto-start. If you need STDIO with forRootAsync, manually instantiate\n * and bootstrap it (e.g. by importing a module that injects StdioService) or add\n * an explicit provider that sets options.transport before use.\n */\n static forRootAsync(options: McpModuleAsyncOptions): DynamicModule {\n const moduleId = `mcp-module-${instanceIdCounter++}`;\n const asyncProviders = this.createAsyncProviders(options);\n const baseProviders: Provider[] = [\n {\n provide: 'MCP_MODULE_ID',\n useValue: moduleId,\n },\n McpRegistryDiscoveryService,\n McpExecutorService,\n ToolAuthorizationService,\n SsePingService,\n McpSseService,\n McpStreamableHttpService,\n McpRegistryService,\n StdioService,\n ];\n\n return {\n module: McpModule,\n imports: options.imports ?? [],\n // No automatic controllers in async mode\n controllers: [],\n providers: [\n ...asyncProviders,\n ...baseProviders,\n ...(options.extraProviders ?? []),\n ],\n exports: [\n McpRegistryDiscoveryService,\n McpSseService,\n McpStreamableHttpService,\n McpRegistryService,\n ],\n };\n }\n\n private static createAsyncProviders(\n options: McpModuleAsyncOptions,\n ): Provider[] {\n if (options.useFactory) {\n return [\n {\n provide: 'MCP_OPTIONS',\n useFactory: async (...args: unknown[]) => {\n const resolved: McpAsyncOptions = await options.useFactory!(\n ...args,\n );\n return this.mergeAndNormalizeAsyncOptions(resolved);\n },\n inject: options.inject ?? [],\n },\n ];\n }\n\n // useClass / useExisting path\n const inject: any[] = [];\n let optionsFactoryProvider: Provider | undefined;\n\n if (options.useExisting || options.useClass) {\n const useExisting = options.useExisting || options.useClass!;\n inject.push(useExisting);\n if (options.useClass) {\n optionsFactoryProvider = {\n provide: options.useClass,\n useClass: options.useClass,\n } as Provider;\n }\n\n return [\n ...(optionsFactoryProvider ? [optionsFactoryProvider] : []),\n {\n provide: 'MCP_OPTIONS',\n useFactory: async (factory: McpOptionsFactory) => {\n const resolved = await factory.createMcpOptions();\n return this.mergeAndNormalizeAsyncOptions(resolved);\n },\n inject,\n },\n ];\n }\n\n throw new Error('Invalid McpModuleAsyncOptions configuration.');\n }\n\n private static mergeAndNormalizeAsyncOptions(\n resolved: McpAsyncOptions,\n ): McpOptions {\n const defaultOptions: Partial<McpOptions> = {\n sseEndpoint: 'sse',\n messagesEndpoint: 'messages',\n mcpEndpoint: 'mcp',\n guards: [],\n decorators: [],\n streamableHttp: {\n enableJsonResponse: true,\n sessionIdGenerator: undefined,\n statelessMode: true,\n },\n sse: {\n pingEnabled: true,\n pingIntervalMs: 30000,\n },\n };\n // Note: transport intentionally omitted\n const merged = { ...defaultOptions, ...resolved } as McpOptions;\n merged.sseEndpoint = normalizeEndpoint(merged.sseEndpoint);\n merged.messagesEndpoint = normalizeEndpoint(merged.messagesEndpoint);\n merged.mcpEndpoint = normalizeEndpoint(merged.mcpEndpoint);\n return merged;\n }\n\n private static createControllersFromOptions(\n options: McpOptions,\n ): Type<any>[] {\n const sseEndpoint = options.sseEndpoint ?? 'sse';\n const messagesEndpoint = options.messagesEndpoint ?? 'messages';\n const mcpEndpoint = options.mcpEndpoint ?? 'mcp';\n const guards = options.guards ?? [];\n const transports = Array.isArray(options.transport)\n ? options.transport\n : [options.transport ?? McpTransportType.SSE];\n const controllers: Type<any>[] = [];\n const decorators = options.decorators ?? [];\n const apiPrefix = options.apiPrefix ?? '';\n\n if (transports.includes(McpTransportType.SSE)) {\n const sseController = createSseController(\n sseEndpoint,\n messagesEndpoint,\n apiPrefix,\n guards,\n decorators,\n options,\n );\n controllers.push(sseController);\n }\n\n if (transports.includes(McpTransportType.STREAMABLE_HTTP)) {\n const streamableHttpController = createStreamableHttpController(\n mcpEndpoint,\n apiPrefix,\n guards,\n decorators,\n options,\n );\n controllers.push(streamableHttpController);\n }\n\n if (transports.includes(McpTransportType.STDIO)) {\n // STDIO transport is handled by injectable StdioService, no controller\n }\n\n return controllers;\n }\n\n private static createProvidersFromOptions(\n options: McpOptions,\n moduleId: string,\n ): Provider[] {\n const providers: Provider[] = [\n {\n provide: 'MCP_OPTIONS',\n useValue: options,\n },\n {\n provide: 'MCP_MODULE_ID',\n useValue: moduleId,\n },\n McpRegistryDiscoveryService,\n McpExecutorService,\n ToolAuthorizationService,\n SsePingService,\n McpSseService,\n McpStreamableHttpService,\n McpRegistryService,\n StdioService,\n ];\n\n return providers;\n }\n}\n"]}
|
|
@@ -4,17 +4,17 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
4
4
|
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
5
5
|
import { Context, McpRequest, HttpRequest } from '../../interfaces';
|
|
6
6
|
import { McpOptions } from '../../interfaces/mcp-options.interface';
|
|
7
|
-
import {
|
|
7
|
+
import { DiscoveredCapability, McpRegistryDiscoveryService } from '../mcp-registry-discovery.service';
|
|
8
8
|
export declare abstract class McpHandlerBase {
|
|
9
9
|
protected readonly moduleRef: ModuleRef;
|
|
10
|
-
protected readonly registry:
|
|
10
|
+
protected readonly registry: McpRegistryDiscoveryService;
|
|
11
11
|
private readonly reflector;
|
|
12
12
|
protected logger: Logger;
|
|
13
|
-
protected constructor(moduleRef: ModuleRef, registry:
|
|
13
|
+
protected constructor(moduleRef: ModuleRef, registry: McpRegistryDiscoveryService, reflector: Reflector, loggerContext: string, options?: McpOptions);
|
|
14
14
|
protected createContext(mcpServer: McpServer, mcpRequest: McpRequest): Context;
|
|
15
15
|
protected createStatelessContext(mcpServer: McpServer, mcpRequest: McpRequest): Context;
|
|
16
16
|
protected createErrorResponse(errorText: string): CallToolResult | never;
|
|
17
|
-
protected handleError(error: Error, capabilityInfo:
|
|
17
|
+
protected handleError(error: Error, capabilityInfo: DiscoveredCapability<object>, httpRequest: HttpRequest): {
|
|
18
18
|
[x: string]: unknown;
|
|
19
19
|
content: ({
|
|
20
20
|
type: "text";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-handler.base.d.ts","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-handler.base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,MAAM,EAAQ,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EACL,cAAc,EAIf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,OAAO,EACP,UAAU,EAEV,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,
|
|
1
|
+
{"version":3,"file":"mcp-handler.base.d.ts","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-handler.base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,MAAM,EAAQ,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EACL,cAAc,EAIf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,OAAO,EACP,UAAU,EAEV,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC5B,MAAM,mCAAmC,CAAC;AAQ3C,8BAAsB,cAAc;IAIhC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS;IACvC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,2BAA2B;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAL5B,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IAEzB,SAAS,aACY,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,2BAA2B,EACvC,SAAS,EAAE,SAAS,EACrC,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,UAAU;IAKtB,SAAS,CAAC,aAAa,CACrB,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,GACrB,OAAO;IAkDV,SAAS,CAAC,sBAAsB,CAC9B,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,GACrB,OAAO;IAgCV,SAAS,CAAC,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,KAAK;IAIxE,SAAS,CAAC,WAAW,CACnB,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAC5C,WAAW,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiD1B,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,mBAAmB;CAY5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-handler.base.js","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-handler.base.ts"],"names":[],"mappings":";;;AAGA,iEAK4C;AAS5C,uEAAiE;AACjE,wDAGkC;AAClC,wFAAmF;AAEnF,MAAsB,cAAc;IAGlC,YACqB,SAAoB,EACpB,QAA4B,EAC9B,SAAoB,EACrC,aAAqB,EACrB,OAAoB;QAJD,cAAS,GAAT,SAAS,CAAW;QACpB,aAAQ,GAAR,QAAQ,CAAoB;QAC9B,cAAS,GAAT,SAAS,CAAW;QAIrC,IAAI,CAAC,MAAM,GAAG,IAAA,oCAAe,EAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAES,aAAa,CACrB,SAAoB,EACpB,UAAsB;QAGtB,IAAK,SAAS,CAAC,MAAM,CAAC,SAAiB,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC,sBAAsB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC;QAC9D,OAAO;YACL,cAAc,EAAE,KAAK,EAAE,QAAkB,EAAE,EAAE;gBAC3C,IAAI,aAAa,EAAE,CAAC;oBAClB,MAAM,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC;wBAClC,MAAM,EAAE,wBAAwB;wBAChC,MAAM,EAAE;4BACN,GAAG,QAAQ;4BACX,aAAa;yBACF;qBACd,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,GAAG,EAAE;gBACH,KAAK,EAAE,CAAC,OAAe,EAAE,OAA2B,EAAE,EAAE;oBACtD,KAAK,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBACvC,KAAK,EAAE,OAAO;wBACd,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;qBAC3B,CAAC,CAAC;gBACL,CAAC;gBACD,KAAK,EAAE,CAAC,OAAe,EAAE,OAA2B,EAAE,EAAE;oBACtD,KAAK,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBACvC,KAAK,EAAE,OAAO;wBACd,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;qBAC3B,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,EAAE,CAAC,OAAe,EAAE,OAA2B,EAAE,EAAE;oBACrD,KAAK,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBACvC,KAAK,EAAE,MAAM;wBACb,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;qBAC3B,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,EAAE,CAAC,OAAe,EAAE,OAA2B,EAAE,EAAE;oBACrD,KAAK,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBACvC,KAAK,EAAE,SAAS;wBAChB,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;qBAC3B,CAAC,CAAC;gBACL,CAAC;aACF;YACD,SAAS;YACT,UAAU;SACX,CAAC;IACJ,CAAC;IAES,sBAAsB,CAC9B,SAAoB,EACpB,UAAsB;QAEtB,MAAM,IAAI,GAAG,CAAC,EAAU,EAAE,EAAE;YAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,qBAAqB,CAAC,CAAC;QACnE,CAAC,CAAC;QACF,OAAO;YAEL,cAAc,EAAE,KAAK,EAAE,SAAmB,EAAE,EAAE;gBAC5C,IAAI,CAAC,2CAA2C,CAAC,CAAC;YACpD,CAAC;YACD,GAAG,EAAE;gBAEH,KAAK,EAAE,CAAC,QAAgB,EAAE,KAAyB,EAAE,EAAE;oBACrD,IAAI,CAAC,kDAAkD,CAAC,CAAC;gBAC3D,CAAC;gBAED,KAAK,EAAE,CAAC,QAAgB,EAAE,KAAyB,EAAE,EAAE;oBACrD,IAAI,CAAC,kDAAkD,CAAC,CAAC;gBAC3D,CAAC;gBAED,IAAI,EAAE,CAAC,QAAgB,EAAE,KAAyB,EAAE,EAAE;oBACpD,IAAI,CAAC,kDAAkD,CAAC,CAAC;gBAC3D,CAAC;gBAED,IAAI,EAAE,CAAC,QAAgB,EAAE,KAAyB,EAAE,EAAE;oBACpD,IAAI,CAAC,kDAAkD,CAAC,CAAC;gBAC3D,CAAC;aACF;YACD,SAAS;YACT,UAAU;SACX,CAAC;IACJ,CAAC;IAES,mBAAmB,CAAC,SAAiB;QAC7C,MAAM,IAAI,mBAAQ,CAAC,oBAAS,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACzD,CAAC;IAES,WAAW,CACnB,KAAY,EACZ,cAAsC,EACtC,WAAwB;QAExB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAGzB,IAAI,KAAK,YAAY,mBAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,cAAc,CAAC,aAAkC,CAAC;QAChE,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,UAAU,CAE5C,CAAC;QAEb,MAAM,aAAa,GACjB,IAAI,CAAC,SAAS,CAAC,GAAG,CAChB,sCAA0B,EAC1B,MAAM,CACP,IAAI,EAAE,CAAC;QAEV,MAAM,YAAY,GAChB,IAAI,CAAC,SAAS,CAAC,GAAG,CAChB,sCAA0B,EAC1B,KAAK,CACN,IAAI,EAAE,CAAC;QAEV,MAAM,UAAU,GAAG,CAAC,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC,CAAC;QAEvD,KAAK,MAAM,WAAW,IAAI,UAAU,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;gBACjD,MAAM,cAAc,GAAG,IAAI,WAAW,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,IAAI,6CAAoB,CACnC,CAAC,WAAW,CAAC,GAAG,CAAC,EACjB,cAAc,CAAC,aAAqB,EACpC,MAAM,CACP,CAAC;gBACF,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBACrB,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAEjD,MAAM,IAAI,GACR,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAE/D,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAEO,iBAAiB,CAAC,MAA6B;QACrD,OAAO,CACL,IAAI,CAAC,SAAS,CAAC,GAAG,CAAgB,mCAAuB,EAAE,MAAM,CAAC,IAAI,EAAE,CACzE,CAAC;IACJ,CAAC;IAEO,mBAAmB,CACzB,KAAY,EACZ,MAA6B;QAE7B,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAEtD,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,YAAY,IAAI,CAAC,CAAC;IAC9D,CAAC;CACF;AA/KD,wCA+KC","sourcesContent":["import { ExceptionFilter, Logger, Type } from '@nestjs/common';\nimport { ModuleRef, Reflector } from '@nestjs/core';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n CallToolResult,\n McpError,\n Progress,\n ErrorCode,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n Context,\n McpRequest,\n SerializableValue,\n HttpRequest,\n} from '../../interfaces';\nimport { McpOptions } from '../../interfaces/mcp-options.interface';\nimport { DiscoveredTool, McpRegistryService } from '../mcp-registry.service';\nimport { createMcpLogger } from '../../utils/mcp-logger.factory';\nimport {\n EXCEPTION_FILTERS_METADATA,\n FILTER_CATCH_EXCEPTIONS,\n} from '@nestjs/common/constants';\nimport { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';\n\nexport abstract class McpHandlerBase {\n protected logger: Logger;\n\n protected constructor(\n protected readonly moduleRef: ModuleRef,\n protected readonly registry: McpRegistryService,\n private readonly reflector: Reflector,\n loggerContext: string,\n options?: McpOptions,\n ) {\n this.logger = createMcpLogger(loggerContext, options);\n }\n\n protected createContext(\n mcpServer: McpServer,\n mcpRequest: McpRequest,\n ): Context {\n // handless stateless traffic where notifications and progress are not supported\n if ((mcpServer.server.transport as any).sessionId === undefined) {\n return this.createStatelessContext(mcpServer, mcpRequest);\n }\n\n const progressToken = mcpRequest.params?._meta?.progressToken;\n return {\n reportProgress: async (progress: Progress) => {\n if (progressToken) {\n await mcpServer.server.notification({\n method: 'notifications/progress',\n params: {\n ...progress,\n progressToken,\n } as Progress,\n });\n }\n },\n log: {\n debug: (message: string, context?: SerializableValue) => {\n void mcpServer.server.sendLoggingMessage({\n level: 'debug',\n data: { message, context },\n });\n },\n error: (message: string, context?: SerializableValue) => {\n void mcpServer.server.sendLoggingMessage({\n level: 'error',\n data: { message, context },\n });\n },\n info: (message: string, context?: SerializableValue) => {\n void mcpServer.server.sendLoggingMessage({\n level: 'info',\n data: { message, context },\n });\n },\n warn: (message: string, context?: SerializableValue) => {\n void mcpServer.server.sendLoggingMessage({\n level: 'warning',\n data: { message, context },\n });\n },\n },\n mcpServer,\n mcpRequest,\n };\n }\n\n protected createStatelessContext(\n mcpServer: McpServer,\n mcpRequest: McpRequest,\n ): Context {\n const warn = (fn: string) => {\n this.logger.warn(`Stateless context: '${fn}' is not supported.`);\n };\n return {\n // eslint-disable-next-line @typescript-eslint/require-await,@typescript-eslint/no-unused-vars\n reportProgress: async (_progress: Progress) => {\n warn('reportProgress not supported in stateless');\n },\n log: {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n debug: (_message: string, _data?: SerializableValue) => {\n warn('server report logging not supported in stateless');\n },\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n error: (_message: string, _data?: SerializableValue) => {\n warn('server report logging not supported in stateless');\n },\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n info: (_message: string, _data?: SerializableValue) => {\n warn('server report logging not supported in stateless');\n },\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n warn: (_message: string, _data?: SerializableValue) => {\n warn('server report logging not supported in stateless');\n },\n },\n mcpServer,\n mcpRequest,\n };\n }\n\n protected createErrorResponse(errorText: string): CallToolResult | never {\n throw new McpError(ErrorCode.InternalError, errorText);\n }\n\n protected handleError(\n error: Error,\n capabilityInfo: DiscoveredTool<object>,\n httpRequest: HttpRequest,\n ) {\n this.logger.error(error);\n\n // Re-throw McpErrors (like validation errors) so they are handled by the MCP protocol layer\n if (error instanceof McpError) {\n throw error;\n }\n\n const clazz = capabilityInfo.providerClass as new () => unknown;\n const method = clazz.prototype[capabilityInfo.methodName] as (\n ...args: unknown[]\n ) => unknown;\n\n const methodFilters =\n this.reflector.get<Type<ExceptionFilter>[]>(\n EXCEPTION_FILTERS_METADATA,\n method,\n ) ?? [];\n\n const classFilters =\n this.reflector.get<Type<ExceptionFilter>[]>(\n EXCEPTION_FILTERS_METADATA,\n clazz,\n ) ?? [];\n\n const allFilters = [...methodFilters, ...classFilters];\n\n for (const FilterClass of allFilters) {\n if (this.isExceptionFiltered(error, FilterClass)) {\n const filterInstance = new FilterClass();\n const host = new ExecutionContextHost(\n [httpRequest.raw],\n capabilityInfo.providerClass as Type,\n method,\n );\n host.setType('http');\n const result = filterInstance.catch(error, host);\n\n const text =\n typeof result === 'string' ? result : JSON.stringify(result);\n\n return this.createErrorResponse(text);\n }\n }\n\n return this.createErrorResponse(error.message);\n }\n\n private getExceptionTypes(filter: Type<ExceptionFilter>): Type<Error>[] {\n return (\n this.reflector.get<Type<Error>[]>(FILTER_CATCH_EXCEPTIONS, filter) ?? []\n );\n }\n\n private isExceptionFiltered(\n error: Error,\n filter: Type<ExceptionFilter>,\n ): boolean {\n const exceptionTypes = this.getExceptionTypes(filter);\n\n if (exceptionTypes.length === 0) {\n return true;\n }\n\n return exceptionTypes.some((type) => error instanceof type);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mcp-handler.base.js","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-handler.base.ts"],"names":[],"mappings":";;;AAGA,iEAK4C;AAY5C,uEAAiE;AACjE,wDAGkC;AAClC,wFAAmF;AAEnF,MAAsB,cAAc;IAGlC,YACqB,SAAoB,EACpB,QAAqC,EACvC,SAAoB,EACrC,aAAqB,EACrB,OAAoB;QAJD,cAAS,GAAT,SAAS,CAAW;QACpB,aAAQ,GAAR,QAAQ,CAA6B;QACvC,cAAS,GAAT,SAAS,CAAW;QAIrC,IAAI,CAAC,MAAM,GAAG,IAAA,oCAAe,EAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAES,aAAa,CACrB,SAAoB,EACpB,UAAsB;QAGtB,IAAK,SAAS,CAAC,MAAM,CAAC,SAAiB,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC,sBAAsB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC;QAC9D,OAAO;YACL,cAAc,EAAE,KAAK,EAAE,QAAkB,EAAE,EAAE;gBAC3C,IAAI,aAAa,EAAE,CAAC;oBAClB,MAAM,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC;wBAClC,MAAM,EAAE,wBAAwB;wBAChC,MAAM,EAAE;4BACN,GAAG,QAAQ;4BACX,aAAa;yBACF;qBACd,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,GAAG,EAAE;gBACH,KAAK,EAAE,CAAC,OAAe,EAAE,OAA2B,EAAE,EAAE;oBACtD,KAAK,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBACvC,KAAK,EAAE,OAAO;wBACd,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;qBAC3B,CAAC,CAAC;gBACL,CAAC;gBACD,KAAK,EAAE,CAAC,OAAe,EAAE,OAA2B,EAAE,EAAE;oBACtD,KAAK,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBACvC,KAAK,EAAE,OAAO;wBACd,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;qBAC3B,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,EAAE,CAAC,OAAe,EAAE,OAA2B,EAAE,EAAE;oBACrD,KAAK,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBACvC,KAAK,EAAE,MAAM;wBACb,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;qBAC3B,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,EAAE,CAAC,OAAe,EAAE,OAA2B,EAAE,EAAE;oBACrD,KAAK,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBACvC,KAAK,EAAE,SAAS;wBAChB,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;qBAC3B,CAAC,CAAC;gBACL,CAAC;aACF;YACD,SAAS;YACT,UAAU;SACX,CAAC;IACJ,CAAC;IAES,sBAAsB,CAC9B,SAAoB,EACpB,UAAsB;QAEtB,MAAM,IAAI,GAAG,CAAC,EAAU,EAAE,EAAE;YAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,qBAAqB,CAAC,CAAC;QACnE,CAAC,CAAC;QACF,OAAO;YAEL,cAAc,EAAE,KAAK,EAAE,SAAmB,EAAE,EAAE;gBAC5C,IAAI,CAAC,2CAA2C,CAAC,CAAC;YACpD,CAAC;YACD,GAAG,EAAE;gBAEH,KAAK,EAAE,CAAC,QAAgB,EAAE,KAAyB,EAAE,EAAE;oBACrD,IAAI,CAAC,kDAAkD,CAAC,CAAC;gBAC3D,CAAC;gBAED,KAAK,EAAE,CAAC,QAAgB,EAAE,KAAyB,EAAE,EAAE;oBACrD,IAAI,CAAC,kDAAkD,CAAC,CAAC;gBAC3D,CAAC;gBAED,IAAI,EAAE,CAAC,QAAgB,EAAE,KAAyB,EAAE,EAAE;oBACpD,IAAI,CAAC,kDAAkD,CAAC,CAAC;gBAC3D,CAAC;gBAED,IAAI,EAAE,CAAC,QAAgB,EAAE,KAAyB,EAAE,EAAE;oBACpD,IAAI,CAAC,kDAAkD,CAAC,CAAC;gBAC3D,CAAC;aACF;YACD,SAAS;YACT,UAAU;SACX,CAAC;IACJ,CAAC;IAES,mBAAmB,CAAC,SAAiB;QAC7C,MAAM,IAAI,mBAAQ,CAAC,oBAAS,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACzD,CAAC;IAES,WAAW,CACnB,KAAY,EACZ,cAA4C,EAC5C,WAAwB;QAExB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAGzB,IAAI,KAAK,YAAY,mBAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,cAAc,CAAC,aAAkC,CAAC;QAChE,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,UAAU,CAE5C,CAAC;QAEb,MAAM,aAAa,GACjB,IAAI,CAAC,SAAS,CAAC,GAAG,CAChB,sCAA0B,EAC1B,MAAM,CACP,IAAI,EAAE,CAAC;QAEV,MAAM,YAAY,GAChB,IAAI,CAAC,SAAS,CAAC,GAAG,CAChB,sCAA0B,EAC1B,KAAK,CACN,IAAI,EAAE,CAAC;QAEV,MAAM,UAAU,GAAG,CAAC,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC,CAAC;QAEvD,KAAK,MAAM,WAAW,IAAI,UAAU,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;gBACjD,MAAM,cAAc,GAAG,IAAI,WAAW,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,IAAI,6CAAoB,CACnC,CAAC,WAAW,CAAC,GAAG,CAAC,EACjB,cAAc,CAAC,aAAqB,EACpC,MAAM,CACP,CAAC;gBACF,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBACrB,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAEjD,MAAM,IAAI,GACR,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAE/D,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAEO,iBAAiB,CAAC,MAA6B;QACrD,OAAO,CACL,IAAI,CAAC,SAAS,CAAC,GAAG,CAAgB,mCAAuB,EAAE,MAAM,CAAC,IAAI,EAAE,CACzE,CAAC;IACJ,CAAC;IAEO,mBAAmB,CACzB,KAAY,EACZ,MAA6B;QAE7B,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAEtD,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,YAAY,IAAI,CAAC,CAAC;IAC9D,CAAC;CACF;AA/KD,wCA+KC","sourcesContent":["import { ExceptionFilter, Logger, Type } from '@nestjs/common';\nimport { ModuleRef, Reflector } from '@nestjs/core';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n CallToolResult,\n McpError,\n Progress,\n ErrorCode,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n Context,\n McpRequest,\n SerializableValue,\n HttpRequest,\n} from '../../interfaces';\nimport { McpOptions } from '../../interfaces/mcp-options.interface';\nimport {\n DiscoveredCapability,\n McpRegistryDiscoveryService,\n} from '../mcp-registry-discovery.service';\nimport { createMcpLogger } from '../../utils/mcp-logger.factory';\nimport {\n EXCEPTION_FILTERS_METADATA,\n FILTER_CATCH_EXCEPTIONS,\n} from '@nestjs/common/constants';\nimport { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';\n\nexport abstract class McpHandlerBase {\n protected logger: Logger;\n\n protected constructor(\n protected readonly moduleRef: ModuleRef,\n protected readonly registry: McpRegistryDiscoveryService,\n private readonly reflector: Reflector,\n loggerContext: string,\n options?: McpOptions,\n ) {\n this.logger = createMcpLogger(loggerContext, options);\n }\n\n protected createContext(\n mcpServer: McpServer,\n mcpRequest: McpRequest,\n ): Context {\n // handless stateless traffic where notifications and progress are not supported\n if ((mcpServer.server.transport as any).sessionId === undefined) {\n return this.createStatelessContext(mcpServer, mcpRequest);\n }\n\n const progressToken = mcpRequest.params?._meta?.progressToken;\n return {\n reportProgress: async (progress: Progress) => {\n if (progressToken) {\n await mcpServer.server.notification({\n method: 'notifications/progress',\n params: {\n ...progress,\n progressToken,\n } as Progress,\n });\n }\n },\n log: {\n debug: (message: string, context?: SerializableValue) => {\n void mcpServer.server.sendLoggingMessage({\n level: 'debug',\n data: { message, context },\n });\n },\n error: (message: string, context?: SerializableValue) => {\n void mcpServer.server.sendLoggingMessage({\n level: 'error',\n data: { message, context },\n });\n },\n info: (message: string, context?: SerializableValue) => {\n void mcpServer.server.sendLoggingMessage({\n level: 'info',\n data: { message, context },\n });\n },\n warn: (message: string, context?: SerializableValue) => {\n void mcpServer.server.sendLoggingMessage({\n level: 'warning',\n data: { message, context },\n });\n },\n },\n mcpServer,\n mcpRequest,\n };\n }\n\n protected createStatelessContext(\n mcpServer: McpServer,\n mcpRequest: McpRequest,\n ): Context {\n const warn = (fn: string) => {\n this.logger.warn(`Stateless context: '${fn}' is not supported.`);\n };\n return {\n // eslint-disable-next-line @typescript-eslint/require-await,@typescript-eslint/no-unused-vars\n reportProgress: async (_progress: Progress) => {\n warn('reportProgress not supported in stateless');\n },\n log: {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n debug: (_message: string, _data?: SerializableValue) => {\n warn('server report logging not supported in stateless');\n },\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n error: (_message: string, _data?: SerializableValue) => {\n warn('server report logging not supported in stateless');\n },\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n info: (_message: string, _data?: SerializableValue) => {\n warn('server report logging not supported in stateless');\n },\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n warn: (_message: string, _data?: SerializableValue) => {\n warn('server report logging not supported in stateless');\n },\n },\n mcpServer,\n mcpRequest,\n };\n }\n\n protected createErrorResponse(errorText: string): CallToolResult | never {\n throw new McpError(ErrorCode.InternalError, errorText);\n }\n\n protected handleError(\n error: Error,\n capabilityInfo: DiscoveredCapability<object>,\n httpRequest: HttpRequest,\n ) {\n this.logger.error(error);\n\n // Re-throw McpErrors (like validation errors) so they are handled by the MCP protocol layer\n if (error instanceof McpError) {\n throw error;\n }\n\n const clazz = capabilityInfo.providerClass as new () => unknown;\n const method = clazz.prototype[capabilityInfo.methodName] as (\n ...args: unknown[]\n ) => unknown;\n\n const methodFilters =\n this.reflector.get<Type<ExceptionFilter>[]>(\n EXCEPTION_FILTERS_METADATA,\n method,\n ) ?? [];\n\n const classFilters =\n this.reflector.get<Type<ExceptionFilter>[]>(\n EXCEPTION_FILTERS_METADATA,\n clazz,\n ) ?? [];\n\n const allFilters = [...methodFilters, ...classFilters];\n\n for (const FilterClass of allFilters) {\n if (this.isExceptionFiltered(error, FilterClass)) {\n const filterInstance = new FilterClass();\n const host = new ExecutionContextHost(\n [httpRequest.raw],\n capabilityInfo.providerClass as Type,\n method,\n );\n host.setType('http');\n const result = filterInstance.catch(error, host);\n\n const text =\n typeof result === 'string' ? result : JSON.stringify(result);\n\n return this.createErrorResponse(text);\n }\n }\n\n return this.createErrorResponse(error.message);\n }\n\n private getExceptionTypes(filter: Type<ExceptionFilter>): Type<Error>[] {\n return (\n this.reflector.get<Type<Error>[]>(FILTER_CATCH_EXCEPTIONS, filter) ?? []\n );\n }\n\n private isExceptionFiltered(\n error: Error,\n filter: Type<ExceptionFilter>,\n ): boolean {\n const exceptionTypes = this.getExceptionTypes(filter);\n\n if (exceptionTypes.length === 0) {\n return true;\n }\n\n return exceptionTypes.some((type) => error instanceof type);\n }\n}\n"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ModuleRef, Reflector } from '@nestjs/core';
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
-
import {
|
|
3
|
+
import { McpRegistryDiscoveryService } from '../mcp-registry-discovery.service';
|
|
4
4
|
import { McpHandlerBase } from './mcp-handler.base';
|
|
5
5
|
import { HttpRequest } from '../../interfaces/http-adapter.interface';
|
|
6
6
|
import type { McpOptions } from '../../interfaces/mcp-options.interface';
|
|
7
7
|
export declare class McpPromptsHandler extends McpHandlerBase {
|
|
8
8
|
private readonly mcpModuleId;
|
|
9
|
-
constructor(moduleRef: ModuleRef, registry:
|
|
9
|
+
constructor(moduleRef: ModuleRef, registry: McpRegistryDiscoveryService, reflector: Reflector, mcpModuleId: string, options?: McpOptions);
|
|
10
10
|
registerHandlers(mcpServer: McpServer, httpRequest: HttpRequest): void;
|
|
11
11
|
}
|
|
12
12
|
//# sourceMappingURL=mcp-prompts.handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-prompts.handler.d.ts","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-prompts.handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,OAAO,
|
|
1
|
+
{"version":3,"file":"mcp-prompts.handler.d.ts","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-prompts.handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,OAAO,EAEL,2BAA2B,EAC5B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAOzE,qBACa,iBAAkB,SAAQ,cAAc;IAKxB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAHrD,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,2BAA2B,EACrC,SAAS,EAAE,SAAS,EACsB,WAAW,EAAE,MAAM,EAC1B,OAAO,CAAC,EAAE,UAAU;IAKzD,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW;CA2GhE"}
|
|
@@ -17,8 +17,9 @@ exports.McpPromptsHandler = void 0;
|
|
|
17
17
|
const common_1 = require("@nestjs/common");
|
|
18
18
|
const core_1 = require("@nestjs/core");
|
|
19
19
|
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
20
|
-
const
|
|
20
|
+
const mcp_registry_discovery_service_1 = require("../mcp-registry-discovery.service");
|
|
21
21
|
const mcp_handler_base_1 = require("./mcp-handler.base");
|
|
22
|
+
const mcp_dynamic_registry_service_1 = require("../mcp-dynamic-registry.service");
|
|
22
23
|
let McpPromptsHandler = McpPromptsHandler_1 = class McpPromptsHandler extends mcp_handler_base_1.McpHandlerBase {
|
|
23
24
|
constructor(moduleRef, registry, reflector, mcpModuleId, options) {
|
|
24
25
|
super(moduleRef, registry, reflector, McpPromptsHandler_1.name, options);
|
|
@@ -57,13 +58,22 @@ let McpPromptsHandler = McpPromptsHandler_1 = class McpPromptsHandler extends mc
|
|
|
57
58
|
if (!promptInfo) {
|
|
58
59
|
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown prompt: ${name}`);
|
|
59
60
|
}
|
|
61
|
+
const context = this.createContext(mcpServer, request);
|
|
62
|
+
if (promptInfo.providerClass === mcp_dynamic_registry_service_1.DYNAMIC_PROMPT_HANDLER_TOKEN) {
|
|
63
|
+
const handler = mcp_dynamic_registry_service_1.McpRegistryService.getPromptHandlerByModuleId(this.mcpModuleId, name);
|
|
64
|
+
if (!handler) {
|
|
65
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Handler not found for dynamic prompt: ${name}`);
|
|
66
|
+
}
|
|
67
|
+
const result = await handler(request.params.arguments, context, httpRequest.raw);
|
|
68
|
+
this.logger.debug('GetPromptRequestSchema result', result);
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
60
71
|
const contextId = core_1.ContextIdFactory.getByRequest(httpRequest);
|
|
61
72
|
this.moduleRef.registerRequestByContextId(httpRequest, contextId);
|
|
62
73
|
const promptInstance = await this.moduleRef.resolve(promptInfo.providerClass, contextId, { strict: false });
|
|
63
74
|
if (!promptInstance) {
|
|
64
75
|
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown prompt: ${name}`);
|
|
65
76
|
}
|
|
66
|
-
const context = this.createContext(mcpServer, request);
|
|
67
77
|
const methodName = promptInfo.methodName;
|
|
68
78
|
const result = await promptInstance[methodName].call(promptInstance, request.params.arguments, context, httpRequest.raw);
|
|
69
79
|
this.logger.debug('GetPromptRequestSchema result', result);
|
|
@@ -82,7 +92,7 @@ exports.McpPromptsHandler = McpPromptsHandler = McpPromptsHandler_1 = __decorate
|
|
|
82
92
|
__param(4, (0, common_1.Optional)()),
|
|
83
93
|
__param(4, (0, common_1.Inject)('MCP_OPTIONS')),
|
|
84
94
|
__metadata("design:paramtypes", [core_1.ModuleRef,
|
|
85
|
-
|
|
95
|
+
mcp_registry_discovery_service_1.McpRegistryDiscoveryService,
|
|
86
96
|
core_1.Reflector, String, Object])
|
|
87
97
|
], McpPromptsHandler);
|
|
88
98
|
//# sourceMappingURL=mcp-prompts.handler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-prompts.handler.js","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-prompts.handler.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAqE;AACrE,uCAAsE;AAEtE,iEAM4C;AAC5C,
|
|
1
|
+
{"version":3,"file":"mcp-prompts.handler.js","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-prompts.handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable, Optional, Scope } from '@nestjs/common';\nimport { ContextIdFactory, ModuleRef, Reflector } from '@nestjs/core';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n ErrorCode,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n McpError,\n PromptArgument,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n DiscoveredCapability,\n McpRegistryDiscoveryService,\n} from '../mcp-registry-discovery.service';\nimport { McpHandlerBase } from './mcp-handler.base';\nimport { HttpRequest } from '../../interfaces/http-adapter.interface';\nimport type { McpOptions } from '../../interfaces/mcp-options.interface';\nimport { PromptMetadata } from '../../decorators';\nimport {\n McpRegistryService,\n DYNAMIC_PROMPT_HANDLER_TOKEN,\n} from '../mcp-dynamic-registry.service';\n\n@Injectable({ scope: Scope.REQUEST })\nexport class McpPromptsHandler extends McpHandlerBase {\n constructor(\n moduleRef: ModuleRef,\n registry: McpRegistryDiscoveryService,\n reflector: Reflector,\n @Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,\n @Optional() @Inject('MCP_OPTIONS') options?: McpOptions,\n ) {\n super(moduleRef, registry, reflector, McpPromptsHandler.name, options);\n }\n\n registerHandlers(mcpServer: McpServer, httpRequest: HttpRequest) {\n if (this.registry.getPrompts(this.mcpModuleId).length === 0) {\n this.logger.debug('No prompts registered, skipping prompt handlers');\n return;\n }\n mcpServer.server.setRequestHandler(ListPromptsRequestSchema, () => {\n this.logger.debug('ListPromptsRequestSchema is being called');\n\n const prompts = this.registry\n .getPrompts(this.mcpModuleId)\n .map((prompt) => ({\n name: prompt.metadata.name,\n description: prompt.metadata.description,\n arguments: prompt.metadata.parameters\n ? Object.entries(prompt.metadata.parameters.shape).map(\n ([name, field]): PromptArgument => ({\n name,\n description: field.description,\n required: !field.isOptional(),\n }),\n )\n : [],\n }));\n\n return {\n prompts,\n };\n });\n\n mcpServer.server.setRequestHandler(\n GetPromptRequestSchema,\n async (request) => {\n this.logger.debug('GetPromptRequestSchema is being called');\n let promptInfo: DiscoveredCapability<PromptMetadata> | undefined;\n\n try {\n const name = request.params.name;\n promptInfo = this.registry.findPrompt(this.mcpModuleId, name);\n\n if (!promptInfo) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown prompt: ${name}`,\n );\n }\n\n const context = this.createContext(mcpServer, request);\n\n if (promptInfo.providerClass === DYNAMIC_PROMPT_HANDLER_TOKEN) {\n const handler = McpRegistryService.getPromptHandlerByModuleId(\n this.mcpModuleId,\n name,\n );\n\n if (!handler) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Handler not found for dynamic prompt: ${name}`,\n );\n }\n\n const result = await handler(\n request.params.arguments,\n context,\n httpRequest.raw,\n );\n\n this.logger.debug('GetPromptRequestSchema result', result);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return result;\n }\n\n const contextId = ContextIdFactory.getByRequest(httpRequest);\n this.moduleRef.registerRequestByContextId(httpRequest, contextId);\n\n const promptInstance = await this.moduleRef.resolve(\n promptInfo.providerClass,\n contextId,\n { strict: false },\n );\n\n if (!promptInstance) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown prompt: ${name}`,\n );\n }\n\n const methodName = promptInfo.methodName;\n\n const result = await promptInstance[methodName].call(\n promptInstance,\n request.params.arguments,\n context,\n httpRequest.raw,\n );\n\n this.logger.debug('GetPromptRequestSchema result', result);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return result;\n } catch (error) {\n this.handleError(error as Error, promptInfo!, httpRequest);\n }\n },\n );\n }\n}\n"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ModuleRef, Reflector } from '@nestjs/core';
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
-
import {
|
|
3
|
+
import { McpRegistryDiscoveryService } from '../mcp-registry-discovery.service';
|
|
4
4
|
import { McpHandlerBase } from './mcp-handler.base';
|
|
5
5
|
import type { McpOptions } from '../../interfaces';
|
|
6
6
|
import { HttpRequest } from '../../interfaces/http-adapter.interface';
|
|
7
7
|
export declare class McpResourcesHandler extends McpHandlerBase {
|
|
8
8
|
private readonly mcpModuleId;
|
|
9
|
-
constructor(moduleRef: ModuleRef, registry:
|
|
9
|
+
constructor(moduleRef: ModuleRef, registry: McpRegistryDiscoveryService, reflector: Reflector, mcpModuleId: string, options?: McpOptions);
|
|
10
10
|
registerHandlers(mcpServer: McpServer, httpRequest: HttpRequest): void;
|
|
11
11
|
private handleRequest;
|
|
12
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-resources.handler.d.ts","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-resources.handler.ts"],"names":[],"mappings":"AAOA,OAAO,EAAoB,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"mcp-resources.handler.d.ts","sourceRoot":"","sources":["../../../../src/mcp/services/handlers/mcp-resources.handler.ts"],"names":[],"mappings":"AAOA,OAAO,EAAoB,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAMtE,qBACa,mBAAoB,SAAQ,cAAc;IAK1B,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAHrD,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,2BAA2B,EACrC,SAAS,EAAE,SAAS,EACsB,WAAW,EAAE,MAAM,EAC1B,OAAO,CAAC,EAAE,UAAU;IAKzD,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW;YA4FjD,aAAa;CAoD5B"}
|