@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.
Files changed (48) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +82 -51
  3. package/dist/index.d.ts +2 -8
  4. package/dist/index.js +2 -8
  5. package/dist/mcp-client/index.d.ts +3 -0
  6. package/dist/mcp-client/index.js +19 -0
  7. package/dist/mcp-client/mcp-client.module.d.ts +2 -6
  8. package/dist/mcp-client/mcp-client.module.js +5 -3
  9. package/dist/mcp-client/mcp-client.service.d.ts +4 -3
  10. package/dist/mcp-client/utils/openai.d.ts +34 -0
  11. package/dist/mcp-client/utils/openai.js +29 -0
  12. package/dist/mcp-server/controllers/mcp.controller.d.ts +6 -5
  13. package/dist/mcp-server/controllers/mcp.controller.js +11 -10
  14. package/dist/mcp-server/controllers/mcp.sse.controller.js +1 -0
  15. package/dist/mcp-server/decorators/mcp-prompt.decorator.d.ts +7 -3
  16. package/dist/mcp-server/decorators/mcp-resource.decorator.d.ts +9 -4
  17. package/dist/mcp-server/decorators/mcp-tool.decorator.d.ts +14 -2
  18. package/dist/mcp-server/dto/IMcpResourceResult.dto.d.ts +4 -0
  19. package/dist/mcp-server/dto/IMcpResourceResult.dto.js +26 -0
  20. package/dist/mcp-server/dto/McpPrompResult.dto.d.ts +5 -0
  21. package/dist/mcp-server/dto/McpPrompResult.dto.js +31 -0
  22. package/dist/mcp-server/dto/McpPromptMessage.dto.d.ts +5 -0
  23. package/dist/mcp-server/dto/McpPromptMessage.dto.js +40 -0
  24. package/dist/mcp-server/dto/McpResourceResult.dto.d.ts +4 -0
  25. package/dist/mcp-server/dto/McpResourceResult.dto.js +26 -0
  26. package/dist/mcp-server/dto/McpResourceResultItem.dto.d.ts +4 -0
  27. package/dist/mcp-server/dto/McpResourceResultItem.dto.js +30 -0
  28. package/dist/mcp-server/dto/McpTool.dto.d.ts +1 -0
  29. package/dist/mcp-server/dto/McpTool.dto.js +10 -0
  30. package/dist/mcp-server/dto/McpToolResult.dto.d.ts +6 -0
  31. package/dist/mcp-server/dto/McpToolResult.dto.js +32 -0
  32. package/dist/mcp-server/dto/McpToolResultMessage.dto.d.ts +4 -0
  33. package/dist/mcp-server/dto/McpToolResultMessage.dto.js +26 -0
  34. package/dist/mcp-server/exceptions/index.d.ts +3 -1
  35. package/dist/mcp-server/exceptions/index.js +3 -1
  36. package/dist/mcp-server/index.d.ts +6 -0
  37. package/dist/mcp-server/index.js +22 -0
  38. package/dist/mcp-server/services/mcp-dynamic.service.d.ts +2 -2
  39. package/dist/mcp-server/services/mcp-dynamic.service.js +5 -0
  40. package/dist/mcp-server/services/mcp.service.d.ts +8 -6
  41. package/dist/mcp-server/services/mcp.service.js +9 -3
  42. package/dist/mcp-server/services/mcp.sse.service.d.ts +3 -0
  43. package/dist/mcp-server/services/mcp.sse.service.js +21 -7
  44. package/dist/mcp-server/utils/http-adapter.d.ts +1 -1
  45. package/dist/mcp-server/utils/openai.d.ts +34 -0
  46. package/dist/mcp-server/utils/openai.js +29 -0
  47. package/dist/mcp-server/utils/zod.js +4 -1
  48. package/package.json +18 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @muzikanto/nestjs-mcp
2
2
 
3
+ ## 1.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ - add exports for (client, server) and update example (add openai)
8
+
9
+ ## 1.7.0
10
+
11
+ ### Minor Changes
12
+
13
+ - fix tool result format
14
+
3
15
  ## 1.6.0
4
16
 
