@hexabot-ai/api 3.2.2-alpha.16 → 3.2.2-alpha.18

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/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.16",
4
+ "version": "3.2.2-alpha.18",
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.16",
96
- "@hexabot-ai/types": "3.0.2-alpha.16"
95
+ "@hexabot-ai/types": "3.0.2-alpha.18",
96
+ "@hexabot-ai/agentic": "3.1.2-alpha.18"
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.16"
147
+ "@hexabot-ai/frontend": "3.2.2-alpha.18"
148
148
  },
149
149
  "optionalDependencies": {
150
150
  "@css-inline/css-inline-linux-arm64-musl": "^0.14.1",
package/src/mcp/README.md CHANGED
@@ -13,11 +13,11 @@ Claude Code.
13
13
 
14
14
  All routes are mounted under the existing API prefix.
15
15
 
16
- | Route | Purpose |
17
- | --- | --- |
18
- | `/api/mcp` | Streamable HTTP MCP endpoint. |
19
- | `/api/mcp-token` | List and create MCP personal access tokens for the current Hexabot user. |
20
- | `/api/mcp-token/:id/revoke` | Revoke one MCP personal access token owned by the current Hexabot user. |
16
+ | Route | Purpose |
17
+ | --------------------------- | ------------------------------------------------------------------------ |
18
+ | `/api/mcp` | Streamable HTTP MCP endpoint. |
19
+ | `/api/mcp-token` | List and create MCP personal access tokens for the current Hexabot user. |
20
+ | `/api/mcp-token/:id/revoke` | Revoke one MCP personal access token owned by the current Hexabot user. |
21
21
 
22
22
  The MCP endpoint is stateful and uses `mcp-session-id` headers for sessions.
23
23
 
@@ -141,19 +141,20 @@ client, but the effective configuration should be equivalent to:
141
141
 
142
142
  ### Workflows
143
143
 
144
- | Tool | Permission | Purpose |
145
- | --- | --- | --- |
146
- | `hexabot_workflow_search` | `workflow:read` | Search workflows by metadata. |
147
- | `hexabot_workflow_get` | `workflow:read` | Read one workflow with populated version metadata. |
148
- | `hexabot_workflow_version_status` | `workflow:read` | Check current and published version pointers for one workflow. |
149
- | `hexabot_workflow_create` | `workflow:create` | Create a workflow and optionally commit initial YAML. |
150
- | `hexabot_workflow_update` | `workflow:update` | Update workflow metadata and optionally commit YAML. |
151
- | `hexabot_workflow_yaml_validate` | `workflow:read` | Validate workflow definition YAML without creating a version. |
152
- | `hexabot_workflow_yaml_commit` | `workflowversion:create` | Validate and commit workflow definition YAML. |
153
- | `hexabot_workflow_rollback` | `workflowversion:create` | Roll back to a previous version by creating a new restore snapshot. |
154
- | `hexabot_workflow_publish` | `workflow:update` | Publish the current workflow version. |
155
- | `hexabot_workflow_unpublish` | `workflow:update` | Clear the published workflow version. |
156
- | `hexabot_workflow_run` | `workflowrun:create` | Run a manual or scheduled workflow and return the run summary. |
144
+ | Tool | Permission | Purpose |
145
+ | --------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------- |
146
+ | `hexabot_workflow_search` | `workflow:read` | Search workflows by metadata. |
147
+ | `hexabot_workflow_get` | `workflow:read` | Read one workflow with compact version metadata. |
148
+ | `hexabot_workflow_version_status` | `workflow:read` | Check current and published version pointers for one workflow. |
149
+ | `hexabot_workflow_create` | `workflow:create` | Create a workflow and optionally commit initial YAML. |
150
+ | `hexabot_workflow_update` | `workflow:update` | Update workflow metadata and optionally commit YAML. |
151
+ | `hexabot_workflow_yaml_validate` | `workflow:read` | Validate workflow definition YAML without creating a version. |
152
+ | `hexabot_workflow_yaml_get` | `workflowversion:read` | Read exact workflow YAML by current workflow version or version ID with byte-range chunking. |
153
+ | `hexabot_workflow_yaml_commit` | `workflowversion:create` | Validate and commit workflow definition YAML. |
154
+ | `hexabot_workflow_rollback` | `workflowversion:create` | Roll back to a previous version by creating a new restore snapshot. |
155
+ | `hexabot_workflow_publish` | `workflow:update` | Publish the current workflow version. |
156
+ | `hexabot_workflow_unpublish` | `workflow:update` | Clear the published workflow version. |
157
+ | `hexabot_workflow_run` | `workflowrun:create` | Run a manual or scheduled workflow and return the run summary. |
157
158
 
158
159
  Workflow YAML is validated with `parseWorkflowDefinition()` before a version is
159
160
  created. Coding agents can call `hexabot_workflow_yaml_validate` first to get
@@ -164,42 +165,53 @@ explicitly supplied. `hexabot_workflow_rollback` and
164
165
  publish that snapshot with `hexabot_workflow_publish` when it should become the
165
166
  published version.
166
167
 
168
+ Large YAML definitions are intentionally omitted from workflow and version list
169
+ or metadata tools. Use `hexabot_workflow_yaml_get` with `workflowId` or
170
+ `versionId` to retrieve the exact YAML. Its `offset`, `limit`, `endOffset`, and
171
+ `nextOffset` fields use UTF-8 byte offsets; the response also includes the
172
+ version checksum and total byte length so clients can verify reconstruction.
173
+
167
174
  ### Workflow versions and runs
168
175
 
169
- | Tool | Permission | Purpose |
170
- | --- | --- | --- |
171
- | `hexabot_workflow_version_search` | `workflowversion:read` | List YAML versions for a workflow. |
172
- | `hexabot_workflow_version_get` | `workflowversion:read` | Read one workflow YAML version. |
173
- | `hexabot_workflow_version_update` | `workflowversion:update` | Update workflow version metadata. |
174
- | `hexabot_workflow_version_restore` | `workflowversion:create` | Restore a previous version by creating a new snapshot. |
175
- | `hexabot_workflow_run_search` | `workflowrun:read` | Search workflow runs by workflow and status. |
176
- | `hexabot_workflow_run_get` | `workflowrun:read` | Read one workflow run with populated workflow metadata. |
177
- | `hexabot_workflow_run_debug` | `workflowrun:read` | Inspect one workflow run with execution state, workflow YAML, and parent/child run context for troubleshooting. |
176
+ | Tool | Permission | Purpose |
177
+ | ---------------------------------- | ------------------------ | ----------------------------------------------------------------------------------------------- |
178
+ | `hexabot_workflow_version_search` | `workflowversion:read` | List compact version metadata for a workflow. |
179
+ | `hexabot_workflow_version_get` | `workflowversion:read` | Read compact version metadata. |
180
+ | `hexabot_workflow_version_update` | `workflowversion:update` | Update workflow version metadata. |
181
+ | `hexabot_workflow_version_restore` | `workflowversion:create` | Restore a previous version by creating a new snapshot. |
182
+ | `hexabot_workflow_run_search` | `workflowrun:read` | Search workflow runs by workflow and status. |
183
+ | `hexabot_workflow_run_get` | `workflowrun:read` | Read one workflow run with populated workflow metadata but no nested YAML body. |
184
+ | `hexabot_workflow_run_debug` | `workflowrun:read` | Inspect one workflow run with execution state and parent/child run context for troubleshooting. |
185
+
186
+ Workflow run search/get responses strip nested `definitionYml` fields from
187
+ populated workflow-version relations. `hexabot_workflow_run_debug` returns the
188
+ executed YAML once as top-level `workflowDefinitionYml` only when
189
+ `includeWorkflowDefinition=true`.
178
190
 
179
191
  ### Memory definitions
180
192
 
181
- | Tool | Permission | Purpose |
182
- | --- | --- | --- |
183
- | `hexabot_memory_definition_search` | `memorydefinition:read` | Search memory definitions. |
184
- | `hexabot_memory_definition_get` | `memorydefinition:read` | Read one memory definition. |
193
+ | Tool | Permission | Purpose |
194
+ | ---------------------------------- | ------------------------- | --------------------------- |
195
+ | `hexabot_memory_definition_search` | `memorydefinition:read` | Search memory definitions. |
196
+ | `hexabot_memory_definition_get` | `memorydefinition:read` | Read one memory definition. |
185
197
  | `hexabot_memory_definition_create` | `memorydefinition:create` | Create a memory definition. |
186
198
  | `hexabot_memory_definition_update` | `memorydefinition:update` | Update a memory definition. |
187
199
 
188
200
  ### Actions and runtime bindings
189
201
 
190
- | Tool | Permission | Purpose |
191
- | --- | --- | --- |
192
- | `hexabot_action_search` | `workflow:read` | Search available workflow actions and schemas. |
193
- | `hexabot_action_get` | `workflow:read` | Read one workflow action schema. |
194
- | `hexabot_binding_search` | `workflow:read` | Search runtime binding kind schemas. |
195
- | `hexabot_binding_get` | `workflow:read` | Read one runtime binding schema. |
202
+ | Tool | Permission | Purpose |
203
+ | ------------------------ | --------------- | ---------------------------------------------- |
204
+ | `hexabot_action_search` | `workflow:read` | Search available workflow actions and schemas. |
205
+ | `hexabot_action_get` | `workflow:read` | Read one workflow action schema. |
206
+ | `hexabot_binding_search` | `workflow:read` | Search runtime binding kind schemas. |
207
+ | `hexabot_binding_get` | `workflow:read` | Read one runtime binding schema. |
196
208
 
197
209
  ### Credentials
198
210
 
199
- | Tool | Permission | Purpose |
200
- | --- | --- | --- |
211
+ | Tool | Permission | Purpose |
212
+ | --------------------------- | ----------------- | -------------------------------------------- |
201
213
  | `hexabot_credential_search` | `credential:read` | Search credential metadata by name or owner. |
202
- | `hexabot_credential_get` | `credential:read` | Read credential metadata. |
214
+ | `hexabot_credential_get` | `credential:read` | Read credential metadata. |
203
215
 
204
216
  Credential secret values are never returned. The MCP tools remove the `value`
205
217
  field from all credential responses and do not support searching by secret
@@ -207,26 +219,26 @@ value.
207
219
 
208
220
  ### MCP servers
209
221
 
210
- | Tool | Permission | Purpose |
211
- | --- | --- | --- |
212
- | `hexabot_mcp_server_search` | `mcpserver:read` | Search configured MCP servers. |
213
- | `hexabot_mcp_server_get` | `mcpserver:read` | Read one configured MCP server. |
222
+ | Tool | Permission | Purpose |
223
+ | --------------------------- | ------------------ | ----------------------------------- |
224
+ | `hexabot_mcp_server_search` | `mcpserver:read` | Search configured MCP servers. |
225
+ | `hexabot_mcp_server_get` | `mcpserver:read` | Read one configured MCP server. |
214
226
  | `hexabot_mcp_server_create` | `mcpserver:create` | Create an MCP server configuration. |
215
227
  | `hexabot_mcp_server_update` | `mcpserver:update` | Update an MCP server configuration. |
216
228
 
217
229
  ### CMS and RAG content
218
230
 
219
- | Tool | Permission | Purpose |
220
- | --- | --- | --- |
221
- | `hexabot_content_type_search` | `contenttype:read` | Search CMS content types. |
222
- | `hexabot_content_type_get` | `contenttype:read` | Read one content type. |
223
- | `hexabot_content_type_create` | `contenttype:create` | Create a content type. |
224
- | `hexabot_content_type_update` | `contenttype:update` | Update a content type. |
225
- | `hexabot_content_search` | `content:read` | Search CMS content records. |
226
- | `hexabot_content_get` | `content:read` | Read one content record. |
227
- | `hexabot_content_create` | `content:create` | Create a content record. |
228
- | `hexabot_content_update` | `content:update` | Update a content record. |
229
- | `hexabot_rag_content_search` | `content:read` | Search indexed CMS content through RAG retrieval. |
231
+ | Tool | Permission | Purpose |
232
+ | ----------------------------- | -------------------- | ------------------------------------------------- |
233
+ | `hexabot_content_type_search` | `contenttype:read` | Search CMS content types. |
234
+ | `hexabot_content_type_get` | `contenttype:read` | Read one content type. |
235
+ | `hexabot_content_type_create` | `contenttype:create` | Create a content type. |
236
+ | `hexabot_content_type_update` | `contenttype:update` | Update a content type. |
237
+ | `hexabot_content_search` | `content:read` | Search CMS content records. |
238
+ | `hexabot_content_get` | `content:read` | Read one content record. |
239
+ | `hexabot_content_create` | `content:create` | Create a content record. |
240
+ | `hexabot_content_update` | `content:update` | Update a content record. |
241
+ | `hexabot_rag_content_search` | `content:read` | Search indexed CMS content through RAG retrieval. |
230
242
 
231
243
  ## Extending the MCP module
232
244
 
@@ -44,9 +44,9 @@ export class HexabotMcpTokenGuard implements CanActivate {
44
44
  return undefined;
45
45
  }
46
46
 
47
- const [type, token] = authHeader.split(' ');
47
+ const match = authHeader.trim().match(/^Bearer\s+(\S+)$/i);
48
48
 
49
- return type === 'Bearer' ? token : undefined;
49
+ return match?.[1];
50
50
  }
