@muzikanto/nestjs-mcp 1.7.0 → 1.7.3
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/CHANGELOG.md +18 -0
- package/README.md +31 -11
- package/dist/index.d.ts +2 -8
- package/dist/index.js +2 -8
- package/dist/mcp-client/index.d.ts +3 -0
- package/dist/mcp-client/index.js +19 -0
- package/dist/mcp-client/mcp-client.module.d.ts +2 -6
- package/dist/mcp-client/mcp-client.module.js +5 -3
- package/dist/mcp-client/mcp-client.service.d.ts +2 -1
- package/dist/mcp-client/utils/openai.d.ts +34 -0
- package/dist/mcp-client/utils/openai.js +29 -0
- package/dist/mcp-server/config.d.ts +5 -0
- package/dist/mcp-server/controllers/mcp.controller.d.ts +2 -2
- package/dist/mcp-server/controllers/mcp.controller.js +5 -4
- package/dist/mcp-server/controllers/mcp.sse.controller.js +1 -0
- package/dist/mcp-server/decorators/mcp-resource.decorator.d.ts +7 -4
- package/dist/mcp-server/decorators/mcp-tool.decorator.d.ts +1 -1
- package/dist/mcp-server/dto/IMcpResourceResult.dto.d.ts +4 -0
- package/dist/mcp-server/dto/IMcpResourceResult.dto.js +26 -0
- package/dist/mcp-server/dto/McpResourceResult.dto.d.ts +4 -0
- package/dist/mcp-server/dto/McpResourceResult.dto.js +26 -0
- package/dist/mcp-server/dto/McpResourceResultItem.dto.d.ts +4 -0
- package/dist/mcp-server/dto/McpResourceResultItem.dto.js +30 -0
- package/dist/mcp-server/dto/McpToolResult.dto.d.ts +2 -2
- package/dist/mcp-server/dto/McpToolResultMessage.dto.d.ts +1 -1
- package/dist/mcp-server/index.d.ts +6 -0
- package/dist/mcp-server/index.js +22 -0
- package/dist/mcp-server/mcp.module.d.ts +13 -1
- package/dist/mcp-server/mcp.module.js +10 -2
- package/dist/mcp-server/services/mcp-dynamic.service.d.ts +5 -1
- package/dist/mcp-server/services/mcp-dynamic.service.js +12 -0
- package/dist/mcp-server/services/mcp.service.d.ts +1 -1
- package/dist/mcp-server/services/mcp.service.js +4 -1
- package/dist/mcp-server/services/mcp.sse.service.js +17 -2
- package/dist/mcp-server/utils/http-adapter.d.ts +1 -1
- package/dist/mcp-server/utils/openai.d.ts +34 -0
- package/dist/mcp-server/utils/openai.js +29 -0
- package/dist/mcp-server/utils/run-fillters.js +5 -2
- package/dist/mcp-server/utils/zod.js +4 -1
- package/package.json +18 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @muzikanto/nestjs-mcp
|
|
2
2
|
|
|
3
|
+
## 1.7.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fix dynamic tools filters
|
|
8
|
+
|
|
9
|
+
## 1.7.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- add transports selection
|
|
14
|
+
|
|
15
|
+
## 1.7.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- add exports for (client, server) and update example (add openai)
|
|
20
|
+
|
|
3
21
|
## 1.7.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -50,6 +50,13 @@ NestJS MCP (Model Context Protocol) module — allows you to create “tools”,
|
|
|
50
50
|
- Full TypeScript typing
|
|
51
51
|
- Support `@UseGuards`, `@UseInterceptors`, `@UseFilters`
|
|
52
52
|
|
|
53
|
+
## Examples
|
|
54
|
+
|
|
55
|
+
- [Example server](https://github.com/Muzikanto/nestjs-mcp/tree/main/example)
|
|
56
|
+
- [Example librechat](https://github.com/Muzikanto/nestjs-mcp/tree/main/example/librechat)
|
|
57
|
+
- [Example openai request](https://github.com/Muzikanto/nestjs-mcp/blob/main/example/src/openai/openai.service.ts)
|
|
58
|
+
- [Example mcp handlers](https://github.com/Muzikanto/nestjs-mcp/tree/main/example/src/mcp-server/handlers)
|
|
59
|
+
|
|
53
60
|
---
|
|
54
61
|
|
|
55
62
|
## Installation
|
|
@@ -74,6 +81,10 @@ import { TelegramAutoReplyPrompt } from "./prompts/telegram-auto-reply.prompt";
|
|
|
74
81
|
imports: [
|
|
75
82
|
McpModule.forRoot({
|
|
76
83
|
providers: [TelegramSendMessageTool, TelegramAutoReplyPrompt],
|
|
84
|
+
transports: {
|
|
85
|
+
sse: true, // SSE endpoints for mcp
|
|
86
|
+
http: true, // HTTP endpoints for custom server
|
|
87
|
+
},
|
|
77
88
|
}),
|
|
78
89
|
],
|
|
79
90
|
})
|
|
@@ -542,7 +553,7 @@ class NotImplExceptionFilter implements ExceptionFilter {
|
|
|
542
553
|
catch(exception: unknown, host: ArgumentsHost) {
|
|
543
554
|
return {
|
|
544
555
|
isError: true,
|
|
545
|
-
text:
|
|
556
|
+
messages: [{ type: "text", text: "Not implemented tool" }],
|
|
546
557
|
};
|
|
547
558
|
}
|
|
548
559
|
}
|
|
@@ -552,7 +563,7 @@ class AuthExceptionFilter implements ExceptionFilter {
|
|
|
552
563
|
catch(exception: unknown, host: ArgumentsHost) {
|
|
553
564
|
return {
|
|
554
565
|
isError: true,
|
|
555
|
-
text:
|
|
566
|
+
messages: [{ type: "text", text: "No access" }],
|
|
556
567
|
};
|
|
557
568
|
}
|
|
558
569
|
}
|
|
@@ -574,6 +585,8 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
574
585
|
|
|
575
586
|
### Integration with OpenAI Function Calls
|
|
576
587
|
|
|
588
|
+
Example with `openai`: `6.25.0`
|
|
589
|
+
|
|
577
590
|
```ts
|
|
578
591
|
import axios from "axios";
|
|
579
592
|
import OpenAI from "openai";
|
|
@@ -583,17 +596,24 @@ const MCP_TELEGRAM_PROMPT_URL =
|
|
|
583
596
|
"http://localhost:3000/mcp/prompts/telegram_auto_reply";
|
|
584
597
|
|
|
585
598
|
// Create OpenAI client
|
|
586
|
-
const client = new OpenAI({
|
|
599
|
+
const client = new OpenAI({
|
|
600
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
601
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
602
|
+
});
|
|
587
603
|
|
|
588
604
|
/**
|
|
589
605
|
* Get all tools
|
|
590
606
|
*/
|
|
591
607
|
async function getMcpTools() {
|
|
592
608
|
const response = await axios.get(MCP_TOOLS_URL);
|
|
609
|
+
|
|
593
610
|
return response.data.tools.map((el) => ({
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
611
|
+
type: "function",
|
|
612
|
+
function: {
|
|
613
|
+
name: el.name,
|
|
614
|
+
description: el.description,
|
|
615
|
+
parameters: el.inputSchema,
|
|
616
|
+
},
|
|
597
617
|
}));
|
|
598
618
|
}
|
|
599
619
|
|
|
@@ -623,16 +643,16 @@ async function callMcpTool(toolName: string, payload: Record<string, any>) {
|
|
|
623
643
|
const promptResponse = await getMcpPrompt();
|
|
624
644
|
|
|
625
645
|
const completion = await client.chat.completions.create({
|
|
626
|
-
model: "
|
|
646
|
+
model: "arcee-ai/trinity-large-preview:free",
|
|
627
647
|
messages: promptResponse.messages,
|
|
628
|
-
|
|
629
|
-
|
|
648
|
+
tools: toolsResponse,
|
|
649
|
+
tool_choice: "auto",
|
|
630
650
|
});
|
|
631
651
|
|
|
632
652
|
const message = completion.choices[0].message;
|
|
633
653
|
|
|
634
|
-
if (message.
|
|
635
|
-
const { name, arguments: argsJson } = message.
|
|
654
|
+
if (message.tool_calls?.length) {
|
|
655
|
+
const { name, arguments: argsJson } = message.tool_calls[0].function;
|
|
636
656
|
const args = JSON.parse(argsJson);
|
|
637
657
|
|
|
638
658
|
const { messages, structuredContent } = await callMcpTool(name, args);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
export * from "./mcp-
|
|
2
|
-
export * from "./mcp-server
|
|
3
|
-
export * from "./mcp-server/decorators/mcp-prompt.decorator";
|
|
4
|
-
export * from "./mcp-server/decorators/mcp-resource.decorator";
|
|
5
|
-
export * from "./mcp-client/mcp-client.module";
|
|
6
|
-
export * from "./mcp-client/mcp-client.service";
|
|
7
|
-
export * from "./mcp-server/services/mcp-dynamic.service";
|
|
8
|
-
export * from "./mcp-server/exceptions";
|
|
1
|
+
export * from "./mcp-client";
|
|
2
|
+
export * from "./mcp-server";
|
package/dist/index.js
CHANGED
|
@@ -14,11 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./mcp-
|
|
18
|
-
__exportStar(require("./mcp-server
|
|
19
|
-
__exportStar(require("./mcp-server/decorators/mcp-prompt.decorator"), exports);
|
|
20
|
-
__exportStar(require("./mcp-server/decorators/mcp-resource.decorator"), exports);
|
|
21
|
-
__exportStar(require("./mcp-client/mcp-client.module"), exports);
|
|
22
|
-
__exportStar(require("./mcp-client/mcp-client.service"), exports);
|
|
23
|
-
__exportStar(require("./mcp-server/services/mcp-dynamic.service"), exports);
|
|
24
|
-
__exportStar(require("./mcp-server/exceptions"), exports);
|
|
17
|
+
__exportStar(require("./mcp-client"), exports);
|
|
18
|
+
__exportStar(require("./mcp-server"), exports);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./mcp-client.module"), exports);
|
|
18
|
+
__exportStar(require("./mcp-client.service"), exports);
|
|
19
|
+
__exportStar(require("./utils/openai"), exports);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DynamicModule, Type } from "@nestjs/common";
|
|
2
2
|
export interface IMcpClientConfig {
|
|
3
3
|
url: string;
|
|
4
4
|
}
|
|
@@ -7,9 +7,5 @@ export declare class McpClientModule {
|
|
|
7
7
|
useValue?: IMcpClientConfig;
|
|
8
8
|
useExisting?: Type<IMcpClientConfig>;
|
|
9
9
|
useFactory?: (...args: any) => IMcpClientConfig | Promise<IMcpClientConfig>;
|
|
10
|
-
}):
|
|
11
|
-
module: typeof McpClientModule;
|
|
12
|
-
implements: import("@nestjs/common").DynamicModule[];
|
|
13
|
-
providers: Provider<IMcpClientConfig>[];
|
|
14
|
-
};
|
|
10
|
+
}): DynamicModule;
|
|
15
11
|
}
|
|
@@ -24,15 +24,17 @@ let McpClientModule = McpClientModule_1 = class McpClientModule {
|
|
|
24
24
|
};
|
|
25
25
|
return {
|
|
26
26
|
module: McpClientModule_1,
|
|
27
|
-
|
|
27
|
+
imports: [
|
|
28
28
|
axios_1.HttpModule.registerAsync({
|
|
29
|
-
inject: [inject_tokens_1.MCP_CLIENT_CONFIG],
|
|
30
29
|
useFactory: (config) => {
|
|
31
|
-
return {
|
|
30
|
+
return { baseURL: config.url };
|
|
32
31
|
},
|
|
32
|
+
inject: [inject_tokens_1.MCP_CLIENT_CONFIG],
|
|
33
|
+
extraProviders: [configProvider],
|
|
33
34
|
}),
|
|
34
35
|
],
|
|
35
36
|
providers: [mcp_client_service_1.McpClientService, configProvider],
|
|
37
|
+
exports: [mcp_client_service_1.McpClientService],
|
|
36
38
|
};
|
|
37
39
|
}
|
|
38
40
|
};
|
|
@@ -2,11 +2,12 @@ import { HttpService } from "@nestjs/axios";
|
|
|
2
2
|
import { McpToolsDto } from "../mcp-server/dto/McpTools.dto";
|
|
3
3
|
import { McpPromptsDto } from "../mcp-server/dto/McpPrompts.dto";
|
|
4
4
|
import { McpPromptResultDto } from "../mcp-server/dto/McpPrompResult.dto";
|
|
5
|
+
import { McpToolResultDto } from "../mcp-server/dto/McpToolResult.dto";
|
|
5
6
|
export declare class McpClientService {
|
|
6
7
|
private readonly httpService;
|
|
7
8
|
constructor(httpService: HttpService);
|
|
8
9
|
getAllTools(): Promise<McpToolsDto>;
|
|
9
10
|
getAllPrompts(): Promise<McpPromptsDto>;
|
|
10
11
|
getPromptByName<Payload = any>(promptName: string, params: Payload): Promise<McpPromptResultDto>;
|
|
11
|
-
callMcpTool<Payload = any, Result = any>(toolName: string, payload: Payload): Promise<Result
|
|
12
|
+
callMcpTool<Payload = any, Result = any>(toolName: string, payload: Payload): Promise<McpToolResultDto<Result>>;
|
|
12
13
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { McpToolDto } from "../../mcp-server/dto/McpTool.dto";
|
|
2
|
+
type OpenAiCall = {
|
|
3
|
+
function: {
|
|
4
|
+
name: string;
|
|
5
|
+
arguments: string;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
export declare class McpOpenAiHelper {
|
|
9
|
+
static convertTools(tools: McpToolDto[]): {
|
|
10
|
+
type: "function";
|
|
11
|
+
function: {
|
|
12
|
+
name: string;
|
|
13
|
+
description: string | undefined;
|
|
14
|
+
parameters: any;
|
|
15
|
+
};
|
|
16
|
+
}[];
|
|
17
|
+
static convertTool(tool: McpToolDto): {
|
|
18
|
+
type: "function";
|
|
19
|
+
function: {
|
|
20
|
+
name: string;
|
|
21
|
+
description: string | undefined;
|
|
22
|
+
parameters: any;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
static convertToolCalls(toolCalls: OpenAiCall[]): {
|
|
26
|
+
name: string;
|
|
27
|
+
payload: any;
|
|
28
|
+
}[];
|
|
29
|
+
static convertToolCall({ function: { name, arguments: args }, }: OpenAiCall): {
|
|
30
|
+
name: string;
|
|
31
|
+
payload: any;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.McpOpenAiHelper = void 0;
|
|
4
|
+
class McpOpenAiHelper {
|
|
5
|
+
static convertTools(tools) {
|
|
6
|
+
return tools.map((tool) => McpOpenAiHelper.convertTool(tool));
|
|
7
|
+
}
|
|
8
|
+
static convertTool(tool) {
|
|
9
|
+
return {
|
|
10
|
+
type: "function",
|
|
11
|
+
function: {
|
|
12
|
+
name: tool.name,
|
|
13
|
+
description: tool.description,
|
|
14
|
+
parameters: tool.inputSchema,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
static convertToolCalls(toolCalls) {
|
|
19
|
+
return toolCalls.map((toolCall) => McpOpenAiHelper.convertToolCall(toolCall));
|
|
20
|
+
}
|
|
21
|
+
static convertToolCall({ function: { name, arguments: args }, }) {
|
|
22
|
+
const argsJson = JSON.parse(args || "{}");
|
|
23
|
+
return {
|
|
24
|
+
name,
|
|
25
|
+
payload: argsJson,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.McpOpenAiHelper = McpOpenAiHelper;
|
|
@@ -3,6 +3,11 @@ export declare const MCP_CONFIG_TOKEN = "mcl:config-token";
|
|
|
3
3
|
export type IMcpConfig = {
|
|
4
4
|
name?: string;
|
|
5
5
|
version?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
icons?: {
|
|
9
|
+
src: string;
|
|
10
|
+
}[];
|
|
6
11
|
httpAdapter: IHttpAdapter;
|
|
7
12
|
};
|
|
8
13
|
export declare const InjectMcpConfig: () => PropertyDecorator & ParameterDecorator;
|
|
@@ -6,7 +6,7 @@ import { McpPromptsDto } from "../dto/McpPrompts.dto";
|
|
|
6
6
|
import { McpPromptResultDto } from "../dto/McpPrompResult.dto";
|
|
7
7
|
import { IMcpConfig } from "../config";
|
|
8
8
|
import { McpResourcesDto } from "../dto/McpResources.dto";
|
|
9
|
-
import {
|
|
9
|
+
import { McpResourceResultDto } from "../dto/McpResourceResult.dto";
|
|
10
10
|
import { McpResourceRequestDto } from "../dto/McpResourceRequest.dto";
|
|
11
11
|
import { McpToolResultDto } from "../dto/McpToolResult.dto";
|
|
12
12
|
export declare class McpController {
|
|
@@ -19,6 +19,6 @@ export declare class McpController {
|
|
|
19
19
|
getPrompts(context: ExecutionContext): Promise<McpPromptsDto>;
|
|
20
20
|
getPrompt(name: string, body: object, context: ExecutionContext): Promise<McpPromptResultDto>;
|
|
21
21
|
getResources(context: ExecutionContext): Promise<McpResourcesDto>;
|
|
22
|
-
executeResource(name: string, body: McpResourceRequestDto, context: ExecutionContext): Promise<
|
|
22
|
+
executeResource(name: string, body: McpResourceRequestDto, context: ExecutionContext): Promise<McpResourceResultDto>;
|
|
23
23
|
private checkGuard;
|
|
24
24
|
}
|
|
@@ -25,7 +25,7 @@ const inject_tokens_1 = require("../utils/inject-tokens");
|
|
|
25
25
|
const config_1 = require("../config");
|
|
26
26
|
const rxjs_1 = require("rxjs");
|
|
27
27
|
const McpResources_dto_1 = require("../dto/McpResources.dto");
|
|
28
|
-
const
|
|
28
|
+
const McpResourceResult_dto_1 = require("../dto/McpResourceResult.dto");
|
|
29
29
|
const McpResourceRequest_dto_1 = require("../dto/McpResourceRequest.dto");
|
|
30
30
|
const uri_1 = require("../utils/uri");
|
|
31
31
|
const McpToolResult_dto_1 = require("../dto/McpToolResult.dto");
|
|
@@ -73,8 +73,8 @@ let McpController = class McpController {
|
|
|
73
73
|
? (0, uri_1.extractResourceParams)(resource.instance.uri, body.uri)
|
|
74
74
|
: {};
|
|
75
75
|
const observable = await this.service.executeResource(name, url, params, context);
|
|
76
|
-
const
|
|
77
|
-
return
|
|
76
|
+
const result = await (0, rxjs_1.firstValueFrom)(observable);
|
|
77
|
+
return result;
|
|
78
78
|
}
|
|
79
79
|
async checkGuard(context) {
|
|
80
80
|
if (!(await this.guard.canActivate(context))) {
|
|
@@ -203,7 +203,7 @@ __decorate([
|
|
|
203
203
|
(0, swagger_1.ApiResponse)({
|
|
204
204
|
status: 200,
|
|
205
205
|
description: "Resource template result",
|
|
206
|
-
type:
|
|
206
|
+
type: McpResourceResult_dto_1.McpResourceResultDto,
|
|
207
207
|
}),
|
|
208
208
|
(0, swagger_1.ApiNotFoundResponse)({
|
|
209
209
|
description: "Not found resource template",
|
|
@@ -219,6 +219,7 @@ __decorate([
|
|
|
219
219
|
__metadata("design:returntype", Promise)
|
|
220
220
|
], McpController.prototype, "executeResource", null);
|
|
221
221
|
exports.McpController = McpController = __decorate([
|
|
222
|
+
(0, swagger_1.ApiTags)("MCP server"),
|
|
222
223
|
(0, common_1.Controller)("mcp"),
|
|
223
224
|
__param(1, (0, common_1.Inject)(inject_tokens_1.MCP_GUARD)),
|
|
224
225
|
__param(2, (0, config_1.InjectMcpConfig)()),
|
|
@@ -72,6 +72,7 @@ __decorate([
|
|
|
72
72
|
__metadata("design:returntype", Promise)
|
|
73
73
|
], McpSseController.prototype, "handleSseMessages", null);
|
|
74
74
|
exports.McpSseController = McpSseController = __decorate([
|
|
75
|
+
(0, swagger_1.ApiTags)("MCP server"),
|
|
75
76
|
(0, common_1.Controller)("mcp"),
|
|
76
77
|
__param(1, (0, common_1.Inject)(inject_tokens_1.MCP_GUARD)),
|
|
77
78
|
__param(2, (0, config_1.InjectMcpConfig)()),
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol";
|
|
2
|
-
import { Resource, ServerNotification, ServerRequest } from "@modelcontextprotocol/sdk/types";
|
|
1
|
+
import { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
2
|
+
import { Resource, ServerNotification, ServerRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
3
3
|
import "reflect-metadata";
|
|
4
|
-
export type
|
|
4
|
+
export type IMcpResourceResultItem = {
|
|
5
5
|
uri: string;
|
|
6
6
|
text: string;
|
|
7
7
|
};
|
|
8
|
+
export type IMcpResourceResult = {
|
|
9
|
+
contents: IMcpResourceResultItem[];
|
|
10
|
+
};
|
|
8
11
|
export type IMcpResourceListItem = {
|
|
9
12
|
name: string;
|
|
10
13
|
uri: string;
|
|
@@ -18,7 +21,7 @@ export interface IMcpResource<Payload = any> {
|
|
|
18
21
|
description?: string;
|
|
19
22
|
annotations?: Resource["annotations"];
|
|
20
23
|
_meta?: Resource["_meta"];
|
|
21
|
-
execute(url: URL, input: Payload): Promise<IMcpResourceResult
|
|
24
|
+
execute(url: URL, input: Payload): Promise<IMcpResourceResult>;
|
|
22
25
|
list?(extra: RequestHandlerExtra<ServerRequest, ServerNotification>): Promise<IMcpResourceListItem[]>;
|
|
23
26
|
}
|
|
24
27
|
export declare const MCP_RESOURCE_METADATA = "mcp:resource-class";
|
|
@@ -0,0 +1,26 @@
|
|
|
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.McpResourceItemsDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const McpResourceItem_dto_1 = require("./McpResourceItem.dto");
|
|
15
|
+
class McpResourceItemsDto {
|
|
16
|
+
contents;
|
|
17
|
+
}
|
|
18
|
+
exports.McpResourceItemsDto = McpResourceItemsDto;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, swagger_1.ApiProperty)({
|
|
21
|
+
type: McpResourceItem_dto_1.McpResourceItemDto,
|
|
22
|
+
isArray: true,
|
|
23
|
+
description: "Resource result list",
|
|
24
|
+
}),
|
|
25
|
+
__metadata("design:type", Array)
|
|
26
|
+
], McpResourceItemsDto.prototype, "contents", void 0);
|
|
@@ -0,0 +1,26 @@
|
|
|
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.McpResourceResultDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
const McpResourceResultItem_dto_1 = require("./McpResourceResultItem.dto");
|
|
15
|
+
class McpResourceResultDto {
|
|
16
|
+
contents;
|
|
17
|
+
}
|
|
18
|
+
exports.McpResourceResultDto = McpResourceResultDto;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, swagger_1.ApiProperty)({
|
|
21
|
+
type: McpResourceResultItem_dto_1.McpResourceResultItemDto,
|
|
22
|
+
isArray: true,
|
|
23
|
+
description: "Resource result list",
|
|
24
|
+
}),
|
|
25
|
+
__metadata("design:type", Array)
|
|
26
|
+
], McpResourceResultDto.prototype, "contents", void 0);
|
|
@@ -0,0 +1,30 @@
|
|
|
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.McpResourceResultItemDto = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
class McpResourceResultItemDto {
|
|
15
|
+
uri;
|
|
16
|
+
text;
|
|
17
|
+
}
|
|
18
|
+
exports.McpResourceResultItemDto = McpResourceResultItemDto;
|
|
19
|
+
__decorate([
|
|
20
|
+
(0, swagger_1.ApiProperty)({ type: "string", description: "Resource uri" }),
|
|
21
|
+
__metadata("design:type", String)
|
|
22
|
+
], McpResourceResultItemDto.prototype, "uri", void 0);
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, swagger_1.ApiProperty)({
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "Resource text",
|
|
27
|
+
nullable: true,
|
|
28
|
+
}),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], McpResourceResultItemDto.prototype, "text", void 0);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { McpToolResultMessageDto } from "./McpToolResultMessage.dto";
|
|
2
|
-
export declare class McpToolResultDto {
|
|
3
|
-
structuredContent?:
|
|
2
|
+
export declare class McpToolResultDto<Result = any> {
|
|
3
|
+
structuredContent?: Result;
|
|
4
4
|
messages: McpToolResultMessageDto[];
|
|
5
5
|
isError?: boolean;
|
|
6
6
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from "./mcp.module";
|
|
2
|
+
export * from "./decorators/mcp-tool.decorator";
|
|
3
|
+
export * from "./decorators/mcp-prompt.decorator";
|
|
4
|
+
export * from "./decorators/mcp-resource.decorator";
|
|
5
|
+
export * from "./services/mcp-dynamic.service";
|
|
6
|
+
export * from "./exceptions";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./mcp.module"), exports);
|
|
18
|
+
__exportStar(require("./decorators/mcp-tool.decorator"), exports);
|
|
19
|
+
__exportStar(require("./decorators/mcp-prompt.decorator"), exports);
|
|
20
|
+
__exportStar(require("./decorators/mcp-resource.decorator"), exports);
|
|
21
|
+
__exportStar(require("./services/mcp-dynamic.service"), exports);
|
|
22
|
+
__exportStar(require("./exceptions"), exports);
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { CanActivate, DynamicModule, ModuleMetadata, Provider } from "@nestjs/common";
|
|
2
2
|
import { IHttpAdapter } from "./utils/http-adapter";
|
|
3
3
|
type Metadata = Pick<ModuleMetadata, "providers" | "imports" | "exports"> & {
|
|
4
|
-
guard?: Provider<CanActivate>;
|
|
5
4
|
name?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
title?: string;
|
|
7
|
+
icons?: {
|
|
8
|
+
src: string;
|
|
9
|
+
}[];
|
|
6
10
|
version?: string;
|
|
11
|
+
/**
|
|
12
|
+
* @default { sse: true, http: true }
|
|
13
|
+
*/
|
|
14
|
+
transports?: {
|
|
15
|
+
sse?: boolean;
|
|
16
|
+
http?: boolean;
|
|
17
|
+
};
|
|
7
18
|
httpAdapter?: IHttpAdapter;
|
|
19
|
+
guard?: Provider<CanActivate>;
|
|
8
20
|
};
|
|
9
21
|
export declare class McpModule {
|
|
10
22
|
static forRoot(metadata?: Metadata): DynamicModule;
|
|
@@ -22,11 +22,16 @@ const mcp_sse_service_1 = require("./services/mcp.sse.service");
|
|
|
22
22
|
const publicGuard = { canActivate: () => Promise.resolve(true) };
|
|
23
23
|
let McpModule = McpModule_1 = class McpModule {
|
|
24
24
|
static forRoot(metadata = {}) {
|
|
25
|
+
// TODO remove defaut in next major version
|
|
26
|
+
const transports = metadata.transports || { sse: true, http: true };
|
|
25
27
|
const configProviver = {
|
|
26
28
|
provide: config_1.MCP_CONFIG_TOKEN,
|
|
27
29
|
useValue: {
|
|
28
30
|
name: metadata.name,
|
|
29
31
|
version: metadata.version,
|
|
32
|
+
description: metadata.description,
|
|
33
|
+
title: metadata.title,
|
|
34
|
+
icons: metadata.icons,
|
|
30
35
|
httpAdapter: metadata.httpAdapter || http_adapter_1.DEFAULT_FASTIFY_ADAPTER,
|
|
31
36
|
},
|
|
32
37
|
};
|
|
@@ -41,7 +46,7 @@ let McpModule = McpModule_1 = class McpModule {
|
|
|
41
46
|
imports: [core_1.DiscoveryModule, ...(metadata.imports || [])],
|
|
42
47
|
providers: [
|
|
43
48
|
mcp_service_1.McpService,
|
|
44
|
-
mcp_sse_service_1.McpSseService,
|
|
49
|
+
...(transports.sse ? [mcp_sse_service_1.McpSseService] : []),
|
|
45
50
|
mcp_explorer_1.McpExplorer,
|
|
46
51
|
mcp_dynamic_service_1.McpDynamicService,
|
|
47
52
|
configProviver,
|
|
@@ -50,7 +55,10 @@ let McpModule = McpModule_1 = class McpModule {
|
|
|
50
55
|
...(metadata.providers || []),
|
|
51
56
|
],
|
|
52
57
|
exports: [mcp_dynamic_service_1.McpDynamicService, ...(metadata.exports || [])],
|
|
53
|
-
controllers: [
|
|
58
|
+
controllers: [
|
|
59
|
+
...(transports.http ? [mcp_controller_1.McpController] : []),
|
|
60
|
+
...(transports.sse ? [mcp_sse_controller_1.McpSseController] : []),
|
|
61
|
+
],
|
|
54
62
|
};
|
|
55
63
|
}
|
|
56
64
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CanActivate, NestInterceptor, Type } from "@nestjs/common";
|
|
1
|
+
import { CanActivate, ExceptionFilter, NestInterceptor, Type } from "@nestjs/common";
|
|
2
2
|
import { ModuleRef } from "@nestjs/core";
|
|
3
3
|
import { McpService } from "../services/mcp.service";
|
|
4
4
|
import { IMcpTool } from "../decorators/mcp-tool.decorator";
|
|
@@ -7,14 +7,17 @@ import { IMcpPrompt } from "../decorators/mcp-prompt.decorator";
|
|
|
7
7
|
export type IMcpDynamicTool<Input, Result extends Record<string, unknown>> = IMcpTool<Input, Result> & {
|
|
8
8
|
guards?: Type<CanActivate>[];
|
|
9
9
|
interceptors?: Type<NestInterceptor>[];
|
|
10
|
+
filters?: Type<ExceptionFilter>[];
|
|
10
11
|
};
|
|
11
12
|
export type IMcpDynamicPrompt<Input> = IMcpPrompt<Input> & {
|
|
12
13
|
guards?: Type<CanActivate>[];
|
|
13
14
|
interceptors?: Type<NestInterceptor>[];
|
|
15
|
+
filters?: Type<ExceptionFilter>[];
|
|
14
16
|
};
|
|
15
17
|
export type IMcpDynamicResource<Input> = IMcpResource<Input> & {
|
|
16
18
|
guards?: Type<CanActivate>[];
|
|
17
19
|
interceptors?: Type<NestInterceptor>[];
|
|
20
|
+
filters?: Type<ExceptionFilter>[];
|
|
18
21
|
};
|
|
19
22
|
export declare class McpDynamicService {
|
|
20
23
|
private readonly moduleRef;
|
|
@@ -28,4 +31,5 @@ export declare class McpDynamicService {
|
|
|
28
31
|
registerResource<Input>(resource: IMcpDynamicResource<Input>): Promise<void>;
|
|
29
32
|
protected applyGuards(item: Function, guards: Type<CanActivate>[]): void;
|
|
30
33
|
protected applyInterceptors(item: Function, interceptors: Type<NestInterceptor>[]): void;
|
|
34
|
+
protected applyFilters(item: Function, filters: Type<ExceptionFilter>[]): void;
|
|
31
35
|
}
|
|
@@ -39,6 +39,9 @@ let McpDynamicService = class McpDynamicService {
|
|
|
39
39
|
if (tool.interceptors) {
|
|
40
40
|
this.applyInterceptors(DynamicToolClass, tool.interceptors);
|
|
41
41
|
}
|
|
42
|
+
if (tool.filters) {
|
|
43
|
+
this.applyFilters(DynamicToolClass, tool.filters);
|
|
44
|
+
}
|
|
42
45
|
const instance = await this.moduleRef.create(DynamicToolClass);
|
|
43
46
|
this.mcpService.registerTool(instance.name, {
|
|
44
47
|
instance,
|
|
@@ -60,6 +63,9 @@ let McpDynamicService = class McpDynamicService {
|
|
|
60
63
|
if (prompt.interceptors) {
|
|
61
64
|
this.applyInterceptors(DynamicPromptClass, prompt.interceptors);
|
|
62
65
|
}
|
|
66
|
+
if (prompt.filters) {
|
|
67
|
+
this.applyFilters(DynamicPromptClass, prompt.filters);
|
|
68
|
+
}
|
|
63
69
|
const instance = await this.moduleRef.create(DynamicPromptClass);
|
|
64
70
|
this.mcpService.registerPrompt(instance.name, {
|
|
65
71
|
instance,
|
|
@@ -84,6 +90,9 @@ let McpDynamicService = class McpDynamicService {
|
|
|
84
90
|
if (resource.interceptors) {
|
|
85
91
|
this.applyInterceptors(DynamicResourceClass, resource.interceptors);
|
|
86
92
|
}
|
|
93
|
+
if (resource.filters) {
|
|
94
|
+
this.applyFilters(DynamicResourceClass, resource.filters);
|
|
95
|
+
}
|
|
87
96
|
const instance = await this.moduleRef.create(DynamicResourceClass);
|
|
88
97
|
this.mcpService.registerResource(instance.name, {
|
|
89
98
|
instance,
|
|
@@ -96,6 +105,9 @@ let McpDynamicService = class McpDynamicService {
|
|
|
96
105
|
applyInterceptors(item, interceptors) {
|
|
97
106
|
Reflect.defineMetadata(constants_1.INTERCEPTORS_METADATA, interceptors, item);
|
|
98
107
|
}
|
|
108
|
+
applyFilters(item, filters) {
|
|
109
|
+
Reflect.defineMetadata(constants_1.EXCEPTION_FILTERS_METADATA, filters, item);
|
|
110
|
+
}
|
|
99
111
|
};
|
|
100
112
|
exports.McpDynamicService = McpDynamicService;
|
|
101
113
|
exports.McpDynamicService = McpDynamicService = __decorate([
|
|
@@ -74,5 +74,5 @@ export declare class McpService implements OnModuleInit {
|
|
|
74
74
|
type: string;
|
|
75
75
|
payload: any;
|
|
76
76
|
}, context: ExecutionContext): Promise<Observable<IMcpToolResult<Record<string, unknown>>>>;
|
|
77
|
-
executeResource(name: string, uri: URL, vars: Record<string, any>, context: ExecutionContext): Promise<Observable<IMcpResourceResult
|
|
77
|
+
executeResource(name: string, uri: URL, vars: Record<string, any>, context: ExecutionContext): Promise<Observable<IMcpResourceResult>>;
|
|
78
78
|
}
|
|
@@ -11,10 +11,13 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
11
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
12
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
13
|
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
14
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
18
|
exports.McpService = void 0;
|
|
16
19
|
const common_1 = require("@nestjs/common");
|
|
17
|
-
const ajv_1 = require("ajv");
|
|
20
|
+
const ajv_1 = __importDefault(require("ajv"));
|
|
18
21
|
const zod_1 = require("../utils/zod");
|
|
19
22
|
const run_guards_1 = require("../utils/run-guards");
|
|
20
23
|
const core_1 = require("@nestjs/core");
|
|
@@ -63,7 +63,22 @@ let McpSseService = class McpSseService {
|
|
|
63
63
|
const server = new mcp_js_1.McpServer({
|
|
64
64
|
version: this.config.version || "1",
|
|
65
65
|
name: this.config.name || "MCP server",
|
|
66
|
-
|
|
66
|
+
description: this.config.description,
|
|
67
|
+
title: this.config.title,
|
|
68
|
+
icons: this.config.icons,
|
|
69
|
+
}, {
|
|
70
|
+
capabilities: {
|
|
71
|
+
prompts: {
|
|
72
|
+
listChanged: true,
|
|
73
|
+
},
|
|
74
|
+
tools: {
|
|
75
|
+
listChanged: true,
|
|
76
|
+
},
|
|
77
|
+
resources: {
|
|
78
|
+
listChanged: true,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
});
|
|
67
82
|
this.registerTools(server, context);
|
|
68
83
|
this.registerPrompts(server, context);
|
|
69
84
|
this.registerResources(server, context);
|
|
@@ -150,7 +165,7 @@ let McpSseService = class McpSseService {
|
|
|
150
165
|
// const resources = await resource.execute(url, variables);
|
|
151
166
|
const observable = await this.service.executeResource(resource.name, url, variables, context);
|
|
152
167
|
const result = await (0, rxjs_1.firstValueFrom)(observable);
|
|
153
|
-
return
|
|
168
|
+
return result;
|
|
154
169
|
}
|
|
155
170
|
catch (e) {
|
|
156
171
|
throw new exceptions_1.McpInternalServerErrorException(`Faild to execute tool ${prompt.name}`, {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { McpToolDto } from "../dto/McpTool.dto";
|
|
2
|
+
type OpenAiCall = {
|
|
3
|
+
function: {
|
|
4
|
+
name: string;
|
|
5
|
+
arguments: string;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
export declare class McpOpenAiHelper {
|
|
9
|
+
static convertTools(tools: McpToolDto[]): {
|
|
10
|
+
type: "function";
|
|
11
|
+
function: {
|
|
12
|
+
name: string;
|
|
13
|
+
description: string | undefined;
|
|
14
|
+
parameters: any;
|
|
15
|
+
};
|
|
16
|
+
}[];
|
|
17
|
+
static convertTool(tool: McpToolDto): {
|
|
18
|
+
type: "function";
|
|
19
|
+
function: {
|
|
20
|
+
name: string;
|
|
21
|
+
description: string | undefined;
|
|
22
|
+
parameters: any;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
static convertToolCalls(toolCalls: OpenAiCall[]): {
|
|
26
|
+
name: string;
|
|
27
|
+
payload: any;
|
|
28
|
+
}[];
|
|
29
|
+
static convertToolCall({ function: { name, arguments: args }, }: OpenAiCall): {
|
|
30
|
+
name: string;
|
|
31
|
+
payload: any;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.McpOpenAiHelper = void 0;
|
|
4
|
+
class McpOpenAiHelper {
|
|
5
|
+
static convertTools(tools) {
|
|
6
|
+
return tools.map((tool) => McpOpenAiHelper.convertTool(tool));
|
|
7
|
+
}
|
|
8
|
+
static convertTool(tool) {
|
|
9
|
+
return {
|
|
10
|
+
type: "function",
|
|
11
|
+
function: {
|
|
12
|
+
name: tool.name,
|
|
13
|
+
description: tool.description,
|
|
14
|
+
parameters: tool.inputSchema,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
static convertToolCalls(toolCalls) {
|
|
19
|
+
return toolCalls.map((toolCall) => McpOpenAiHelper.convertToolCall(toolCall));
|
|
20
|
+
}
|
|
21
|
+
static convertToolCall({ function: { name, arguments: args }, }) {
|
|
22
|
+
const argsJson = JSON.parse(args || "{}");
|
|
23
|
+
return {
|
|
24
|
+
name,
|
|
25
|
+
payload: argsJson,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.McpOpenAiHelper = McpOpenAiHelper;
|
|
@@ -22,8 +22,11 @@ async function runFilters(moduleRef, metatype, exception, host) {
|
|
|
22
22
|
const filters = Reflect.getMetadata(constants_1.EXCEPTION_FILTERS_METADATA, metatype) || [];
|
|
23
23
|
for (const Filter of filters) {
|
|
24
24
|
const filterInstance = await resolveFilter(Filter);
|
|
25
|
-
const filterExceptions = (Reflect.getMetadata(constants_1.FILTER_CATCH_EXCEPTIONS, Filter)
|
|
26
|
-
if (!filterExceptions
|
|
25
|
+
const filterExceptions = (Reflect.getMetadata(constants_1.FILTER_CATCH_EXCEPTIONS, Filter));
|
|
26
|
+
if (!filterExceptions) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (filterExceptions.length > 0 &&
|
|
27
30
|
!filterExceptions.some((ex) => exception instanceof ex)) {
|
|
28
31
|
continue;
|
|
29
32
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.zodToJsonSchema = zodToJsonSchema;
|
|
4
7
|
const v3_1 = require("zod/v3");
|
|
5
8
|
const v4_1 = require("zod/v4");
|
|
6
|
-
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
9
|
+
const zod_to_json_schema_1 = __importDefault(require("zod-to-json-schema"));
|
|
7
10
|
// Функция преобразования Zod в JSON Schema
|
|
8
11
|
function zodToJsonSchema(schema, deep = 0) {
|
|
9
12
|
if (schema && deep === 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muzikanto/nestjs-mcp",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.3",
|
|
4
4
|
"description": "NestJS MCP (Model Context Protocol) module for creating tools for LLM or HTTP with validation, decorators, and OpenAI Function Calls integration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nestjs",
|
|
@@ -13,6 +13,23 @@
|
|
|
13
13
|
],
|
|
14
14
|
"main": "dist/index.js",
|
|
15
15
|
"types": "dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"require": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts"
|
|
21
|
+
},
|
|
22
|
+
"./client": {
|
|
23
|
+
"import": "./dist/mcp-client/index.js",
|
|
24
|
+
"require": "./dist/mcp-client/index.js",
|
|
25
|
+
"types": "./dist/mcp-client/index.d.ts"
|
|
26
|
+
},
|
|
27
|
+
"./server": {
|
|
28
|
+
"import": "./dist/mcp-server/index.js",
|
|
29
|
+
"require": "./dist/mcp-server/index.js",
|
|
30
|
+
"types": "./dist/mcp-server/index.d.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
16
33
|
"files": [
|
|
17
34
|
"dist"
|
|
18
35
|
],
|