@hexabot-ai/api 3.2.2-alpha.13 → 3.2.2-alpha.15
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/mcp/mcp-api.module.js +2 -2
- package/dist/mcp/mcp-api.module.js.map +1 -1
- package/dist/mcp/tools/catalog-mcp.tools.d.ts +63 -0
- package/dist/mcp/tools/catalog-mcp.tools.js +135 -0
- package/dist/mcp/tools/catalog-mcp.tools.js.map +1 -0
- package/dist/mcp/tools/cms-mcp.tools.d.ts +128 -0
- package/dist/mcp/tools/cms-mcp.tools.js +242 -0
- package/dist/mcp/tools/cms-mcp.tools.js.map +1 -0
- package/dist/mcp/tools/credential-mcp.tools.d.ts +19 -0
- package/dist/mcp/tools/credential-mcp.tools.js +82 -0
- package/dist/mcp/tools/credential-mcp.tools.js.map +1 -0
- package/dist/mcp/tools/hexabot-mcp-tool.base.d.ts +22 -0
- package/dist/mcp/tools/hexabot-mcp-tool.base.js +48 -0
- package/dist/mcp/tools/hexabot-mcp-tool.base.js.map +1 -0
- package/dist/mcp/tools/hexabot-mcp.schemas.d.ts +41 -0
- package/dist/mcp/tools/hexabot-mcp.schemas.js +36 -0
- package/dist/mcp/tools/hexabot-mcp.schemas.js.map +1 -0
- package/dist/mcp/tools/hexabot-mcp.tools.d.ts +1 -1199
- package/dist/mcp/tools/hexabot-mcp.tools.js +14 -953
- package/dist/mcp/tools/hexabot-mcp.tools.js.map +1 -1
- package/dist/mcp/tools/hexabot-mcp.utils.d.ts +1 -0
- package/dist/mcp/tools/hexabot-mcp.utils.js +9 -0
- package/dist/mcp/tools/hexabot-mcp.utils.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +22 -0
- package/dist/mcp/tools/index.js +50 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/mcp-server-mcp.tools.d.ts +77 -0
- package/dist/mcp/tools/mcp-server-mcp.tools.js +130 -0
- package/dist/mcp/tools/mcp-server-mcp.tools.js.map +1 -0
- package/dist/mcp/tools/memory-definition-mcp.tools.d.ts +57 -0
- package/dist/mcp/tools/memory-definition-mcp.tools.js +128 -0
- package/dist/mcp/tools/memory-definition-mcp.tools.js.map +1 -0
- package/dist/mcp/tools/workflow-mcp.helper.d.ts +141 -0
- package/dist/mcp/tools/workflow-mcp.helper.js +108 -0
- package/dist/mcp/tools/workflow-mcp.helper.js.map +1 -0
- package/dist/mcp/tools/workflow-mcp.tools.d.ts +468 -0
- package/dist/mcp/tools/workflow-mcp.tools.js +222 -0
- package/dist/mcp/tools/workflow-mcp.tools.js.map +1 -0
- package/dist/mcp/tools/workflow-run-mcp.tools.d.ts +347 -0
- package/dist/mcp/tools/workflow-run-mcp.tools.js +229 -0
- package/dist/mcp/tools/workflow-run-mcp.tools.js.map +1 -0
- package/dist/mcp/tools/workflow-version-mcp.tools.d.ts +230 -0
- package/dist/mcp/tools/workflow-version-mcp.tools.js +211 -0
- package/dist/mcp/tools/workflow-version-mcp.tools.js.map +1 -0
- package/dist/static/assets/{browser-ponyfill-BAQMT4v6.js → browser-ponyfill-D3QB7SUD.js} +1 -1
- package/dist/static/assets/{cssMode-Ck2GqK0z.js → cssMode-Bk0-m_Ij.js} +1 -1
- package/dist/static/assets/{freemarker2-D6BTrnBM.js → freemarker2-D1tTqqt8.js} +1 -1
- package/dist/static/assets/{handlebars-BZezzX8Y.js → handlebars-D3VQYLDj.js} +1 -1
- package/dist/static/assets/{html-BaHYviVY.js → html-Cmhr3-6_.js} +1 -1
- package/dist/static/assets/{htmlMode-DUmaotGP.js → htmlMode-Bb5Kynv_.js} +1 -1
- package/dist/static/assets/{index-BHEX1fRT.js → index-JPQj6OiL.js} +2000 -2000
- package/dist/static/assets/{javascript-B9CVllx-.js → javascript-BkQdNyFT.js} +1 -1
- package/dist/static/assets/{jsonMode-CKDg1one.js → jsonMode-CS1296LF.js} +1 -1
- package/dist/static/assets/{liquid-B0Y1CBIq.js → liquid-C9ufUE-r.js} +1 -1
- package/dist/static/assets/{lspLanguageFeatures-CEFdgYOu.js → lspLanguageFeatures-Dxd2SsrE.js} +1 -1
- package/dist/static/assets/{mdx-Deeg6oYM.js → mdx-Dm4bC48D.js} +1 -1
- package/dist/static/assets/{python-CwGXs8Vo.js → python-ZvBWpr_q.js} +1 -1
- package/dist/static/assets/{razor-DNVdulkX.js → razor-DBj-LyWR.js} +1 -1
- package/dist/static/assets/{tsMode-C1iFfVv3.js → tsMode-DzMlJB2i.js} +1 -1
- package/dist/static/assets/{typescript-BbwxPKOl.js → typescript-Cfo3bzpy.js} +1 -1
- package/dist/static/assets/{xml-mxS5SzT4.js → xml-ZyceR0L3.js} +1 -1
- package/dist/static/assets/{yaml-CScJydFV.js → yaml-oyu_gOar.js} +1 -1
- package/dist/static/index.html +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/test/port.d.ts +8 -0
- package/dist/utils/test/port.js +34 -0
- package/dist/utils/test/port.js.map +1 -0
- package/dist/workflow/services/workflow.service.d.ts +7 -7
- package/dist/workflow/services/workflow.service.js +40 -35
- package/dist/workflow/services/workflow.service.js.map +1 -1
- package/package.json +4 -4
- package/src/mcp/README.md +24 -3
- package/src/mcp/mcp-api.module.ts +2 -2
- package/src/mcp/tools/catalog-mcp.tools.ts +122 -0
- package/src/mcp/tools/cms-mcp.tools.ts +239 -0
- package/src/mcp/tools/credential-mcp.tools.ts +81 -0
- package/src/mcp/tools/hexabot-mcp-tool.base.ts +74 -0
- package/src/mcp/tools/hexabot-mcp.schemas.ts +55 -0
- package/src/mcp/tools/hexabot-mcp.tools.ts +1 -1035
- package/src/mcp/tools/hexabot-mcp.utils.ts +13 -0
- package/src/mcp/tools/index.ts +51 -0
- package/src/mcp/tools/mcp-server-mcp.tools.ts +135 -0
- package/src/mcp/tools/memory-definition-mcp.tools.ts +125 -0
- package/src/mcp/tools/workflow-mcp.helper.ts +166 -0
- package/src/mcp/tools/workflow-mcp.tools.ts +254 -0
- package/src/mcp/tools/workflow-run-mcp.tools.ts +274 -0
- package/src/mcp/tools/workflow-version-mcp.tools.ts +226 -0
- package/src/utils/test/port.ts +48 -0
- package/src/workflow/services/workflow.service.ts +49 -29
|
@@ -4,1038 +4,4 @@
|
|
|
4
4
|
* Full terms: see LICENSE.md.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
BadRequestException,
|
|
10
|
-
Injectable,
|
|
11
|
-
NotFoundException,
|
|
12
|
-
UnauthorizedException,
|
|
13
|
-
} from '@nestjs/common';
|
|
14
|
-
import { Tool, ToolGuards } from '@rekog/mcp-nest';
|
|
15
|
-
import { FindManyOptions, Like } from 'typeorm';
|
|
16
|
-
import { z } from 'zod';
|
|
17
|
-
|
|
18
|
-
import { ActionService } from '@/actions/actions.service';
|
|
19
|
-
import { RuntimeBindingsService } from '@/bindings/runtime-bindings.service';
|
|
20
|
-
import { ContentTypeOrmEntity } from '@/cms/entities/content-type.entity';
|
|
21
|
-
import { ContentOrmEntity } from '@/cms/entities/content.entity';
|
|
22
|
-
import { ContentTypeService } from '@/cms/services/content-type.service';
|
|
23
|
-
import { ContentService } from '@/cms/services/content.service';
|
|
24
|
-
import { CredentialService } from '@/user/services/credential.service';
|
|
25
|
-
import { WorkflowNewVersionDto } from '@/workflow/dto/workflow-version.dto';
|
|
26
|
-
import { WorkflowRunOrmEntity } from '@/workflow/entities/workflow-run.entity';
|
|
27
|
-
import { WorkflowVersionOrmEntity } from '@/workflow/entities/workflow-version.entity';
|
|
28
|
-
import { WorkflowOrmEntity } from '@/workflow/entities/workflow.entity';
|
|
29
|
-
import {
|
|
30
|
-
ManualEventWrapper,
|
|
31
|
-
ScheduledEventWrapper,
|
|
32
|
-
} from '@/workflow/lib/trigger-event-wrapper';
|
|
33
|
-
import { parseWorkflowDefinition } from '@/workflow/lib/workflow-definition';
|
|
34
|
-
import { AgenticService } from '@/workflow/services/agentic.service';
|
|
35
|
-
import { MemoryDefinitionService } from '@/workflow/services/memory-definition.service';
|
|
36
|
-
import { WorkflowRunService } from '@/workflow/services/workflow-run.service';
|
|
37
|
-
import { WorkflowVersionService } from '@/workflow/services/workflow-version.service';
|
|
38
|
-
import { WorkflowService } from '@/workflow/services/workflow.service';
|
|
39
|
-
import {
|
|
40
|
-
DirectionType,
|
|
41
|
-
MemoryScope,
|
|
42
|
-
WorkflowType,
|
|
43
|
-
WorkflowVersionAction,
|
|
44
|
-
} from '@/workflow/types';
|
|
45
|
-
|
|
46
|
-
import { McpPermission } from '../decorators/mcp-permission.decorator';
|
|
47
|
-
import { McpPermissionGuard } from '../guards/mcp-permission.guard';
|
|
48
|
-
import { HexabotMcpRequest } from '../types';
|
|
49
|
-
|
|
50
|
-
const uuidSchema = z.string().uuid();
|
|
51
|
-
const jsonObjectSchema = z.record(z.string(), z.unknown());
|
|
52
|
-
const paginationSchema = {
|
|
53
|
-
limit: z.number().int().min(1).max(100).default(20),
|
|
54
|
-
skip: z.number().int().min(0).default(0),
|
|
55
|
-
sortBy: z.string().default('createdAt'),
|
|
56
|
-
sortDirection: z.enum(['ASC', 'DESC']).default('DESC'),
|
|
57
|
-
};
|
|
58
|
-
const workflowPayloadSchema = {
|
|
59
|
-
name: z.string().min(1).optional(),
|
|
60
|
-
description: z.string().optional(),
|
|
61
|
-
type: z.enum(WorkflowType).optional(),
|
|
62
|
-
schedule: z.string().nullable().optional(),
|
|
63
|
-
inputSchema: jsonObjectSchema.optional(),
|
|
64
|
-
builtin: z.boolean().optional(),
|
|
65
|
-
x: z.number().optional(),
|
|
66
|
-
y: z.number().optional(),
|
|
67
|
-
zoom: z.number().optional(),
|
|
68
|
-
direction: z.enum(DirectionType).optional(),
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
type PaginationArgs = {
|
|
72
|
-
limit: number;
|
|
73
|
-
skip: number;
|
|
74
|
-
sortBy: string;
|
|
75
|
-
sortDirection: 'ASC' | 'DESC';
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
@Injectable()
|
|
79
|
-
export class HexabotMcpTools {
|
|
80
|
-
constructor(
|
|
81
|
-
private readonly workflowService: WorkflowService,
|
|
82
|
-
private readonly workflowVersionService: WorkflowVersionService,
|
|
83
|
-
private readonly workflowRunService: WorkflowRunService,
|
|
84
|
-
private readonly agenticService: AgenticService,
|
|
85
|
-
private readonly memoryDefinitionService: MemoryDefinitionService,
|
|
86
|
-
private readonly actionService: ActionService,
|
|
87
|
-
private readonly runtimeBindingsService: RuntimeBindingsService,
|
|
88
|
-
private readonly credentialService: CredentialService,
|
|
89
|
-
private readonly contentTypeService: ContentTypeService,
|
|
90
|
-
private readonly contentService: ContentService,
|
|
91
|
-
) {}
|
|
92
|
-
|
|
93
|
-
@McpPermission('workflow', Action.READ)
|
|
94
|
-
@ToolGuards([McpPermissionGuard])
|
|
95
|
-
@Tool({
|
|
96
|
-
name: 'hexabot_workflow_search',
|
|
97
|
-
description: 'Search Hexabot workflows by metadata.',
|
|
98
|
-
parameters: z.object({
|
|
99
|
-
query: z.string().optional(),
|
|
100
|
-
type: z.enum(WorkflowType).optional(),
|
|
101
|
-
createdById: uuidSchema.optional(),
|
|
102
|
-
...paginationSchema,
|
|
103
|
-
}),
|
|
104
|
-
})
|
|
105
|
-
async searchWorkflows(
|
|
106
|
-
args: {
|
|
107
|
-
query?: string;
|
|
108
|
-
type?: WorkflowType;
|
|
109
|
-
createdById?: string;
|
|
110
|
-
} & PaginationArgs,
|
|
111
|
-
) {
|
|
112
|
-
const where = this.buildWorkflowWhere(args);
|
|
113
|
-
const options = this.findOptions<WorkflowOrmEntity>(args, where);
|
|
114
|
-
|
|
115
|
-
return await this.listWithCount(this.workflowService, options);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
@McpPermission('workflow', Action.READ)
|
|
119
|
-
@ToolGuards([McpPermissionGuard])
|
|
120
|
-
@Tool({
|
|
121
|
-
name: 'hexabot_workflow_get',
|
|
122
|
-
description: 'Read a Hexabot workflow with populated version metadata.',
|
|
123
|
-
parameters: z.object({
|
|
124
|
-
id: uuidSchema,
|
|
125
|
-
}),
|
|
126
|
-
})
|
|
127
|
-
async getWorkflow(args: { id: string }) {
|
|
128
|
-
return await this.requireWorkflow(args.id);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
@McpPermission('workflow', Action.CREATE)
|
|
132
|
-
@ToolGuards([McpPermissionGuard])
|
|
133
|
-
@Tool({
|
|
134
|
-
name: 'hexabot_workflow_create',
|
|
135
|
-
description:
|
|
136
|
-
'Create a Hexabot workflow. Optionally commit an initial workflow definition YAML.',
|
|
137
|
-
parameters: z.object({
|
|
138
|
-
...workflowPayloadSchema,
|
|
139
|
-
name: z.string().min(1),
|
|
140
|
-
definitionYml: z.string().optional(),
|
|
141
|
-
versionMessage: z.string().optional(),
|
|
142
|
-
}),
|
|
143
|
-
})
|
|
144
|
-
async createWorkflow(
|
|
145
|
-
args: {
|
|
146
|
-
name: string;
|
|
147
|
-
description?: string;
|
|
148
|
-
type?: WorkflowType;
|
|
149
|
-
schedule?: string | null;
|
|
150
|
-
inputSchema?: Record<string, unknown>;
|
|
151
|
-
builtin?: boolean;
|
|
152
|
-
x?: number;
|
|
153
|
-
y?: number;
|
|
154
|
-
zoom?: number;
|
|
155
|
-
direction?: DirectionType;
|
|
156
|
-
definitionYml?: string;
|
|
157
|
-
versionMessage?: string;
|
|
158
|
-
},
|
|
159
|
-
_context: unknown,
|
|
160
|
-
request?: HexabotMcpRequest,
|
|
161
|
-
) {
|
|
162
|
-
const actorId = this.getActorId(request);
|
|
163
|
-
const { definitionYml, versionMessage, ...workflowPayload } = args;
|
|
164
|
-
const workflow = await this.workflowService.create({
|
|
165
|
-
...workflowPayload,
|
|
166
|
-
createdBy: actorId,
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
if (definitionYml) {
|
|
170
|
-
await this.commitWorkflowDefinition({
|
|
171
|
-
workflowId: workflow.id,
|
|
172
|
-
definitionYml,
|
|
173
|
-
message: versionMessage,
|
|
174
|
-
action: WorkflowVersionAction.update,
|
|
175
|
-
createdBy: actorId,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return await this.requireWorkflow(workflow.id);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
@McpPermission('workflow', Action.UPDATE)
|
|
183
|
-
@ToolGuards([McpPermissionGuard])
|
|
184
|
-
@Tool({
|
|
185
|
-
name: 'hexabot_workflow_update',
|
|
186
|
-
description:
|
|
187
|
-
'Update workflow metadata. Optionally commit a new workflow definition YAML version.',
|
|
188
|
-
parameters: z.object({
|
|
189
|
-
id: uuidSchema,
|
|
190
|
-
...workflowPayloadSchema,
|
|
191
|
-
definitionYml: z.string().optional(),
|
|
192
|
-
versionMessage: z.string().optional(),
|
|
193
|
-
}),
|
|
194
|
-
})
|
|
195
|
-
async updateWorkflow(
|
|
196
|
-
args: {
|
|
197
|
-
id: string;
|
|
198
|
-
definitionYml?: string;
|
|
199
|
-
versionMessage?: string;
|
|
200
|
-
} & Record<string, unknown>,
|
|
201
|
-
_context: unknown,
|
|
202
|
-
request?: HexabotMcpRequest,
|
|
203
|
-
) {
|
|
204
|
-
const actorId = this.getActorId(request);
|
|
205
|
-
const { id, definitionYml, versionMessage, ...updates } = args;
|
|
206
|
-
await this.requireWorkflow(id);
|
|
207
|
-
|
|
208
|
-
if (Object.keys(updates).length > 0) {
|
|
209
|
-
await this.workflowService.updateOne(id, updates as any);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (definitionYml) {
|
|
213
|
-
await this.commitWorkflowDefinition({
|
|
214
|
-
workflowId: id,
|
|
215
|
-
definitionYml,
|
|
216
|
-
message: versionMessage,
|
|
217
|
-
action: WorkflowVersionAction.update,
|
|
218
|
-
createdBy: actorId,
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
return await this.requireWorkflow(id);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
@McpPermission('workflowversion', Action.CREATE)
|
|
226
|
-
@ToolGuards([McpPermissionGuard])
|
|
227
|
-
@Tool({
|
|
228
|
-
name: 'hexabot_workflow_yaml_commit',
|
|
229
|
-
description:
|
|
230
|
-
'Validate and commit workflow definition YAML as a new version.',
|
|
231
|
-
parameters: z.object({
|
|
232
|
-
workflowId: uuidSchema,
|
|
233
|
-
definitionYml: z.string().min(1),
|
|
234
|
-
message: z.string().optional(),
|
|
235
|
-
parentVersion: uuidSchema.nullable().optional(),
|
|
236
|
-
action: z
|
|
237
|
-
.enum(WorkflowVersionAction)
|
|
238
|
-
.default(WorkflowVersionAction.update),
|
|
239
|
-
}),
|
|
240
|
-
})
|
|
241
|
-
async commitWorkflowYaml(
|
|
242
|
-
args: {
|
|
243
|
-
workflowId: string;
|
|
244
|
-
definitionYml: string;
|
|
245
|
-
message?: string;
|
|
246
|
-
parentVersion?: string | null;
|
|
247
|
-
action: WorkflowVersionAction;
|
|
248
|
-
},
|
|
249
|
-
_context: unknown,
|
|
250
|
-
request?: HexabotMcpRequest,
|
|
251
|
-
) {
|
|
252
|
-
const actorId = this.getActorId(request);
|
|
253
|
-
|
|
254
|
-
return await this.commitWorkflowDefinition({
|
|
255
|
-
...args,
|
|
256
|
-
createdBy: actorId,
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
@McpPermission('workflowversion', Action.READ)
|
|
261
|
-
@ToolGuards([McpPermissionGuard])
|
|
262
|
-
@Tool({
|
|
263
|
-
name: 'hexabot_workflow_version_search',
|
|
264
|
-
description: 'List workflow definition YAML versions for a workflow.',
|
|
265
|
-
parameters: z.object({
|
|
266
|
-
workflowId: uuidSchema,
|
|
267
|
-
...paginationSchema,
|
|
268
|
-
sortBy: z.string().default('version'),
|
|
269
|
-
sortDirection: z.enum(['ASC', 'DESC']).default('DESC'),
|
|
270
|
-
}),
|
|
271
|
-
})
|
|
272
|
-
async searchWorkflowVersions(args: { workflowId: string } & PaginationArgs) {
|
|
273
|
-
const where = { workflow: { id: args.workflowId } } as any;
|
|
274
|
-
|
|
275
|
-
return await this.listWithCount(
|
|
276
|
-
this.workflowVersionService,
|
|
277
|
-
this.findOptions<WorkflowVersionOrmEntity>(args, where),
|
|
278
|
-
);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
@McpPermission('workflowversion', Action.READ)
|
|
282
|
-
@ToolGuards([McpPermissionGuard])
|
|
283
|
-
@Tool({
|
|
284
|
-
name: 'hexabot_workflow_version_get',
|
|
285
|
-
description: 'Read one workflow definition YAML version.',
|
|
286
|
-
parameters: z.object({
|
|
287
|
-
id: uuidSchema,
|
|
288
|
-
workflowId: uuidSchema.optional(),
|
|
289
|
-
}),
|
|
290
|
-
})
|
|
291
|
-
async getWorkflowVersion(args: { id: string; workflowId?: string }) {
|
|
292
|
-
const version = await this.workflowVersionService.findOneAndPopulate({
|
|
293
|
-
where: {
|
|
294
|
-
id: args.id,
|
|
295
|
-
...(args.workflowId ? { workflow: { id: args.workflowId } } : {}),
|
|
296
|
-
} as any,
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
if (!version) {
|
|
300
|
-
throw new NotFoundException(`Workflow version ${args.id} not found`);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return version;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
@McpPermission('workflowversion', Action.UPDATE)
|
|
307
|
-
@ToolGuards([McpPermissionGuard])
|
|
308
|
-
@Tool({
|
|
309
|
-
name: 'hexabot_workflow_version_update',
|
|
310
|
-
description:
|
|
311
|
-
'Update workflow version metadata such as the version message.',
|
|
312
|
-
parameters: z.object({
|
|
313
|
-
id: uuidSchema,
|
|
314
|
-
message: z.string().nullable().optional(),
|
|
315
|
-
}),
|
|
316
|
-
})
|
|
317
|
-
async updateWorkflowVersion(args: { id: string; message?: string | null }) {
|
|
318
|
-
return await this.workflowVersionService.updateOne(args.id, {
|
|
319
|
-
message: args.message ?? undefined,
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
@McpPermission('workflowversion', Action.CREATE)
|
|
324
|
-
@ToolGuards([McpPermissionGuard])
|
|
325
|
-
@Tool({
|
|
326
|
-
name: 'hexabot_workflow_version_restore',
|
|
327
|
-
description:
|
|
328
|
-
'Restore a workflow to a previous YAML version by creating a new restore snapshot.',
|
|
329
|
-
parameters: z.object({
|
|
330
|
-
workflowId: uuidSchema,
|
|
331
|
-
versionId: uuidSchema,
|
|
332
|
-
message: z.string().optional(),
|
|
333
|
-
}),
|
|
334
|
-
})
|
|
335
|
-
async restoreWorkflowVersion(
|
|
336
|
-
args: { workflowId: string; versionId: string; message?: string },
|
|
337
|
-
_context: unknown,
|
|
338
|
-
request?: HexabotMcpRequest,
|
|
339
|
-
) {
|
|
340
|
-
return await this.workflowVersionService.restoreVersion(
|
|
341
|
-
args.workflowId,
|
|
342
|
-
args.versionId,
|
|
343
|
-
{
|
|
344
|
-
updatedBy: this.getActorId(request),
|
|
345
|
-
message: args.message,
|
|
346
|
-
},
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
@McpPermission('workflow', Action.UPDATE)
|
|
351
|
-
@ToolGuards([McpPermissionGuard])
|
|
352
|
-
@Tool({
|
|
353
|
-
name: 'hexabot_workflow_publish',
|
|
354
|
-
description: 'Publish the current workflow version.',
|
|
355
|
-
parameters: z.object({
|
|
356
|
-
id: uuidSchema,
|
|
357
|
-
}),
|
|
358
|
-
})
|
|
359
|
-
async publishWorkflow(args: { id: string }) {
|
|
360
|
-
const workflow = await this.workflowService.findOne(args.id);
|
|
361
|
-
if (!workflow) {
|
|
362
|
-
throw new NotFoundException(`Workflow ${args.id} not found`);
|
|
363
|
-
}
|
|
364
|
-
if (!workflow.currentVersion) {
|
|
365
|
-
throw new BadRequestException(
|
|
366
|
-
'Workflow must have a current version to be published',
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
await this.workflowService.updateOne(args.id, {
|
|
371
|
-
publishedVersion: workflow.currentVersion,
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
return await this.requireWorkflow(args.id);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
@McpPermission('workflow', Action.UPDATE)
|
|
378
|
-
@ToolGuards([McpPermissionGuard])
|
|
379
|
-
@Tool({
|
|
380
|
-
name: 'hexabot_workflow_unpublish',
|
|
381
|
-
description: 'Clear the published workflow version.',
|
|
382
|
-
parameters: z.object({
|
|
383
|
-
id: uuidSchema,
|
|
384
|
-
}),
|
|
385
|
-
})
|
|
386
|
-
async unpublishWorkflow(args: { id: string }) {
|
|
387
|
-
await this.requireWorkflow(args.id);
|
|
388
|
-
await this.workflowService.updateOne(args.id, { publishedVersion: null });
|
|
389
|
-
|
|
390
|
-
return await this.requireWorkflow(args.id);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
@McpPermission('workflowrun', Action.CREATE)
|
|
394
|
-
@ToolGuards([McpPermissionGuard])
|
|
395
|
-
@Tool({
|
|
396
|
-
name: 'hexabot_workflow_run',
|
|
397
|
-
description:
|
|
398
|
-
'Run a manual or scheduled workflow and return the run summary.',
|
|
399
|
-
parameters: z.object({
|
|
400
|
-
workflowId: uuidSchema,
|
|
401
|
-
input: jsonObjectSchema.default({}),
|
|
402
|
-
}),
|
|
403
|
-
})
|
|
404
|
-
async runWorkflow(
|
|
405
|
-
args: { workflowId: string; input: Record<string, unknown> },
|
|
406
|
-
_context: unknown,
|
|
407
|
-
request?: HexabotMcpRequest,
|
|
408
|
-
) {
|
|
409
|
-
const actor = this.getActor(request);
|
|
410
|
-
const workflow = await this.workflowService.findOne(args.workflowId);
|
|
411
|
-
if (!workflow) {
|
|
412
|
-
throw new NotFoundException(`Workflow ${args.workflowId} not found`);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
if (
|
|
416
|
-
workflow.type !== WorkflowType.manual &&
|
|
417
|
-
workflow.type !== WorkflowType.scheduled
|
|
418
|
-
) {
|
|
419
|
-
throw new BadRequestException(
|
|
420
|
-
'Workflow must be manual or scheduled to run manually',
|
|
421
|
-
);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
const event =
|
|
425
|
-
workflow.type === WorkflowType.scheduled
|
|
426
|
-
? new ScheduledEventWrapper({
|
|
427
|
-
schedule: workflow.schedule ?? null,
|
|
428
|
-
triggeredAt: new Date(),
|
|
429
|
-
})
|
|
430
|
-
: new ManualEventWrapper(
|
|
431
|
-
this.workflowService.validateManualInput(
|
|
432
|
-
args.input ?? {},
|
|
433
|
-
workflow.inputSchema,
|
|
434
|
-
),
|
|
435
|
-
actor.id,
|
|
436
|
-
);
|
|
437
|
-
event.setInitiator(actor);
|
|
438
|
-
event.setWorkflowId(workflow.id);
|
|
439
|
-
|
|
440
|
-
const run = await this.agenticService.handleEvent(event);
|
|
441
|
-
|
|
442
|
-
return { accepted: true, run };
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
@McpPermission('workflowrun', Action.READ)
|
|
446
|
-
@ToolGuards([McpPermissionGuard])
|
|
447
|
-
@Tool({
|
|
448
|
-
name: 'hexabot_workflow_run_search',
|
|
449
|
-
description: 'Search workflow runs by workflow and status.',
|
|
450
|
-
parameters: z.object({
|
|
451
|
-
workflowId: uuidSchema.optional(),
|
|
452
|
-
status: z.string().optional(),
|
|
453
|
-
...paginationSchema,
|
|
454
|
-
}),
|
|
455
|
-
})
|
|
456
|
-
async searchWorkflowRuns(
|
|
457
|
-
args: { workflowId?: string; status?: string } & PaginationArgs,
|
|
458
|
-
) {
|
|
459
|
-
const where = {
|
|
460
|
-
...(args.workflowId ? { workflow: { id: args.workflowId } } : {}),
|
|
461
|
-
...(args.status ? { status: args.status } : {}),
|
|
462
|
-
} as any;
|
|
463
|
-
|
|
464
|
-
return await this.listWithCount(
|
|
465
|
-
this.workflowRunService,
|
|
466
|
-
this.findOptions<WorkflowRunOrmEntity>(args, where),
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
@McpPermission('workflowrun', Action.READ)
|
|
471
|
-
@ToolGuards([McpPermissionGuard])
|
|
472
|
-
@Tool({
|
|
473
|
-
name: 'hexabot_workflow_run_get',
|
|
474
|
-
description: 'Read one workflow run with populated workflow metadata.',
|
|
475
|
-
parameters: z.object({
|
|
476
|
-
id: uuidSchema,
|
|
477
|
-
}),
|
|
478
|
-
})
|
|
479
|
-
async getWorkflowRun(args: { id: string }) {
|
|
480
|
-
const run = await this.workflowRunService.findOneAndPopulate(args.id);
|
|
481
|
-
if (!run) {
|
|
482
|
-
throw new NotFoundException(`Workflow run ${args.id} not found`);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
return run;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
@McpPermission('memorydefinition', Action.READ)
|
|
489
|
-
@ToolGuards([McpPermissionGuard])
|
|
490
|
-
@Tool({
|
|
491
|
-
name: 'hexabot_memory_definition_search',
|
|
492
|
-
description: 'Search workflow memory definitions.',
|
|
493
|
-
parameters: z.object({
|
|
494
|
-
query: z.string().optional(),
|
|
495
|
-
scope: z.enum(MemoryScope).optional(),
|
|
496
|
-
...paginationSchema,
|
|
497
|
-
}),
|
|
498
|
-
})
|
|
499
|
-
async searchMemoryDefinitions(
|
|
500
|
-
args: { query?: string; scope?: MemoryScope } & PaginationArgs,
|
|
501
|
-
) {
|
|
502
|
-
const base = args.scope ? { scope: args.scope } : {};
|
|
503
|
-
const where = args.query
|
|
504
|
-
? [
|
|
505
|
-
{ ...base, name: this.contains(args.query) },
|
|
506
|
-
{ ...base, slug: this.contains(args.query) },
|
|
507
|
-
]
|
|
508
|
-
: base;
|
|
509
|
-
|
|
510
|
-
return await this.listWithCount(
|
|
511
|
-
this.memoryDefinitionService,
|
|
512
|
-
this.findOptions(args, where),
|
|
513
|
-
);
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
@McpPermission('memorydefinition', Action.READ)
|
|
517
|
-
@ToolGuards([McpPermissionGuard])
|
|
518
|
-
@Tool({
|
|
519
|
-
name: 'hexabot_memory_definition_get',
|
|
520
|
-
description: 'Read one workflow memory definition.',
|
|
521
|
-
parameters: z.object({
|
|
522
|
-
id: uuidSchema,
|
|
523
|
-
}),
|
|
524
|
-
})
|
|
525
|
-
async getMemoryDefinition(args: { id: string }) {
|
|
526
|
-
const definition = await this.memoryDefinitionService.findOne(args.id);
|
|
527
|
-
if (!definition) {
|
|
528
|
-
throw new NotFoundException(`Memory definition ${args.id} not found`);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
return definition;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
@McpPermission('memorydefinition', Action.CREATE)
|
|
535
|
-
@ToolGuards([McpPermissionGuard])
|
|
536
|
-
@Tool({
|
|
537
|
-
name: 'hexabot_memory_definition_create',
|
|
538
|
-
description: 'Create a workflow memory definition.',
|
|
539
|
-
parameters: z.object({
|
|
540
|
-
name: z.string().min(1),
|
|
541
|
-
slug: z.string().regex(/^[a-z0-9_]+$/),
|
|
542
|
-
scope: z.enum(MemoryScope),
|
|
543
|
-
schema: jsonObjectSchema,
|
|
544
|
-
ttlSeconds: z.number().int().min(1).nullable().optional(),
|
|
545
|
-
}),
|
|
546
|
-
})
|
|
547
|
-
async createMemoryDefinition(args: {
|
|
548
|
-
name: string;
|
|
549
|
-
slug: string;
|
|
550
|
-
scope: MemoryScope;
|
|
551
|
-
schema: Record<string, unknown>;
|
|
552
|
-
ttlSeconds?: number | null;
|
|
553
|
-
}) {
|
|
554
|
-
return await this.memoryDefinitionService.create(args as any);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
@McpPermission('memorydefinition', Action.UPDATE)
|
|
558
|
-
@ToolGuards([McpPermissionGuard])
|
|
559
|
-
@Tool({
|
|
560
|
-
name: 'hexabot_memory_definition_update',
|
|
561
|
-
description: 'Update a workflow memory definition.',
|
|
562
|
-
parameters: z.object({
|
|
563
|
-
id: uuidSchema,
|
|
564
|
-
name: z.string().min(1).optional(),
|
|
565
|
-
slug: z
|
|
566
|
-
.string()
|
|
567
|
-
.regex(/^[a-z0-9_]+$/)
|
|
568
|
-
.optional(),
|
|
569
|
-
scope: z.enum(MemoryScope).optional(),
|
|
570
|
-
schema: jsonObjectSchema.optional(),
|
|
571
|
-
ttlSeconds: z.number().int().min(1).nullable().optional(),
|
|
572
|
-
}),
|
|
573
|
-
})
|
|
574
|
-
async updateMemoryDefinition(args: { id: string } & Record<string, unknown>) {
|
|
575
|
-
const { id, ...updates } = args;
|
|
576
|
-
|
|
577
|
-
return await this.memoryDefinitionService.updateOne(id, updates as any);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
@McpPermission('workflow', Action.READ)
|
|
581
|
-
@ToolGuards([McpPermissionGuard])
|
|
582
|
-
@Tool({
|
|
583
|
-
name: 'hexabot_action_search',
|
|
584
|
-
description: 'Search available workflow actions and their schemas.',
|
|
585
|
-
parameters: z.object({
|
|
586
|
-
query: z.string().optional(),
|
|
587
|
-
workflowType: z.enum(WorkflowType).optional(),
|
|
588
|
-
}),
|
|
589
|
-
})
|
|
590
|
-
async searchActions(args: { query?: string; workflowType?: WorkflowType }) {
|
|
591
|
-
const query = args.query?.toLowerCase();
|
|
592
|
-
const actions = this.actionService.getAllSchemaDefinitions(
|
|
593
|
-
args.workflowType,
|
|
594
|
-
);
|
|
595
|
-
|
|
596
|
-
return {
|
|
597
|
-
items: query
|
|
598
|
-
? actions.filter((action) =>
|
|
599
|
-
[
|
|
600
|
-
action.name,
|
|
601
|
-
action.description,
|
|
602
|
-
action.group,
|
|
603
|
-
...(action.workflowTypes ?? []),
|
|
604
|
-
]
|
|
605
|
-
.filter(Boolean)
|
|
606
|
-
.some((value) => `${value}`.toLowerCase().includes(query)),
|
|
607
|
-
)
|
|
608
|
-
: actions,
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
@McpPermission('workflow', Action.READ)
|
|
613
|
-
@ToolGuards([McpPermissionGuard])
|
|
614
|
-
@Tool({
|
|
615
|
-
name: 'hexabot_action_get',
|
|
616
|
-
description: 'Read schema metadata for one workflow action.',
|
|
617
|
-
parameters: z.object({
|
|
618
|
-
name: z.string().min(1),
|
|
619
|
-
}),
|
|
620
|
-
})
|
|
621
|
-
async getAction(args: { name: string }) {
|
|
622
|
-
const action = this.actionService
|
|
623
|
-
.getAllSchemaDefinitions()
|
|
624
|
-
.find((entry) => entry.name === args.name);
|
|
625
|
-
if (!action) {
|
|
626
|
-
throw new NotFoundException(`Action ${args.name} not found`);
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
return action;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
@McpPermission('workflow', Action.READ)
|
|
633
|
-
@ToolGuards([McpPermissionGuard])
|
|
634
|
-
@Tool({
|
|
635
|
-
name: 'hexabot_binding_search',
|
|
636
|
-
description: 'Search workflow runtime binding kind schemas.',
|
|
637
|
-
parameters: z.object({
|
|
638
|
-
query: z.string().optional(),
|
|
639
|
-
}),
|
|
640
|
-
})
|
|
641
|
-
async searchBindings(args: { query?: string }) {
|
|
642
|
-
const query = args.query?.toLowerCase();
|
|
643
|
-
const entries = Object.entries(
|
|
644
|
-
this.runtimeBindingsService.getAllSchemaDefinitions(),
|
|
645
|
-
).map(([kind, definition]) => ({ kind, ...definition }));
|
|
646
|
-
|
|
647
|
-
return {
|
|
648
|
-
items: query
|
|
649
|
-
? entries.filter((entry) =>
|
|
650
|
-
[entry.kind, entry.icon, entry.color]
|
|
651
|
-
.filter(Boolean)
|
|
652
|
-
.some((value) => `${value}`.toLowerCase().includes(query)),
|
|
653
|
-
)
|
|
654
|
-
: entries,
|
|
655
|
-
};
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
@McpPermission('workflow', Action.READ)
|
|
659
|
-
@ToolGuards([McpPermissionGuard])
|
|
660
|
-
@Tool({
|
|
661
|
-
name: 'hexabot_binding_get',
|
|
662
|
-
description: 'Read schema metadata for one workflow runtime binding kind.',
|
|
663
|
-
parameters: z.object({
|
|
664
|
-
kind: z.string().min(1),
|
|
665
|
-
}),
|
|
666
|
-
})
|
|
667
|
-
async getBinding(args: { kind: string }) {
|
|
668
|
-
const bindings = this.runtimeBindingsService.getAllSchemaDefinitions();
|
|
669
|
-
const binding = bindings[args.kind];
|
|
670
|
-
if (!binding) {
|
|
671
|
-
throw new NotFoundException(`Binding kind ${args.kind} not found`);
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
return { kind: args.kind, ...binding };
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
@McpPermission('credential', Action.READ)
|
|
678
|
-
@ToolGuards([McpPermissionGuard])
|
|
679
|
-
@Tool({
|
|
680
|
-
name: 'hexabot_credential_search',
|
|
681
|
-
description:
|
|
682
|
-
'Search credentials by metadata only. Secret credential values are never returned.',
|
|
683
|
-
parameters: z.object({
|
|
684
|
-
query: z.string().optional(),
|
|
685
|
-
ownerId: uuidSchema.optional(),
|
|
686
|
-
...paginationSchema,
|
|
687
|
-
}),
|
|
688
|
-
})
|
|
689
|
-
async searchCredentials(
|
|
690
|
-
args: { query?: string; ownerId?: string } & PaginationArgs,
|
|
691
|
-
) {
|
|
692
|
-
const where = {
|
|
693
|
-
...(args.ownerId ? { owner: { id: args.ownerId } } : {}),
|
|
694
|
-
...(args.query ? { name: this.contains(args.query) } : {}),
|
|
695
|
-
} as any;
|
|
696
|
-
const result = await this.listWithCount(
|
|
697
|
-
this.credentialService,
|
|
698
|
-
this.findOptions(args, where),
|
|
699
|
-
);
|
|
700
|
-
|
|
701
|
-
return {
|
|
702
|
-
...result,
|
|
703
|
-
items: result.items.map(HexabotMcpTools.sanitizeCredential),
|
|
704
|
-
};
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
@McpPermission('credential', Action.READ)
|
|
708
|
-
@ToolGuards([McpPermissionGuard])
|
|
709
|
-
@Tool({
|
|
710
|
-
name: 'hexabot_credential_get',
|
|
711
|
-
description:
|
|
712
|
-
'Read credential metadata. Secret credential values are never returned.',
|
|
713
|
-
parameters: z.object({
|
|
714
|
-
id: uuidSchema,
|
|
715
|
-
}),
|
|
716
|
-
})
|
|
717
|
-
async getCredential(args: { id: string }) {
|
|
718
|
-
const credential = await this.credentialService.findOneAndPopulate(args.id);
|
|
719
|
-
if (!credential) {
|
|
720
|
-
throw new NotFoundException(`Credential ${args.id} not found`);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
return HexabotMcpTools.sanitizeCredential(credential);
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
@McpPermission('contenttype', Action.READ)
|
|
727
|
-
@ToolGuards([McpPermissionGuard])
|
|
728
|
-
@Tool({
|
|
729
|
-
name: 'hexabot_content_type_search',
|
|
730
|
-
description: 'Search CMS content types.',
|
|
731
|
-
parameters: z.object({
|
|
732
|
-
query: z.string().optional(),
|
|
733
|
-
...paginationSchema,
|
|
734
|
-
}),
|
|
735
|
-
})
|
|
736
|
-
async searchContentTypes(args: { query?: string } & PaginationArgs) {
|
|
737
|
-
const where = args.query ? { name: this.contains(args.query) } : {};
|
|
738
|
-
|
|
739
|
-
return await this.listWithCount(
|
|
740
|
-
this.contentTypeService,
|
|
741
|
-
this.findOptions<ContentTypeOrmEntity>(args, where),
|
|
742
|
-
);
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
@McpPermission('contenttype', Action.READ)
|
|
746
|
-
@ToolGuards([McpPermissionGuard])
|
|
747
|
-
@Tool({
|
|
748
|
-
name: 'hexabot_content_type_get',
|
|
749
|
-
description: 'Read one CMS content type.',
|
|
750
|
-
parameters: z.object({
|
|
751
|
-
id: uuidSchema,
|
|
752
|
-
}),
|
|
753
|
-
})
|
|
754
|
-
async getContentType(args: { id: string }) {
|
|
755
|
-
const contentType = await this.contentTypeService.findOne(args.id);
|
|
756
|
-
if (!contentType) {
|
|
757
|
-
throw new NotFoundException(`Content type ${args.id} not found`);
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
return contentType;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
@McpPermission('contenttype', Action.CREATE)
|
|
764
|
-
@ToolGuards([McpPermissionGuard])
|
|
765
|
-
@Tool({
|
|
766
|
-
name: 'hexabot_content_type_create',
|
|
767
|
-
description: 'Create a CMS content type.',
|
|
768
|
-
parameters: z.object({
|
|
769
|
-
name: z.string().min(1),
|
|
770
|
-
schema: jsonObjectSchema,
|
|
771
|
-
}),
|
|
772
|
-
})
|
|
773
|
-
async createContentType(args: {
|
|
774
|
-
name: string;
|
|
775
|
-
schema: Record<string, unknown>;
|
|
776
|
-
}) {
|
|
777
|
-
return await this.contentTypeService.create(args as any);
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
@McpPermission('contenttype', Action.UPDATE)
|
|
781
|
-
@ToolGuards([McpPermissionGuard])
|
|
782
|
-
@Tool({
|
|
783
|
-
name: 'hexabot_content_type_update',
|
|
784
|
-
description: 'Update a CMS content type.',
|
|
785
|
-
parameters: z.object({
|
|
786
|
-
id: uuidSchema,
|
|
787
|
-
name: z.string().min(1).optional(),
|
|
788
|
-
schema: jsonObjectSchema.optional(),
|
|
789
|
-
}),
|
|
790
|
-
})
|
|
791
|
-
async updateContentType(args: { id: string } & Record<string, unknown>) {
|
|
792
|
-
const { id, ...updates } = args;
|
|
793
|
-
|
|
794
|
-
return await this.contentTypeService.updateOne(id, updates as any);
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
@McpPermission('content', Action.READ)
|
|
798
|
-
@ToolGuards([McpPermissionGuard])
|
|
799
|
-
@Tool({
|
|
800
|
-
name: 'hexabot_content_search',
|
|
801
|
-
description: 'Search CMS content records.',
|
|
802
|
-
parameters: z.object({
|
|
803
|
-
query: z.string().optional(),
|
|
804
|
-
contentTypeId: uuidSchema.optional(),
|
|
805
|
-
status: z.boolean().optional(),
|
|
806
|
-
...paginationSchema,
|
|
807
|
-
}),
|
|
808
|
-
})
|
|
809
|
-
async searchContent(
|
|
810
|
-
args: {
|
|
811
|
-
query?: string;
|
|
812
|
-
contentTypeId?: string;
|
|
813
|
-
status?: boolean;
|
|
814
|
-
} & PaginationArgs,
|
|
815
|
-
) {
|
|
816
|
-
if (args.query) {
|
|
817
|
-
return {
|
|
818
|
-
items: await this.contentService.textSearch(args.query, {
|
|
819
|
-
status: args.status,
|
|
820
|
-
contentTypeId: args.contentTypeId,
|
|
821
|
-
limit: args.limit,
|
|
822
|
-
}),
|
|
823
|
-
limit: args.limit,
|
|
824
|
-
skip: 0,
|
|
825
|
-
};
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
const where = {
|
|
829
|
-
...(args.contentTypeId
|
|
830
|
-
? { contentType: { id: args.contentTypeId } }
|
|
831
|
-
: {}),
|
|
832
|
-
...(args.status !== undefined ? { status: args.status } : {}),
|
|
833
|
-
} as any;
|
|
834
|
-
|
|
835
|
-
return await this.listWithCount(
|
|
836
|
-
this.contentService,
|
|
837
|
-
this.findOptions<ContentOrmEntity>(args, where),
|
|
838
|
-
);
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
@McpPermission('content', Action.READ)
|
|
842
|
-
@ToolGuards([McpPermissionGuard])
|
|
843
|
-
@Tool({
|
|
844
|
-
name: 'hexabot_content_get',
|
|
845
|
-
description: 'Read one CMS content record.',
|
|
846
|
-
parameters: z.object({
|
|
847
|
-
id: uuidSchema,
|
|
848
|
-
}),
|
|
849
|
-
})
|
|
850
|
-
async getContent(args: { id: string }) {
|
|
851
|
-
const content = await this.contentService.findOneAndPopulate(args.id);
|
|
852
|
-
if (!content) {
|
|
853
|
-
throw new NotFoundException(`Content ${args.id} not found`);
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
return content;
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
@McpPermission('content', Action.CREATE)
|
|
860
|
-
@ToolGuards([McpPermissionGuard])
|
|
861
|
-
@Tool({
|
|
862
|
-
name: 'hexabot_content_create',
|
|
863
|
-
description: 'Create a CMS content record.',
|
|
864
|
-
parameters: z.object({
|
|
865
|
-
contentType: uuidSchema,
|
|
866
|
-
title: z.string().min(1),
|
|
867
|
-
status: z.boolean().optional(),
|
|
868
|
-
properties: jsonObjectSchema.optional(),
|
|
869
|
-
}),
|
|
870
|
-
})
|
|
871
|
-
async createContent(args: {
|
|
872
|
-
contentType: string;
|
|
873
|
-
title: string;
|
|
874
|
-
status?: boolean;
|
|
875
|
-
properties?: Record<string, unknown>;
|
|
876
|
-
}) {
|
|
877
|
-
return await this.contentService.create(args as any);
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
@McpPermission('content', Action.UPDATE)
|
|
881
|
-
@ToolGuards([McpPermissionGuard])
|
|
882
|
-
@Tool({
|
|
883
|
-
name: 'hexabot_content_update',
|
|
884
|
-
description: 'Update a CMS content record.',
|
|
885
|
-
parameters: z.object({
|
|
886
|
-
id: uuidSchema,
|
|
887
|
-
contentType: uuidSchema.optional(),
|
|
888
|
-
title: z.string().min(1).optional(),
|
|
889
|
-
status: z.boolean().optional(),
|
|
890
|
-
properties: jsonObjectSchema.optional(),
|
|
891
|
-
}),
|
|
892
|
-
})
|
|
893
|
-
async updateContent(args: { id: string } & Record<string, unknown>) {
|
|
894
|
-
const { id, ...updates } = args;
|
|
895
|
-
|
|
896
|
-
return await this.contentService.updateOne(id, updates as any);
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
@McpPermission('content', Action.READ)
|
|
900
|
-
@ToolGuards([McpPermissionGuard])
|
|
901
|
-
@Tool({
|
|
902
|
-
name: 'hexabot_rag_content_search',
|
|
903
|
-
description: 'Search indexed CMS content through Hexabot RAG retrieval.',
|
|
904
|
-
parameters: z.object({
|
|
905
|
-
query: z.string().min(1),
|
|
906
|
-
mode: z.enum(['embedding', 'lexical']).optional(),
|
|
907
|
-
limit: z.number().int().min(1).max(50).default(10),
|
|
908
|
-
contentTypeId: uuidSchema.optional(),
|
|
909
|
-
includeInactive: z.boolean().optional(),
|
|
910
|
-
}),
|
|
911
|
-
})
|
|
912
|
-
async searchRagContent(args: {
|
|
913
|
-
query: string;
|
|
914
|
-
mode?: 'embedding' | 'lexical';
|
|
915
|
-
limit: number;
|
|
916
|
-
contentTypeId?: string;
|
|
917
|
-
includeInactive?: boolean;
|
|
918
|
-
}) {
|
|
919
|
-
return {
|
|
920
|
-
items: await this.contentService.retrieve(args.query, {
|
|
921
|
-
mode: args.mode,
|
|
922
|
-
limit: args.limit,
|
|
923
|
-
contentTypeId: args.contentTypeId,
|
|
924
|
-
includeInactive: args.includeInactive,
|
|
925
|
-
}),
|
|
926
|
-
};
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
static sanitizeCredential<T extends Record<string, unknown>>(
|
|
930
|
-
credential: T,
|
|
931
|
-
): T {
|
|
932
|
-
const { value: _value, ...safeCredential } = credential;
|
|
933
|
-
|
|
934
|
-
return safeCredential as T;
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
private buildWorkflowWhere(args: {
|
|
938
|
-
query?: string;
|
|
939
|
-
type?: WorkflowType;
|
|
940
|
-
createdById?: string;
|
|
941
|
-
}) {
|
|
942
|
-
const base = {
|
|
943
|
-
...(args.type ? { type: args.type } : {}),
|
|
944
|
-
...(args.createdById ? { createdBy: { id: args.createdById } } : {}),
|
|
945
|
-
};
|
|
946
|
-
|
|
947
|
-
return args.query
|
|
948
|
-
? [
|
|
949
|
-
{ ...base, name: this.contains(args.query) },
|
|
950
|
-
{ ...base, description: this.contains(args.query) },
|
|
951
|
-
]
|
|
952
|
-
: base;
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
private async requireWorkflow(id: string) {
|
|
956
|
-
const workflow = await this.workflowService.findOneAndPopulate(id);
|
|
957
|
-
if (!workflow) {
|
|
958
|
-
throw new NotFoundException(`Workflow ${id} not found`);
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
return workflow;
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
private async commitWorkflowDefinition(params: {
|
|
965
|
-
workflowId: string;
|
|
966
|
-
definitionYml: string;
|
|
967
|
-
message?: string | null;
|
|
968
|
-
parentVersion?: string | null;
|
|
969
|
-
action?: WorkflowVersionAction;
|
|
970
|
-
createdBy: string;
|
|
971
|
-
}) {
|
|
972
|
-
await this.requireWorkflow(params.workflowId);
|
|
973
|
-
try {
|
|
974
|
-
parseWorkflowDefinition(params.definitionYml);
|
|
975
|
-
} catch (error) {
|
|
976
|
-
throw new BadRequestException(
|
|
977
|
-
error instanceof Error ? error.message : 'Invalid workflow YAML',
|
|
978
|
-
);
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
const payload: WorkflowNewVersionDto = {
|
|
982
|
-
workflow: params.workflowId,
|
|
983
|
-
definitionYml: params.definitionYml,
|
|
984
|
-
message: params.message ?? undefined,
|
|
985
|
-
parentVersion: params.parentVersion ?? undefined,
|
|
986
|
-
action: params.action ?? WorkflowVersionAction.update,
|
|
987
|
-
createdBy: params.createdBy,
|
|
988
|
-
};
|
|
989
|
-
|
|
990
|
-
return await this.workflowVersionService.commit(payload);
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
private findOptions<Entity>(
|
|
994
|
-
args: PaginationArgs,
|
|
995
|
-
where: FindManyOptions<Entity>['where'],
|
|
996
|
-
): FindManyOptions<Entity> {
|
|
997
|
-
return {
|
|
998
|
-
where,
|
|
999
|
-
take: args.limit,
|
|
1000
|
-
skip: args.skip,
|
|
1001
|
-
order: { [args.sortBy]: args.sortDirection } as any,
|
|
1002
|
-
};
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
private async listWithCount<Entity>(
|
|
1006
|
-
service: {
|
|
1007
|
-
findAndPopulate(options?: FindManyOptions<Entity>): Promise<unknown[]>;
|
|
1008
|
-
count(options?: FindManyOptions<Entity>): Promise<number>;
|
|
1009
|
-
},
|
|
1010
|
-
options: FindManyOptions<Entity>,
|
|
1011
|
-
) {
|
|
1012
|
-
const [items, total] = await Promise.all([
|
|
1013
|
-
service.findAndPopulate(options),
|
|
1014
|
-
service.count({ where: options.where }),
|
|
1015
|
-
]);
|
|
1016
|
-
|
|
1017
|
-
return {
|
|
1018
|
-
items,
|
|
1019
|
-
total,
|
|
1020
|
-
limit: options.take,
|
|
1021
|
-
skip: options.skip,
|
|
1022
|
-
};
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
private contains(value: string) {
|
|
1026
|
-
return Like(`%${value}%`);
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
private getActor(request?: HexabotMcpRequest): User {
|
|
1030
|
-
const actor = request?.hexabotUser ?? request?.user;
|
|
1031
|
-
if (!actor?.id) {
|
|
1032
|
-
throw new UnauthorizedException('MCP Hexabot user is required');
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
return actor as User;
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
private getActorId(request?: HexabotMcpRequest): string {
|
|
1039
|
-
return this.getActor(request).id;
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
7
|
+
export * from './index';
|