51
51
 
52
52
  private getMcpTokenService(): McpTokenService {
@@ -6,8 +6,24 @@
6
6
 
7
7
  export const sanitizeCredential = <T extends Record<string, unknown>>(
8
8
  credential: T,
9
- ): T => {
9
+ ): Omit<T, 'value'> => {
10
10
  const { value: _value, ...safeCredential } = credential;
11
11
 
12
- return safeCredential as T;
12
+ return safeCredential;
13
+ };
14
+
15
+ export const omitKeysDeep = <T>(value: T, keys: readonly string[]): T => {
16
+ if (Array.isArray(value)) {
17
+ return value.map((item) => omitKeysDeep(item, keys)) as T;
18
+ }
19
+
20
+ if (value === null || typeof value !== 'object' || value instanceof Date) {
21
+ return value;
22
+ }
23
+
24
+ return Object.fromEntries(
25
+ Object.entries(value as Record<string, unknown>)
26
+ .filter(([key]) => !keys.includes(key))
27
+ .map(([key, nestedValue]) => [key, omitKeysDeep(nestedValue, keys)]),
28
+ ) as T;
13
29
  };
@@ -4,7 +4,11 @@
4
4
  * Full terms: see LICENSE.md.
5
5
  */
6
6
 
7
- import { type WorkflowFull, type WorkflowVersion } from '@hexabot-ai/types';
7
+ import {
8
+ type WorkflowFull,
9
+ type WorkflowVersion,
10
+ type WorkflowVersionFull,
11
+ } from '@hexabot-ai/types';
8
12
  import {
9
13
  BadRequestException,
10
14
  Injectable,
@@ -17,6 +21,8 @@ import { WorkflowVersionService } from '@/workflow/services/workflow-version.ser
17
21
  import { WorkflowService } from '@/workflow/services/workflow.service';
18
22
  import { WorkflowVersionAction } from '@/workflow/types';
19
23
 
24
+ type WorkflowVersionLike = WorkflowVersion | WorkflowVersionFull;
25
+
20
26
  type WorkflowVersionSummary = Pick<
21
27
  WorkflowVersion,
22
28
  | 'id'
@@ -24,12 +30,26 @@ type WorkflowVersionSummary = Pick<
24
30
  | 'checksum'
25
31
  | 'message'
26
32
  | 'action'
27
- | 'parentVersion'
28
- | 'workflow'
29
- | 'createdBy'
30
33
  | 'createdAt'
31
34
  | 'updatedAt'
32
- >;
35
+ > & {
36
+ parentVersion:
37
+ | WorkflowVersion['parentVersion']
38
+ | WorkflowVersionFull['parentVersion'];
39
+ workflow: WorkflowVersion['workflow'] | WorkflowVersionFull['workflow'];
40
+ createdBy: WorkflowVersion['createdBy'] | WorkflowVersionFull['createdBy'];
41
+ definitionYmlByteLength?: number;
42
+ };
43
+
44
+ type WorkflowSummary = Omit<
45
+ WorkflowFull,
46
+ 'currentVersion' | 'publishedVersion' | 'definitionYml' | 'definition'
47
+ > & {
48
+ currentVersion: WorkflowVersionSummary | null;
49
+ publishedVersion: WorkflowVersionSummary | null;
50
+ currentVersionId: string | null;
51
+ publishedVersionId: string | null;
52
+ };
33
53
 
34
54
  @Injectable()
35
55
  export class HexabotWorkflowMcpHelper {
@@ -121,8 +141,30 @@ export class HexabotWorkflowMcpHelper {
121
141
  };
122
142
  }
123
143
 
124
- private summarizeWorkflowVersion(
125
- version: WorkflowVersion | null | undefined,
144
+ summarizeWorkflow(workflow: WorkflowFull): WorkflowSummary {
145
+ const {
146
+ currentVersion,
147
+ publishedVersion,
148
+ definitionYml: _definitionYml,
149
+ definition: _definition,
150
+ ...metadata
151
+ } = workflow;
152
+ const currentVersionSummary = this.summarizeWorkflowVersion(currentVersion);
153
+ const publishedVersionSummary =
154
+ this.summarizeWorkflowVersion(publishedVersion);
155
+
156
+ return {
157
+ ...metadata,
158
+ currentVersion: currentVersionSummary,
159
+ publishedVersion: publishedVersionSummary,
160
+ currentVersionId: currentVersionSummary?.id ?? null,
161
+ publishedVersionId: publishedVersionSummary?.id ?? null,
162
+ };
163
+ }
164
+
165
+ summarizeWorkflowVersion(
166
+ version: WorkflowVersionLike | null | undefined,
167
+ options?: { includeDefinitionYmlByteLength?: boolean },
126
168
  ): WorkflowVersionSummary | null {
127
169
  if (!version) {
128
170
  return null;
@@ -139,8 +181,7 @@ export class HexabotWorkflowMcpHelper {
139
181
  createdAt,
140
182
  updatedAt,
141
183
  } = version;
142
-
143
- return {
184
+ const summary = {
144
185
  id,
145
186
  version: versionNumber,
146
187
  checksum,
@@ -151,7 +192,19 @@ export class HexabotWorkflowMcpHelper {
151
192
  createdBy,
152
193
  createdAt,
153
194
  updatedAt,
195
+ ...(options?.includeDefinitionYmlByteLength
196
+ ? {
197
+ definitionYmlByteLength:
198
+ typeof version.definitionYml === 'string'
199
+ ? Buffer.byteLength(version.definitionYml, 'utf8')
200
+ : undefined,
201
+ }
202
+ : {}),
154
203
  };
204
+
205
+ return Object.fromEntries(
206
+ Object.entries(summary).filter(([, value]) => value !== undefined),
207
+ ) as WorkflowVersionSummary;
155
208
  }
156
209
 
157
210
  private resolveRelationId(
@@ -4,7 +4,7 @@
4
4
  * Full terms: see LICENSE.md.
5
5
  */
6
6
 
7
- import { Action } from '@hexabot-ai/types';
7
+ import { Action, type WorkflowFull } from '@hexabot-ai/types';
8
8
  import {
9
9
  BadRequestException,
10
10
  Injectable,
@@ -64,21 +64,30 @@ export class HexabotWorkflowMcpTools extends HexabotMcpToolBase {
64
64
  ) {
65
65
  const where = this.buildWorkflowWhere(args);
66
66
  const options = this.findOptions<WorkflowOrmEntity>(args, where);
67
+ const result = await this.listWithCount(this.workflowService, options);
67
68
 
68
- return await this.listWithCount(this.workflowService, options);
69
+ return {
70
+ ...result,
71
+ items: result.items.map((workflow) =>
72
+ this.workflowHelper.summarizeWorkflow(workflow as WorkflowFull),
73
+ ),
74
+ };
69
75
  }
70
76
 
71
77
  @McpPermission('workflow', Action.READ)
72
78
  @ToolGuards([McpPermissionGuard])
73
79
  @Tool({
74
80
  name: 'hexabot_workflow_get',
75
- description: 'Read a Hexabot workflow with populated version metadata.',
81
+ description:
82
+ 'Read a Hexabot workflow with compact version metadata, excluding YAML definition bodies.',
76
83
  parameters: z.object({
77
84
  id: uuidSchema,
78
85
  }),
79
86
  })
80
87
  async getWorkflow(args: { id: string }) {
81
- return await this.workflowHelper.requireWorkflow(args.id);
88
+ const workflow = await this.workflowHelper.requireWorkflow(args.id);
89
+
90
+ return this.workflowHelper.summarizeWorkflow(workflow);
82
91
  }
83
92
 
84
93
  @McpPermission('workflow', Action.READ)
@@ -145,7 +154,9 @@ export class HexabotWorkflowMcpTools extends HexabotMcpToolBase {
145
154
  });
146
155
  }
147
156
 
148
- return await this.workflowHelper.requireWorkflow(workflow.id);
157
+ return this.workflowHelper.summarizeWorkflow(
158
+ await this.workflowHelper.requireWorkflow(workflow.id),
159
+ );
149
160
  }
150
161
 
151
162
  @McpPermission('workflow', Action.UPDATE)
@@ -188,7 +199,9 @@ export class HexabotWorkflowMcpTools extends HexabotMcpToolBase {
188
199
  });
189
200
  }
190
201
 
191
- return await this.workflowHelper.requireWorkflow(id);
202
+ return this.workflowHelper.summarizeWorkflow(
203
+ await this.workflowHelper.requireWorkflow(id),
204
+ );
192
205
  }
193
206
 
194
207
  @McpPermission('workflow', Action.UPDATE)
@@ -215,7 +228,9 @@ export class HexabotWorkflowMcpTools extends HexabotMcpToolBase {
215
228
  publishedVersion: workflow.currentVersion,
216
229
  });
217
230
 
218
- return await this.workflowHelper.requireWorkflow(args.id);
231
+ return this.workflowHelper.summarizeWorkflow(
232
+ await this.workflowHelper.requireWorkflow(args.id),
233
+ );
219
234
  }
