@hexabot-ai/api 3.2.2-alpha.12 → 3.2.2-alpha.14
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/tools/hexabot-mcp.tools.d.ts +132 -2
- package/dist/mcp/tools/hexabot-mcp.tools.js +146 -2
- package/dist/mcp/tools/hexabot-mcp.tools.js.map +1 -1
- package/dist/static/assets/{browser-ponyfill-jlQAUd0m.js → browser-ponyfill-D3QB7SUD.js} +1 -1
- package/dist/static/assets/{cssMode-CmMO_Mso.js → cssMode-Bk0-m_Ij.js} +1 -1
- package/dist/static/assets/{freemarker2-DcQVPFyh.js → freemarker2-D1tTqqt8.js} +1 -1
- package/dist/static/assets/{handlebars-DcnzpFQC.js → handlebars-D3VQYLDj.js} +1 -1
- package/dist/static/assets/{html-BFzOjuas.js → html-Cmhr3-6_.js} +1 -1
- package/dist/static/assets/{htmlMode-C-vRCUKF.js → htmlMode-Bb5Kynv_.js} +1 -1
- package/dist/static/assets/{index-BKczCDFq.js → index-JPQj6OiL.js} +75 -75
- package/dist/static/assets/{javascript-Cw6lfMAI.js → javascript-BkQdNyFT.js} +1 -1
- package/dist/static/assets/{jsonMode-5xhIbw7r.js → jsonMode-CS1296LF.js} +1 -1
- package/dist/static/assets/{liquid-DRY_tZKy.js → liquid-C9ufUE-r.js} +1 -1
- package/dist/static/assets/{lspLanguageFeatures-g0jq7rI8.js → lspLanguageFeatures-Dxd2SsrE.js} +1 -1
- package/dist/static/assets/{mdx-Cj1GGNiS.js → mdx-Dm4bC48D.js} +1 -1
- package/dist/static/assets/{python-Cx_web_-.js → python-ZvBWpr_q.js} +1 -1
- package/dist/static/assets/{razor-Bf3Htwpg.js → razor-DBj-LyWR.js} +1 -1
- package/dist/static/assets/{tsMode-DcrJAKHJ.js → tsMode-DzMlJB2i.js} +1 -1
- package/dist/static/assets/{typescript-D_NLpP2s.js → typescript-Cfo3bzpy.js} +1 -1
- package/dist/static/assets/{xml-DX7g-Nrp.js → xml-ZyceR0L3.js} +1 -1
- package/dist/static/assets/{yaml-BO2WdsT4.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/package.json +4 -4
- package/src/mcp/README.md +13 -2
- package/src/mcp/tools/hexabot-mcp.tools.ts +159 -0
- package/src/utils/test/port.ts +48 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const getJestPort: () => number;
|
|
2
|
+
export declare const getJestHost: () => string;
|
|
3
|
+
export declare const getJestBaseUrl: () => string;
|
|
4
|
+
export declare const configureJestNetworkEnv: () => {
|
|
5
|
+
port: number;
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
apiOrigin: string;
|
|
8
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureJestNetworkEnv = exports.getJestBaseUrl = exports.getJestHost = exports.getJestPort = void 0;
|
|
4
|
+
const DEFAULT_JEST_PORT = 3001;
|
|
5
|
+
const JEST_HOST = '127.0.0.1';
|
|
6
|
+
const parsePort = (value, envName) => {
|
|
7
|
+
if (!value) {
|
|
8
|
+
return DEFAULT_JEST_PORT;
|
|
9
|
+
}
|
|
10
|
+
if (!/^\d+$/.test(value)) {
|
|
11
|
+
throw new Error(`Invalid ${envName} "${value}". Expected a TCP port between 1 and 65535.`);
|
|
12
|
+
}
|
|
13
|
+
const port = Number(value);
|
|
14
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
15
|
+
throw new Error(`Invalid ${envName} "${value}". Expected a TCP port between 1 and 65535.`);
|
|
16
|
+
}
|
|
17
|
+
return port;
|
|
18
|
+
};
|
|
19
|
+
const getJestPort = () => parsePort(process.env.JEST_PORT, 'JEST_PORT');
|
|
20
|
+
exports.getJestPort = getJestPort;
|
|
21
|
+
const getJestHost = () => JEST_HOST;
|
|
22
|
+
exports.getJestHost = getJestHost;
|
|
23
|
+
const getJestBaseUrl = () => `http://${(0, exports.getJestHost)()}:${(0, exports.getJestPort)()}`;
|
|
24
|
+
exports.getJestBaseUrl = getJestBaseUrl;
|
|
25
|
+
const configureJestNetworkEnv = () => {
|
|
26
|
+
const port = (0, exports.getJestPort)();
|
|
27
|
+
const baseUrl = `http://${(0, exports.getJestHost)()}:${port}`;
|
|
28
|
+
const apiOrigin = process.env.JEST_API_ORIGIN ?? `${baseUrl}/api`;
|
|
29
|
+
process.env.PORT = `${port}`;
|
|
30
|
+
process.env.API_ORIGIN = apiOrigin;
|
|
31
|
+
return { port, baseUrl, apiOrigin };
|
|
32
|
+
};
|
|
33
|
+
exports.configureJestNetworkEnv = configureJestNetworkEnv;
|
|
34
|
+
//# sourceMappingURL=port.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port.js","sourceRoot":"","sources":["../../../src/utils/test/port.ts"],"names":[],"mappings":";;;AAMA,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,SAAS,GAAG,WAAW,CAAC;AAC9B,MAAM,SAAS,GAAG,CAAC,KAAyB,EAAE,OAAe,EAAU,EAAE;IACvE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,WAAW,OAAO,KAAK,KAAK,6CAA6C,CAC1E,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE3B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CACb,WAAW,OAAO,KAAK,KAAK,6CAA6C,CAC1E,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEK,MAAM,WAAW,GAAG,GAAW,EAAE,CACtC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AADnC,QAAA,WAAW,eACwB;AAEzC,MAAM,WAAW,GAAG,GAAW,EAAE,CAAC,SAAS,CAAC;AAAtC,QAAA,WAAW,eAA2B;AAE5C,MAAM,cAAc,GAAG,GAAW,EAAE,CACzC,UAAU,IAAA,mBAAW,GAAE,IAAI,IAAA,mBAAW,GAAE,EAAE,CAAC;AADhC,QAAA,cAAc,kBACkB;AAEtC,MAAM,uBAAuB,GAAG,GAAG,EAAE;IAC1C,MAAM,IAAI,GAAG,IAAA,mBAAW,GAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,UAAU,IAAA,mBAAW,GAAE,IAAI,IAAI,EAAE,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,GAAG,OAAO,MAAM,CAAC;IAElE,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,IAAI,EAAE,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,SAAS,CAAC;IAEnC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AACtC,CAAC,CAAC;AATW,QAAA,uBAAuB,2BASlC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hexabot-ai/api",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "3.2.2-alpha.
|
|
4
|
+
"version": "3.2.2-alpha.14",
|
|
5
5
|
"description": "Hexabot is a solution for creating and managing chatbots across multiple channels, leveraging AI for advanced conversational capabilities. It provides a user-friendly interface for building, training, and deploying chatbots with integrated support for various messaging platforms.",
|
|
6
6
|
"author": "Hexastack",
|
|
7
7
|
"license": "FCL-1.0-ALv2",
|
|
@@ -92,8 +92,8 @@
|
|
|
92
92
|
"typeorm": "^0.3.28",
|
|
93
93
|
"yaml": "^2.8.3",
|
|
94
94
|
"zod": "^4.3.6",
|
|
95
|
-
"@hexabot-ai/agentic": "3.1.2-alpha.
|
|
96
|
-
"@hexabot-ai/types": "3.0.2-alpha.
|
|
95
|
+
"@hexabot-ai/agentic": "3.1.2-alpha.14",
|
|
96
|
+
"@hexabot-ai/types": "3.0.2-alpha.14"
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
99
|
"@compodoc/compodoc": "^1.1.31",
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
"tsconfig-paths": "^4.2.0",
|
|
145
145
|
"tsconfig-paths-jest": "^0.0.1",
|
|
146
146
|
"typescript": "^5.1.3",
|
|
147
|
-
"@hexabot-ai/frontend": "3.2.2-alpha.
|
|
147
|
+
"@hexabot-ai/frontend": "3.2.2-alpha.14"
|
|
148
148
|
},
|
|
149
149
|
"optionalDependencies": {
|
|
150
150
|
"@css-inline/css-inline-linux-arm64-musl": "^0.14.1",
|
package/src/mcp/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This module exposes Hexabot API capabilities through the Model Context Protocol
|
|
4
4
|
(MCP) so coding agents can inspect and manage workflows, workflow runs, memory
|
|
5
|
-
definitions, actions, credentials, and CMS content.
|
|
5
|
+
definitions, actions, credentials, MCP servers, and CMS content.
|
|
6
6
|
|
|
7
7
|
The implementation uses `@rekog/mcp-nest` with Streamable HTTP transport.
|
|
8
8
|
Authentication is Hexabot-native: users create personal MCP bearer tokens from
|
|
@@ -147,13 +147,15 @@ client, but the effective configuration should be equivalent to:
|
|
|
147
147
|
| `hexabot_workflow_get` | `workflow:read` | Read one workflow with populated version metadata. |
|
|
148
148
|
| `hexabot_workflow_create` | `workflow:create` | Create a workflow and optionally commit initial YAML. |
|
|
149
149
|
| `hexabot_workflow_update` | `workflow:update` | Update workflow metadata and optionally commit YAML. |
|
|
150
|
+
| `hexabot_workflow_yaml_validate` | `workflow:read` | Validate workflow definition YAML without creating a version. |
|
|
150
151
|
| `hexabot_workflow_yaml_commit` | `workflowversion:create` | Validate and commit workflow definition YAML. |
|
|
151
152
|
| `hexabot_workflow_publish` | `workflow:update` | Publish the current workflow version. |
|
|
152
153
|
| `hexabot_workflow_unpublish` | `workflow:update` | Clear the published workflow version. |
|
|
153
154
|
| `hexabot_workflow_run` | `workflowrun:create` | Run a manual or scheduled workflow and return the run summary. |
|
|
154
155
|
|
|
155
156
|
Workflow YAML is validated with `parseWorkflowDefinition()` before a version is
|
|
156
|
-
created.
|
|
157
|
+
created. Coding agents can call `hexabot_workflow_yaml_validate` first to get
|
|
158
|
+
structured validation errors without mutating workflow state.
|
|
157
159
|
|
|
158
160
|
### Workflow versions and runs
|
|
159
161
|
|
|
@@ -195,6 +197,15 @@ Credential secret values are never returned. The MCP tools remove the `value`
|
|
|
195
197
|
field from all credential responses and do not support searching by secret
|
|
196
198
|
value.
|
|
197
199
|
|
|
200
|
+
### MCP servers
|
|
201
|
+
|
|
202
|
+
| Tool | Permission | Purpose |
|
|
203
|
+
| --- | --- | --- |
|
|
204
|
+
| `hexabot_mcp_server_search` | `mcpserver:read` | Search configured MCP servers. |
|
|
205
|
+
| `hexabot_mcp_server_get` | `mcpserver:read` | Read one configured MCP server. |
|
|
206
|
+
| `hexabot_mcp_server_create` | `mcpserver:create` | Create an MCP server configuration. |
|
|
207
|
+
| `hexabot_mcp_server_update` | `mcpserver:update` | Update an MCP server configuration. |
|
|
208
|
+
|
|
198
209
|
### CMS and RAG content
|
|
199
210
|
|
|
200
211
|
| Tool | Permission | Purpose |
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Full terms: see LICENSE.md.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { validateWorkflow } from '@hexabot-ai/agentic';
|
|
7
8
|
import { Action, type User } from '@hexabot-ai/types';
|
|
8
9
|
import {
|
|
9
10
|
BadRequestException,
|
|
@@ -23,6 +24,7 @@ import { ContentTypeService } from '@/cms/services/content-type.service';
|
|
|
23
24
|
import { ContentService } from '@/cms/services/content.service';
|
|
24
25
|
import { CredentialService } from '@/user/services/credential.service';
|
|
25
26
|
import { WorkflowNewVersionDto } from '@/workflow/dto/workflow-version.dto';
|
|
27
|
+
import { McpServerOrmEntity } from '@/workflow/entities/mcp-server.entity';
|
|
26
28
|
import { WorkflowRunOrmEntity } from '@/workflow/entities/workflow-run.entity';
|
|
27
29
|
import { WorkflowVersionOrmEntity } from '@/workflow/entities/workflow-version.entity';
|
|
28
30
|
import { WorkflowOrmEntity } from '@/workflow/entities/workflow.entity';
|
|
@@ -32,12 +34,14 @@ import {
|
|
|
32
34
|
} from '@/workflow/lib/trigger-event-wrapper';
|
|
33
35
|
import { parseWorkflowDefinition } from '@/workflow/lib/workflow-definition';
|
|
34
36
|
import { AgenticService } from '@/workflow/services/agentic.service';
|
|
37
|
+
import { McpServerService } from '@/workflow/services/mcp-server.service';
|
|
35
38
|
import { MemoryDefinitionService } from '@/workflow/services/memory-definition.service';
|
|
36
39
|
import { WorkflowRunService } from '@/workflow/services/workflow-run.service';
|
|
37
40
|
import { WorkflowVersionService } from '@/workflow/services/workflow-version.service';
|
|
38
41
|
import { WorkflowService } from '@/workflow/services/workflow.service';
|
|
39
42
|
import {
|
|
40
43
|
DirectionType,
|
|
44
|
+
McpServerTransport,
|
|
41
45
|
MemoryScope,
|
|
42
46
|
WorkflowType,
|
|
43
47
|
WorkflowVersionAction,
|
|
@@ -67,6 +71,16 @@ const workflowPayloadSchema = {
|
|
|
67
71
|
zoom: z.number().optional(),
|
|
68
72
|
direction: z.enum(DirectionType).optional(),
|
|
69
73
|
};
|
|
74
|
+
const mcpServerPayloadSchema = {
|
|
75
|
+
name: z.string().min(1).optional(),
|
|
76
|
+
enabled: z.boolean().optional(),
|
|
77
|
+
transport: z.enum(McpServerTransport).optional(),
|
|
78
|
+
url: z.string().nullable().optional(),
|
|
79
|
+
command: z.string().nullable().optional(),
|
|
80
|
+
args: z.array(z.string()).nullable().optional(),
|
|
81
|
+
cwd: z.string().nullable().optional(),
|
|
82
|
+
credential: uuidSchema.nullable().optional(),
|
|
83
|
+
};
|
|
70
84
|
|
|
71
85
|
type PaginationArgs = {
|
|
72
86
|
limit: number;
|
|
@@ -88,6 +102,7 @@ export class HexabotMcpTools {
|
|
|
88
102
|
private readonly credentialService: CredentialService,
|
|
89
103
|
private readonly contentTypeService: ContentTypeService,
|
|
90
104
|
private readonly contentService: ContentService,
|
|
105
|
+
private readonly mcpServerService: McpServerService,
|
|
91
106
|
) {}
|
|
92
107
|
|
|
93
108
|
@McpPermission('workflow', Action.READ)
|
|
@@ -257,6 +272,36 @@ export class HexabotMcpTools {
|
|
|
257
272
|
});
|
|
258
273
|
}
|
|
259
274
|
|
|
275
|
+
@McpPermission('workflow', Action.READ)
|
|
276
|
+
@ToolGuards([McpPermissionGuard])
|
|
277
|
+
@Tool({
|
|
278
|
+
name: 'hexabot_workflow_yaml_validate',
|
|
279
|
+
description:
|
|
280
|
+
'Validate workflow definition YAML without creating a workflow version.',
|
|
281
|
+
parameters: z.object({
|
|
282
|
+
definitionYml: z.string().min(1),
|
|
283
|
+
validateActions: z.boolean().default(true),
|
|
284
|
+
}),
|
|
285
|
+
})
|
|
286
|
+
async validateWorkflowYaml(args: {
|
|
287
|
+
definitionYml: string;
|
|
288
|
+
validateActions?: boolean;
|
|
289
|
+
}) {
|
|
290
|
+
const validateActions = args.validateActions ?? true;
|
|
291
|
+
const validation = validateWorkflow(args.definitionYml, {
|
|
292
|
+
bindingKinds: this.runtimeBindingsService.getRegistry(),
|
|
293
|
+
...(validateActions
|
|
294
|
+
? { actions: this.getWorkflowValidationActions() }
|
|
295
|
+
: {}),
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
if (!validation.success) {
|
|
299
|
+
return { valid: false, errors: validation.errors };
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return { valid: true, errors: [], definition: validation.data };
|
|
303
|
+
}
|
|
304
|
+
|
|
260
305
|
@McpPermission('workflowversion', Action.READ)
|
|
261
306
|
@ToolGuards([McpPermissionGuard])
|
|
262
307
|
@Tool({
|
|
@@ -723,6 +768,109 @@ export class HexabotMcpTools {
|
|
|
723
768
|
return HexabotMcpTools.sanitizeCredential(credential);
|
|
724
769
|
}
|
|
725
770
|
|
|
771
|
+
@McpPermission('mcpserver', Action.READ)
|
|
772
|
+
@ToolGuards([McpPermissionGuard])
|
|
773
|
+
@Tool({
|
|
774
|
+
name: 'hexabot_mcp_server_search',
|
|
775
|
+
description: 'Search configured MCP servers.',
|
|
776
|
+
parameters: z.object({
|
|
777
|
+
query: z.string().optional(),
|
|
778
|
+
enabled: z.boolean().optional(),
|
|
779
|
+
transport: z.enum(McpServerTransport).optional(),
|
|
780
|
+
credentialId: uuidSchema.optional(),
|
|
781
|
+
...paginationSchema,
|
|
782
|
+
}),
|
|
783
|
+
})
|
|
784
|
+
async searchMcpServers(
|
|
785
|
+
args: {
|
|
786
|
+
query?: string;
|
|
787
|
+
enabled?: boolean;
|
|
788
|
+
transport?: McpServerTransport;
|
|
789
|
+
credentialId?: string;
|
|
790
|
+
} & PaginationArgs,
|
|
791
|
+
) {
|
|
792
|
+
const base = {
|
|
793
|
+
...(args.enabled !== undefined ? { enabled: args.enabled } : {}),
|
|
794
|
+
...(args.transport ? { transport: args.transport } : {}),
|
|
795
|
+
...(args.credentialId ? { credential: { id: args.credentialId } } : {}),
|
|
796
|
+
};
|
|
797
|
+
const where = args.query
|
|
798
|
+
? [
|
|
799
|
+
{ ...base, name: this.contains(args.query) },
|
|
800
|
+
{ ...base, url: this.contains(args.query) },
|
|
801
|
+
{ ...base, command: this.contains(args.query) },
|
|
802
|
+
]
|
|
803
|
+
: base;
|
|
804
|
+
|
|
805
|
+
return await this.listWithCount(
|
|
806
|
+
this.mcpServerService,
|
|
807
|
+
this.findOptions<McpServerOrmEntity>(args, where as any),
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
@McpPermission('mcpserver', Action.READ)
|
|
812
|
+
@ToolGuards([McpPermissionGuard])
|
|
813
|
+
@Tool({
|
|
814
|
+
name: 'hexabot_mcp_server_get',
|
|
815
|
+
description: 'Read one configured MCP server.',
|
|
816
|
+
parameters: z.object({
|
|
817
|
+
id: uuidSchema,
|
|
818
|
+
}),
|
|
819
|
+
})
|
|
820
|
+
async getMcpServer(args: { id: string }) {
|
|
821
|
+
const server = await this.mcpServerService.findOneAndPopulate(args.id);
|
|
822
|
+
if (!server) {
|
|
823
|
+
throw new NotFoundException(`MCP server ${args.id} not found`);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
return server;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
@McpPermission('mcpserver', Action.CREATE)
|
|
830
|
+
@ToolGuards([McpPermissionGuard])
|
|
831
|
+
@Tool({
|
|
832
|
+
name: 'hexabot_mcp_server_create',
|
|
833
|
+
description: 'Create an MCP server configuration.',
|
|
834
|
+
parameters: z.object({
|
|
835
|
+
...mcpServerPayloadSchema,
|
|
836
|
+
name: z.string().min(1),
|
|
837
|
+
}),
|
|
838
|
+
})
|
|
839
|
+
async createMcpServer(args: {
|
|
840
|
+
name: string;
|
|
841
|
+
enabled?: boolean;
|
|
842
|
+
transport?: McpServerTransport;
|
|
843
|
+
url?: string | null;
|
|
844
|
+
command?: string | null;
|
|
845
|
+
args?: string[] | null;
|
|
846
|
+
cwd?: string | null;
|
|
847
|
+
credential?: string | null;
|
|
848
|
+
}) {
|
|
849
|
+
return await this.mcpServerService.create({
|
|
850
|
+
enabled: true,
|
|
851
|
+
transport: McpServerTransport.http,
|
|
852
|
+
...args,
|
|
853
|
+
} as any);
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
@McpPermission('mcpserver', Action.UPDATE)
|
|
857
|
+
@ToolGuards([McpPermissionGuard])
|
|
858
|
+
@Tool({
|
|
859
|
+
name: 'hexabot_mcp_server_update',
|
|
860
|
+
description: 'Update an MCP server configuration.',
|
|
861
|
+
parameters: z.object({
|
|
862
|
+
id: uuidSchema,
|
|
863
|
+
...mcpServerPayloadSchema,
|
|
864
|
+
}),
|
|
865
|
+
})
|
|
866
|
+
async updateMcpServer(args: { id: string } & Record<string, unknown>) {
|
|
867
|
+
const { id, ...updates } = args;
|
|
868
|
+
|
|
869
|
+
await this.getMcpServer({ id });
|
|
870
|
+
|
|
871
|
+
return await this.mcpServerService.updateOne(id, updates as any);
|
|
872
|
+
}
|
|
873
|
+
|
|
726
874
|
@McpPermission('contenttype', Action.READ)
|
|
727
875
|
@ToolGuards([McpPermissionGuard])
|
|
728
876
|
@Tool({
|
|
@@ -1026,6 +1174,17 @@ export class HexabotMcpTools {
|
|
|
1026
1174
|
return Like(`%${value}%`);
|
|
1027
1175
|
}
|
|
1028
1176
|
|
|
1177
|
+
private getWorkflowValidationActions() {
|
|
1178
|
+
return Object.fromEntries(
|
|
1179
|
+
Object.entries(this.actionService.getRegistry()).map(
|
|
1180
|
+
([actionName, action]) => [
|
|
1181
|
+
actionName,
|
|
1182
|
+
{ supportedBindings: action.supportedBindings ?? [] },
|
|
1183
|
+
],
|
|
1184
|
+
),
|
|
1185
|
+
);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1029
1188
|
private getActor(request?: HexabotMcpRequest): User {
|
|
1030
1189
|
const actor = request?.hexabotUser ?? request?.user;
|
|
1031
1190
|
if (!actor?.id) {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2025 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const DEFAULT_JEST_PORT = 3001;
|
|
8
|
+
const JEST_HOST = '127.0.0.1';
|
|
9
|
+
const parsePort = (value: string | undefined, envName: string): number => {
|
|
10
|
+
if (!value) {
|
|
11
|
+
return DEFAULT_JEST_PORT;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (!/^\d+$/.test(value)) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
`Invalid ${envName} "${value}". Expected a TCP port between 1 and 65535.`,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const port = Number(value);
|
|
21
|
+
|
|
22
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`Invalid ${envName} "${value}". Expected a TCP port between 1 and 65535.`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return port;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const getJestPort = (): number =>
|
|
32
|
+
parsePort(process.env.JEST_PORT, 'JEST_PORT');
|
|
33
|
+
|
|
34
|
+
export const getJestHost = (): string => JEST_HOST;
|
|
35
|
+
|
|
36
|
+
export const getJestBaseUrl = (): string =>
|
|
37
|
+
`http://${getJestHost()}:${getJestPort()}`;
|
|
38
|
+
|
|
39
|
+
export const configureJestNetworkEnv = () => {
|
|
40
|
+
const port = getJestPort();
|
|
41
|
+
const baseUrl = `http://${getJestHost()}:${port}`;
|
|
42
|
+
const apiOrigin = process.env.JEST_API_ORIGIN ?? `${baseUrl}/api`;
|
|
43
|
+
|
|
44
|
+
process.env.PORT = `${port}`;
|
|
45
|
+
process.env.API_ORIGIN = apiOrigin;
|
|
46
|
+
|
|
47
|
+
return { port, baseUrl, apiOrigin };
|
|
48
|
+
};
|