@carlonicora/nestjs-neo4jsonapi 1.111.0 → 1.112.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/dist/agents/graph/tools/describe-entity.tool.d.ts +1 -1
- package/dist/agents/graph/tools/describe-entity.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/describe-entity.tool.js +2 -1
- package/dist/agents/graph/tools/describe-entity.tool.js.map +1 -1
- package/dist/agents/graph/tools/read-entity.tool.d.ts +1 -1
- package/dist/agents/graph/tools/read-entity.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/read-entity.tool.js +2 -1
- package/dist/agents/graph/tools/read-entity.tool.js.map +1 -1
- package/dist/agents/graph/tools/resolve-entity.tool.d.ts +1 -1
- package/dist/agents/graph/tools/resolve-entity.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/resolve-entity.tool.js +2 -1
- package/dist/agents/graph/tools/resolve-entity.tool.js.map +1 -1
- package/dist/agents/graph/tools/search-entities.tool.d.ts +1 -1
- package/dist/agents/graph/tools/search-entities.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/search-entities.tool.js +2 -1
- package/dist/agents/graph/tools/search-entities.tool.js.map +1 -1
- package/dist/agents/graph/tools/traverse.tool.d.ts +1 -1
- package/dist/agents/graph/tools/traverse.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/traverse.tool.js +2 -1
- package/dist/agents/graph/tools/traverse.tool.js.map +1 -1
- package/dist/agents/operator/tools/search-documents.tool.d.ts +1 -1
- package/dist/agents/operator/tools/search-documents.tool.d.ts.map +1 -1
- package/dist/agents/operator/tools/search-documents.tool.js +2 -1
- package/dist/agents/operator/tools/search-documents.tool.js.map +1 -1
- package/dist/bootstrap/app.module.factory.d.ts.map +1 -1
- package/dist/bootstrap/app.module.factory.js +3 -0
- package/dist/bootstrap/app.module.factory.js.map +1 -1
- package/dist/bootstrap/bootstrap.options.d.ts +2 -0
- package/dist/bootstrap/bootstrap.options.d.ts.map +1 -1
- package/dist/config/base.config.d.ts.map +1 -1
- package/dist/config/base.config.js +9 -0
- package/dist/config/base.config.js.map +1 -1
- package/dist/config/interfaces/base.config.interface.d.ts +2 -0
- package/dist/config/interfaces/base.config.interface.d.ts.map +1 -1
- package/dist/config/interfaces/config.mcp.interface.d.ts +34 -0
- package/dist/config/interfaces/config.mcp.interface.d.ts.map +1 -0
- package/dist/config/interfaces/config.mcp.interface.js +3 -0
- package/dist/config/interfaces/config.mcp.interface.js.map +1 -0
- package/dist/config/interfaces/index.d.ts +1 -0
- package/dist/config/interfaces/index.d.ts.map +1 -1
- package/dist/config/interfaces/index.js +1 -0
- package/dist/config/interfaces/index.js.map +1 -1
- package/dist/foundations/oauth/constants/oauth.scopes.d.ts +2 -0
- package/dist/foundations/oauth/constants/oauth.scopes.d.ts.map +1 -1
- package/dist/foundations/oauth/constants/oauth.scopes.js +4 -0
- package/dist/foundations/oauth/constants/oauth.scopes.js.map +1 -1
- package/dist/foundations/oauth/controllers/index.d.ts +2 -0
- package/dist/foundations/oauth/controllers/index.d.ts.map +1 -1
- package/dist/foundations/oauth/controllers/index.js +2 -0
- package/dist/foundations/oauth/controllers/index.js.map +1 -1
- package/dist/foundations/oauth/controllers/oauth.discovery.controller.d.ts +46 -0
- package/dist/foundations/oauth/controllers/oauth.discovery.controller.d.ts.map +1 -0
- package/dist/foundations/oauth/controllers/oauth.discovery.controller.js +102 -0
- package/dist/foundations/oauth/controllers/oauth.discovery.controller.js.map +1 -0
- package/dist/foundations/oauth/controllers/oauth.registration.controller.d.ts +36 -0
- package/dist/foundations/oauth/controllers/oauth.registration.controller.d.ts.map +1 -0
- package/dist/foundations/oauth/controllers/oauth.registration.controller.js +81 -0
- package/dist/foundations/oauth/controllers/oauth.registration.controller.js.map +1 -0
- package/dist/foundations/oauth/dtos/index.d.ts +1 -0
- package/dist/foundations/oauth/dtos/index.d.ts.map +1 -1
- package/dist/foundations/oauth/dtos/index.js +1 -0
- package/dist/foundations/oauth/dtos/index.js.map +1 -1
- package/dist/foundations/oauth/dtos/oauth.register.dto.d.ts +14 -0
- package/dist/foundations/oauth/dtos/oauth.register.dto.d.ts.map +1 -0
- package/dist/foundations/oauth/dtos/oauth.register.dto.js +49 -0
- package/dist/foundations/oauth/dtos/oauth.register.dto.js.map +1 -0
- package/dist/foundations/oauth/index.d.ts +1 -0
- package/dist/foundations/oauth/index.d.ts.map +1 -1
- package/dist/foundations/oauth/index.js +3 -1
- package/dist/foundations/oauth/index.js.map +1 -1
- package/dist/foundations/oauth/oauth.module.d.ts +3 -1
- package/dist/foundations/oauth/oauth.module.d.ts.map +1 -1
- package/dist/foundations/oauth/oauth.module.js +12 -2
- package/dist/foundations/oauth/oauth.module.js.map +1 -1
- package/dist/foundations/oauth/repositories/oauth.repository.d.ts +2 -1
- package/dist/foundations/oauth/repositories/oauth.repository.d.ts.map +1 -1
- package/dist/foundations/oauth/repositories/oauth.repository.js +16 -34
- package/dist/foundations/oauth/repositories/oauth.repository.js.map +1 -1
- package/dist/foundations/oauth/services/oauth.client.service.d.ts +2 -1
- package/dist/foundations/oauth/services/oauth.client.service.d.ts.map +1 -1
- package/dist/foundations/oauth/services/oauth.client.service.js.map +1 -1
- package/dist/foundations/rbac/index.d.ts +4 -0
- package/dist/foundations/rbac/index.d.ts.map +1 -1
- package/dist/foundations/rbac/index.js +7 -1
- package/dist/foundations/rbac/index.js.map +1 -1
- package/dist/foundations/rbac/rbac-permission.module.d.ts +14 -0
- package/dist/foundations/rbac/rbac-permission.module.d.ts.map +1 -0
- package/dist/foundations/rbac/rbac-permission.module.js +33 -0
- package/dist/foundations/rbac/rbac-permission.module.js.map +1 -0
- package/dist/foundations/rbac/repositories/rbac-permission.repository.d.ts +31 -0
- package/dist/foundations/rbac/repositories/rbac-permission.repository.d.ts.map +1 -0
- package/dist/foundations/rbac/repositories/rbac-permission.repository.js +80 -0
- package/dist/foundations/rbac/repositories/rbac-permission.repository.js.map +1 -0
- package/dist/foundations/rbac/services/rbac-permission.service.d.ts +31 -0
- package/dist/foundations/rbac/services/rbac-permission.service.d.ts.map +1 -0
- package/dist/foundations/rbac/services/rbac-permission.service.js +41 -0
- package/dist/foundations/rbac/services/rbac-permission.service.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/controllers/mcp.controller.d.ts +34 -0
- package/dist/mcp/controllers/mcp.controller.d.ts.map +1 -0
- package/dist/mcp/controllers/mcp.controller.js +108 -0
- package/dist/mcp/controllers/mcp.controller.js.map +1 -0
- package/dist/mcp/filters/mcp.auth.filter.d.ts +21 -0
- package/dist/mcp/filters/mcp.auth.filter.d.ts.map +1 -0
- package/dist/mcp/filters/mcp.auth.filter.js +52 -0
- package/dist/mcp/filters/mcp.auth.filter.js.map +1 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +11 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/interfaces/mcp.tool.interface.d.ts +37 -0
- package/dist/mcp/interfaces/mcp.tool.interface.d.ts.map +1 -0
- package/dist/mcp/interfaces/mcp.tool.interface.js +6 -0
- package/dist/mcp/interfaces/mcp.tool.interface.js.map +1 -0
- package/dist/mcp/mcp.module.d.ts +23 -0
- package/dist/mcp/mcp.module.d.ts.map +1 -0
- package/dist/mcp/mcp.module.js +59 -0
- package/dist/mcp/mcp.module.js.map +1 -0
- package/dist/mcp/services/mcp.entity.write.service.d.ts +79 -0
- package/dist/mcp/services/mcp.entity.write.service.d.ts.map +1 -0
- package/dist/mcp/services/mcp.entity.write.service.js +270 -0
- package/dist/mcp/services/mcp.entity.write.service.js.map +1 -0
- package/dist/mcp/services/mcp.errors.d.ts +24 -0
- package/dist/mcp/services/mcp.errors.d.ts.map +1 -0
- package/dist/mcp/services/mcp.errors.js +50 -0
- package/dist/mcp/services/mcp.errors.js.map +1 -0
- package/dist/mcp/services/mcp.generic.tools.service.d.ts +26 -0
- package/dist/mcp/services/mcp.generic.tools.service.d.ts.map +1 -0
- package/dist/mcp/services/mcp.generic.tools.service.js +108 -0
- package/dist/mcp/services/mcp.generic.tools.service.js.map +1 -0
- package/dist/mcp/services/mcp.promoted.tools.factory.d.ts +58 -0
- package/dist/mcp/services/mcp.promoted.tools.factory.d.ts.map +1 -0
- package/dist/mcp/services/mcp.promoted.tools.factory.js +260 -0
- package/dist/mcp/services/mcp.promoted.tools.factory.js.map +1 -0
- package/dist/mcp/services/mcp.server.factory.d.ts +24 -0
- package/dist/mcp/services/mcp.server.factory.d.ts.map +1 -0
- package/dist/mcp/services/mcp.server.factory.js +60 -0
- package/dist/mcp/services/mcp.server.factory.js.map +1 -0
- package/dist/mcp/services/mcp.tool.registry.d.ts +21 -0
- package/dist/mcp/services/mcp.tool.registry.d.ts.map +1 -0
- package/dist/mcp/services/mcp.tool.registry.js +72 -0
- package/dist/mcp/services/mcp.tool.registry.js.map +1 -0
- package/package.json +17 -12
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ConfigService } from "@nestjs/config";
|
|
2
|
+
import { FastifyReply, FastifyRequest } from "fastify";
|
|
3
|
+
import { ClsService } from "nestjs-cls";
|
|
4
|
+
import { UserModulesRepository } from "../../agents/graph/repositories/user-modules.repository";
|
|
5
|
+
import { McpServerFactory } from "../services/mcp.server.factory";
|
|
6
|
+
/**
|
|
7
|
+
* MCP (Model Context Protocol) endpoint — stateless Streamable HTTP.
|
|
8
|
+
*
|
|
9
|
+
* Each `POST /mcp` request is authenticated by the existing OAuthTokenGuard
|
|
10
|
+
* (which populates CLS `userId`/`companyId`), then handed to a fresh per-request
|
|
11
|
+
* MCP Server + StreamableHTTPServerTransport pair (`sessionIdGenerator:
|
|
12
|
+
* undefined` — stateless mode, no session tracking). GET/DELETE are rejected
|
|
13
|
+
* with 405: stateless servers expose no SSE notification channel and no
|
|
14
|
+
* session to terminate.
|
|
15
|
+
*
|
|
16
|
+
* Uses `@Res()` with raw reply writing (the SDK transport writes directly to
|
|
17
|
+
* `res.raw`), which opts this handler out of Nest response serialization —
|
|
18
|
+
* the MCP wire format is JSON-RPC, not JSON:API, matching how the OAuth
|
|
19
|
+
* controllers speak their own RFC-mandated wire formats.
|
|
20
|
+
*/
|
|
21
|
+
export declare class McpController {
|
|
22
|
+
private readonly factory;
|
|
23
|
+
private readonly cls;
|
|
24
|
+
private readonly userModules;
|
|
25
|
+
private readonly configService;
|
|
26
|
+
constructor(factory: McpServerFactory, cls: ClsService, userModules: UserModulesRepository, configService: ConfigService);
|
|
27
|
+
/** Handles one stateless MCP Streamable-HTTP request (initialize, tools/list, tools/call, ...). */
|
|
28
|
+
handle(req: FastifyRequest, res: FastifyReply): Promise<void>;
|
|
29
|
+
/** Stateless server: no SSE notification stream is offered. */
|
|
30
|
+
rejectGet(): never;
|
|
31
|
+
/** Stateless server: there is no session to terminate. */
|
|
32
|
+
rejectDelete(): never;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=mcp.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.controller.d.ts","sourceRoot":"","sources":["../../../src/mcp/controllers/mcp.controller.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yDAAyD,CAAC;AAKhG,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,qBAGa,aAAa;IAEtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAHb,OAAO,EAAE,gBAAgB,EACzB,GAAG,EAAE,UAAU,EACf,WAAW,EAAE,qBAAqB,EAClC,aAAa,EAAE,aAAa;IAG/C,mGAAmG;IAE7F,MAAM,CAAQ,GAAG,EAAE,cAAc,EAAS,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBjF,+DAA+D;IAE/D,SAAS,IAAI,KAAK;IAIlB,0DAA0D;IAE1D,YAAY,IAAI,KAAK;CAGtB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
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 config_1 = require("@nestjs/config");
|
|
18
|
+
const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
19
|
+
const nestjs_cls_1 = require("nestjs-cls");
|
|
20
|
+
const user_modules_repository_1 = require("../../agents/graph/repositories/user-modules.repository");
|
|
21
|
+
const oauth_token_guard_1 = require("../../foundations/oauth/guards/oauth.token.guard");
|
|
22
|
+
const mcp_auth_filter_1 = require("../filters/mcp.auth.filter");
|
|
23
|
+
const mcp_server_factory_1 = require("../services/mcp.server.factory");
|
|
24
|
+
/**
|
|
25
|
+
* MCP (Model Context Protocol) endpoint — stateless Streamable HTTP.
|
|
26
|
+
*
|
|
27
|
+
* Each `POST /mcp` request is authenticated by the existing OAuthTokenGuard
|
|
28
|
+
* (which populates CLS `userId`/`companyId`), then handed to a fresh per-request
|
|
29
|
+
* MCP Server + StreamableHTTPServerTransport pair (`sessionIdGenerator:
|
|
30
|
+
* undefined` — stateless mode, no session tracking). GET/DELETE are rejected
|
|
31
|
+
* with 405: stateless servers expose no SSE notification channel and no
|
|
32
|
+
* session to terminate.
|
|
33
|
+
*
|
|
34
|
+
* Uses `@Res()` with raw reply writing (the SDK transport writes directly to
|
|
35
|
+
* `res.raw`), which opts this handler out of Nest response serialization —
|
|
36
|
+
* the MCP wire format is JSON-RPC, not JSON:API, matching how the OAuth
|
|
37
|
+
* controllers speak their own RFC-mandated wire formats.
|
|
38
|
+
*/
|
|
39
|
+
let McpController = class McpController {
|
|
40
|
+
constructor(factory, cls, userModules, configService) {
|
|
41
|
+
this.factory = factory;
|
|
42
|
+
this.cls = cls;
|
|
43
|
+
this.userModules = userModules;
|
|
44
|
+
this.configService = configService;
|
|
45
|
+
}
|
|
46
|
+
/** Handles one stateless MCP Streamable-HTTP request (initialize, tools/list, tools/call, ...). */
|
|
47
|
+
async handle(req, res) {
|
|
48
|
+
if (!this.configService.get("mcp")?.enabled) {
|
|
49
|
+
throw new common_1.NotFoundException();
|
|
50
|
+
}
|
|
51
|
+
const userId = this.cls.get("userId");
|
|
52
|
+
const companyId = this.cls.get("companyId");
|
|
53
|
+
const ctx = {
|
|
54
|
+
userId,
|
|
55
|
+
companyId,
|
|
56
|
+
userModuleIds: await this.userModules.findModuleIdsForUser(userId),
|
|
57
|
+
};
|
|
58
|
+
const server = this.factory.create(ctx);
|
|
59
|
+
const transport = new streamableHttp_js_1.StreamableHTTPServerTransport({ sessionIdGenerator: undefined }); // stateless
|
|
60
|
+
res.raw.on("close", () => {
|
|
61
|
+
void transport.close();
|
|
62
|
+
void server.close();
|
|
63
|
+
});
|
|
64
|
+
await server.connect(transport);
|
|
65
|
+
// Fastify has already parsed the JSON body — pass it through so the SDK
|
|
66
|
+
// does not attempt to re-read the (already consumed) request stream.
|
|
67
|
+
await transport.handleRequest(req.raw, res.raw, req.body);
|
|
68
|
+
}
|
|
69
|
+
/** Stateless server: no SSE notification stream is offered. */
|
|
70
|
+
rejectGet() {
|
|
71
|
+
throw new common_1.HttpException("Method Not Allowed", 405);
|
|
72
|
+
}
|
|
73
|
+
/** Stateless server: there is no session to terminate. */
|
|
74
|
+
rejectDelete() {
|
|
75
|
+
throw new common_1.HttpException("Method Not Allowed", 405);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
exports.McpController = McpController;
|
|
79
|
+
__decorate([
|
|
80
|
+
(0, common_1.Post)(),
|
|
81
|
+
__param(0, (0, common_1.Req)()),
|
|
82
|
+
__param(1, (0, common_1.Res)()),
|
|
83
|
+
__metadata("design:type", Function),
|
|
84
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
85
|
+
__metadata("design:returntype", Promise)
|
|
86
|
+
], McpController.prototype, "handle", null);
|
|
87
|
+
__decorate([
|
|
88
|
+
(0, common_1.Get)(),
|
|
89
|
+
__metadata("design:type", Function),
|
|
90
|
+
__metadata("design:paramtypes", []),
|
|
91
|
+
__metadata("design:returntype", void 0)
|
|
92
|
+
], McpController.prototype, "rejectGet", null);
|
|
93
|
+
__decorate([
|
|
94
|
+
(0, common_1.Delete)(),
|
|
95
|
+
__metadata("design:type", Function),
|
|
96
|
+
__metadata("design:paramtypes", []),
|
|
97
|
+
__metadata("design:returntype", void 0)
|
|
98
|
+
], McpController.prototype, "rejectDelete", null);
|
|
99
|
+
exports.McpController = McpController = __decorate([
|
|
100
|
+
(0, common_1.Controller)("mcp"),
|
|
101
|
+
(0, common_1.UseFilters)(mcp_auth_filter_1.McpAuthFilter),
|
|
102
|
+
(0, common_1.UseGuards)(oauth_token_guard_1.OAuthTokenGuard),
|
|
103
|
+
__metadata("design:paramtypes", [mcp_server_factory_1.McpServerFactory,
|
|
104
|
+
nestjs_cls_1.ClsService,
|
|
105
|
+
user_modules_repository_1.UserModulesRepository,
|
|
106
|
+
config_1.ConfigService])
|
|
107
|
+
], McpController);
|
|
108
|
+
//# sourceMappingURL=mcp.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.controller.js","sourceRoot":"","sources":["../../../src/mcp/controllers/mcp.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAWwB;AACxB,2CAA+C;AAC/C,0FAAmG;AAEnG,2CAAwC;AACxC,qGAAgG;AAEhG,wFAAmF;AACnF,gEAA2D;AAE3D,uEAAkE;AAElE;;;;;;;;;;;;;;GAcG;AAII,IAAM,aAAa,GAAnB,MAAM,aAAa;IACxB,YACmB,OAAyB,EACzB,GAAe,EACf,WAAkC,EAClC,aAA4B;QAH5B,YAAO,GAAP,OAAO,CAAkB;QACzB,QAAG,GAAH,GAAG,CAAY;QACf,gBAAW,GAAX,WAAW,CAAuB;QAClC,kBAAa,GAAb,aAAa,CAAe;IAC5C,CAAC;IAEJ,mGAAmG;IAE7F,AAAN,KAAK,CAAC,MAAM,CAAQ,GAAmB,EAAS,GAAiB;QAC/D,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAqB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;YAChE,MAAM,IAAI,0BAAiB,EAAE,CAAC;QAChC,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAmB;YAC1B,MAAM;YACN,SAAS;YACT,aAAa,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAAC,MAAM,CAAC;SACnE,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,iDAA6B,CAAC,EAAE,kBAAkB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,YAAY;QACpG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC;YACvB,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,wEAAwE;QACxE,qEAAqE;QACrE,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED,+DAA+D;IAE/D,SAAS;QACP,MAAM,IAAI,sBAAa,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,0DAA0D;IAE1D,YAAY;QACV,MAAM,IAAI,sBAAa,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;CACF,CAAA;AA9CY,sCAAa;AAUlB;IADL,IAAA,aAAI,GAAE;IACO,WAAA,IAAA,YAAG,GAAE,CAAA;IAAuB,WAAA,IAAA,YAAG,GAAE,CAAA;;;;2CAuB9C;AAID;IADC,IAAA,YAAG,GAAE;;;;8CAGL;AAID;IADC,IAAA,eAAM,GAAE;;;;iDAGR;wBA7CU,aAAa;IAHzB,IAAA,mBAAU,EAAC,KAAK,CAAC;IACjB,IAAA,mBAAU,EAAC,+BAAa,CAAC;IACzB,IAAA,kBAAS,EAAC,mCAAe,CAAC;qCAGG,qCAAgB;QACpB,uBAAU;QACF,+CAAqB;QACnB,sBAAa;GALpC,aAAa,CA8CzB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ArgumentsHost, HttpException } from "@nestjs/common";
|
|
2
|
+
import { ConfigService } from "@nestjs/config";
|
|
3
|
+
import { HttpExceptionFilter } from "../../common/filters/http-exception.filter";
|
|
4
|
+
import { AppLoggingService } from "../../core/logging/services/logging.service";
|
|
5
|
+
/**
|
|
6
|
+
* MCP-scoped exception filter.
|
|
7
|
+
*
|
|
8
|
+
* RFC 9728 requires 401 responses from a protected resource to carry a
|
|
9
|
+
* `WWW-Authenticate` header pointing at the protected-resource metadata so MCP
|
|
10
|
+
* clients can discover the authorization server. On 401 this filter sets that
|
|
11
|
+
* header, then delegates the JSON error body to the library's standard
|
|
12
|
+
* HttpExceptionFilter; every other HttpException is handled identically to the
|
|
13
|
+
* global filter (non-HttpException errors fall through to the global filter
|
|
14
|
+
* because of the `@Catch(HttpException)` scope).
|
|
15
|
+
*/
|
|
16
|
+
export declare class McpAuthFilter extends HttpExceptionFilter {
|
|
17
|
+
private readonly configService;
|
|
18
|
+
constructor(configService: ConfigService, logger?: AppLoggingService);
|
|
19
|
+
catch(exception: HttpException, host: ArgumentsHost): void;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=mcp.auth.filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.auth.filter.d.ts","sourceRoot":"","sources":["../../../src/mcp/filters/mcp.auth.filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAS,aAAa,EAAY,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAEhF;;;;;;;;;;GAUG;AACH,qBACa,aAAc,SAAQ,mBAAmB;IAElD,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa,EACjC,MAAM,CAAC,EAAE,iBAAiB;IAKxC,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;CAQ3D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
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.McpAuthFilter = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const config_1 = require("@nestjs/config");
|
|
18
|
+
const http_exception_filter_1 = require("../../common/filters/http-exception.filter");
|
|
19
|
+
const logging_service_1 = require("../../core/logging/services/logging.service");
|
|
20
|
+
/**
|
|
21
|
+
* MCP-scoped exception filter.
|
|
22
|
+
*
|
|
23
|
+
* RFC 9728 requires 401 responses from a protected resource to carry a
|
|
24
|
+
* `WWW-Authenticate` header pointing at the protected-resource metadata so MCP
|
|
25
|
+
* clients can discover the authorization server. On 401 this filter sets that
|
|
26
|
+
* header, then delegates the JSON error body to the library's standard
|
|
27
|
+
* HttpExceptionFilter; every other HttpException is handled identically to the
|
|
28
|
+
* global filter (non-HttpException errors fall through to the global filter
|
|
29
|
+
* because of the `@Catch(HttpException)` scope).
|
|
30
|
+
*/
|
|
31
|
+
let McpAuthFilter = class McpAuthFilter extends http_exception_filter_1.HttpExceptionFilter {
|
|
32
|
+
constructor(configService, logger) {
|
|
33
|
+
super(logger);
|
|
34
|
+
this.configService = configService;
|
|
35
|
+
}
|
|
36
|
+
catch(exception, host) {
|
|
37
|
+
if (exception.getStatus() === 401) {
|
|
38
|
+
const reply = host.switchToHttp().getResponse();
|
|
39
|
+
const base = (this.configService.get("api")?.url ?? "").replace(/\/$/, "");
|
|
40
|
+
reply.header("WWW-Authenticate", `Bearer resource_metadata="${base}/.well-known/oauth-protected-resource"`);
|
|
41
|
+
}
|
|
42
|
+
super.catch(exception, host);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
exports.McpAuthFilter = McpAuthFilter;
|
|
46
|
+
exports.McpAuthFilter = McpAuthFilter = __decorate([
|
|
47
|
+
(0, common_1.Catch)(common_1.HttpException),
|
|
48
|
+
__param(1, (0, common_1.Optional)()),
|
|
49
|
+
__metadata("design:paramtypes", [config_1.ConfigService,
|
|
50
|
+
logging_service_1.AppLoggingService])
|
|
51
|
+
], McpAuthFilter);
|
|
52
|
+
//# sourceMappingURL=mcp.auth.filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.auth.filter.js","sourceRoot":"","sources":["../../../src/mcp/filters/mcp.auth.filter.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA+E;AAC/E,2CAA+C;AAE/C,sFAAiF;AACjF,iFAAgF;AAEhF;;;;;;;;;;GAUG;AAEI,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,2CAAmB;IACpD,YACmB,aAA4B,EACjC,MAA0B;QAEtC,KAAK,CAAC,MAAM,CAAC,CAAC;QAHG,kBAAa,GAAb,aAAa,CAAe;IAI/C,CAAC;IAED,KAAK,CAAC,SAAwB,EAAE,IAAmB;QACjD,IAAI,SAAS,CAAC,SAAS,EAAE,KAAK,GAAG,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,WAAW,EAAgB,CAAC;YAC9D,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAkB,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC5F,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAAE,6BAA6B,IAAI,wCAAwC,CAAC,CAAC;QAC9G,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;CACF,CAAA;AAhBY,sCAAa;wBAAb,aAAa;IADzB,IAAA,cAAK,EAAC,sBAAa,CAAC;IAIhB,WAAA,IAAA,iBAAQ,GAAE,CAAA;qCADqB,sBAAa;QACxB,mCAAiB;GAH7B,aAAa,CAgBzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,cAAc,GACf,MAAM,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// MCP (Model Context Protocol) server — public entry point.
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.MCP_TOOLS = exports.McpModule = void 0;
|
|
5
|
+
// Module (mounted via BootstrapOptions.mcp === true)
|
|
6
|
+
var mcp_module_1 = require("./mcp.module");
|
|
7
|
+
Object.defineProperty(exports, "McpModule", { enumerable: true, get: function () { return mcp_module_1.McpModule; } });
|
|
8
|
+
// App-contribution surface: register McpToolContribution factories under MCP_TOOLS.
|
|
9
|
+
var mcp_tool_interface_1 = require("./interfaces/mcp.tool.interface");
|
|
10
|
+
Object.defineProperty(exports, "MCP_TOOLS", { enumerable: true, get: function () { return mcp_tool_interface_1.MCP_TOOLS; } });
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AAAA,4DAA4D;;;AAE5D,qDAAqD;AACrD,2CAAyC;AAAhC,uGAAA,SAAS,OAAA;AAElB,oFAAoF;AACpF,sEAA4D;AAAnD,+GAAA,SAAS,OAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Per-request user context every MCP tool executes with (company scoping + RBAC module visibility). */
|
|
2
|
+
export interface McpUserContext {
|
|
3
|
+
userId: string;
|
|
4
|
+
companyId: string;
|
|
5
|
+
userModuleIds: string[];
|
|
6
|
+
}
|
|
7
|
+
/** MCP tool-call result: text content blocks, with `isError` set on failures. */
|
|
8
|
+
export interface McpToolResult {
|
|
9
|
+
content: Array<{
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
}>;
|
|
13
|
+
isError?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A single MCP tool as exposed over tools/list + tools/call.
|
|
17
|
+
* `inputSchema` is JSON Schema (draft 2020-12); `readOnly` maps to `annotations.readOnlyHint`.
|
|
18
|
+
*/
|
|
19
|
+
export interface McpToolDefinition {
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
inputSchema: Record<string, unknown>;
|
|
23
|
+
readOnly: boolean;
|
|
24
|
+
execute(input: Record<string, unknown>, ctx: McpUserContext): Promise<McpToolResult>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Factory contract for app-contributed MCP tools.
|
|
28
|
+
* Built once per request — like the built-ins — so contributed tools can
|
|
29
|
+
* apply company scoping and RBAC filtering from the request context.
|
|
30
|
+
*/
|
|
31
|
+
export interface McpToolContribution {
|
|
32
|
+
/** Called once per MCP request with the authenticated user context. */
|
|
33
|
+
build(ctx: McpUserContext): McpToolDefinition[];
|
|
34
|
+
}
|
|
35
|
+
/** Multi-provider DI token: consuming apps contribute McpToolContribution factories. */
|
|
36
|
+
export declare const MCP_TOOLS: unique symbol;
|
|
37
|
+
//# sourceMappingURL=mcp.tool.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.tool.interface.d.ts","sourceRoot":"","sources":["../../../src/mcp/interfaces/mcp.tool.interface.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACtF;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,uEAAuE;IACvE,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,iBAAiB,EAAE,CAAC;CACjD;AAED,wFAAwF;AACxF,eAAO,MAAM,SAAS,eAAsB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MCP_TOOLS = void 0;
|
|
4
|
+
/** Multi-provider DI token: consuming apps contribute McpToolContribution factories. */
|
|
5
|
+
exports.MCP_TOOLS = Symbol("MCP_TOOLS");
|
|
6
|
+
//# sourceMappingURL=mcp.tool.interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.tool.interface.js","sourceRoot":"","sources":["../../../src/mcp/interfaces/mcp.tool.interface.ts"],"names":[],"mappings":";;;AAmCA,wFAAwF;AAC3E,QAAA,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP (Model Context Protocol) server module.
|
|
3
|
+
*
|
|
4
|
+
* Mounted by the bootstrap gate (`BootstrapOptions.mcp === true`) and served
|
|
5
|
+
* at `POST /mcp`, OAuth-authenticated and RBAC-gated. Exports McpToolRegistry
|
|
6
|
+
* so consuming apps can contribute additional tools via the MCP_TOOLS token.
|
|
7
|
+
*
|
|
8
|
+
* Module wiring notes:
|
|
9
|
+
* - `RbacPermissionModule` supplies RbacPermissionService (the RbacModule
|
|
10
|
+
* proper is a config-requiring dynamic module and cannot be imported here).
|
|
11
|
+
* - Audit is NOT wired here: AbstractService.create/put audits internally when
|
|
12
|
+
* the concrete entity service injects AuditService, so MCP writes audit
|
|
13
|
+
* exactly like HTTP writes.
|
|
14
|
+
* - `SearchDocumentsTool` is provided locally: OperatorModule declares but
|
|
15
|
+
* does not export it, and importing OperatorModule would drag in its
|
|
16
|
+
* forwardRef(AssistantModule) cycle. Its dependencies (ToolFactory,
|
|
17
|
+
* ContextualiserService) are exported by AgentsModule's inner modules.
|
|
18
|
+
* - EntityServiceRegistry, Neo4jService, ClsService and ConfigService resolve
|
|
19
|
+
* through the global core/cls/config modules.
|
|
20
|
+
*/
|
|
21
|
+
export declare class McpModule {
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=mcp.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.module.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp.module.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAaa,SAAS;CAAG"}
|
|
@@ -0,0 +1,59 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.McpModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const agents_modules_1 = require("../agents/agents.modules");
|
|
12
|
+
const search_documents_tool_1 = require("../agents/operator/tools/search-documents.tool");
|
|
13
|
+
const oauth_module_1 = require("../foundations/oauth/oauth.module");
|
|
14
|
+
const rbac_permission_module_1 = require("../foundations/rbac/rbac-permission.module");
|
|
15
|
+
const mcp_controller_1 = require("./controllers/mcp.controller");
|
|
16
|
+
const mcp_entity_write_service_1 = require("./services/mcp.entity.write.service");
|
|
17
|
+
const mcp_generic_tools_service_1 = require("./services/mcp.generic.tools.service");
|
|
18
|
+
const mcp_promoted_tools_factory_1 = require("./services/mcp.promoted.tools.factory");
|
|
19
|
+
const mcp_server_factory_1 = require("./services/mcp.server.factory");
|
|
20
|
+
const mcp_tool_registry_1 = require("./services/mcp.tool.registry");
|
|
21
|
+
/**
|
|
22
|
+
* MCP (Model Context Protocol) server module.
|
|
23
|
+
*
|
|
24
|
+
* Mounted by the bootstrap gate (`BootstrapOptions.mcp === true`) and served
|
|
25
|
+
* at `POST /mcp`, OAuth-authenticated and RBAC-gated. Exports McpToolRegistry
|
|
26
|
+
* so consuming apps can contribute additional tools via the MCP_TOOLS token.
|
|
27
|
+
*
|
|
28
|
+
* Module wiring notes:
|
|
29
|
+
* - `RbacPermissionModule` supplies RbacPermissionService (the RbacModule
|
|
30
|
+
* proper is a config-requiring dynamic module and cannot be imported here).
|
|
31
|
+
* - Audit is NOT wired here: AbstractService.create/put audits internally when
|
|
32
|
+
* the concrete entity service injects AuditService, so MCP writes audit
|
|
33
|
+
* exactly like HTTP writes.
|
|
34
|
+
* - `SearchDocumentsTool` is provided locally: OperatorModule declares but
|
|
35
|
+
* does not export it, and importing OperatorModule would drag in its
|
|
36
|
+
* forwardRef(AssistantModule) cycle. Its dependencies (ToolFactory,
|
|
37
|
+
* ContextualiserService) are exported by AgentsModule's inner modules.
|
|
38
|
+
* - EntityServiceRegistry, Neo4jService, ClsService and ConfigService resolve
|
|
39
|
+
* through the global core/cls/config modules.
|
|
40
|
+
*/
|
|
41
|
+
let McpModule = class McpModule {
|
|
42
|
+
};
|
|
43
|
+
exports.McpModule = McpModule;
|
|
44
|
+
exports.McpModule = McpModule = __decorate([
|
|
45
|
+
(0, common_1.Module)({
|
|
46
|
+
imports: [oauth_module_1.OAuthModule, rbac_permission_module_1.RbacPermissionModule, agents_modules_1.AgentsModule],
|
|
47
|
+
controllers: [mcp_controller_1.McpController],
|
|
48
|
+
providers: [
|
|
49
|
+
mcp_server_factory_1.McpServerFactory,
|
|
50
|
+
mcp_tool_registry_1.McpToolRegistry,
|
|
51
|
+
mcp_generic_tools_service_1.McpGenericToolsService,
|
|
52
|
+
mcp_entity_write_service_1.McpEntityWriteService,
|
|
53
|
+
mcp_promoted_tools_factory_1.McpPromotedToolsFactory,
|
|
54
|
+
search_documents_tool_1.SearchDocumentsTool,
|
|
55
|
+
],
|
|
56
|
+
exports: [mcp_tool_registry_1.McpToolRegistry],
|
|
57
|
+
})
|
|
58
|
+
], McpModule);
|
|
59
|
+
//# sourceMappingURL=mcp.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.module.js","sourceRoot":"","sources":["../../src/mcp/mcp.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,6DAAwD;AACxD,0FAAqF;AACrF,oEAAgE;AAChE,uFAAkF;AAClF,iEAA6D;AAC7D,kFAA4E;AAC5E,oFAA8E;AAC9E,sFAAgF;AAChF,sEAAiE;AACjE,oEAA+D;AAE/D;;;;;;;;;;;;;;;;;;;GAmBG;AAcI,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IAbrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,0BAAW,EAAE,6CAAoB,EAAE,6BAAY,CAAC;QAC1D,WAAW,EAAE,CAAC,8BAAa,CAAC;QAC5B,SAAS,EAAE;YACT,qCAAgB;YAChB,mCAAe;YACf,kDAAsB;YACtB,gDAAqB;YACrB,oDAAuB;YACvB,2CAAmB;SACpB;QACD,OAAO,EAAE,CAAC,mCAAe,CAAC;KAC3B,CAAC;GACW,SAAS,CAAG"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { GraphCatalogService } from "../../agents/graph/services/graph.catalog.service";
|
|
2
|
+
import { EntityServiceRegistry } from "../../common/registries/entity.service.registry";
|
|
3
|
+
import { RbacPermissionService } from "../../foundations/rbac/services/rbac-permission.service";
|
|
4
|
+
import type { McpToolDefinition, McpToolResult, McpUserContext } from "../interfaces/mcp.tool.interface";
|
|
5
|
+
/**
|
|
6
|
+
* MCP write executors (C4): create/update entities and add/remove to-many
|
|
7
|
+
* relationship items for any JSON:API type registered in EntityServiceRegistry.
|
|
8
|
+
*
|
|
9
|
+
* Every write is gated by the catalog (type visible to the user's modules) and
|
|
10
|
+
* RBAC (`create`/`update` permission on the entity's module), dispatched through
|
|
11
|
+
* the framework's `AbstractService.*FromDTO` path (never hand-built JSON:API
|
|
12
|
+
* beyond the `JsonApiDTOData` framework type). Audit is NOT performed here:
|
|
13
|
+
* `AbstractService.create/put` audits internally when the concrete entity
|
|
14
|
+
* service injects AuditService, so MCP writes audit exactly like HTTP writes.
|
|
15
|
+
*/
|
|
16
|
+
export declare class McpEntityWriteService {
|
|
17
|
+
private readonly registry;
|
|
18
|
+
private readonly catalog;
|
|
19
|
+
private readonly rbac;
|
|
20
|
+
constructor(registry: EntityServiceRegistry, catalog: GraphCatalogService, rbac: RbacPermissionService);
|
|
21
|
+
/**
|
|
22
|
+
* The four write McpToolDefinitions (all `readOnly: false`) with hand-written
|
|
23
|
+
* JSON Schemas matching the C4 method params. Consumed by McpGenericToolsService.
|
|
24
|
+
*/
|
|
25
|
+
buildTools(_ctx: McpUserContext): McpToolDefinition[];
|
|
26
|
+
/** Create a new entity of the given type. RBAC action: `create`. */
|
|
27
|
+
createEntity(params: {
|
|
28
|
+
type: string;
|
|
29
|
+
attributes: Record<string, unknown>;
|
|
30
|
+
relationships?: Record<string, {
|
|
31
|
+
data: Array<{
|
|
32
|
+
type: string;
|
|
33
|
+
id: string;
|
|
34
|
+
}>;
|
|
35
|
+
}>;
|
|
36
|
+
}, ctx: McpUserContext): Promise<McpToolResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Update an existing entity. RBAC action: `update`.
|
|
39
|
+
*
|
|
40
|
+
* PATCH semantics via `patchFromDTO` — only the provided attributes change.
|
|
41
|
+
* Deliberately NOT `putFromDTO`: the framework's PUT maps every descriptor
|
|
42
|
+
* relationship and treats the ones absent from the DTO as "delete all
|
|
43
|
+
* edges". The HTTP path is safe because the frontend model always sends the
|
|
44
|
+
* complete relationship set on PUT, but an MCP caller sends attributes only —
|
|
45
|
+
* a PUT here would silently strip every mutable relationship off the record.
|
|
46
|
+
*/
|
|
47
|
+
updateEntity(params: {
|
|
48
|
+
type: string;
|
|
49
|
+
id: string;
|
|
50
|
+
attributes: Record<string, unknown>;
|
|
51
|
+
}, ctx: McpUserContext): Promise<McpToolResult>;
|
|
52
|
+
/** Add items to a to-many relationship. RBAC action: `update`. */
|
|
53
|
+
addRelationship(params: {
|
|
54
|
+
type: string;
|
|
55
|
+
id: string;
|
|
56
|
+
relationship: string;
|
|
57
|
+
relatedType: string;
|
|
58
|
+
relatedIds: string[];
|
|
59
|
+
}, ctx: McpUserContext): Promise<McpToolResult>;
|
|
60
|
+
/** Remove items from a to-many relationship. RBAC action: `update`. */
|
|
61
|
+
removeRelationship(params: {
|
|
62
|
+
type: string;
|
|
63
|
+
id: string;
|
|
64
|
+
relationship: string;
|
|
65
|
+
relatedType: string;
|
|
66
|
+
relatedIds: string[];
|
|
67
|
+
}, ctx: McpUserContext): Promise<McpToolResult>;
|
|
68
|
+
/**
|
|
69
|
+
* Shared gate: catalog visibility (unknown_type), RBAC (forbidden), and
|
|
70
|
+
* service registration (unknown_type).
|
|
71
|
+
*/
|
|
72
|
+
private gate;
|
|
73
|
+
/**
|
|
74
|
+
* Rejects attribute keys that are not in the entity's catalog field list.
|
|
75
|
+
* Catalog fields are a CatalogField[] array — keys are the `name` property.
|
|
76
|
+
*/
|
|
77
|
+
private unknownAttributes;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=mcp.entity.write.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.entity.write.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp.entity.write.service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mDAAmD,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,MAAM,iDAAiD,CAAC;AAExF,OAAO,EAAE,qBAAqB,EAAE,MAAM,yDAAyD,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAMzG;;;;;;;;;;GAUG;AACH,qBACa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAFJ,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,qBAAqB;IAG9C;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,iBAAiB,EAAE;IAsHrD,oEAAoE;IAC9D,YAAY,CAChB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,IAAI,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,EAAE,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CAAC,CAAC;KAC/E,EACD,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,aAAa,CAAC;IAoBzB;;;;;;;;;OASG;IACG,YAAY,CAChB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EACzE,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,aAAa,CAAC;IAiBzB,kEAAkE;IAC5D,eAAe,CACnB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,EACrG,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,aAAa,CAAC;IAiBzB,uEAAuE;IACjE,kBAAkB,CACtB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,EACrG,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,aAAa,CAAC;IAiBzB;;;OAGG;YACW,IAAI;IA0BlB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;CAW1B"}
|