220
235
 
221
236
  @McpPermission('workflow', Action.UPDATE)
@@ -231,7 +246,9 @@ export class HexabotWorkflowMcpTools extends HexabotMcpToolBase {
231
246
  await this.workflowHelper.requireWorkflow(args.id);
232
247
  await this.workflowService.updateOne(args.id, { publishedVersion: null });
233
248
 
234
- return await this.workflowHelper.requireWorkflow(args.id);
249
+ return this.workflowHelper.summarizeWorkflow(
250
+ await this.workflowHelper.requireWorkflow(args.id),
251
+ );
235
252
  }
236
253
 
237
254
  private buildWorkflowWhere(args: {
@@ -39,6 +39,9 @@ import {
39
39
  paginationSchema,
40
40
  uuidSchema,
41
41
  } from './hexabot-mcp.schemas';
42
+ import { omitKeysDeep } from './hexabot-mcp.utils';
43
+
44
+ const WORKFLOW_DEFINITION_RESPONSE_KEYS = ['definitionYml'] as const;
42
45
 
43
46
  @Injectable()
44
47
  export class HexabotWorkflowRunMcpTools extends HexabotMcpToolBase {
@@ -120,11 +123,12 @@ export class HexabotWorkflowRunMcpTools extends HexabotMcpToolBase {
120
123
  ...(args.workflowId ? { workflow: { id: args.workflowId } } : {}),
121
124
  ...(args.status ? { status: args.status } : {}),
122
125
  } as any;
123
-
124
- return await this.listWithCount(
126
+ const result = await this.listWithCount(
125
127
  this.workflowRunService,
126
128
  this.findOptions<WorkflowRunOrmEntity>(args, where),
127
129
  );
130
+
131
+ return this.sanitizeWorkflowRunResponse(result);
128
132
  }
129
133
 
130
134
  @McpPermission('workflowrun', Action.READ)
@@ -142,7 +146,7 @@ export class HexabotWorkflowRunMcpTools extends HexabotMcpToolBase {
142
146
  throw new NotFoundException(`Workflow run ${args.id} not found`);
143
147
  }
144
148
 
145
- return run;
149
+ return this.withoutWorkflowDefinition(run);
146
150
  }
147
151
 
148
152
  @McpPermission('workflowrun', Action.READ)
@@ -186,18 +190,19 @@ export class HexabotWorkflowRunMcpTools extends HexabotMcpToolBase {
186
190
  this.workflowRunService.count({ where: childWhere }),
187
191
  ])
188
192
  : ([null, [], 0] as const);
193
+ const includeWorkflowDefinition = args.includeWorkflowDefinition ?? true;
189
194
  const response: Record<string, unknown> = {
190
- run,
195
+ run: this.withoutWorkflowDefinition(run),
191
196
  relatedRuns: {
192
- parent: parentRun,
193
- children: childRuns,
197
+ parent: this.withoutWorkflowDefinition(parentRun),
198
+ children: this.withoutWorkflowDefinition(childRuns),
194
199
  childRunTotal,
195
200
  childRunsLimit: includeRelatedRuns ? childRunsLimit : 0,
196
201
  },
197
202
  summary: this.buildWorkflowRunDebugSummary(run, childRunTotal),
198
203
  };
199
204
 
200
- if (args.includeWorkflowDefinition ?? true) {
205
+ if (includeWorkflowDefinition) {
201
206
  response.workflowDefinitionYml =
202
207
  run.workflowVersion?.definitionYml ?? null;
203
208
  }
@@ -271,4 +276,17 @@ export class HexabotWorkflowRunMcpTools extends HexabotMcpToolBase {
271
276
  childRunTotal,
272
277
  };
273
278
  }
279
+
280
+ private sanitizeWorkflowRunResponse<T extends { items: unknown[] }>(
281
+ response: T,
282
+ ): T {
283
+ return {
284
+ ...response,
285
+ items: this.withoutWorkflowDefinition(response.items),
286
+ };
287
+ }
288
+
289
+ private withoutWorkflowDefinition<T>(value: T): T {
290
+ return omitKeysDeep(value, WORKFLOW_DEFINITION_RESPONSE_KEYS);
291
+ }
274
292
  }