@muzikanto/nestjs-mcp 1.5.1 → 1.7.0
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 +182 -96
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp-client/mcp-client.service.d.ts +2 -2
- package/dist/mcp-server/config.d.ts +2 -0
- package/dist/mcp-server/controllers/mcp.controller.d.ts +24 -0
- package/dist/mcp-server/controllers/mcp.controller.js +226 -0
- package/dist/mcp-server/controllers/mcp.sse.controller.d.ts +12 -0
- package/dist/mcp-server/controllers/mcp.sse.controller.js +79 -0
- package/dist/mcp-server/decorators/mcp-prompt.decorator.d.ts +7 -3
- package/dist/mcp-server/decorators/mcp-resource.decorator.d.ts +3 -1
- package/dist/mcp-server/decorators/mcp-tool.decorator.d.ts +14 -2
- package/dist/mcp-server/dto/McpMessage.dto.d.ts +1 -1
- 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/McpResource.dto.d.ts +6 -0
- package/dist/mcp-server/dto/McpResource.dto.js +44 -0
- package/dist/mcp-server/dto/McpResourceItem.dto.d.ts +4 -0
- package/dist/mcp-server/dto/McpResourceItem.dto.js +30 -0
- package/dist/mcp-server/dto/McpResourceItems.dto.d.ts +4 -0
- package/dist/mcp-server/dto/McpResourceItems.dto.js +26 -0
- package/dist/mcp-server/dto/McpResourceRequest.dto.d.ts +3 -0
- package/dist/mcp-server/dto/McpResourceRequest.dto.js +21 -0
- package/dist/mcp-server/dto/McpResources.dto.d.ts +4 -0
- package/dist/mcp-server/dto/McpResources.dto.js +26 -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/mcp.controller.d.ts +0 -2
- package/dist/mcp-server/mcp.controller.js +0 -36
- package/dist/mcp-server/mcp.explorer.d.ts +1 -1
- package/dist/mcp-server/mcp.explorer.js +1 -1
- package/dist/mcp-server/mcp.module.js +9 -4
- package/dist/mcp-server/mcp.service.d.ts +15 -9
- package/dist/mcp-server/mcp.service.js +9 -114
- package/dist/mcp-server/mcp.sse.controller.d.ts +12 -0
- package/dist/mcp-server/mcp.sse.controller.js +79 -0
- package/dist/mcp-server/mcp.sse.service.d.ts +25 -0
- package/dist/mcp-server/mcp.sse.service.js +153 -0
- package/dist/mcp-server/services/mcp-dynamic.service.d.ts +31 -0
- package/dist/mcp-server/services/mcp-dynamic.service.js +105 -0
- package/dist/mcp-server/services/mcp.service.d.ts +78 -0
- package/dist/mcp-server/services/mcp.service.js +172 -0
- package/dist/mcp-server/services/mcp.sse.service.d.ts +28 -0
- package/dist/mcp-server/services/mcp.sse.service.js +170 -0
- package/dist/mcp-server/utils/uri.d.ts +3 -0
- package/dist/mcp-server/utils/uri.js +19 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -21,8 +21,10 @@ NestJS MCP (Model Context Protocol) module — allows you to create “tools”,
|
|
|
21
21
|
- [Dynamic creation](#dynamic-creation)
|
|
22
22
|
- [Calling MCP tools via HTTP](#calling-mcp-tools-via-http)
|
|
23
23
|
- [Calling MCP prompt via HTTP](#obtain-prompt)
|
|
24
|
+
- [Calling MCP resource via HTTP](#obtain-resource)
|
|
24
25
|
- [Obtaining all tools](#obtaining-all-tools)
|
|
25
26
|
- [Obtaining all prompts](#obtaining-all-prompts)
|
|
27
|
+
- [Obtaining all resources](#obtaining-all-resources)
|
|
26
28
|
- [Guards](#guards)
|
|
27
29
|
- [For one](#for-one)
|
|
28
30
|
- [For all](#for-all)
|
|
@@ -39,9 +41,9 @@ NestJS MCP (Model Context Protocol) module — allows you to create “tools”,
|
|
|
39
41
|
- Automatic detection of all providers (tools) in the module
|
|
40
42
|
- Input data validation
|
|
41
43
|
- SSE endpoints for MCP (`GET /mcp/sse, POST /mcp/messages`)
|
|
42
|
-
- Endpoint for calling tool (`POST /mcp/
|
|
44
|
+
- Endpoint for calling a tool (`POST /mcp/tools`)
|
|
43
45
|
- Endpoint for a list of all tools (`GET /mcp/tools`)
|
|
44
|
-
- Endpoint for calling prompt (`POST /mcp/prompts/:name`)
|
|
46
|
+
- Endpoint for calling a prompt (`POST /mcp/prompts/:name`)
|
|
45
47
|
- Endpoint for a list of all prompts (`GET /mcp/prompts`)
|
|
46
48
|
- Easy integration with LLM (OpenAI Function Calls)
|
|
47
49
|
- Support http adapters (default fastify)
|
|
@@ -56,7 +58,7 @@ NestJS MCP (Model Context Protocol) module — allows you to create “tools”,
|
|
|
56
58
|
yarn add @muzikanto/nestjs-mcp
|
|
57
59
|
```
|
|
58
60
|
|
|
59
|
-
Peer dependencies: `@nestjs/common, @nestjs/core, @nestjs/swagger, reflect-metadata`
|
|
61
|
+
Peer dependencies: `@nestjs/common, @nestjs/core, @nestjs/swagger, @nestjs/axios, reflect-metadata`
|
|
60
62
|
|
|
61
63
|
## Usage
|
|
62
64
|
|
|
@@ -83,10 +85,10 @@ export class AppModule {}
|
|
|
83
85
|
```ts
|
|
84
86
|
import { IMcpTool, McpTool } from "@muzikanto/nestjs-mcp";
|
|
85
87
|
import { Telegraf } from "telegraf";
|
|
86
|
-
import z from "zod";
|
|
88
|
+
import z from "zod/v3";
|
|
87
89
|
|
|
88
90
|
const schema = {
|
|
89
|
-
chatId: z.
|
|
91
|
+
chatId: z.number().describe("Telegram chat id"), // строка с описанием
|
|
90
92
|
text: z.string().describe("Message text"), // строка с описанием
|
|
91
93
|
};
|
|
92
94
|
|
|
@@ -96,21 +98,23 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
96
98
|
{ success: boolean }
|
|
97
99
|
> {
|
|
98
100
|
name = "telegram.sendMessage";
|
|
99
|
-
|
|
100
101
|
inputSchema = schema;
|
|
101
102
|
|
|
102
103
|
constructor(private readonly bot: Telegraf) {}
|
|
103
104
|
|
|
104
105
|
async execute(input: { chatId: string; text: string }) {
|
|
105
106
|
await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
106
|
-
return {
|
|
107
|
+
return {
|
|
108
|
+
structuredContent: { success: true },
|
|
109
|
+
messages: [{ type: "text", text: "Success sent to user" }],
|
|
110
|
+
};
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
113
|
```
|
|
110
114
|
|
|
111
115
|
### Calling MCP tools via HTTP
|
|
112
116
|
|
|
113
|
-
POST /mcp
|
|
117
|
+
POST /mcp/tools
|
|
114
118
|
|
|
115
119
|
```json
|
|
116
120
|
{
|
|
@@ -126,47 +130,50 @@ POST /mcp
|
|
|
126
130
|
|
|
127
131
|
```json
|
|
128
132
|
{
|
|
129
|
-
"
|
|
133
|
+
"structuredContent": {
|
|
130
134
|
"success": true
|
|
131
|
-
}
|
|
135
|
+
},
|
|
136
|
+
"messages": [{ "type": "text", "text": "Success sent to user" }]"
|
|
132
137
|
}
|
|
133
138
|
```
|
|
134
139
|
|
|
135
140
|
### Obtaining all tools
|
|
136
141
|
|
|
137
|
-
GET /mcp/
|
|
142
|
+
GET /mcp/tools
|
|
138
143
|
|
|
139
144
|
```json
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
"
|
|
146
|
-
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
|
|
145
|
+
{
|
|
146
|
+
"tools": [
|
|
147
|
+
{
|
|
148
|
+
"name": "telegram.sendMessage",
|
|
149
|
+
"description": "Sent message via Telegram",
|
|
150
|
+
"inputSchema": {
|
|
151
|
+
"type": "object",
|
|
152
|
+
"properties": {
|
|
153
|
+
"chatId": {
|
|
154
|
+
"type": "number",
|
|
155
|
+
"description": "Telegram chat ID"
|
|
156
|
+
},
|
|
157
|
+
"text": {
|
|
158
|
+
"type": "string",
|
|
159
|
+
"description": "Message text"
|
|
160
|
+
}
|
|
150
161
|
},
|
|
151
|
-
"
|
|
152
|
-
|
|
153
|
-
"description": "Message text"
|
|
154
|
-
}
|
|
155
|
-
},
|
|
156
|
-
"required": ["chatId", "text"]
|
|
162
|
+
"required": ["chatId", "text"]
|
|
163
|
+
}
|
|
157
164
|
}
|
|
158
|
-
|
|
159
|
-
|
|
165
|
+
]
|
|
166
|
+
}
|
|
160
167
|
```
|
|
161
168
|
|
|
162
169
|
### Create MCP prompt
|
|
163
170
|
|
|
164
171
|
```ts
|
|
165
172
|
import { IMcpPrompt, McpPrompt } from "@muzikanto/nestjs-mcp";
|
|
166
|
-
import z from "zod";
|
|
173
|
+
import z from "zod/v3";
|
|
167
174
|
|
|
168
175
|
const schema = {
|
|
169
|
-
chatId: z.
|
|
176
|
+
chatId: z.number().describe("Telegram chat id"), // строка с описанием
|
|
170
177
|
text: z.string().describe("Message text"), // строка с описанием
|
|
171
178
|
};
|
|
172
179
|
|
|
@@ -177,30 +184,32 @@ export class TelegramAutoReplyPrompt implements IMcpPrompt<{
|
|
|
177
184
|
}> {
|
|
178
185
|
name = "telegram_auto_reply";
|
|
179
186
|
description =
|
|
180
|
-
"Generate a short,
|
|
187
|
+
"Generate a short, friendly reply to an incoming Telegram message and send it back to the same chat using telegram.sendMessage tool";
|
|
181
188
|
schema = schema;
|
|
182
189
|
|
|
183
190
|
async execute({ text, chatId }: { text: string; chatId: number }) {
|
|
184
|
-
return
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
+
},
|
|
200
209
|
},
|
|
201
210
|
},
|
|
202
|
-
|
|
203
|
-
|
|
211
|
+
],
|
|
212
|
+
};
|
|
204
213
|
}
|
|
205
214
|
}
|
|
206
215
|
```
|
|
@@ -210,26 +219,28 @@ export class TelegramAutoReplyPrompt implements IMcpPrompt<{
|
|
|
210
219
|
GET /mcp/prompts
|
|
211
220
|
|
|
212
221
|
```json
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
"
|
|
219
|
-
|
|
220
|
-
"
|
|
221
|
-
"
|
|
222
|
-
|
|
222
|
+
{
|
|
223
|
+
"prompts": [
|
|
224
|
+
{
|
|
225
|
+
"name": "telegram_auto_reply",
|
|
226
|
+
"description": "Generate a short, friendly reply to an incoming Telegram message and send it back to the same chat using telegram.sendMessage tool",
|
|
227
|
+
"inputSchema": {
|
|
228
|
+
"type": "object",
|
|
229
|
+
"properties": {
|
|
230
|
+
"chatId": {
|
|
231
|
+
"type": "number",
|
|
232
|
+
"description": "Telegram chat ID"
|
|
233
|
+
},
|
|
234
|
+
"text": {
|
|
235
|
+
"type": "string",
|
|
236
|
+
"description": "Message text"
|
|
237
|
+
}
|
|
223
238
|
},
|
|
224
|
-
"
|
|
225
|
-
|
|
226
|
-
"description": "Message text"
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
"required": ["chatId", "text"]
|
|
239
|
+
"required": ["chatId", "text"]
|
|
240
|
+
}
|
|
230
241
|
}
|
|
231
|
-
|
|
232
|
-
|
|
242
|
+
]
|
|
243
|
+
}
|
|
233
244
|
```
|
|
234
245
|
|
|
235
246
|
### Calling MCP prompt via HTTP
|
|
@@ -282,12 +293,51 @@ export class TestResource implements IMcpResource<{ userId: string }> {
|
|
|
282
293
|
title = "Get test user";
|
|
283
294
|
description = "Get user by id";
|
|
284
295
|
|
|
285
|
-
async execute(
|
|
286
|
-
return [{ uri
|
|
296
|
+
async execute(uri: string, vars: { userId: string }) {
|
|
297
|
+
return [{ uri, text: `Hello ${vars.userId}` }];
|
|
287
298
|
}
|
|
288
299
|
}
|
|
289
300
|
```
|
|
290
301
|
|
|
302
|
+
### Calling MCP resource via HTTP
|
|
303
|
+
|
|
304
|
+
POST /mcp/resources/users.get
|
|
305
|
+
|
|
306
|
+
```json
|
|
307
|
+
{
|
|
308
|
+
"uri": "users://user/1"
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Response
|
|
313
|
+
|
|
314
|
+
```json
|
|
315
|
+
{
|
|
316
|
+
"contents": [
|
|
317
|
+
{
|
|
318
|
+
"uri": "users://user/1",
|
|
319
|
+
"content": "Hello 1"
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Obtaining all resources
|
|
326
|
+
|
|
327
|
+
GET /mcp/resources
|
|
328
|
+
|
|
329
|
+
```json
|
|
330
|
+
{
|
|
331
|
+
"resources": [
|
|
332
|
+
{
|
|
333
|
+
"name": "users.get",
|
|
334
|
+
"title": "Get user by id",
|
|
335
|
+
"uri": "users://user/{userId}"
|
|
336
|
+
}
|
|
337
|
+
]
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
291
341
|
### Dynamic creation
|
|
292
342
|
|
|
293
343
|
```ts
|
|
@@ -304,7 +354,11 @@ export class McpDynamic {
|
|
|
304
354
|
this.mcpDynamicService.registerTool({
|
|
305
355
|
name: "dynamic_tool",
|
|
306
356
|
title: "Dynamic tool",
|
|
307
|
-
execute: () =>
|
|
357
|
+
execute: () =>
|
|
358
|
+
Promise.resolve({
|
|
359
|
+
structuredContent: { text: "test" },
|
|
360
|
+
messages: [{ type: "text" as const, text: "test" }],
|
|
361
|
+
}),
|
|
308
362
|
guards: [ExampleGuard],
|
|
309
363
|
interceptors: [ExampleInterceptor],
|
|
310
364
|
});
|
|
@@ -312,7 +366,8 @@ export class McpDynamic {
|
|
|
312
366
|
this.mcpDynamicService.registerPrompt({
|
|
313
367
|
name: "dynamic_prompt",
|
|
314
368
|
title: "Dynamic prompt",
|
|
315
|
-
execute: () =>
|
|
369
|
+
execute: () =>
|
|
370
|
+
Promise.resolve({ messages: [{ role: "assistant", content: "test" }] }),
|
|
316
371
|
guards: [ExampleGuard],
|
|
317
372
|
interceptors: [ExampleInterceptor],
|
|
318
373
|
});
|
|
@@ -325,6 +380,11 @@ export class McpDynamic {
|
|
|
325
380
|
Promise.resolve([{ uri: uri.href, text: `ID: ${input.testId}` }]),
|
|
326
381
|
guards: [ExampleGuard],
|
|
327
382
|
interceptors: [ExampleInterceptor],
|
|
383
|
+
list: async () => {
|
|
384
|
+
return [
|
|
385
|
+
{ uri: "dynamic://test/1", name: "dynamice_1", title: "Dynamic 1" },
|
|
386
|
+
];
|
|
387
|
+
},
|
|
328
388
|
});
|
|
329
389
|
}
|
|
330
390
|
}
|
|
@@ -350,7 +410,7 @@ class TestGuard implements CanActivate {
|
|
|
350
410
|
}
|
|
351
411
|
}
|
|
352
412
|
|
|
353
|
-
@
|
|
413
|
+
@UseGuards(TestGuard)
|
|
354
414
|
@McpTool()
|
|
355
415
|
export class TelegramSendMessageTool implements IMcpTool<
|
|
356
416
|
{ chatId: string; text: string },
|
|
@@ -359,8 +419,11 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
359
419
|
name = "telegram.sendMessage";
|
|
360
420
|
|
|
361
421
|
async execute() {
|
|
362
|
-
await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
363
|
-
return {
|
|
422
|
+
// await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
423
|
+
return {
|
|
424
|
+
structuredContent: { success: true },
|
|
425
|
+
messages: { type: "text", text: "Success sent" },
|
|
426
|
+
};
|
|
364
427
|
}
|
|
365
428
|
}
|
|
366
429
|
```
|
|
@@ -418,7 +481,7 @@ export class ExampleInterceptor implements NestInterceptor {
|
|
|
418
481
|
}
|
|
419
482
|
}
|
|
420
483
|
|
|
421
|
-
@UseInterceptors(
|
|
484
|
+
@UseInterceptors(ExampleInterceptor)
|
|
422
485
|
@McpTool()
|
|
423
486
|
export class TelegramSendMessageTool implements IMcpTool<
|
|
424
487
|
{ chatId: string; text: string },
|
|
@@ -427,8 +490,11 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
427
490
|
name = "telegram.sendMessage";
|
|
428
491
|
|
|
429
492
|
async execute() {
|
|
430
|
-
await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
431
|
-
return {
|
|
493
|
+
// await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
494
|
+
return {
|
|
495
|
+
success: true,
|
|
496
|
+
messagse: [{ type: "text", text: "Success sent" }],
|
|
497
|
+
};
|
|
432
498
|
}
|
|
433
499
|
}
|
|
434
500
|
```
|
|
@@ -447,7 +513,7 @@ import { APP_INTERCEPTOR } from "@nestjs/core";
|
|
|
447
513
|
McpModule.forRoot({
|
|
448
514
|
providers: [
|
|
449
515
|
ToolWithoutInterceptors,
|
|
450
|
-
|
|
516
|
+
TestInterceptor,
|
|
451
517
|
{ provide: APP_INTERCEPTOR, useExisting: TestInterceptor },
|
|
452
518
|
],
|
|
453
519
|
}),
|
|
@@ -459,7 +525,11 @@ export class TestModule {}
|
|
|
459
525
|
### Filters
|
|
460
526
|
|
|
461
527
|
```ts
|
|
462
|
-
import {
|
|
528
|
+
import {
|
|
529
|
+
IMcpTool,
|
|
530
|
+
McpTool,
|
|
531
|
+
McpUnauthorizedException,
|
|
532
|
+
} from "@muzikanto/nestjs-mcp";
|
|
463
533
|
import {
|
|
464
534
|
ExceptionFilter,
|
|
465
535
|
Catch,
|
|
@@ -467,8 +537,18 @@ import {
|
|
|
467
537
|
UseFilters,
|
|
468
538
|
} from "@nestjs/common";
|
|
469
539
|
|
|
540
|
+
@Catch(NotImplementedException)
|
|
541
|
+
class NotImplExceptionFilter implements ExceptionFilter {
|
|
542
|
+
catch(exception: unknown, host: ArgumentsHost) {
|
|
543
|
+
return {
|
|
544
|
+
isError: true,
|
|
545
|
+
text: (exception as Error).message,
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
470
550
|
@Catch(McpUnauthorizedException)
|
|
471
|
-
class
|
|
551
|
+
class AuthExceptionFilter implements ExceptionFilter {
|
|
472
552
|
catch(exception: unknown, host: ArgumentsHost) {
|
|
473
553
|
return {
|
|
474
554
|
isError: true,
|
|
@@ -477,7 +557,8 @@ class ExampleFilter implements ExceptionFilter {
|
|
|
477
557
|
}
|
|
478
558
|
}
|
|
479
559
|
|
|
480
|
-
@
|
|
560
|
+
@UseGuards(AuthGuard)
|
|
561
|
+
@UseFilters(AuthExceptionFilter, NotImplExceptionFilter)
|
|
481
562
|
@McpTool()
|
|
482
563
|
export class TelegramSendMessageTool implements IMcpTool<
|
|
483
564
|
{ chatId: string; text: string },
|
|
@@ -494,11 +575,12 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
494
575
|
### Integration with OpenAI Function Calls
|
|
495
576
|
|
|
496
577
|
```ts
|
|
497
|
-
import axios from
|
|
498
|
-
import OpenAI from
|
|
578
|
+
import axios from "axios";
|
|
579
|
+
import OpenAI from "openai";
|
|
499
580
|
|
|
500
|
-
const MCP_TOOLS_URL =
|
|
501
|
-
const MCP_TELEGRAM_PROMPT_URL =
|
|
581
|
+
const MCP_TOOLS_URL = "http://localhost:3000/mcp/tools";
|
|
582
|
+
const MCP_TELEGRAM_PROMPT_URL =
|
|
583
|
+
"http://localhost:3000/mcp/prompts/telegram_auto_reply";
|
|
502
584
|
|
|
503
585
|
// Create OpenAI client
|
|
504
586
|
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
@@ -508,24 +590,28 @@ const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
|
508
590
|
*/
|
|
509
591
|
async function getMcpTools() {
|
|
510
592
|
const response = await axios.get(MCP_TOOLS_URL);
|
|
511
|
-
return response.data.tools.map(el => ({
|
|
593
|
+
return response.data.tools.map((el) => ({
|
|
594
|
+
name: el.name,
|
|
595
|
+
description: el.description,
|
|
596
|
+
parameters: el.inputSchema,
|
|
597
|
+
}));
|
|
512
598
|
}
|
|
513
599
|
|
|
514
600
|
/**
|
|
515
601
|
* Get all prompts
|
|
516
602
|
*/
|
|
517
603
|
async function getMcpPrompt() {
|
|
518
|
-
const response = await axios.post(MCP_TELEGRAM_PROMPT_URL, {
|
|
604
|
+
const response = await axios.post(MCP_TELEGRAM_PROMPT_URL, {
|
|
605
|
+
/* prompt generation arguments */
|
|
606
|
+
});
|
|
519
607
|
return response.data;
|
|
608
|
+
}
|
|
520
609
|
|
|
521
610
|
/**
|
|
522
611
|
* Request mcp tool
|
|
523
612
|
*/
|
|
524
613
|
async function callMcpTool(toolName: string, payload: Record<string, any>) {
|
|
525
|
-
const response = await axios.post(
|
|
526
|
-
MCP_TOOLS_URL,
|
|
527
|
-
{ type: toolName, payload },
|
|
528
|
-
);
|
|
614
|
+
const response = await axios.post(MCP_TOOLS_URL, { type: toolName, payload });
|
|
529
615
|
return response.data;
|
|
530
616
|
}
|
|
531
617
|
|
|
@@ -537,10 +623,10 @@ async function callMcpTool(toolName: string, payload: Record<string, any>) {
|
|
|
537
623
|
const promptResponse = await getMcpPrompt();
|
|
538
624
|
|
|
539
625
|
const completion = await client.chat.completions.create({
|
|
540
|
-
model:
|
|
626
|
+
model: "gpt-4.1-mini",
|
|
541
627
|
messages: promptResponse.messages,
|
|
542
628
|
functions: toolsResponse.tools,
|
|
543
|
-
function_call:
|
|
629
|
+
function_call: "auto",
|
|
544
630
|
});
|
|
545
631
|
|
|
546
632
|
const message = completion.choices[0].message;
|
|
@@ -549,8 +635,8 @@ async function callMcpTool(toolName: string, payload: Record<string, any>) {
|
|
|
549
635
|
const { name, arguments: argsJson } = message.function_call;
|
|
550
636
|
const args = JSON.parse(argsJson);
|
|
551
637
|
|
|
552
|
-
const
|
|
553
|
-
console.log(
|
|
638
|
+
const { messages, structuredContent } = await callMcpTool(name, args);
|
|
639
|
+
console.log("Result from MCP tool:", messages, structuredContent);
|
|
554
640
|
}
|
|
555
641
|
})();
|
|
556
642
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ export * from "./mcp-server/decorators/mcp-prompt.decorator";
|
|
|
4
4
|
export * from "./mcp-server/decorators/mcp-resource.decorator";
|
|
5
5
|
export * from "./mcp-client/mcp-client.module";
|
|
6
6
|
export * from "./mcp-client/mcp-client.service";
|
|
7
|
-
export * from "./mcp-server/mcp-dynamic.service";
|
|
7
|
+
export * from "./mcp-server/services/mcp-dynamic.service";
|
|
8
8
|
export * from "./mcp-server/exceptions";
|
package/dist/index.js
CHANGED
|
@@ -20,5 +20,5 @@ __exportStar(require("./mcp-server/decorators/mcp-prompt.decorator"), exports);
|
|
|
20
20
|
__exportStar(require("./mcp-server/decorators/mcp-resource.decorator"), exports);
|
|
21
21
|
__exportStar(require("./mcp-client/mcp-client.module"), exports);
|
|
22
22
|
__exportStar(require("./mcp-client/mcp-client.service"), exports);
|
|
23
|
-
__exportStar(require("./mcp-server/mcp-dynamic.service"), exports);
|
|
23
|
+
__exportStar(require("./mcp-server/services/mcp-dynamic.service"), exports);
|
|
24
24
|
__exportStar(require("./mcp-server/exceptions"), exports);
|
|
@@ -1,12 +1,12 @@
|
|
|
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
5
|
export declare class McpClientService {
|
|
6
6
|
private readonly httpService;
|
|
7
7
|
constructor(httpService: HttpService);
|
|
8
8
|
getAllTools(): Promise<McpToolsDto>;
|
|
9
9
|
getAllPrompts(): Promise<McpPromptsDto>;
|
|
10
|
-
getPromptByName<Payload = any>(promptName: string, params: Payload): Promise<
|
|
10
|
+
getPromptByName<Payload = any>(promptName: string, params: Payload): Promise<McpPromptResultDto>;
|
|
11
11
|
callMcpTool<Payload = any, Result = any>(toolName: string, payload: Payload): Promise<Result>;
|
|
12
12
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { IHttpAdapter } from "./utils/http-adapter";
|
|
2
2
|
export declare const MCP_CONFIG_TOKEN = "mcl:config-token";
|
|
3
3
|
export type IMcpConfig = {
|
|
4
|
+
name?: string;
|
|
5
|
+
version?: string;
|
|
4
6
|
httpAdapter: IHttpAdapter;
|
|
5
7
|
};
|
|
6
8
|
export declare const InjectMcpConfig: () => PropertyDecorator & ParameterDecorator;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ExecutionContext, CanActivate } from "@nestjs/common";
|
|
2
|
+
import { McpService } from "../services/mcp.service";
|
|
3
|
+
import { McpMessageDto } from "../dto/McpMessage.dto";
|
|
4
|
+
import { McpToolsDto } from "../dto/McpTools.dto";
|
|
5
|
+
import { McpPromptsDto } from "../dto/McpPrompts.dto";
|
|
6
|
+
import { McpPromptResultDto } from "../dto/McpPrompResult.dto";
|
|
7
|
+
import { IMcpConfig } from "../config";
|
|
8
|
+
import { McpResourcesDto } from "../dto/McpResources.dto";
|
|
9
|
+
import { McpResourceItemsDto } from "../dto/McpResourceItems.dto";
|
|
10
|
+
import { McpResourceRequestDto } from "../dto/McpResourceRequest.dto";
|
|
11
|
+
import { McpToolResultDto } from "../dto/McpToolResult.dto";
|
|
12
|
+
export declare class McpController {
|
|
13
|
+
private readonly service;
|
|
14
|
+
private readonly guard;
|
|
15
|
+
private readonly config;
|
|
16
|
+
constructor(service: McpService, guard: CanActivate, config: IMcpConfig);
|
|
17
|
+
handleTool(body: McpMessageDto, request: any, context: ExecutionContext): Promise<McpToolResultDto>;
|
|
18
|
+
getTools(context: ExecutionContext): Promise<McpToolsDto>;
|
|
19
|
+
getPrompts(context: ExecutionContext): Promise<McpPromptsDto>;
|
|
20
|
+
getPrompt(name: string, body: object, context: ExecutionContext): Promise<McpPromptResultDto>;
|
|
21
|
+
getResources(context: ExecutionContext): Promise<McpResourcesDto>;
|
|
22
|
+
executeResource(name: string, body: McpResourceRequestDto, context: ExecutionContext): Promise<McpResourceItemsDto>;
|
|
23
|
+
private checkGuard;
|
|
24
|
+
}
|