@muzikanto/nestjs-mcp 1.5.0 → 1.6.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 +123 -59
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/mcp-server/config.d.ts +2 -0
- package/dist/mcp-server/controllers/mcp.controller.d.ts +23 -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/dto/McpMessage.dto.d.ts +1 -1
- 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/exceptions/index.d.ts +31 -0
- package/dist/mcp-server/exceptions/index.js +40 -0
- 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 +57 -144
- 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 +100 -0
- package/dist/mcp-server/services/mcp.service.d.ts +76 -0
- package/dist/mcp-server/services/mcp.service.js +169 -0
- package/dist/mcp-server/services/mcp.sse.service.d.ts +25 -0
- package/dist/mcp-server/services/mcp.sse.service.js +156 -0
- package/dist/mcp-server/utils/run-guards.js +2 -2
- 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
|
|
|
@@ -86,7 +88,7 @@ import { Telegraf } from "telegraf";
|
|
|
86
88
|
import z from "zod";
|
|
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
|
|
|
@@ -110,7 +112,7 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
110
112
|
|
|
111
113
|
### Calling MCP tools via HTTP
|
|
112
114
|
|
|
113
|
-
POST /mcp
|
|
115
|
+
POST /mcp/tools
|
|
114
116
|
|
|
115
117
|
```json
|
|
116
118
|
{
|
|
@@ -134,29 +136,31 @@ POST /mcp
|
|
|
134
136
|
|
|
135
137
|
### Obtaining all tools
|
|
136
138
|
|
|
137
|
-
GET /mcp/
|
|
139
|
+
GET /mcp/tools
|
|
138
140
|
|
|
139
141
|
```json
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
"
|
|
146
|
-
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
|
|
142
|
+
{
|
|
143
|
+
"tools": [
|
|
144
|
+
{
|
|
145
|
+
"name": "telegram.sendMessage",
|
|
146
|
+
"description": "Sent message via Telegram",
|
|
147
|
+
"inputSchema": {
|
|
148
|
+
"type": "object",
|
|
149
|
+
"properties": {
|
|
150
|
+
"chatId": {
|
|
151
|
+
"type": "number",
|
|
152
|
+
"description": "Telegram chat ID"
|
|
153
|
+
},
|
|
154
|
+
"text": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"description": "Message text"
|
|
157
|
+
}
|
|
150
158
|
},
|
|
151
|
-
"
|
|
152
|
-
|
|
153
|
-
"description": "Message text"
|
|
154
|
-
}
|
|
155
|
-
},
|
|
156
|
-
"required": ["chatId", "text"]
|
|
159
|
+
"required": ["chatId", "text"]
|
|
160
|
+
}
|
|
157
161
|
}
|
|
158
|
-
|
|
159
|
-
|
|
162
|
+
]
|
|
163
|
+
}
|
|
160
164
|
```
|
|
161
165
|
|
|
162
166
|
### Create MCP prompt
|
|
@@ -166,7 +170,7 @@ import { IMcpPrompt, McpPrompt } from "@muzikanto/nestjs-mcp";
|
|
|
166
170
|
import z from "zod";
|
|
167
171
|
|
|
168
172
|
const schema = {
|
|
169
|
-
chatId: z.
|
|
173
|
+
chatId: z.number().describe("Telegram chat id"), // строка с описанием
|
|
170
174
|
text: z.string().describe("Message text"), // строка с описанием
|
|
171
175
|
};
|
|
172
176
|
|
|
@@ -177,7 +181,7 @@ export class TelegramAutoReplyPrompt implements IMcpPrompt<{
|
|
|
177
181
|
}> {
|
|
178
182
|
name = "telegram_auto_reply";
|
|
179
183
|
description =
|
|
180
|
-
"Generate a short,
|
|
184
|
+
"Generate a short, friendly reply to an incoming Telegram message and send it back to the same chat using telegram.sendMessage tool";
|
|
181
185
|
schema = schema;
|
|
182
186
|
|
|
183
187
|
async execute({ text, chatId }: { text: string; chatId: number }) {
|
|
@@ -210,26 +214,28 @@ export class TelegramAutoReplyPrompt implements IMcpPrompt<{
|
|
|
210
214
|
GET /mcp/prompts
|
|
211
215
|
|
|
212
216
|
```json
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
"
|
|
219
|
-
|
|
220
|
-
"
|
|
221
|
-
"
|
|
222
|
-
|
|
217
|
+
{
|
|
218
|
+
"prompts": [
|
|
219
|
+
{
|
|
220
|
+
"name": "telegram_auto_reply",
|
|
221
|
+
"description": "Generate a short, friendly reply to an incoming Telegram message and send it back to the same chat using telegram.sendMessage tool",
|
|
222
|
+
"inputSchema": {
|
|
223
|
+
"type": "object",
|
|
224
|
+
"properties": {
|
|
225
|
+
"chatId": {
|
|
226
|
+
"type": "number",
|
|
227
|
+
"description": "Telegram chat ID"
|
|
228
|
+
},
|
|
229
|
+
"text": {
|
|
230
|
+
"type": "string",
|
|
231
|
+
"description": "Message text"
|
|
232
|
+
}
|
|
223
233
|
},
|
|
224
|
-
"
|
|
225
|
-
|
|
226
|
-
"description": "Message text"
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
"required": ["chatId", "text"]
|
|
234
|
+
"required": ["chatId", "text"]
|
|
235
|
+
}
|
|
230
236
|
}
|
|
231
|
-
|
|
232
|
-
|
|
237
|
+
]
|
|
238
|
+
}
|
|
233
239
|
```
|
|
234
240
|
|
|
235
241
|
### Calling MCP prompt via HTTP
|
|
@@ -282,12 +288,51 @@ export class TestResource implements IMcpResource<{ userId: string }> {
|
|
|
282
288
|
title = "Get test user";
|
|
283
289
|
description = "Get user by id";
|
|
284
290
|
|
|
285
|
-
async execute(
|
|
286
|
-
return [{ uri
|
|
291
|
+
async execute(uri: string, vars: { userId: string }) {
|
|
292
|
+
return [{ uri, text: `Hello ${vars.userId}` }];
|
|
287
293
|
}
|
|
288
294
|
}
|
|
289
295
|
```
|
|
290
296
|
|
|
297
|
+
### Calling MCP resource via HTTP
|
|
298
|
+
|
|
299
|
+
POST /mcp/resources/users.get
|
|
300
|
+
|
|
301
|
+
```json
|
|
302
|
+
{
|
|
303
|
+
"uri": "users://user/1"
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Response
|
|
308
|
+
|
|
309
|
+
```json
|
|
310
|
+
{
|
|
311
|
+
"contents": [
|
|
312
|
+
{
|
|
313
|
+
"uri": "users://user/1",
|
|
314
|
+
"content": "Hello 1"
|
|
315
|
+
}
|
|
316
|
+
]
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Obtaining all resources
|
|
321
|
+
|
|
322
|
+
GET /mcp/resources
|
|
323
|
+
|
|
324
|
+
```json
|
|
325
|
+
{
|
|
326
|
+
"resources": [
|
|
327
|
+
{
|
|
328
|
+
"name": "users.get",
|
|
329
|
+
"title": "Get user by id",
|
|
330
|
+
"uri": "users://user/{userId}"
|
|
331
|
+
}
|
|
332
|
+
]
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
291
336
|
### Dynamic creation
|
|
292
337
|
|
|
293
338
|
```ts
|
|
@@ -350,7 +395,7 @@ class TestGuard implements CanActivate {
|
|
|
350
395
|
}
|
|
351
396
|
}
|
|
352
397
|
|
|
353
|
-
@
|
|
398
|
+
@UseGuards(TestGuard)
|
|
354
399
|
@McpTool()
|
|
355
400
|
export class TelegramSendMessageTool implements IMcpTool<
|
|
356
401
|
{ chatId: string; text: string },
|
|
@@ -359,7 +404,7 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
359
404
|
name = "telegram.sendMessage";
|
|
360
405
|
|
|
361
406
|
async execute() {
|
|
362
|
-
await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
407
|
+
// await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
363
408
|
return { success: true };
|
|
364
409
|
}
|
|
365
410
|
}
|
|
@@ -418,7 +463,7 @@ export class ExampleInterceptor implements NestInterceptor {
|
|
|
418
463
|
}
|
|
419
464
|
}
|
|
420
465
|
|
|
421
|
-
@UseInterceptors(
|
|
466
|
+
@UseInterceptors(ExampleInterceptor)
|
|
422
467
|
@McpTool()
|
|
423
468
|
export class TelegramSendMessageTool implements IMcpTool<
|
|
424
469
|
{ chatId: string; text: string },
|
|
@@ -427,7 +472,7 @@ export class TelegramSendMessageTool implements IMcpTool<
|
|
|
427
472
|
name = "telegram.sendMessage";
|
|
428
473
|
|
|
429
474
|
async execute() {
|
|
430
|
-
await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
475
|
+
// await this.bot.telegram.sendMessage(input.chatId, input.text);
|
|
431
476
|
return { success: true };
|
|
432
477
|
}
|
|
433
478
|
}
|
|
@@ -447,7 +492,7 @@ import { APP_INTERCEPTOR } from "@nestjs/core";
|
|
|
447
492
|
McpModule.forRoot({
|
|
448
493
|
providers: [
|
|
449
494
|
ToolWithoutInterceptors,
|
|
450
|
-
|
|
495
|
+
TestInterceptor,
|
|
451
496
|
{ provide: APP_INTERCEPTOR, useExisting: TestInterceptor },
|
|
452
497
|
],
|
|
453
498
|
}),
|
|
@@ -456,28 +501,43 @@ import { APP_INTERCEPTOR } from "@nestjs/core";
|
|
|
456
501
|
export class TestModule {}
|
|
457
502
|
```
|
|
458
503
|
|
|
459
|
-
###
|
|
504
|
+
### Filters
|
|
460
505
|
|
|
461
506
|
```ts
|
|
462
|
-
import {
|
|
507
|
+
import {
|
|
508
|
+
IMcpTool,
|
|
509
|
+
McpTool,
|
|
510
|
+
McpUnauthorizedException,
|
|
511
|
+
} from "@muzikanto/nestjs-mcp";
|
|
463
512
|
import {
|
|
464
513
|
ExceptionFilter,
|
|
465
514
|
Catch,
|
|
466
515
|
ArgumentsHost,
|
|
467
|
-
NotImplementedException,
|
|
468
516
|
UseFilters,
|
|
469
517
|
} from "@nestjs/common";
|
|
470
518
|
|
|
471
519
|
@Catch(NotImplementedException)
|
|
472
|
-
class
|
|
520
|
+
class NotImplExceptionFilter implements ExceptionFilter {
|
|
521
|
+
catch(exception: unknown, host: ArgumentsHost) {
|
|
522
|
+
return {
|
|
523
|
+
isError: true,
|
|
524
|
+
text: (exception as Error).message,
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
@Catch(McpUnauthorizedException)
|
|
530
|
+
class AuthExceptionFilter implements ExceptionFilter {
|
|
473
531
|
catch(exception: unknown, host: ArgumentsHost) {
|
|
474
532
|
return {
|
|
475
|
-
|
|
533
|
+
isError: true,
|
|
534
|
+
text: (exception as Error).message,
|
|
476
535
|
};
|
|
477
536
|
}
|
|
478
537
|
}
|
|
479
538
|
|
|
480
|
-
@
|
|
539
|
+
@UseGuards(AuthGuard)
|
|
540
|
+
@UseFilters(AuthExceptionFilter, NotImplExceptionFilter)
|
|
481
541
|
@McpTool()
|
|
482
542
|
export class TelegramSendMessageTool implements IMcpTool<
|
|
483
543
|
{ chatId: string; text: string },
|
|
@@ -508,14 +568,18 @@ const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
|
|
508
568
|
*/
|
|
509
569
|
async function getMcpTools() {
|
|
510
570
|
const response = await axios.get(MCP_TOOLS_URL);
|
|
511
|
-
return response.data.tools.map(el => ({
|
|
571
|
+
return response.data.tools.map(el => ({
|
|
572
|
+
name: el.name,
|
|
573
|
+
description: el.description,
|
|
574
|
+
parameters: el.inputSchema,
|
|
575
|
+
}));
|
|
512
576
|
}
|
|
513
577
|
|
|
514
578
|
/**
|
|
515
579
|
* Get all prompts
|
|
516
580
|
*/
|
|
517
581
|
async function getMcpPrompt() {
|
|
518
|
-
const response = await axios.post(MCP_TELEGRAM_PROMPT_URL, {/*
|
|
582
|
+
const response = await axios.post(MCP_TELEGRAM_PROMPT_URL, {/* prompt generation arguments */});
|
|
519
583
|
return response.data;
|
|
520
584
|
|
|
521
585
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +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
|
+
export * from "./mcp-server/exceptions";
|
package/dist/index.js
CHANGED
|
@@ -20,4 +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
|
+
__exportStar(require("./mcp-server/exceptions"), exports);
|
|
@@ -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,23 @@
|
|
|
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 { McpPromptMessagesDto } from "../dto/McpPromptMessages.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
|
+
export declare class McpController {
|
|
12
|
+
private readonly service;
|
|
13
|
+
private readonly guard;
|
|
14
|
+
private readonly config;
|
|
15
|
+
constructor(service: McpService, guard: CanActivate, config: IMcpConfig);
|
|
16
|
+
handleTool(body: McpMessageDto, request: any, context: ExecutionContext): Promise<any>;
|
|
17
|
+
getTools(context: ExecutionContext): Promise<McpToolsDto>;
|
|
18
|
+
getPrompts(context: ExecutionContext): Promise<McpPromptsDto>;
|
|
19
|
+
getPrompt(name: string, body: object, context: ExecutionContext): Promise<McpPromptMessagesDto>;
|
|
20
|
+
getResources(context: ExecutionContext): Promise<McpResourcesDto>;
|
|
21
|
+
executeResource(name: string, body: McpResourceRequestDto, context: ExecutionContext): Promise<McpResourceItemsDto>;
|
|
22
|
+
private checkGuard;
|
|
23
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.McpController = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const mcp_service_1 = require("../services/mcp.service");
|
|
18
|
+
const McpMessage_dto_1 = require("../dto/McpMessage.dto");
|
|
19
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
20
|
+
const McpTools_dto_1 = require("../dto/McpTools.dto");
|
|
21
|
+
const McpPrompts_dto_1 = require("../dto/McpPrompts.dto");
|
|
22
|
+
const McpPromptMessages_dto_1 = require("../dto/McpPromptMessages.dto");
|
|
23
|
+
const context_decorator_1 = require("../utils/context.decorator");
|
|
24
|
+
const inject_tokens_1 = require("../utils/inject-tokens");
|
|
25
|
+
const config_1 = require("../config");
|
|
26
|
+
const rxjs_1 = require("rxjs");
|
|
27
|
+
const McpResources_dto_1 = require("../dto/McpResources.dto");
|
|
28
|
+
const McpResourceItems_dto_1 = require("../dto/McpResourceItems.dto");
|
|
29
|
+
const McpResourceRequest_dto_1 = require("../dto/McpResourceRequest.dto");
|
|
30
|
+
const uri_1 = require("../utils/uri");
|
|
31
|
+
let McpController = class McpController {
|
|
32
|
+
service;
|
|
33
|
+
guard;
|
|
34
|
+
config;
|
|
35
|
+
constructor(service, guard, config) {
|
|
36
|
+
this.service = service;
|
|
37
|
+
this.guard = guard;
|
|
38
|
+
this.config = config;
|
|
39
|
+
}
|
|
40
|
+
async handleTool(body, request, context) {
|
|
41
|
+
await this.checkGuard(context);
|
|
42
|
+
const observable = await this.service.executeTool(body, context);
|
|
43
|
+
const result = await (0, rxjs_1.firstValueFrom)(observable);
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
async getTools(context) {
|
|
47
|
+
await this.checkGuard(context);
|
|
48
|
+
const tools = this.service.listTools();
|
|
49
|
+
return { tools };
|
|
50
|
+
}
|
|
51
|
+
async getPrompts(context) {
|
|
52
|
+
await this.checkGuard(context);
|
|
53
|
+
const prompts = this.service.listPrompts();
|
|
54
|
+
return { prompts };
|
|
55
|
+
}
|
|
56
|
+
async getPrompt(name, body, context) {
|
|
57
|
+
await this.checkGuard(context);
|
|
58
|
+
const observable = await this.service.executePrompt(name, body, context);
|
|
59
|
+
const messages = await (0, rxjs_1.firstValueFrom)(observable);
|
|
60
|
+
return {
|
|
61
|
+
messages,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async getResources(context) {
|
|
65
|
+
await this.checkGuard(context);
|
|
66
|
+
const resources = this.service.listResources();
|
|
67
|
+
return { resources };
|
|
68
|
+
}
|
|
69
|
+
async executeResource(name, body, context) {
|
|
70
|
+
await this.checkGuard(context);
|
|
71
|
+
const url = new URL(body.uri);
|
|
72
|
+
const resource = this.service.resources.get(name);
|
|
73
|
+
const params = resource
|
|
74
|
+
? (0, uri_1.extractResourceParams)(resource.instance.uri, body.uri)
|
|
75
|
+
: {};
|
|
76
|
+
const observable = await this.service.executeResource(name, url, params, context);
|
|
77
|
+
const contents = await (0, rxjs_1.firstValueFrom)(observable);
|
|
78
|
+
return { contents };
|
|
79
|
+
}
|
|
80
|
+
async checkGuard(context) {
|
|
81
|
+
if (!(await this.guard.canActivate(context))) {
|
|
82
|
+
throw new common_1.ForbiddenException();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
exports.McpController = McpController;
|
|
87
|
+
__decorate([
|
|
88
|
+
(0, common_1.Post)("/tools"),
|
|
89
|
+
(0, common_1.Header)("Content-Type", "application/json"),
|
|
90
|
+
(0, swagger_1.ApiOperation)({
|
|
91
|
+
summary: "Request tool",
|
|
92
|
+
}),
|
|
93
|
+
(0, swagger_1.ApiResponse)({
|
|
94
|
+
status: 200,
|
|
95
|
+
description: "Tool execution result",
|
|
96
|
+
}),
|
|
97
|
+
(0, swagger_1.ApiBadRequestResponse)({
|
|
98
|
+
description: "Invalid request body",
|
|
99
|
+
}),
|
|
100
|
+
(0, swagger_1.ApiForbiddenResponse)({
|
|
101
|
+
description: "No access to method",
|
|
102
|
+
}),
|
|
103
|
+
__param(0, (0, common_1.Body)()),
|
|
104
|
+
__param(1, (0, common_1.Request)()),
|
|
105
|
+
__param(2, (0, context_decorator_1.Context)()),
|
|
106
|
+
__metadata("design:type", Function),
|
|
107
|
+
__metadata("design:paramtypes", [McpMessage_dto_1.McpMessageDto, Object, Object]),
|
|
108
|
+
__metadata("design:returntype", Promise)
|
|
109
|
+
], McpController.prototype, "handleTool", null);
|
|
110
|
+
__decorate([
|
|
111
|
+
(0, common_1.Get)("tools"),
|
|
112
|
+
(0, swagger_1.ApiOperation)({
|
|
113
|
+
summary: "Get tool list",
|
|
114
|
+
}),
|
|
115
|
+
(0, swagger_1.ApiResponse)({
|
|
116
|
+
status: 200,
|
|
117
|
+
description: "Tools list",
|
|
118
|
+
type: McpTools_dto_1.McpToolsDto,
|
|
119
|
+
}),
|
|
120
|
+
(0, swagger_1.ApiForbiddenResponse)({
|
|
121
|
+
description: "No access to method",
|
|
122
|
+
}),
|
|
123
|
+
__param(0, (0, context_decorator_1.Context)()),
|
|
124
|
+
__metadata("design:type", Function),
|
|
125
|
+
__metadata("design:paramtypes", [Object]),
|
|
126
|
+
__metadata("design:returntype", Promise)
|
|
127
|
+
], McpController.prototype, "getTools", null);
|
|
128
|
+
__decorate([
|
|
129
|
+
(0, common_1.Get)("prompts"),
|
|
130
|
+
(0, swagger_1.ApiOperation)({
|
|
131
|
+
summary: "Get prompt list",
|
|
132
|
+
}),
|
|
133
|
+
(0, swagger_1.ApiResponse)({
|
|
134
|
+
status: 200,
|
|
135
|
+
description: "Prompts list",
|
|
136
|
+
type: McpPrompts_dto_1.McpPromptsDto,
|
|
137
|
+
}),
|
|
138
|
+
(0, swagger_1.ApiForbiddenResponse)({
|
|
139
|
+
description: "No access to method",
|
|
140
|
+
}),
|
|
141
|
+
__param(0, (0, context_decorator_1.Context)()),
|
|
142
|
+
__metadata("design:type", Function),
|
|
143
|
+
__metadata("design:paramtypes", [Object]),
|
|
144
|
+
__metadata("design:returntype", Promise)
|
|
145
|
+
], McpController.prototype, "getPrompts", null);
|
|
146
|
+
__decorate([
|
|
147
|
+
(0, common_1.Post)("prompts/:name"),
|
|
148
|
+
(0, swagger_1.ApiOperation)({
|
|
149
|
+
summary: "Generate messages by prompt name",
|
|
150
|
+
}),
|
|
151
|
+
(0, swagger_1.ApiBody)({
|
|
152
|
+
description: "Any body structure",
|
|
153
|
+
type: Object, // Указываем, что тело может быть любым объектом
|
|
154
|
+
}),
|
|
155
|
+
(0, swagger_1.ApiResponse)({
|
|
156
|
+
status: 200,
|
|
157
|
+
description: "Prompt messages",
|
|
158
|
+
type: McpPromptMessages_dto_1.McpPromptMessagesDto,
|
|
159
|
+
}),
|
|
160
|
+
(0, swagger_1.ApiNotFoundResponse)({
|
|
161
|
+
description: "Not found prompt",
|
|
162
|
+
}),
|
|
163
|
+
(0, swagger_1.ApiBadRequestResponse)({
|
|
164
|
+
description: "Invalid prompt arguments",
|
|
165
|
+
}),
|
|
166
|
+
(0, swagger_1.ApiForbiddenResponse)({
|
|
167
|
+
description: "No access to method",
|
|
168
|
+
}),
|
|
169
|
+
__param(0, (0, common_1.Param)("name")),
|
|
170
|
+
__param(1, (0, common_1.Body)()),
|
|
171
|
+
__param(2, (0, context_decorator_1.Context)()),
|
|
172
|
+
__metadata("design:type", Function),
|
|
173
|
+
__metadata("design:paramtypes", [String, Object, Object]),
|
|
174
|
+
__metadata("design:returntype", Promise)
|
|
175
|
+
], McpController.prototype, "getPrompt", null);
|
|
176
|
+
__decorate([
|
|
177
|
+
(0, common_1.Get)("resources/templates"),
|
|
178
|
+
(0, swagger_1.ApiOperation)({
|
|
179
|
+
summary: "Get resources templates list",
|
|
180
|
+
}),
|
|
181
|
+
(0, swagger_1.ApiResponse)({
|
|
182
|
+
status: 200,
|
|
183
|
+
description: "Resources templates list",
|
|
184
|
+
type: McpResources_dto_1.McpResourcesDto,
|
|
185
|
+
}),
|
|
186
|
+
(0, swagger_1.ApiForbiddenResponse)({
|
|
187
|
+
description: "No access to method",
|
|
188
|
+
}),
|
|
189
|
+
__param(0, (0, context_decorator_1.Context)()),
|
|
190
|
+
__metadata("design:type", Function),
|
|
191
|
+
__metadata("design:paramtypes", [Object]),
|
|
192
|
+
__metadata("design:returntype", Promise)
|
|
193
|
+
], McpController.prototype, "getResources", null);
|
|
194
|
+
__decorate([
|
|
195
|
+
(0, common_1.Post)("resources/templates/:name"),
|
|
196
|
+
(0, swagger_1.ApiOperation)({
|
|
197
|
+
summary: "Get resource template result",
|
|
198
|
+
}),
|
|
199
|
+
(0, swagger_1.ApiBody)({
|
|
200
|
+
description: "Any body structure",
|
|
201
|
+
type: Object, // Указываем, что тело может быть любым объектом
|
|
202
|
+
}),
|
|
203
|
+
(0, swagger_1.ApiResponse)({
|
|
204
|
+
status: 200,
|
|
205
|
+
description: "Resource template result",
|
|
206
|
+
type: McpResourceItems_dto_1.McpResourceItemsDto,
|
|
207
|
+
}),
|
|
208
|
+
(0, swagger_1.ApiNotFoundResponse)({
|
|
209
|
+
description: "Not found resource template",
|
|
210
|
+
}),
|
|
211
|
+
(0, swagger_1.ApiForbiddenResponse)({
|
|
212
|
+
description: "No access to method",
|
|
213
|
+
}),
|
|
214
|
+
__param(0, (0, common_1.Param)("name")),
|
|
215
|
+
__param(1, (0, common_1.Body)()),
|
|
216
|
+
__param(2, (0, context_decorator_1.Context)()),
|
|
217
|
+
__metadata("design:type", Function),
|
|
218
|
+
__metadata("design:paramtypes", [String, McpResourceRequest_dto_1.McpResourceRequestDto, Object]),
|
|
219
|
+
__metadata("design:returntype", Promise)
|
|
220
|
+
], McpController.prototype, "executeResource", null);
|
|
221
|
+
exports.McpController = McpController = __decorate([
|
|
222
|
+
(0, common_1.Controller)("mcp"),
|
|
223
|
+
__param(1, (0, common_1.Inject)(inject_tokens_1.MCP_GUARD)),
|
|
224
|
+
__param(2, (0, config_1.InjectMcpConfig)()),
|
|
225
|
+
__metadata("design:paramtypes", [mcp_service_1.McpService, Object, Object])
|
|
226
|
+
], McpController);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ExecutionContext, CanActivate } from "@nestjs/common";
|
|
2
|
+
import { IMcpConfig } from "../config";
|
|
3
|
+
import { McpSseService } from "../services/mcp.sse.service";
|
|
4
|
+
export declare class McpSseController {
|
|
5
|
+
private readonly service;
|
|
6
|
+
private readonly guard;
|
|
7
|
+
private readonly config;
|
|
8
|
+
constructor(service: McpSseService, guard: CanActivate, config: IMcpConfig);
|
|
9
|
+
handleSse(rawReq: any, rawRes: any, context: ExecutionContext): Promise<void>;
|
|
10
|
+
handleSseMessages(rawReq: any, rawRes: any, context: ExecutionContext): Promise<void>;
|
|
11
|
+
private checkGuard;
|
|
12
|
+
}
|