@rekog/mcp-nest 1.6.3-alpha.2 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/services/handlers/mcp-tools.handler.d.ts +2 -0
- package/dist/services/handlers/mcp-tools.handler.d.ts.map +1 -1
- package/dist/services/handlers/mcp-tools.handler.js +29 -2
- package/dist/services/handlers/mcp-tools.handler.js.map +1 -1
- package/package.json +3 -3
- package/src/services/handlers/mcp-tools.handler.ts +38 -2
|
@@ -6,6 +6,8 @@ import { McpHandlerBase } from './mcp-handler.base';
|
|
|
6
6
|
export declare class McpToolsHandler extends McpHandlerBase {
|
|
7
7
|
private readonly mcpModuleId;
|
|
8
8
|
constructor(moduleRef: ModuleRef, registry: McpRegistryService, mcpModuleId: string);
|
|
9
|
+
private buildDefaultContentBlock;
|
|
10
|
+
private formatToolResult;
|
|
9
11
|
registerHandlers(mcpServer: McpServer, httpRequest: Request): void;
|
|
10
12
|
}
|
|
11
13
|
//# sourceMappingURL=mcp-tools.handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-tools.handler.d.ts","sourceRoot":"","sources":["../../../src/services/handlers/mcp-tools.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-tools.handler.d.ts","sourceRoot":"","sources":["../../../src/services/handlers/mcp-tools.handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,qBACa,eAAgB,SAAQ,cAAc;IAItB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAFrD,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,kBAAkB,EACc,WAAW,EAAE,MAAM;IAK/D,OAAO,CAAC,wBAAwB;IAShC,OAAO,CAAC,gBAAgB;IAwBxB,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO;CAoG5D"}
|
|
@@ -25,6 +25,32 @@ let McpToolsHandler = McpToolsHandler_1 = class McpToolsHandler extends mcp_hand
|
|
|
25
25
|
super(moduleRef, registry, McpToolsHandler_1.name);
|
|
26
26
|
this.mcpModuleId = mcpModuleId;
|
|
27
27
|
}
|
|
28
|
+
buildDefaultContentBlock(result) {
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
type: 'text',
|
|
32
|
+
text: JSON.stringify(result, null, 2),
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
formatToolResult(result, outputSchema) {
|
|
37
|
+
if (result && typeof result === 'object' && Array.isArray(result.content)) {
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
if (outputSchema) {
|
|
41
|
+
const validation = outputSchema.safeParse(result);
|
|
42
|
+
if (!validation.success) {
|
|
43
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Tool result does not match outputSchema: ${validation.error.message}`);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
structuredContent: result,
|
|
47
|
+
content: this.buildDefaultContentBlock(result),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
content: this.buildDefaultContentBlock(result),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
28
54
|
registerHandlers(mcpServer, httpRequest) {
|
|
29
55
|
if (this.registry.getTools(this.mcpModuleId).length === 0) {
|
|
30
56
|
this.logger.debug('No tools registered, skipping tool handlers');
|
|
@@ -69,8 +95,9 @@ let McpToolsHandler = McpToolsHandler_1 = class McpToolsHandler extends mcp_hand
|
|
|
69
95
|
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
|
|
70
96
|
}
|
|
71
97
|
const result = await toolInstance[toolInfo.methodName].call(toolInstance, request.params.arguments, context, httpRequest);
|
|
72
|
-
this.
|
|
73
|
-
|
|
98
|
+
const transformedResult = this.formatToolResult(result, toolInfo.metadata.outputSchema);
|
|
99
|
+
this.logger.debug(transformedResult, 'CallToolRequestSchema result');
|
|
100
|
+
return transformedResult;
|
|
74
101
|
}
|
|
75
102
|
catch (error) {
|
|
76
103
|
this.logger.error(error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-tools.handler.js","sourceRoot":"","sources":["../../../src/services/handlers/mcp-tools.handler.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,iEAK4C;AAC5C,2CAA2D;AAC3D,uCAA2D;AAE3D,2DAAqD;AACrD,kEAA6D;AAC7D,yDAAoD;
|
|
1
|
+
{"version":3,"file":"mcp-tools.handler.js","sourceRoot":"","sources":["../../../src/services/handlers/mcp-tools.handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n CallToolRequestSchema,\n ErrorCode,\n ListToolsRequestSchema,\n McpError,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { Inject, Injectable, Scope } from '@nestjs/common';\nimport { ContextIdFactory, ModuleRef } from '@nestjs/core';\nimport { Request } from 'express';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport { McpRegistryService } from '../mcp-registry.service';\nimport { McpHandlerBase } from './mcp-handler.base';\nimport { ZodTypeAny } from 'zod';\n\n@Injectable({ scope: Scope.REQUEST })\nexport class McpToolsHandler extends McpHandlerBase {\n constructor(\n moduleRef: ModuleRef,\n registry: McpRegistryService,\n @Inject('MCP_MODULE_ID') private readonly mcpModuleId: string,\n ) {\n super(moduleRef, registry, McpToolsHandler.name);\n }\n\n private buildDefaultContentBlock(result: any) {\n return [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ];\n }\n\n private formatToolResult(result: any, outputSchema?: ZodTypeAny): any {\n if (result && typeof result === 'object' && Array.isArray(result.content)) {\n return result;\n }\n\n if (outputSchema) {\n const validation = outputSchema.safeParse(result);\n if (!validation.success) {\n throw new McpError(\n ErrorCode.InternalError,\n `Tool result does not match outputSchema: ${validation.error.message}`\n );\n }\n return {\n structuredContent: result,\n content: this.buildDefaultContentBlock(result),\n };\n }\n\n return {\n content: this.buildDefaultContentBlock(result),\n };\n }\n\n registerHandlers(mcpServer: McpServer, httpRequest: Request) {\n if (this.registry.getTools(this.mcpModuleId).length === 0) {\n this.logger.debug('No tools registered, skipping tool handlers');\n return;\n }\n\n mcpServer.server.setRequestHandler(ListToolsRequestSchema, () => {\n const tools = this.registry.getTools(this.mcpModuleId).map((tool) => {\n // Create base schema\n const toolSchema = {\n name: tool.metadata.name,\n description: tool.metadata.description,\n annotations: tool.metadata.annotations,\n };\n\n // Add input schema if defined\n if (tool.metadata.parameters) {\n toolSchema['inputSchema'] = zodToJsonSchema(tool.metadata.parameters);\n }\n\n // Add output schema if defined, ensuring it has type: 'object'\n if (tool.metadata.outputSchema) {\n const outputSchema = zodToJsonSchema(tool.metadata.outputSchema);\n\n // Create a new object that explicitly includes type: 'object'\n const jsonSchema = {\n ...outputSchema,\n type: 'object',\n };\n\n toolSchema['outputSchema'] = jsonSchema;\n }\n\n return toolSchema;\n });\n\n return {\n tools,\n };\n });\n\n mcpServer.server.setRequestHandler(\n CallToolRequestSchema,\n async (request) => {\n this.logger.debug('CallToolRequestSchema is being called');\n\n const toolInfo = this.registry.findTool(\n this.mcpModuleId,\n request.params.name,\n );\n\n if (!toolInfo) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown tool: ${request.params.name}`,\n );\n }\n\n try {\n const contextId = ContextIdFactory.getByRequest(httpRequest);\n this.moduleRef.registerRequestByContextId(httpRequest, contextId);\n\n const toolInstance = await this.moduleRef.resolve(\n toolInfo.providerClass,\n contextId,\n { strict: false },\n );\n\n const context = this.createContext(mcpServer, request);\n\n if (!toolInstance) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown tool: ${request.params.name}`,\n );\n }\n\n const result = await toolInstance[toolInfo.methodName].call(\n toolInstance,\n request.params.arguments,\n context,\n httpRequest,\n );\n\n const transformedResult = this.formatToolResult(result, toolInfo.metadata.outputSchema);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n this.logger.debug(transformedResult, 'CallToolRequestSchema result');\n\n return transformedResult;\n } catch (error) {\n this.logger.error(error);\n return {\n content: [{ type: 'text', text: error.message }],\n isError: true,\n };\n }\n },\n );\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rekog/mcp-nest",
|
|
3
|
-
"version": "1.6.3
|
|
3
|
+
"version": "1.6.3",
|
|
4
4
|
"description": "NestJS module for creating Model Context Protocol (MCP) servers",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"@nestjs/core": ">=9.0.0",
|
|
34
34
|
"express": ">=4.0.0",
|
|
35
35
|
"reflect-metadata": ">=0.1.14",
|
|
36
|
-
"zod": "
|
|
36
|
+
"zod": "^3.0.0",
|
|
37
37
|
"zod-to-json-schema": ">=3.23.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@eslint/eslintrc": "^3.2.0",
|
|
41
41
|
"@eslint/js": "^9.18.0",
|
|
42
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
42
|
+
"@modelcontextprotocol/sdk": "^1.13.0",
|
|
43
43
|
"@nestjs/common": "^11.1.1",
|
|
44
44
|
"@nestjs/core": "^11.1.1",
|
|
45
45
|
"@nestjs/platform-express": "^11.1.1",
|
|
@@ -11,6 +11,7 @@ import { Request } from 'express';
|
|
|
11
11
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
12
12
|
import { McpRegistryService } from '../mcp-registry.service';
|
|
13
13
|
import { McpHandlerBase } from './mcp-handler.base';
|
|
14
|
+
import { ZodTypeAny } from 'zod';
|
|
14
15
|
|
|
15
16
|
@Injectable({ scope: Scope.REQUEST })
|
|
16
17
|
export class McpToolsHandler extends McpHandlerBase {
|
|
@@ -22,6 +23,39 @@ export class McpToolsHandler extends McpHandlerBase {
|
|
|
22
23
|
super(moduleRef, registry, McpToolsHandler.name);
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
private buildDefaultContentBlock(result: any) {
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
type: 'text',
|
|
30
|
+
text: JSON.stringify(result, null, 2),
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private formatToolResult(result: any, outputSchema?: ZodTypeAny): any {
|
|
36
|
+
if (result && typeof result === 'object' && Array.isArray(result.content)) {
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (outputSchema) {
|
|
41
|
+
const validation = outputSchema.safeParse(result);
|
|
42
|
+
if (!validation.success) {
|
|
43
|
+
throw new McpError(
|
|
44
|
+
ErrorCode.InternalError,
|
|
45
|
+
`Tool result does not match outputSchema: ${validation.error.message}`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
structuredContent: result,
|
|
50
|
+
content: this.buildDefaultContentBlock(result),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
content: this.buildDefaultContentBlock(result),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
25
59
|
registerHandlers(mcpServer: McpServer, httpRequest: Request) {
|
|
26
60
|
if (this.registry.getTools(this.mcpModuleId).length === 0) {
|
|
27
61
|
this.logger.debug('No tools registered, skipping tool handlers');
|
|
@@ -106,10 +140,12 @@ export class McpToolsHandler extends McpHandlerBase {
|
|
|
106
140
|
httpRequest,
|
|
107
141
|
);
|
|
108
142
|
|
|
109
|
-
this.
|
|
143
|
+
const transformedResult = this.formatToolResult(result, toolInfo.metadata.outputSchema);
|
|
110
144
|
|
|
111
145
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
112
|
-
|
|
146
|
+
this.logger.debug(transformedResult, 'CallToolRequestSchema result');
|
|
147
|
+
|
|
148
|
+
return transformedResult;
|
|
113
149
|
} catch (error) {
|
|
114
150
|
this.logger.error(error);
|
|
115
151
|
return {
|