@muzikanto/nestjs-mcp 1.6.0 → 1.7.1
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 +12 -0
- package/README.md +82 -51
- 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 +4 -3
- package/dist/mcp-client/utils/openai.d.ts +34 -0
- package/dist/mcp-client/utils/openai.js +29 -0
- package/dist/mcp-server/controllers/mcp.controller.d.ts +6 -5
- package/dist/mcp-server/controllers/mcp.controller.js +11 -10
- package/dist/mcp-server/controllers/mcp.sse.controller.js +1 -0
- package/dist/mcp-server/decorators/mcp-prompt.decorator.d.ts +7 -3
- package/dist/mcp-server/decorators/mcp-resource.decorator.d.ts +9 -4
- package/dist/mcp-server/decorators/mcp-tool.decorator.d.ts +14 -2
- 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/McpPrompResult.dto.d.ts +5 -0
- package/dist/mcp-server/dto/McpPrompResult.dto.js +31 -0
- package/dist/mcp-server/dto/McpPromptMessage.dto.d.ts +5 -0
- package/dist/mcp-server/dto/McpPromptMessage.dto.js +40 -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/McpTool.dto.d.ts +1 -0
- package/dist/mcp-server/dto/McpTool.dto.js +10 -0
- package/dist/mcp-server/dto/McpToolResult.dto.d.ts +6 -0
- package/dist/mcp-server/dto/McpToolResult.dto.js +32 -0
- package/dist/mcp-server/dto/McpToolResultMessage.dto.d.ts +4 -0
- package/dist/mcp-server/dto/McpToolResultMessage.dto.js +26 -0
- package/dist/mcp-server/exceptions/index.d.ts +3 -1
- package/dist/mcp-server/exceptions/index.js +3 -1
- package/dist/mcp-server/index.d.ts +6 -0
- package/dist/mcp-server/index.js +22 -0
- package/dist/mcp-server/services/mcp-dynamic.service.d.ts +2 -2
- package/dist/mcp-server/services/mcp-dynamic.service.js +5 -0
- package/dist/mcp-server/services/mcp.service.d.ts +8 -6
- package/dist/mcp-server/services/mcp.service.js +9 -3
- package/dist/mcp-server/services/mcp.sse.service.d.ts +3 -0
- package/dist/mcp-server/services/mcp.sse.service.js +21 -7
- 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/zod.js +4 -1
- package/package.json +18 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -85,7 +85,7 @@ export class AppModule {}
|
|
|
85
85
|
```ts
|
|
86
86
|
import { IMcpTool, McpTool } from "@muzikanto/nestjs-mcp";
|
|
87
87
|
import { Telegraf } from "telegraf";
|
|
88
|
-
import z from "zod";
|
|
88
|
+
import z from "zod/v3";
|
|
89
89
|
|
|
90
90
|
const schema = {
|
|
91
91
|
chatId: z.number().describe("Telegram chat id"), // строка с описанием
|
|
@@ -98,14 +98,16 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
98
98
|
{ success: boolean }
|
|
99
99
|
> {
|
|
100
100
|
name = "telegram.sendMessage";
|
|
101
|
-
|
|
102
101
|
inputSchema = schema;
|
|
103
102
|
|
|
104
103
|
constructor(private readonly bot: Telegraf) {}
|
|
105
104
|
|
|
106
105
|
async execute(input: { chatId: string; text: string }) {
|
|
107
106
|
await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
108
|
-
return {
|
|
107
|
+
return {
|
|
108
|
+
structuredContent: { success: true },
|
|
109
|
+
messages: [{ type: "text", text: "Success sent to user" }],
|
|
110
|
+
};
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
```
|
|
@@ -128,9 +130,10 @@ POST /mcp/tools
|
|
|
128
130
|
|
|
129
131
|
```json
|
|
130
132
|
{
|
|
131
|
-
"
|
|
133
|
+
"structuredContent": {
|
|
132
134
|
"success": true
|
|
133
|
-
}
|
|
135
|
+
},
|
|
136
|
+
"messages": [{ "type": "text", "text": "Success sent to user" }]"
|
|
134
137
|
}
|
|
135
138
|
```
|
|
136
139
|
|
|
@@ -167,7 +170,7 @@ GET /mcp/tools
|
|
|
167
170
|
|
|
168
171
|
```ts
|
|
169
172
|
import { IMcpPrompt, McpPrompt } from "@muzikanto/nestjs-mcp";
|
|
170
|
-
import z from "zod";
|
|
173
|
+
import z from "zod/v3";
|
|
171
174
|
|
|
172
175
|
const schema = {
|
|
173
176
|
chatId: z.number().describe("Telegram chat id"), // строка с описанием
|
|
@@ -185,26 +188,28 @@ export class TelegramAutoReplyPrompt implements IMcpPrompt<{
|
|
|
185
188
|
schema = schema;
|
|
186
189
|
|
|
187
190
|
async execute({ text, chatId }: { text: string; chatId: number }) {
|
|
188
|
-
return
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
191
|
+
return {
|
|
192
|
+
messages: [
|
|
193
|
+
{
|
|
194
|
+
role: "system",
|
|
195
|
+
content: `You are a friendly Telegram bot. Reply briefly and to the point.`,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
role: "user",
|
|
199
|
+
content: text,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
role: "assistant",
|
|
203
|
+
tool_call: {
|
|
204
|
+
name: "telegram.sendMessage",
|
|
205
|
+
arguments: {
|
|
206
|
+
chatId,
|
|
207
|
+
text: "{{model_output}}",
|
|
208
|
+
},
|
|
204
209
|
},
|
|
205
210
|
},
|
|
206
|
-
|
|
207
|
-
|
|
211
|
+
],
|
|
212
|
+
};
|
|
208
213
|
}
|
|
209
214
|
}
|
|
210
215
|
```
|
|
@@ -349,7 +354,11 @@ export class McpDynamic {
|
|
|
349
354
|
this.mcpDynamicService.registerTool({
|
|
350
355
|
name: "dynamic_tool",
|
|
351
356
|
title: "Dynamic tool",
|
|
352
|
-
execute: () =>
|
|
357
|
+
execute: () =>
|
|
358
|
+
Promise.resolve({
|
|
359
|
+
structuredContent: { text: "test" },
|
|
360
|
+
messages: [{ type: "text" as const, text: "test" }],
|
|
361
|
+
}),
|
|
353
362
|
guards: [ExampleGuard],
|
|
354
363
|
interceptors: [ExampleInterceptor],
|
|
355
364
|
});
|
|
@@ -357,7 +366,8 @@ export class McpDynamic {
|
|
|
357
366
|
this.mcpDynamicService.registerPrompt({
|
|
358
367
|
name: "dynamic_prompt",
|
|
359
368
|
title: "Dynamic prompt",
|
|
360
|
-
execute: () =>
|
|
369
|
+
execute: () =>
|
|
370
|
+
Promise.resolve({ messages: [{ role: "assistant", content: "test" }] }),
|
|
361
371
|
guards: [ExampleGuard],
|
|
362
372
|
interceptors: [ExampleInterceptor],
|
|
363
373
|
});
|
|
@@ -370,6 +380,11 @@ export class McpDynamic {
|
|
|
370
380
|
Promise.resolve([{ uri: uri.href, text: `ID: ${input.testId}` }]),
|
|
371
381
|
guards: [ExampleGuard],
|
|
372
382
|
interceptors: [ExampleInterceptor],
|
|
383
|
+
list: async () => {
|
|
384
|
+
return [
|
|
385
|
+
{ uri: "dynamic://test/1", name: "dynamice_1", title: "Dynamic 1" },
|
|
386
|
+
];
|
|
387
|
+
},
|
|
373
388
|
});
|
|
374
389
|
}
|
|
375
390
|
}
|
|
@@ -405,7 +420,10 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
405
420
|
|
|
406
421
|
async execute() {
|
|
407
422
|
// await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
408
|
-
return {
|
|
423
|
+
return {
|
|
424
|
+
structuredContent: { success: true },
|
|
425
|
+
messages: { type: "text", text: "Success sent" },
|
|
426
|
+
};
|
|
409
427
|
}
|
|
410
428
|
}
|
|
411
429
|
```
|
|
@@ -473,7 +491,10 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
473
491
|
|
|
474
492
|
async execute() {
|
|
475
493
|
// await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
476
|
-
return {
|
|
494
|
+
return {
|
|
495
|
+
success: true,
|
|
496
|
+
messagse: [{ type: "text", text: "Success sent" }],
|
|
497
|
+
};
|
|
477
498
|
}
|
|
478
499
|
}
|
|
479
500
|
```
|
|
@@ -521,7 +542,7 @@ class NotImplExceptionFilter implements ExceptionFilter {
|
|
|
521
542
|
catch(exception: unknown, host: ArgumentsHost) {
|
|
522
543
|
return {
|
|
523
544
|
isError: true,
|
|
524
|
-
text:
|
|
545
|
+
messages: [{ type: "text", text: "Not implemented tool" }],
|
|
525
546
|
};
|
|
526
547
|
}
|
|
527
548
|
}
|
|
@@ -531,7 +552,7 @@ class AuthExceptionFilter implements ExceptionFilter {
|
|
|
531
552
|
catch(exception: unknown, host: ArgumentsHost) {
|
|
532
553
|
return {
|
|
533
554
|
isError: true,
|
|
534
|
-
text:
|
|
555
|
+
messages: [{ type: "text", text: "No access" }],
|
|
535
556
|
};
|
|
536
557
|
}
|
|
537
558
|
}
|
|
@@ -553,25 +574,35 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
553
574
|
|
|
554
575
|
### Integration with OpenAI Function Calls
|
|
555
576
|
|
|
577
|
+
Example with `openai`: `6.25.0`
|
|
578
|
+
|
|
556
579
|
```ts
|
|
557
|
-
import axios from
|
|
558
|
-
import OpenAI from
|
|
580
|
+
import axios from "axios";
|
|
581
|
+
import OpenAI from "openai";
|
|
559
582
|
|
|
560
|
-
const MCP_TOOLS_URL =
|
|
561
|
-
const MCP_TELEGRAM_PROMPT_URL =
|
|
583
|
+
const MCP_TOOLS_URL = "http://localhost:3000/mcp/tools";
|
|
584
|
+
const MCP_TELEGRAM_PROMPT_URL =
|
|
585
|
+
"http://localhost:3000/mcp/prompts/telegram_auto_reply";
|
|
562
586
|
|
|
563
587
|
// Create OpenAI client
|
|
564
|
-
const client = new OpenAI({
|
|
588
|
+
const client = new OpenAI({
|
|
589
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
590
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
591
|
+
});
|
|
565
592
|
|
|
566
593
|
/**
|
|
567
594
|
* Get all tools
|
|
568
595
|
*/
|
|
569
596
|
async function getMcpTools() {
|
|
570
597
|
const response = await axios.get(MCP_TOOLS_URL);
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
598
|
+
|
|
599
|
+
return response.data.tools.map((el) => ({
|
|
600
|
+
type: "function",
|
|
601
|
+
function: {
|
|
602
|
+
name: el.name,
|
|
603
|
+
description: el.description,
|
|
604
|
+
parameters: el.inputSchema,
|
|
605
|
+
},
|
|
575
606
|
}));
|
|
576
607
|
}
|
|
577
608
|
|
|
@@ -579,17 +610,17 @@ async function getMcpTools() {
|
|
|
579
610
|
* Get all prompts
|
|
580
611
|
*/
|
|
581
612
|
async function getMcpPrompt() {
|
|
582
|
-
const response = await axios.post(MCP_TELEGRAM_PROMPT_URL, {
|
|
613
|
+
const response = await axios.post(MCP_TELEGRAM_PROMPT_URL, {
|
|
614
|
+
/* prompt generation arguments */
|
|
615
|
+
});
|
|
583
616
|
return response.data;
|
|
617
|
+
}
|
|
584
618
|
|
|
585
619
|
/**
|
|
586
620
|
* Request mcp tool
|
|
587
621
|
*/
|
|
588
622
|
async function callMcpTool(toolName: string, payload: Record<string, any>) {
|
|
589
|
-
const response = await axios.post(
|
|
590
|
-
MCP_TOOLS_URL,
|
|
591
|
-
{ type: toolName, payload },
|
|
592
|
-
);
|
|
623
|
+
const response = await axios.post(MCP_TOOLS_URL, { type: toolName, payload });
|
|
593
624
|
return response.data;
|
|
594
625
|
}
|
|
595
626
|
|
|
@@ -601,20 +632,20 @@ async function callMcpTool(toolName: string, payload: Record<string, any>) {
|
|
|
601
632
|
const promptResponse = await getMcpPrompt();
|
|
602
633
|
|
|
603
634
|
const completion = await client.chat.completions.create({
|
|
604
|
-
model:
|
|
635
|
+
model: "arcee-ai/trinity-large-preview:free",
|
|
605
636
|
messages: promptResponse.messages,
|
|
606
|
-
|
|
607
|
-
|
|
637
|
+
tools: toolsResponse,
|
|
638
|
+
tool_choice: "auto",
|
|
608
639
|
});
|
|
609
640
|
|
|
610
641
|
const message = completion.choices[0].message;
|
|
611
642
|
|
|
612
|
-
if (message.
|
|
613
|
-
const { name, arguments: argsJson } = message.
|
|
643
|
+
if (message.tool_calls?.length) {
|
|
644
|
+
const { name, arguments: argsJson } = message.tool_calls[0].function;
|
|
614
645
|
const args = JSON.parse(argsJson);
|
|
615
646
|
|
|
616
|
-
const
|
|
617
|
-
console.log(
|
|
647
|
+
const { messages, structuredContent } = await callMcpTool(name, args);
|
|
648
|
+
console.log("Result from MCP tool:", messages, structuredContent);
|
|
618
649
|
}
|
|
619
650
|
})();
|
|
620
651
|
```
|
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
|
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
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
|
-
import {
|
|
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
|
-
getPromptByName<Payload = any>(promptName: string, params: Payload): Promise<
|
|
11
|
-
callMcpTool<Payload = any, Result = any>(toolName: string, payload: Payload): Promise<Result
|
|
11
|
+
getPromptByName<Payload = any>(promptName: string, params: Payload): Promise<McpPromptResultDto>;
|
|
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,21 +3,22 @@ import { McpService } from "../services/mcp.service";
|
|
|
3
3
|
import { McpMessageDto } from "../dto/McpMessage.dto";
|
|
4
4
|
import { McpToolsDto } from "../dto/McpTools.dto";
|
|
5
5
|
import { McpPromptsDto } from "../dto/McpPrompts.dto";
|
|
6
|
-
import {
|
|
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
|
+
import { McpToolResultDto } from "../dto/McpToolResult.dto";
|
|
11
12
|
export declare class McpController {
|
|
12
13
|
private readonly service;
|
|
13
14
|
private readonly guard;
|
|
14
15
|
private readonly config;
|
|
15
16
|
constructor(service: McpService, guard: CanActivate, config: IMcpConfig);
|
|
16
|
-
handleTool(body: McpMessageDto, request: any, context: ExecutionContext): Promise<
|
|
17
|
+
handleTool(body: McpMessageDto, request: any, context: ExecutionContext): Promise<McpToolResultDto>;
|
|
17
18
|
getTools(context: ExecutionContext): Promise<McpToolsDto>;
|
|
18
19
|
getPrompts(context: ExecutionContext): Promise<McpPromptsDto>;
|
|
19
|
-
getPrompt(name: string, body: object, context: ExecutionContext): Promise<
|
|
20
|
+
getPrompt(name: string, body: object, context: ExecutionContext): Promise<McpPromptResultDto>;
|
|
20
21
|
getResources(context: ExecutionContext): Promise<McpResourcesDto>;
|
|
21
|
-
executeResource(name: string, body: McpResourceRequestDto, context: ExecutionContext): Promise<
|
|
22
|
+
executeResource(name: string, body: McpResourceRequestDto, context: ExecutionContext): Promise<McpResourceResultDto>;
|
|
22
23
|
private checkGuard;
|
|
23
24
|
}
|
|
@@ -19,15 +19,16 @@ const McpMessage_dto_1 = require("../dto/McpMessage.dto");
|
|
|
19
19
|
const swagger_1 = require("@nestjs/swagger");
|
|
20
20
|
const McpTools_dto_1 = require("../dto/McpTools.dto");
|
|
21
21
|
const McpPrompts_dto_1 = require("../dto/McpPrompts.dto");
|
|
22
|
-
const
|
|
22
|
+
const McpPrompResult_dto_1 = require("../dto/McpPrompResult.dto");
|
|
23
23
|
const context_decorator_1 = require("../utils/context.decorator");
|
|
24
24
|
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
|
+
const McpToolResult_dto_1 = require("../dto/McpToolResult.dto");
|
|
31
32
|
let McpController = class McpController {
|
|
32
33
|
service;
|
|
33
34
|
guard;
|
|
@@ -56,10 +57,8 @@ let McpController = class McpController {
|
|
|
56
57
|
async getPrompt(name, body, context) {
|
|
57
58
|
await this.checkGuard(context);
|
|
58
59
|
const observable = await this.service.executePrompt(name, body, context);
|
|
59
|
-
const
|
|
60
|
-
return
|
|
61
|
-
messages,
|
|
62
|
-
};
|
|
60
|
+
const result = await (0, rxjs_1.firstValueFrom)(observable);
|
|
61
|
+
return result;
|
|
63
62
|
}
|
|
64
63
|
async getResources(context) {
|
|
65
64
|
await this.checkGuard(context);
|
|
@@ -74,8 +73,8 @@ let McpController = class McpController {
|
|
|
74
73
|
? (0, uri_1.extractResourceParams)(resource.instance.uri, body.uri)
|
|
75
74
|
: {};
|
|
76
75
|
const observable = await this.service.executeResource(name, url, params, context);
|
|
77
|
-
const
|
|
78
|
-
return
|
|
76
|
+
const result = await (0, rxjs_1.firstValueFrom)(observable);
|
|
77
|
+
return result;
|
|
79
78
|
}
|
|
80
79
|
async checkGuard(context) {
|
|
81
80
|
if (!(await this.guard.canActivate(context))) {
|
|
@@ -91,6 +90,7 @@ __decorate([
|
|
|
91
90
|
summary: "Request tool",
|
|
92
91
|
}),
|
|
93
92
|
(0, swagger_1.ApiResponse)({
|
|
93
|
+
type: McpToolResult_dto_1.McpToolResultDto,
|
|
94
94
|
status: 200,
|
|
95
95
|
description: "Tool execution result",
|
|
96
96
|
}),
|
|
@@ -155,7 +155,7 @@ __decorate([
|
|
|
155
155
|
(0, swagger_1.ApiResponse)({
|
|
156
156
|
status: 200,
|
|
157
157
|
description: "Prompt messages",
|
|
158
|
-
type:
|
|
158
|
+
type: McpPrompResult_dto_1.McpPromptResultDto,
|
|
159
159
|
}),
|
|
160
160
|
(0, swagger_1.ApiNotFoundResponse)({
|
|
161
161
|
description: "Not found prompt",
|
|
@@ -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)()),
|
|
@@ -2,7 +2,11 @@ import "reflect-metadata";
|
|
|
2
2
|
import type * as z3 from "zod/v3";
|
|
3
3
|
type AnySchema = z3.ZodTypeAny;
|
|
4
4
|
type ZodRawShapeCompat = Record<string, AnySchema>;
|
|
5
|
-
export type
|
|
5
|
+
export type IMcpPromptResult = {
|
|
6
|
+
messages: IMcpPromptResultMessage[];
|
|
7
|
+
description?: string;
|
|
8
|
+
};
|
|
9
|
+
export type IMcpPromptResultMessage = {
|
|
6
10
|
role: "user" | "assistant" | "system";
|
|
7
11
|
content?: string;
|
|
8
12
|
tool_call?: {
|
|
@@ -10,12 +14,12 @@ export type IMcpPromptMessage = {
|
|
|
10
14
|
arguments: object;
|
|
11
15
|
};
|
|
12
16
|
};
|
|
13
|
-
export interface IMcpPrompt<Payload = any
|
|
17
|
+
export interface IMcpPrompt<Payload = any> {
|
|
14
18
|
name: string;
|
|
15
19
|
title?: string;
|
|
16
20
|
description?: string;
|
|
17
21
|
inputSchema?: ZodRawShapeCompat;
|
|
18
|
-
execute(input: Payload): Promise<
|
|
22
|
+
execute(input: Payload): Promise<IMcpPromptResult>;
|
|
19
23
|
}
|
|
20
24
|
export declare const MCP_PROMPT_METADATA = "mcp:prompt-class";
|
|
21
25
|
/**
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol";
|
|
2
|
-
import { 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;
|
|
@@ -16,7 +19,9 @@ export interface IMcpResource<Payload = any> {
|
|
|
16
19
|
uri: string;
|
|
17
20
|
title?: string;
|
|
18
21
|
description?: string;
|
|
19
|
-
|
|
22
|
+
annotations?: Resource["annotations"];
|
|
23
|
+
_meta?: Resource["_meta"];
|
|
24
|
+
execute(url: URL, input: Payload): Promise<IMcpResourceResult>;
|
|
20
25
|
list?(extra: RequestHandlerExtra<ServerRequest, ServerNotification>): Promise<IMcpResourceListItem[]>;
|
|
21
26
|
}
|
|
22
27
|
export declare const MCP_RESOURCE_METADATA = "mcp:resource-class";
|
|
@@ -1,13 +1,25 @@
|
|
|
1
|
+
import { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
|
|
1
2
|
import "reflect-metadata";
|
|
2
3
|
import type * as z3 from "zod/v3";
|
|
3
4
|
type AnySchema = z3.ZodTypeAny;
|
|
4
5
|
type ZodRawShapeCompat = Record<string, AnySchema>;
|
|
5
|
-
export
|
|
6
|
+
export type IMcpToolResult<Result extends Record<string, unknown>> = {
|
|
7
|
+
structuredContent?: Result;
|
|
8
|
+
messages: Array<{
|
|
9
|
+
type: "text";
|
|
10
|
+
text: string;
|
|
11
|
+
}>;
|
|
12
|
+
isError?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export interface IMcpTool<Payload = any, Result extends Record<string, unknown> = Record<string, unknown>> {
|
|
6
15
|
name: string;
|
|
7
16
|
title?: string;
|
|
8
17
|
description?: string;
|
|
9
18
|
inputSchema?: ZodRawShapeCompat;
|
|
10
|
-
|
|
19
|
+
outputSchema?: ZodRawShapeCompat;
|
|
20
|
+
annotations?: ToolAnnotations;
|
|
21
|
+
_meta?: Record<string, unknown>;
|
|
22
|
+
execute(input: Payload): Promise<IMcpToolResult<Result>>;
|
|
11
23
|
}
|
|
12
24
|
export declare const MCP_TOOL_METADATA = "mcp:tool-class";
|
|
13
25
|
/**
|