@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,270 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.McpEntityWriteService = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const node_crypto_1 = require("node:crypto");
|
|
15
|
+
const graph_catalog_service_1 = require("../../agents/graph/services/graph.catalog.service");
|
|
16
|
+
const entity_service_registry_1 = require("../../common/registries/entity.service.registry");
|
|
17
|
+
const rbac_permission_service_1 = require("../../foundations/rbac/services/rbac-permission.service");
|
|
18
|
+
const mcp_errors_1 = require("./mcp.errors");
|
|
19
|
+
const UPDATE_SEMANTICS = "Partial update: only the attributes you provide are changed; omitted attributes and all relationships are left untouched. Use add_relationship/remove_relationship to change relationships.";
|
|
20
|
+
/**
|
|
21
|
+
* MCP write executors (C4): create/update entities and add/remove to-many
|
|
22
|
+
* relationship items for any JSON:API type registered in EntityServiceRegistry.
|
|
23
|
+
*
|
|
24
|
+
* Every write is gated by the catalog (type visible to the user's modules) and
|
|
25
|
+
* RBAC (`create`/`update` permission on the entity's module), dispatched through
|
|
26
|
+
* the framework's `AbstractService.*FromDTO` path (never hand-built JSON:API
|
|
27
|
+
* beyond the `JsonApiDTOData` framework type). Audit is NOT performed here:
|
|
28
|
+
* `AbstractService.create/put` audits internally when the concrete entity
|
|
29
|
+
* service injects AuditService, so MCP writes audit exactly like HTTP writes.
|
|
30
|
+
*/
|
|
31
|
+
let McpEntityWriteService = class McpEntityWriteService {
|
|
32
|
+
constructor(registry, catalog, rbac) {
|
|
33
|
+
this.registry = registry;
|
|
34
|
+
this.catalog = catalog;
|
|
35
|
+
this.rbac = rbac;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The four write McpToolDefinitions (all `readOnly: false`) with hand-written
|
|
39
|
+
* JSON Schemas matching the C4 method params. Consumed by McpGenericToolsService.
|
|
40
|
+
*/
|
|
41
|
+
buildTools(_ctx) {
|
|
42
|
+
const typeProperty = {
|
|
43
|
+
type: "string",
|
|
44
|
+
description: 'JSON:API entity type (plural, e.g. "orders"). Call describe_entity first for the field list.',
|
|
45
|
+
};
|
|
46
|
+
const idProperty = { type: "string", description: "The id of the target record." };
|
|
47
|
+
return [
|
|
48
|
+
{
|
|
49
|
+
name: "create_entity",
|
|
50
|
+
description: "Create a new record of the given JSON:API entity type. " +
|
|
51
|
+
"Call describe_entity first to learn the valid attributes and relationships.",
|
|
52
|
+
inputSchema: {
|
|
53
|
+
type: "object",
|
|
54
|
+
properties: {
|
|
55
|
+
type: typeProperty,
|
|
56
|
+
attributes: {
|
|
57
|
+
type: "object",
|
|
58
|
+
description: "Attribute values keyed by field name (see describe_entity).",
|
|
59
|
+
},
|
|
60
|
+
relationships: {
|
|
61
|
+
type: "object",
|
|
62
|
+
description: "Optional JSON:API relationships keyed by relationship name.",
|
|
63
|
+
additionalProperties: {
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {
|
|
66
|
+
data: {
|
|
67
|
+
type: "array",
|
|
68
|
+
items: {
|
|
69
|
+
type: "object",
|
|
70
|
+
properties: { type: { type: "string" }, id: { type: "string" } },
|
|
71
|
+
required: ["type", "id"],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
required: ["data"],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
required: ["type", "attributes"],
|
|
80
|
+
},
|
|
81
|
+
readOnly: false,
|
|
82
|
+
execute: (input, ctx) => this.createEntity(input, ctx),
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "update_entity",
|
|
86
|
+
description: `Update an existing record. ${UPDATE_SEMANTICS}`,
|
|
87
|
+
inputSchema: {
|
|
88
|
+
type: "object",
|
|
89
|
+
properties: {
|
|
90
|
+
type: typeProperty,
|
|
91
|
+
id: idProperty,
|
|
92
|
+
attributes: {
|
|
93
|
+
type: "object",
|
|
94
|
+
description: `The attribute values to change. ${UPDATE_SEMANTICS}`,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
required: ["type", "id", "attributes"],
|
|
98
|
+
},
|
|
99
|
+
readOnly: false,
|
|
100
|
+
execute: (input, ctx) => this.updateEntity(input, ctx),
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "add_relationship",
|
|
104
|
+
description: "Add one or more related records to a to-many relationship of an existing record. " +
|
|
105
|
+
"Call describe_entity first for the relationship names.",
|
|
106
|
+
inputSchema: {
|
|
107
|
+
type: "object",
|
|
108
|
+
properties: {
|
|
109
|
+
type: typeProperty,
|
|
110
|
+
id: idProperty,
|
|
111
|
+
relationship: { type: "string", description: "Relationship name on the entity (see describe_entity)." },
|
|
112
|
+
relatedType: { type: "string", description: "JSON:API type of the related records." },
|
|
113
|
+
relatedIds: { type: "array", items: { type: "string" }, minItems: 1 },
|
|
114
|
+
},
|
|
115
|
+
required: ["type", "id", "relationship", "relatedType", "relatedIds"],
|
|
116
|
+
},
|
|
117
|
+
readOnly: false,
|
|
118
|
+
execute: (input, ctx) => this.addRelationship(input, ctx),
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "remove_relationship",
|
|
122
|
+
description: "Remove one or more related records from a to-many relationship of an existing record.",
|
|
123
|
+
inputSchema: {
|
|
124
|
+
type: "object",
|
|
125
|
+
properties: {
|
|
126
|
+
type: typeProperty,
|
|
127
|
+
id: idProperty,
|
|
128
|
+
relationship: { type: "string", description: "Relationship name on the entity (see describe_entity)." },
|
|
129
|
+
relatedType: { type: "string", description: "JSON:API type of the related records." },
|
|
130
|
+
relatedIds: { type: "array", items: { type: "string" }, minItems: 1 },
|
|
131
|
+
},
|
|
132
|
+
required: ["type", "id", "relationship", "relatedType", "relatedIds"],
|
|
133
|
+
},
|
|
134
|
+
readOnly: false,
|
|
135
|
+
execute: (input, ctx) => this.removeRelationship(input, ctx),
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
/** Create a new entity of the given type. RBAC action: `create`. */
|
|
140
|
+
async createEntity(params, ctx) {
|
|
141
|
+
const gate = await this.gate(params.type, "create", ctx);
|
|
142
|
+
if ("error" in gate)
|
|
143
|
+
return gate.error;
|
|
144
|
+
const { entity, service } = gate;
|
|
145
|
+
const invalid = this.unknownAttributes(entity, params.attributes);
|
|
146
|
+
if (invalid)
|
|
147
|
+
return invalid;
|
|
148
|
+
try {
|
|
149
|
+
const data = {
|
|
150
|
+
id: (0, node_crypto_1.randomUUID)(),
|
|
151
|
+
type: params.type,
|
|
152
|
+
attributes: params.attributes,
|
|
153
|
+
...(params.relationships ? { relationships: params.relationships } : {}),
|
|
154
|
+
};
|
|
155
|
+
const result = await service.createFromDTO({ data });
|
|
156
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
return (0, mcp_errors_1.mcpError)(e);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Update an existing entity. RBAC action: `update`.
|
|
164
|
+
*
|
|
165
|
+
* PATCH semantics via `patchFromDTO` — only the provided attributes change.
|
|
166
|
+
* Deliberately NOT `putFromDTO`: the framework's PUT maps every descriptor
|
|
167
|
+
* relationship and treats the ones absent from the DTO as "delete all
|
|
168
|
+
* edges". The HTTP path is safe because the frontend model always sends the
|
|
169
|
+
* complete relationship set on PUT, but an MCP caller sends attributes only —
|
|
170
|
+
* a PUT here would silently strip every mutable relationship off the record.
|
|
171
|
+
*/
|
|
172
|
+
async updateEntity(params, ctx) {
|
|
173
|
+
const gate = await this.gate(params.type, "update", ctx);
|
|
174
|
+
if ("error" in gate)
|
|
175
|
+
return gate.error;
|
|
176
|
+
const { entity, service } = gate;
|
|
177
|
+
const invalid = this.unknownAttributes(entity, params.attributes);
|
|
178
|
+
if (invalid)
|
|
179
|
+
return invalid;
|
|
180
|
+
try {
|
|
181
|
+
const before = await service.findRecordById({ id: params.id });
|
|
182
|
+
if (!before)
|
|
183
|
+
return (0, mcp_errors_1.mcpFlatError)("not_found", `No ${params.type} record with id ${params.id}.`);
|
|
184
|
+
const data = { id: params.id, type: params.type, attributes: params.attributes };
|
|
185
|
+
const result = await service.patchFromDTO({ data });
|
|
186
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
return (0, mcp_errors_1.mcpError)(e);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/** Add items to a to-many relationship. RBAC action: `update`. */
|
|
193
|
+
async addRelationship(params, ctx) {
|
|
194
|
+
const gate = await this.gate(params.type, "update", ctx);
|
|
195
|
+
if ("error" in gate)
|
|
196
|
+
return gate.error;
|
|
197
|
+
const { service } = gate;
|
|
198
|
+
try {
|
|
199
|
+
const data = params.relatedIds.map((id) => ({ type: params.relatedType, id }));
|
|
200
|
+
const result = await service.addToRelationshipFromDTO({
|
|
201
|
+
id: params.id,
|
|
202
|
+
relationship: params.relationship,
|
|
203
|
+
data,
|
|
204
|
+
});
|
|
205
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
return (0, mcp_errors_1.mcpError)(e);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/** Remove items from a to-many relationship. RBAC action: `update`. */
|
|
212
|
+
async removeRelationship(params, ctx) {
|
|
213
|
+
const gate = await this.gate(params.type, "update", ctx);
|
|
214
|
+
if ("error" in gate)
|
|
215
|
+
return gate.error;
|
|
216
|
+
const { service } = gate;
|
|
217
|
+
try {
|
|
218
|
+
const data = params.relatedIds.map((id) => ({ type: params.relatedType, id }));
|
|
219
|
+
const result = await service.removeFromRelationshipFromDTO({
|
|
220
|
+
id: params.id,
|
|
221
|
+
relationship: params.relationship,
|
|
222
|
+
data,
|
|
223
|
+
});
|
|
224
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
225
|
+
}
|
|
226
|
+
catch (e) {
|
|
227
|
+
return (0, mcp_errors_1.mcpError)(e);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Shared gate: catalog visibility (unknown_type), RBAC (forbidden), and
|
|
232
|
+
* service registration (unknown_type).
|
|
233
|
+
*/
|
|
234
|
+
async gate(type, action, ctx) {
|
|
235
|
+
const entity = this.catalog.getEntityDetail(type, ctx.userModuleIds);
|
|
236
|
+
if (!entity) {
|
|
237
|
+
return {
|
|
238
|
+
error: (0, mcp_errors_1.mcpFlatError)("unknown_type", `Unknown or inaccessible entity type: ${type}. Call describe_entity first.`),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
if (!(await this.rbac.can({ userId: ctx.userId, moduleId: entity.moduleId, action }))) {
|
|
242
|
+
return { error: (0, mcp_errors_1.mcpFlatError)("forbidden", `You lack ${action} permission on ${type}.`) };
|
|
243
|
+
}
|
|
244
|
+
const service = this.registry.get(type);
|
|
245
|
+
if (!service) {
|
|
246
|
+
return { error: (0, mcp_errors_1.mcpFlatError)("unknown_type", `No service registered for ${type}.`) };
|
|
247
|
+
}
|
|
248
|
+
return { entity, service };
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Rejects attribute keys that are not in the entity's catalog field list.
|
|
252
|
+
* Catalog fields are a CatalogField[] array — keys are the `name` property.
|
|
253
|
+
*/
|
|
254
|
+
unknownAttributes(entity, attributes) {
|
|
255
|
+
const known = new Set(entity.fields.map((f) => f.name));
|
|
256
|
+
const unknown = Object.keys(attributes).filter((k) => !known.has(k));
|
|
257
|
+
if (unknown.length) {
|
|
258
|
+
return (0, mcp_errors_1.mcpFlatError)("validation_failed", `Unknown attributes: ${unknown.join(", ")}. Call describe_entity("${entity.type}") for the field list.`);
|
|
259
|
+
}
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
exports.McpEntityWriteService = McpEntityWriteService;
|
|
264
|
+
exports.McpEntityWriteService = McpEntityWriteService = __decorate([
|
|
265
|
+
(0, common_1.Injectable)(),
|
|
266
|
+
__metadata("design:paramtypes", [entity_service_registry_1.EntityServiceRegistry,
|
|
267
|
+
graph_catalog_service_1.GraphCatalogService,
|
|
268
|
+
rbac_permission_service_1.RbacPermissionService])
|
|
269
|
+
], McpEntityWriteService);
|
|
270
|
+
//# sourceMappingURL=mcp.entity.write.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.entity.write.service.js","sourceRoot":"","sources":["../../../src/mcp/services/mcp.entity.write.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { McpToolResult } from "../interfaces/mcp.tool.interface";
|
|
2
|
+
/**
|
|
3
|
+
* MCP tool error codes (C10). Every executor failure is returned to the MCP
|
|
4
|
+
* client as a FLAT JSON payload `{ code, message, ...meta }` — mirroring the
|
|
5
|
+
* flat-error convention used by the HTTP layer's HttpExceptionFilter.
|
|
6
|
+
*/
|
|
7
|
+
export type McpErrorCode = "unknown_type" | "forbidden" | "validation_failed" | "not_found" | "internal";
|
|
8
|
+
/**
|
|
9
|
+
* Maps an unknown thrown value to a flat MCP error result.
|
|
10
|
+
*
|
|
11
|
+
* - `HttpException` → status-derived code (404 → not_found, 403 → forbidden,
|
|
12
|
+
* 400/422 → validation_failed, anything else → internal)
|
|
13
|
+
* - `ZodError` → validation_failed with per-issue `issues` meta
|
|
14
|
+
* - other `Error` → internal with the error message
|
|
15
|
+
*
|
|
16
|
+
* Never includes stack traces.
|
|
17
|
+
*/
|
|
18
|
+
export declare function mcpError(e: unknown): McpToolResult;
|
|
19
|
+
/**
|
|
20
|
+
* Builds a flat MCP error result directly from a code + message (+ optional meta).
|
|
21
|
+
* The payload shape is intentionally flat: `{ code, message, ...meta }`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function mcpFlatError(code: string, message: string, meta?: Record<string, unknown>): McpToolResult;
|
|
24
|
+
//# sourceMappingURL=mcp.errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.errors.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp.errors.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAEtE;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,cAAc,GAAG,WAAW,GAAG,mBAAmB,GAAG,WAAW,GAAG,UAAU,CAAC;AAEzG;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,aAAa,CAuBlD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,aAAa,CAE7G"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mcpError = mcpError;
|
|
4
|
+
exports.mcpFlatError = mcpFlatError;
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
/**
|
|
8
|
+
* Maps an unknown thrown value to a flat MCP error result.
|
|
9
|
+
*
|
|
10
|
+
* - `HttpException` → status-derived code (404 → not_found, 403 → forbidden,
|
|
11
|
+
* 400/422 → validation_failed, anything else → internal)
|
|
12
|
+
* - `ZodError` → validation_failed with per-issue `issues` meta
|
|
13
|
+
* - other `Error` → internal with the error message
|
|
14
|
+
*
|
|
15
|
+
* Never includes stack traces.
|
|
16
|
+
*/
|
|
17
|
+
function mcpError(e) {
|
|
18
|
+
let code = "internal";
|
|
19
|
+
let message = "Unexpected error";
|
|
20
|
+
let meta = {};
|
|
21
|
+
if (e instanceof common_1.HttpException) {
|
|
22
|
+
const status = e.getStatus();
|
|
23
|
+
code =
|
|
24
|
+
status === 404
|
|
25
|
+
? "not_found"
|
|
26
|
+
: status === 403
|
|
27
|
+
? "forbidden"
|
|
28
|
+
: status === 400 || status === 422
|
|
29
|
+
? "validation_failed"
|
|
30
|
+
: "internal";
|
|
31
|
+
message = e.message;
|
|
32
|
+
}
|
|
33
|
+
else if (e instanceof zod_1.ZodError) {
|
|
34
|
+
code = "validation_failed";
|
|
35
|
+
message = "Input validation failed";
|
|
36
|
+
meta = { issues: e.issues.map((i) => ({ path: i.path.join("."), message: i.message })) };
|
|
37
|
+
}
|
|
38
|
+
else if (e instanceof Error) {
|
|
39
|
+
message = e.message;
|
|
40
|
+
}
|
|
41
|
+
return mcpFlatError(code, message, meta);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Builds a flat MCP error result directly from a code + message (+ optional meta).
|
|
45
|
+
* The payload shape is intentionally flat: `{ code, message, ...meta }`.
|
|
46
|
+
*/
|
|
47
|
+
function mcpFlatError(code, message, meta = {}) {
|
|
48
|
+
return { isError: true, content: [{ type: "text", text: JSON.stringify({ code, message, ...meta }) }] };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=mcp.errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.errors.js","sourceRoot":"","sources":["../../../src/mcp/services/mcp.errors.ts"],"names":[],"mappings":";;AAqBA,4BAuBC;AAMD,oCAEC;AApDD,2CAA+C;AAC/C,6BAA+B;AAU/B;;;;;;;;;GASG;AACH,SAAgB,QAAQ,CAAC,CAAU;IACjC,IAAI,IAAI,GAAiB,UAAU,CAAC;IACpC,IAAI,OAAO,GAAG,kBAAkB,CAAC;IACjC,IAAI,IAAI,GAA4B,EAAE,CAAC;IACvC,IAAI,CAAC,YAAY,sBAAa,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC;QAC7B,IAAI;YACF,MAAM,KAAK,GAAG;gBACZ,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,MAAM,KAAK,GAAG;oBACd,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG;wBAChC,CAAC,CAAC,mBAAmB;wBACrB,CAAC,CAAC,UAAU,CAAC;QACrB,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;IACtB,CAAC;SAAM,IAAI,CAAC,YAAY,cAAQ,EAAE,CAAC;QACjC,IAAI,GAAG,mBAAmB,CAAC;QAC3B,OAAO,GAAG,yBAAyB,CAAC;QACpC,IAAI,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC;IAC3F,CAAC;SAAM,IAAI,CAAC,YAAY,KAAK,EAAE,CAAC;QAC9B,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;IACtB,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,SAAgB,YAAY,CAAC,IAAY,EAAE,OAAe,EAAE,OAAgC,EAAE;IAC5F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1G,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DescribeEntityTool } from "../../agents/graph/tools/describe-entity.tool";
|
|
2
|
+
import { ReadEntityTool } from "../../agents/graph/tools/read-entity.tool";
|
|
3
|
+
import { ResolveEntityTool } from "../../agents/graph/tools/resolve-entity.tool";
|
|
4
|
+
import { SearchEntitiesTool } from "../../agents/graph/tools/search-entities.tool";
|
|
5
|
+
import { TraverseTool } from "../../agents/graph/tools/traverse.tool";
|
|
6
|
+
import { SearchDocumentsTool } from "../../agents/operator/tools/search-documents.tool";
|
|
7
|
+
import { McpToolDefinition, McpUserContext } from "../interfaces/mcp.tool.interface";
|
|
8
|
+
import { McpEntityWriteService } from "./mcp.entity.write.service";
|
|
9
|
+
/**
|
|
10
|
+
* Builds the generic MCP tool set for one authenticated request:
|
|
11
|
+
* the five graph read tools, the document-retrieval tool, and the four
|
|
12
|
+
* entity write tools contributed by McpEntityWriteService.
|
|
13
|
+
*/
|
|
14
|
+
export declare class McpGenericToolsService {
|
|
15
|
+
private readonly resolveEntityTool;
|
|
16
|
+
private readonly describeEntityTool;
|
|
17
|
+
private readonly searchEntitiesTool;
|
|
18
|
+
private readonly readEntityTool;
|
|
19
|
+
private readonly traverseTool;
|
|
20
|
+
private readonly searchDocumentsTool;
|
|
21
|
+
private readonly writeService;
|
|
22
|
+
constructor(resolveEntityTool: ResolveEntityTool, describeEntityTool: DescribeEntityTool, searchEntitiesTool: SearchEntitiesTool, readEntityTool: ReadEntityTool, traverseTool: TraverseTool, searchDocumentsTool: SearchDocumentsTool, writeService: McpEntityWriteService);
|
|
23
|
+
/** Builds the per-request generic tool definitions (read tools + write tools). */
|
|
24
|
+
build(ctx: McpUserContext): McpToolDefinition[];
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=mcp.generic.tools.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.generic.tools.service.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp.generic.tools.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAA6B,MAAM,+CAA+C,CAAC;AAC9G,OAAO,EAAE,cAAc,EAAyB,MAAM,2CAA2C,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAA4B,MAAM,8CAA8C,CAAC;AAC3G,OAAO,EAAE,kBAAkB,EAA6B,MAAM,+CAA+C,CAAC;AAE9G,OAAO,EAAE,YAAY,EAAuB,MAAM,wCAAwC,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAA8B,MAAM,mDAAmD,CAAC;AACpH,OAAO,EAAE,iBAAiB,EAAiB,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAEpG,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAgBnE;;;;GAIG;AACH,qBACa,sBAAsB;IAE/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY;gBANZ,iBAAiB,EAAE,iBAAiB,EACpC,kBAAkB,EAAE,kBAAkB,EACtC,kBAAkB,EAAE,kBAAkB,EACtC,cAAc,EAAE,cAAc,EAC9B,YAAY,EAAE,YAAY,EAC1B,mBAAmB,EAAE,mBAAmB,EACxC,YAAY,EAAE,qBAAqB;IAGtD,kFAAkF;IAClF,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,iBAAiB,EAAE;CA2EhD"}
|
|
@@ -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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.McpGenericToolsService = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const zod_1 = require("zod");
|
|
15
|
+
const describe_entity_tool_1 = require("../../agents/graph/tools/describe-entity.tool");
|
|
16
|
+
const read_entity_tool_1 = require("../../agents/graph/tools/read-entity.tool");
|
|
17
|
+
const resolve_entity_tool_1 = require("../../agents/graph/tools/resolve-entity.tool");
|
|
18
|
+
const search_entities_tool_1 = require("../../agents/graph/tools/search-entities.tool");
|
|
19
|
+
const traverse_tool_1 = require("../../agents/graph/tools/traverse.tool");
|
|
20
|
+
const search_documents_tool_1 = require("../../agents/operator/tools/search-documents.tool");
|
|
21
|
+
const mcp_errors_1 = require("./mcp.errors");
|
|
22
|
+
const mcp_entity_write_service_1 = require("./mcp.entity.write.service");
|
|
23
|
+
// Descriptions copied verbatim from each tool's build() (single source is the
|
|
24
|
+
// DynamicStructuredTool literal in the tool file; not exportable without
|
|
25
|
+
// restructuring those files beyond the schema-export-only change).
|
|
26
|
+
const DESCRIBE_DESCRIPTION = "Returns the described fields and relationships for an entity type.";
|
|
27
|
+
const RESOLVE_DESCRIPTION = "Resolve a user-named entity across every visible type. Returns ranked candidates from the highest-confidence tier that yielded any match anywhere. Use this before search_entities / read_entity / traverse whenever the user refers to a named record.";
|
|
28
|
+
const SEARCH_DESCRIPTION = "Find records of a known type by filter and sort. Use this when you already have the type (from resolve_entity or because the user referred to a kind of record without identifying a specific one). To look up a specific record by its label, call resolve_entity first.";
|
|
29
|
+
const READ_DESCRIPTION = "Fetches one record by id, optionally pulling related records across described relationships.";
|
|
30
|
+
const TRAVERSE_DESCRIPTION = "Walks a relationship from a known record to related records, optionally filtered and sorted.";
|
|
31
|
+
const SEARCH_DOCS_DESCRIPTION = "Search the company's documents (GraphRAG) for information relevant to a question. Returns the retrieved passages, each prefixed by its chunkId.";
|
|
32
|
+
/**
|
|
33
|
+
* Builds the generic MCP tool set for one authenticated request:
|
|
34
|
+
* the five graph read tools, the document-retrieval tool, and the four
|
|
35
|
+
* entity write tools contributed by McpEntityWriteService.
|
|
36
|
+
*/
|
|
37
|
+
let McpGenericToolsService = class McpGenericToolsService {
|
|
38
|
+
constructor(resolveEntityTool, describeEntityTool, searchEntitiesTool, readEntityTool, traverseTool, searchDocumentsTool, writeService) {
|
|
39
|
+
this.resolveEntityTool = resolveEntityTool;
|
|
40
|
+
this.describeEntityTool = describeEntityTool;
|
|
41
|
+
this.searchEntitiesTool = searchEntitiesTool;
|
|
42
|
+
this.readEntityTool = readEntityTool;
|
|
43
|
+
this.traverseTool = traverseTool;
|
|
44
|
+
this.searchDocumentsTool = searchDocumentsTool;
|
|
45
|
+
this.writeService = writeService;
|
|
46
|
+
}
|
|
47
|
+
/** Builds the per-request generic tool definitions (read tools + write tools). */
|
|
48
|
+
build(ctx) {
|
|
49
|
+
const recorder = [];
|
|
50
|
+
// The graph tools enforce a describe-first contract via the recorder. That
|
|
51
|
+
// works in the operator, where one recorder spans a whole LangGraph turn —
|
|
52
|
+
// but MCP is stateless: every tools/call gets a fresh recorder, so a prior
|
|
53
|
+
// describe_entity call can never be seen and the contract would loop
|
|
54
|
+
// forever. Seed the recorder with the requested type instead (same
|
|
55
|
+
// approach as McpPromotedToolsFactory); the schema stays discoverable
|
|
56
|
+
// through the describe_entity MCP tool itself.
|
|
57
|
+
const seedDescribe = (type) => {
|
|
58
|
+
if (typeof type === "string" && type.length > 0) {
|
|
59
|
+
recorder.push({ tool: "describe_entity", input: { type }, durationMs: 0 });
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const read = (name, description, schema, invoke, seedType) => ({
|
|
63
|
+
name,
|
|
64
|
+
description,
|
|
65
|
+
inputSchema: zod_1.z.toJSONSchema(schema),
|
|
66
|
+
readOnly: true,
|
|
67
|
+
execute: async (input) => {
|
|
68
|
+
try {
|
|
69
|
+
const parsed = schema.parse(input);
|
|
70
|
+
if (seedType)
|
|
71
|
+
seedDescribe(seedType(parsed));
|
|
72
|
+
const result = await invoke(parsed);
|
|
73
|
+
return {
|
|
74
|
+
content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result) }],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
return (0, mcp_errors_1.mcpError)(e);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
return [
|
|
83
|
+
read("describe_entity", DESCRIBE_DESCRIPTION, describe_entity_tool_1.describeEntityInputSchema, (i) => this.describeEntityTool.invoke(i, ctx, recorder)),
|
|
84
|
+
read("resolve_entity", RESOLVE_DESCRIPTION, resolve_entity_tool_1.resolveEntityInputSchema, (i) => this.resolveEntityTool.invoke(i, ctx, recorder)),
|
|
85
|
+
read("search_entities", SEARCH_DESCRIPTION, search_entities_tool_1.searchEntitiesInputSchema, (i) => this.searchEntitiesTool.invoke(i, ctx, recorder), (parsed) => parsed.type),
|
|
86
|
+
read("read_entity", READ_DESCRIPTION, read_entity_tool_1.readEntityInputSchema, (i) => this.readEntityTool.invoke(i, ctx, recorder), (parsed) => parsed.type),
|
|
87
|
+
read("traverse", TRAVERSE_DESCRIPTION, traverse_tool_1.traverseInputSchema, (i) => this.traverseTool.invoke(i, ctx, recorder), (parsed) => parsed.fromType),
|
|
88
|
+
read("search_documents", SEARCH_DOCS_DESCRIPTION, search_documents_tool_1.searchDocumentsInputSchema, (i) =>
|
|
89
|
+
// SearchDocumentsTool needs an OperatorRetrievalContext; MCP has no
|
|
90
|
+
// conversation, so dataLimits defaults to {} (all fields optional)
|
|
91
|
+
// and messages to [] — the documented fallback.
|
|
92
|
+
this.searchDocumentsTool.invoke(i, { ...ctx, dataLimits: {}, messages: [] }, recorder)),
|
|
93
|
+
...this.writeService.buildTools(ctx),
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
exports.McpGenericToolsService = McpGenericToolsService;
|
|
98
|
+
exports.McpGenericToolsService = McpGenericToolsService = __decorate([
|
|
99
|
+
(0, common_1.Injectable)(),
|
|
100
|
+
__metadata("design:paramtypes", [resolve_entity_tool_1.ResolveEntityTool,
|
|
101
|
+
describe_entity_tool_1.DescribeEntityTool,
|
|
102
|
+
search_entities_tool_1.SearchEntitiesTool,
|
|
103
|
+
read_entity_tool_1.ReadEntityTool,
|
|
104
|
+
traverse_tool_1.TraverseTool,
|
|
105
|
+
search_documents_tool_1.SearchDocumentsTool,
|
|
106
|
+
mcp_entity_write_service_1.McpEntityWriteService])
|
|
107
|
+
], McpGenericToolsService);
|
|
108
|
+
//# sourceMappingURL=mcp.generic.tools.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.generic.tools.service.js","sourceRoot":"","sources":["../../../src/mcp/services/mcp.generic.tools.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ConfigService } from "@nestjs/config";
|
|
2
|
+
import { GraphCatalogService } from "../../agents/graph/services/graph.catalog.service";
|
|
3
|
+
import { ReadEntityTool } from "../../agents/graph/tools/read-entity.tool";
|
|
4
|
+
import { SearchEntitiesTool } from "../../agents/graph/tools/search-entities.tool";
|
|
5
|
+
import type { McpToolDefinition, McpUserContext } from "../interfaces/mcp.tool.interface";
|
|
6
|
+
import { McpEntityWriteService } from "./mcp.entity.write.service";
|
|
7
|
+
/**
|
|
8
|
+
* Maps an entity-descriptor field (as exposed by the graph catalog) to a JSON
|
|
9
|
+
* Schema property for MCP tool input schemas.
|
|
10
|
+
*
|
|
11
|
+
* Date and datetime fields are advertised as ISO strings on the wire
|
|
12
|
+
* (`format: "date"` / `format: "date-time"`); storage stays native Neo4j
|
|
13
|
+
* `Date`/`DateTime` because writes flow through the standard
|
|
14
|
+
* `AbstractService.createFromDTO`/`putFromDTO` path, which auto-casts —
|
|
15
|
+
* no custom Cypher is involved.
|
|
16
|
+
*
|
|
17
|
+
* Unknown descriptor types fall back to `{ type: "string" }`. The field's
|
|
18
|
+
* catalog description is carried through when present.
|
|
19
|
+
*/
|
|
20
|
+
export declare function descriptorFieldToJsonSchema(field: {
|
|
21
|
+
type: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
}): Record<string, unknown>;
|
|
24
|
+
/**
|
|
25
|
+
* Generates dedicated per-entity MCP tools (`search_<type>`, `get_<type>`,
|
|
26
|
+
* `create_<type>`, `update_<type>`) for every JSON:API type listed in
|
|
27
|
+
* `ConfigMcpInterface.promotedEntities`.
|
|
28
|
+
*
|
|
29
|
+
* Types the user cannot access (unknown type or module not granted) are
|
|
30
|
+
* skipped: `GraphCatalogService.getEntityDetail` returns `null` for both
|
|
31
|
+
* cases. Read tools delegate straight to the graph tool classes with the
|
|
32
|
+
* `type` pre-bound; write tools delegate to {@link McpEntityWriteService},
|
|
33
|
+
* which enforces RBAC and attribute validation.
|
|
34
|
+
*/
|
|
35
|
+
export declare class McpPromotedToolsFactory {
|
|
36
|
+
private readonly config;
|
|
37
|
+
private readonly catalog;
|
|
38
|
+
private readonly searchTool;
|
|
39
|
+
private readonly readTool;
|
|
40
|
+
private readonly writeService;
|
|
41
|
+
constructor(config: ConfigService, catalog: GraphCatalogService, searchTool: SearchEntitiesTool, readTool: ReadEntityTool, writeService: McpEntityWriteService);
|
|
42
|
+
/**
|
|
43
|
+
* Builds the promoted per-entity tool definitions for the given user
|
|
44
|
+
* context. Returns an empty array when no promoted entities are configured
|
|
45
|
+
* or none are accessible.
|
|
46
|
+
*/
|
|
47
|
+
build(ctx: McpUserContext): McpToolDefinition[];
|
|
48
|
+
private buildSearchTool;
|
|
49
|
+
private buildGetTool;
|
|
50
|
+
private buildCreateTool;
|
|
51
|
+
private buildUpdateTool;
|
|
52
|
+
private buildAttributesSchema;
|
|
53
|
+
private buildRelationshipsSchema;
|
|
54
|
+
private entityBlurb;
|
|
55
|
+
private textResult;
|
|
56
|
+
private internalError;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=mcp.promoted.tools.factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.promoted.tools.factory.d.ts","sourceRoot":"","sources":["../../../src/mcp/services/mcp.promoted.tools.factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mDAAmD,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,+CAA+C,CAAC;AAGnF,OAAO,KAAK,EAAE,iBAAiB,EAAiB,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACzG,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuBlH;AAED;;;;;;;;;;GAUG;AACH,qBACa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAJZ,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,mBAAmB,EAC5B,UAAU,EAAE,kBAAkB,EAC9B,QAAQ,EAAE,cAAc,EACxB,YAAY,EAAE,qBAAqB;IAGtD;;;;OAIG;IACH,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,iBAAiB,EAAE;IAyB/C,OAAO,CAAC,eAAe;IAkCvB,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,eAAe;IAyBvB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,wBAAwB;IAqBhC,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,aAAa;CAItB"}
|