5
17
  ### Minor Changes
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 { success: true };
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
- "data": {
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
- role: "system",
191
- content: `You are a friendly Telegram bot. Reply briefly and to the point.`,
192
- },
193
- {
194
- role: "user",
195
- content: text,
196
- },
197
- {
198
- role: "assistant",
199
- tool_call: {
200
- name: "telegram.sendMessage",
201
- arguments: {
202
- chatId,
203
- text: "{{model_output}}",
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: () => Promise.resolve("test"),
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: () => Promise.resolve([{ role: "assistant", content: "test" }]),
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 { success: true };
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 { success: true };
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: (exception as Error).message,
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: (exception as Error).message,
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 'axios';
558
- import OpenAI from 'openai';
580
+ import axios from "axios";
581
+ import OpenAI from "openai";
559
582
 
560
- const MCP_TOOLS_URL = 'http://localhost:3000/mcp/tools';
561
- const MCP_TELEGRAM_PROMPT_URL = 'http://localhost:3000/mcp/prompts/telegram_auto_reply';
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({ apiKey: process.env.OPENAI_API_KEY });
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
- return response.data.tools.map(el => ({
572
- name: el.name,
573
- description: el.description,
574
- parameters: el.inputSchema,
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, {/* prompt generation arguments */});
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: 'gpt-4.1-mini',
635
+ model: "arcee-ai/trinity-large-preview:free",
605
636
  messages: promptResponse.messages,
606
- functions: toolsResponse.tools,
607
- function_call: 'auto',
637
+ tools: toolsResponse,
638
+ tool_choice: "auto",
608
639
  });
609
640
 
610
641
  const message = completion.choices[0].message;
611
642
 
612
- if (message.function_call) {
613
- const { name, arguments: argsJson } = message.function_call;
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 result = await callMcpTool(name, args);
617
- console.log('Result from MCP tool:', result);
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-server/mcp.module";
2
- export * from "./mcp-server/decorators/mcp-tool.decorator";
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-server/mcp.module"), exports);
18
- __exportStar(require("./mcp-server/decorators/mcp-tool.decorator"), exports);
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,3 @@
1
+ export * from "./mcp-client.module";
2
+ export * from "./mcp-client.service";
3
+ export * from "./utils/openai";
@@ -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 { Provider, Type } from "@nestjs/common";
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
- implements: [
27
+ imports: [
28
28
  axios_1.HttpModule.registerAsync({
29
- inject: [inject_tokens_1.MCP_CLIENT_CONFIG],
30
29
  useFactory: (config) => {
31
- return { baseUrl: config.url };
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 { McpPromptMessagesDto } from "../mcp-server/dto/McpPromptMessages.dto";
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<McpPromptMessagesDto>;
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 { McpPromptMessagesDto } from "../dto/McpPromptMessages.dto";
6
+ import { McpPromptResultDto } from "../dto/McpPrompResult.dto";
7
7
  import { IMcpConfig } from "../config";
8
8
  import { McpResourcesDto } from "../dto/McpResources.dto";
9
- import { McpResourceItemsDto } from "../dto/McpResourceItems.dto";
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<any>;
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<McpPromptMessagesDto>;
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<McpResourceItemsDto>;
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 McpPromptMessages_dto_1 = require("../dto/McpPromptMessages.dto");
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 McpResourceItems_dto_1 = require("../dto/McpResourceItems.dto");
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 messages = await (0, rxjs_1.firstValueFrom)(observable);
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 contents = await (0, rxjs_1.firstValueFrom)(observable);
78
- return { contents };
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: McpPromptMessages_dto_1.McpPromptMessagesDto,
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: McpResourceItems_dto_1.McpResourceItemsDto,
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 IMcpPromptMessage = {
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, Result extends IMcpPromptMessage[] = IMcpPromptMessage[]> {
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<Result>;
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 IMcpResourceResult = {
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
- execute(url: URL, input: Payload): Promise<IMcpResourceResult[]>;
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 interface IMcpTool<Payload = any, Result = any> {
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
- execute(input: Payload): Promise<Result>;
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
  /**
@@ -0,0 +1,4 @@
1
+ import { McpResourceItemDto } from "./McpResourceItem.dto";
2
+ export declare class McpResourceItemsDto {
3
+ contents: McpResourceItemDto[];
4
+ }