@owox/backend 0.30.1 → 0.31.0-next-20260723121133

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.
Files changed (46) hide show
  1. package/dist/src/data-marts/dto/domain/list-data-marts.command.d.ts +1 -3
  2. package/dist/src/data-marts/dto/domain/list-data-marts.command.js +1 -3
  3. package/dist/src/data-marts/facades/mcp-data-marts.facade.d.ts +0 -13
  4. package/dist/src/data-marts/facades/mcp-data-marts.facade.impl.d.ts +1 -2
  5. package/dist/src/data-marts/facades/mcp-data-marts.facade.impl.js +7 -31
  6. package/dist/src/data-marts/services/blended-report-data.service.js +1 -2
  7. package/dist/src/data-marts/services/data-mart.service.d.ts +0 -2
  8. package/dist/src/data-marts/services/data-mart.service.js +0 -3
  9. package/dist/src/data-marts/services/report-sql-composer.service.js +1 -2
  10. package/dist/src/data-marts/use-cases/list-data-marts.service.js +0 -1
  11. package/dist/src/data-marts/use-cases/query-data-mart.service.js +2 -13
  12. package/dist/src/ee/mcp/instructions/mcp-system-instructions.d.ts +1 -1
  13. package/dist/src/ee/mcp/instructions/mcp-system-instructions.js +2 -4
  14. package/dist/src/ee/mcp/tools/add-destination.tool.d.ts +0 -1
  15. package/dist/src/ee/mcp/tools/add-destination.tool.js +0 -7
  16. package/dist/src/ee/mcp/tools/create-report-run-schedule.tool.d.ts +1 -4
  17. package/dist/src/ee/mcp/tools/create-report-run-schedule.tool.js +2 -9
  18. package/dist/src/ee/mcp/tools/data-mart-catalog.tool.d.ts +4 -24
  19. package/dist/src/ee/mcp/tools/data-mart-catalog.tool.js +11 -29
  20. package/dist/src/ee/mcp/tools/data-mart-details.tool.d.ts +2 -16
  21. package/dist/src/ee/mcp/tools/data-mart-details.tool.js +4 -25
  22. package/dist/src/ee/mcp/tools/data-mart-ui-path.d.ts +0 -2
  23. package/dist/src/ee/mcp/tools/data-mart-ui-path.js +0 -9
  24. package/dist/src/ee/mcp/tools/delete-report-run-schedule.tool.d.ts +1 -4
  25. package/dist/src/ee/mcp/tools/delete-report-run-schedule.tool.js +2 -9
  26. package/dist/src/ee/mcp/tools/get-data-mart-reports.tool.d.ts +1 -9
  27. package/dist/src/ee/mcp/tools/get-data-mart-reports.tool.js +3 -18
  28. package/dist/src/ee/mcp/tools/list-destinations.tool.d.ts +1 -6
  29. package/dist/src/ee/mcp/tools/list-destinations.tool.js +3 -15
  30. package/dist/src/ee/mcp/tools/list-report-run-schedules.tool.d.ts +1 -16
  31. package/dist/src/ee/mcp/tools/list-report-run-schedules.tool.js +6 -21
  32. package/dist/src/ee/mcp/tools/query-data-mart.tool.d.ts +2 -65
  33. package/dist/src/ee/mcp/tools/query-data-mart.tool.js +8 -72
  34. package/dist/src/ee/mcp/tools/search-data-marts.tool.d.ts +1 -13
  35. package/dist/src/ee/mcp/tools/search-data-marts.tool.js +11 -21
  36. package/dist/src/ee/mcp/tools/summarize-data-catalog.tool.d.ts +1 -13
  37. package/dist/src/ee/mcp/tools/summarize-data-catalog.tool.js +7 -17
  38. package/dist/src/ee/mcp/tools/tabular-serializer.d.ts +0 -6
  39. package/dist/src/ee/mcp/tools/tabular-serializer.js +3 -32
  40. package/dist/src/ee/mcp/tools/update-report-run-schedule.tool.d.ts +1 -4
  41. package/dist/src/ee/mcp/tools/update-report-run-schedule.tool.js +2 -9
  42. package/package.json +5 -5
  43. package/dist/src/data-marts/services/blended-field-display-name.d.ts +0 -7
  44. package/dist/src/data-marts/services/blended-field-display-name.js +0 -8
  45. package/dist/src/ee/mcp/tools/mcp-project-summary.util.d.ts +0 -7
  46. package/dist/src/ee/mcp/tools/mcp-project-summary.util.js +0 -17
@@ -1,11 +1,9 @@
1
1
  import { OwnerFilter } from '../../enums/owner-filter.enum';
2
- import { DataMartStatus } from '../../enums/data-mart-status.enum';
3
2
  export declare class ListDataMartsCommand {
4
3
  readonly projectId: string;
5
4
  readonly userId: string;
6
5
  readonly roles: string[];
7
6
  readonly offset?: number | undefined;
8
7
  readonly ownerFilter?: OwnerFilter | undefined;
9
- readonly status?: DataMartStatus | undefined;
10
- constructor(projectId: string, userId: string, roles: string[], offset?: number | undefined, ownerFilter?: OwnerFilter | undefined, status?: DataMartStatus | undefined);
8
+ constructor(projectId: string, userId: string, roles: string[], offset?: number | undefined, ownerFilter?: OwnerFilter | undefined);
11
9
  }
@@ -7,14 +7,12 @@ class ListDataMartsCommand {
7
7
  roles;
8
8
  offset;
9
9
  ownerFilter;
10
- status;
11
- constructor(projectId, userId, roles, offset, ownerFilter, status) {
10
+ constructor(projectId, userId, roles, offset, ownerFilter) {
12
11
  this.projectId = projectId;
13
12
  this.userId = userId;
14
13
  this.roles = roles;
15
14
  this.offset = offset;
16
15
  this.ownerFilter = ownerFilter;
17
- this.status = status;
18
16
  }
19
17
  }
20
18
  exports.ListDataMartsCommand = ListDataMartsCommand;
@@ -7,7 +7,6 @@ export interface McpListDataMartsRequest {
7
7
  projectId: string;
8
8
  userId: string;
9
9
  roles: string[];
10
- status?: 'published';
11
10
  }
12
11
  export interface McpSummarizeDataCatalogRequest {
13
12
  projectId: string;
@@ -16,7 +15,6 @@ export interface McpSummarizeDataCatalogRequest {
16
15
  }
17
16
  export interface McpGetDataMartDetailsRequest extends McpListDataMartsRequest {
18
17
  dataMartId: string;
19
- includeJoinedFields?: boolean;
20
18
  }
21
19
  export interface McpDataMartListItem {
22
20
  id: string;
@@ -30,7 +28,6 @@ export interface McpListDataMartsResponse {
30
28
  }
31
29
  export interface McpJoinedFieldDto {
32
30
  name: string;
33
- displayName: string;
34
31
  type: string;
35
32
  description: string;
36
33
  sourceDataMart: string;
@@ -58,19 +55,9 @@ export interface McpQueryDataMartRequest {
58
55
  }
59
56
  export interface McpQueryDataMartResponse {
60
57
  columns: string[];
61
- columnMetadata: Array<{
62
- name: string;
63
- displayName: string;
64
- description?: string;
65
- type?: string;
66
- }>;
67
58
  rows: unknown[][];
68
59
  truncated: boolean;
69
60
  totals: Record<string, number | string | boolean | null> | null;
70
- dataMart: {
71
- id: string;
72
- title: string;
73
- };
74
61
  executedSql?: string;
75
62
  }
76
63
  export interface McpDataCatalogSummaryItem {
@@ -21,7 +21,6 @@ export declare class McpDataMartsFacadeImpl implements McpDataMartsFacade {
21
21
  private resolveJoinedFields;
22
22
  queryDataMart(request: McpQueryDataMartRequest, signal?: AbortSignal): Promise<McpQueryDataMartResponse>;
23
23
  summarizeDataCatalog(request: McpSummarizeDataCatalogRequest): Promise<McpDataCatalogSummaryResponse>;
24
- private ensurePublishedDataMartAccessible;
25
- private withDisplayNames;
24
+ private ensureDataMartAccessible;
26
25
  private filterAvailableFields;
27
26
  }
@@ -19,10 +19,8 @@ const get_data_mart_command_1 = require("../dto/domain/get-data-mart.command");
19
19
  const list_data_marts_command_1 = require("../dto/domain/list-data-marts.command");
20
20
  const summarize_mcp_data_catalog_command_1 = require("../dto/domain/summarize-mcp-data-catalog.command");
21
21
  const blendable_schema_service_1 = require("../services/blendable-schema.service");
22
- const blended_field_display_name_1 = require("../services/blended-field-display-name");
23
22
  const data_mart_relationship_service_1 = require("../services/data-mart-relationship.service");
24
23
  const data_mart_service_1 = require("../services/data-mart.service");
25
- const data_mart_status_enum_1 = require("../enums/data-mart-status.enum");
26
24
  const get_data_mart_service_1 = require("../use-cases/get-data-mart.service");
27
25
  const list_data_marts_service_1 = require("../use-cases/list-data-marts.service");
28
26
  const query_data_mart_service_1 = require("../use-cases/query-data-mart.service");
@@ -46,11 +44,9 @@ let McpDataMartsFacadeImpl = McpDataMartsFacadeImpl_1 = class McpDataMartsFacade
46
44
  this.summarizeMcpDataCatalogService = summarizeMcpDataCatalogService;
47
45
  }
48
46
  async listDataMarts(request) {
49
- const result = await this.listDataMartsService.run(new list_data_marts_command_1.ListDataMartsCommand(request.projectId, request.userId, request.roles, undefined, undefined, data_mart_status_enum_1.DataMartStatus.PUBLISHED));
47
+ const result = await this.listDataMartsService.run(new list_data_marts_command_1.ListDataMartsCommand(request.projectId, request.userId, request.roles));
50
48
  return {
51
- dataMarts: result.items
52
- .filter(item => item.status === data_mart_status_enum_1.DataMartStatus.PUBLISHED)
53
- .map(item => ({
49
+ dataMarts: result.items.map(item => ({
54
50
  id: item.id,
55
51
  title: item.title,
56
52
  description: item.description,
@@ -60,7 +56,7 @@ let McpDataMartsFacadeImpl = McpDataMartsFacadeImpl_1 = class McpDataMartsFacade
60
56
  };
61
57
  }
62
58
  async getDataMartDetails(request) {
63
- await this.ensurePublishedDataMartAccessible(request);
59
+ await this.ensureDataMartAccessible(request);
64
60
  const dataMart = await this.dataMartService.actualizeSchemaIfExpired(request.dataMartId, request.projectId, ai_insights_constants_1.AI_INSIGHTS_SCHEMA_EXPIRES_AFTER_MS);
65
61
  const schema = dataMart.schema
66
62
  ? (0, prepare_schema_1.prepareSchema)({
@@ -72,8 +68,8 @@ let McpDataMartsFacadeImpl = McpDataMartsFacadeImpl_1 = class McpDataMartsFacade
72
68
  id: dataMart.id,
73
69
  name: dataMart.title,
74
70
  description: dataMart.description ?? '',
75
- fields: this.withDisplayNames(schema?.fields ?? []),
76
- joinedFields: request.includeJoinedFields ? await this.resolveJoinedFields(request) : [],
71
+ fields: schema?.fields ?? [],
72
+ joinedFields: await this.resolveJoinedFields(request),
77
73
  };
78
74
  }
79
75
  async resolveJoinedFields(request) {
@@ -90,7 +86,6 @@ let McpDataMartsFacadeImpl = McpDataMartsFacadeImpl_1 = class McpDataMartsFacade
90
86
  .filter(f => !f.isHidden && accessiblePaths.has(f.aliasPath))
91
87
  .map(f => ({
92
88
  name: f.name,
93
- displayName: (0, blended_field_display_name_1.formatBlendedFieldDisplayName)(f),
94
89
  type: f.type,
95
90
  description: f.description ?? '',
96
91
  sourceDataMart: f.sourceDataMartTitle,
@@ -113,27 +108,8 @@ let McpDataMartsFacadeImpl = McpDataMartsFacadeImpl_1 = class McpDataMartsFacade
113
108
  async summarizeDataCatalog(request) {
114
109
  return this.summarizeMcpDataCatalogService.run(new summarize_mcp_data_catalog_command_1.SummarizeMcpDataCatalogCommand(request.projectId, request.userId, request.roles));
115
110
  }
116
- async ensurePublishedDataMartAccessible(request) {
117
- const dataMart = await this.getDataMartService.run(new get_data_mart_command_1.GetDataMartCommand(request.dataMartId, request.projectId, request.userId, request.roles));
118
- if (dataMart.status !== data_mart_status_enum_1.DataMartStatus.PUBLISHED) {
119
- throw new common_1.NotFoundException('Data Mart not found');
120
- }
121
- }
122
- withDisplayNames(fields) {
123
- return fields.map(field => {
124
- const name = typeof field['name'] === 'string' ? field['name'] : undefined;
125
- const businessName = typeof field['businessName'] === 'string' && field['businessName'].trim()
126
- ? field['businessName'].trim()
127
- : undefined;
128
- const nestedFields = Array.isArray(field['fields'])
129
- ? this.withDisplayNames(field['fields'])
130
- : undefined;
131
- return {
132
- ...field,
133
- ...(name ? { displayName: businessName ?? name } : {}),
134
- ...(nestedFields ? { fields: nestedFields } : {}),
135
- };
136
- });
111
+ async ensureDataMartAccessible(request) {
112
+ await this.getDataMartService.run(new get_data_mart_command_1.GetDataMartCommand(request.dataMartId, request.projectId, request.userId, request.roles));
137
113
  }
138
114
  filterAvailableFields(fields) {
139
115
  return fields
@@ -12,7 +12,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.BlendedReportDataService = void 0;
13
13
  const common_1 = require("@nestjs/common");
14
14
  const blendable_schema_service_1 = require("./blendable-schema.service");
15
- const blended_field_display_name_1 = require("./blended-field-display-name");
16
15
  const data_mart_relationship_service_1 = require("./data-mart-relationship.service");
17
16
  const data_mart_table_reference_service_1 = require("./data-mart-table-reference.service");
18
17
  const output_controls_validator_service_1 = require("./output-controls-validator.service");
@@ -162,7 +161,7 @@ let BlendedReportDataService = class BlendedReportDataService {
162
161
  const blendedField = blendedFieldsByName.get(col);
163
162
  if (blendedField) {
164
163
  const effectiveType = (0, field_aggregation_1.computeEffectiveType)(blendedField.type, blendedField.aggregateFunction, storageType);
165
- headers.push(new report_data_header_dto_1.ReportDataHeader(blendedField.name, (0, blended_field_display_name_1.formatBlendedFieldDisplayName)(blendedField), blendedField.description || undefined, effectiveType, blendedField.aggregateFunction));
164
+ headers.push(new report_data_header_dto_1.ReportDataHeader(blendedField.name, `${blendedField.outputPrefix} ${blendedField.alias || blendedField.originalFieldName}`, blendedField.description || undefined, effectiveType, blendedField.aggregateFunction));
166
165
  }
167
166
  }
168
167
  return headers;
@@ -4,7 +4,6 @@ import { DataMartSchemaProviderFacade } from '../data-storage-types/facades/data
4
4
  import { DataMart } from '../entities/data-mart.entity';
5
5
  import { DataStorage } from '../entities/data-storage.entity';
6
6
  import { DataMartDefinitionType } from '../enums/data-mart-definition-type.enum';
7
- import { DataMartStatus } from '../enums/data-mart-status.enum';
8
7
  import { OwnerFilter } from '../enums/owner-filter.enum';
9
8
  import { RoleScope } from '../enums/role-scope.enum';
10
9
  import { DataMartSearchIndexInvalidationService } from './data-mart-search-index-invalidation.service';
@@ -25,7 +24,6 @@ export declare class DataMartService {
25
24
  userId?: string;
26
25
  roles?: string[];
27
26
  roleScope?: RoleScope;
28
- status?: DataMartStatus;
29
27
  }): Promise<{
30
28
  items: DataMart[];
31
29
  total: number;
@@ -97,9 +97,6 @@ let DataMartService = DataMartService_1 = class DataMartService {
97
97
  .setParameter('connectorDefinitionType', data_mart_definition_type_enum_1.DataMartDefinitionType.CONNECTOR)
98
98
  .where('dm.projectId = :projectId', { projectId })
99
99
  .andWhere('dm.deletedAt IS NULL');
100
- if (options?.status) {
101
- qb.andWhere('dm.status = :status', { status: options.status });
102
- }
103
100
  this.applyNonAdminVisibilityGate(qb, projectId, options);
104
101
  if (options?.ownerFilter === owner_filter_enum_1.OwnerFilter.HAS_OWNERS) {
105
102
  qb.andWhere(`(EXISTS (SELECT 1 FROM data_mart_technical_owners t WHERE t.data_mart_id = dm.id)
@@ -15,7 +15,6 @@ const data_mart_query_builder_facade_1 = require("../data-storage-types/facades/
15
15
  const report_like_read_plan_1 = require("../dto/domain/report-like-read-plan");
16
16
  const blendable_schema_service_1 = require("./blendable-schema.service");
17
17
  const blended_report_data_service_1 = require("./blended-report-data.service");
18
- const blended_field_display_name_1 = require("./blended-field-display-name");
19
18
  const data_mart_query_builder_interface_1 = require("../data-storage-types/interfaces/data-mart-query-builder.interface");
20
19
  const data_mart_table_reference_service_1 = require("./data-mart-table-reference.service");
21
20
  const output_controls_capability_service_1 = require("./output-controls-capability.service");
@@ -136,7 +135,7 @@ let ReportSqlComposerService = class ReportSqlComposerService {
136
135
  const field = blendedByName.get(col);
137
136
  if (!field)
138
137
  continue;
139
- headers.push(new report_data_header_dto_1.ReportDataHeader(field.name, (0, blended_field_display_name_1.formatBlendedFieldDisplayName)(field), field.description || undefined, field.type));
138
+ headers.push(new report_data_header_dto_1.ReportDataHeader(field.name, `${field.outputPrefix} ${field.alias || field.originalFieldName}`, field.description || undefined, field.type));
140
139
  }
141
140
  return headers.length > 0 ? headers : undefined;
142
141
  }
@@ -53,7 +53,6 @@ let ListDataMartsService = class ListDataMartsService {
53
53
  userId: command.userId,
54
54
  roles: command.roles,
55
55
  roleScope,
56
- ...(command.status ? { status: command.status } : {}),
57
56
  });
58
57
  if (dataMarts.length === 0) {
59
58
  return { items: [], total, offset };
@@ -156,12 +156,6 @@ let QueryDataMartService = QueryDataMartService_1 = class QueryDataMartService {
156
156
  signal: workController.signal,
157
157
  });
158
158
  const columns = description.dataHeaders.map(header => header.name);
159
- const columnMetadata = description.dataHeaders.map(header => ({
160
- name: header.name,
161
- displayName: header.alias ?? header.name,
162
- ...(header.description ? { description: header.description } : {}),
163
- ...(header.storageFieldType ? { type: header.storageFieldType } : {}),
164
- }));
165
159
  const rows = [];
166
160
  let batchId;
167
161
  do {
@@ -177,7 +171,7 @@ let QueryDataMartService = QueryDataMartService_1 = class QueryDataMartService {
177
171
  const truncated = rows.length > r.limit;
178
172
  const trimmed = truncated ? rows.slice(0, r.limit) : rows;
179
173
  const totals = await totalsPromise;
180
- return { columns, columnMetadata, trimmed, truncated, totals };
174
+ return { columns, trimmed, truncated, totals };
181
175
  }
182
176
  finally {
183
177
  workController.abort();
@@ -189,7 +183,7 @@ let QueryDataMartService = QueryDataMartService_1 = class QueryDataMartService {
189
183
  }
190
184
  }
191
185
  })();
192
- const { columns, columnMetadata, trimmed, truncated, totals } = await Promise.race([
186
+ const { columns, trimmed, truncated, totals } = await Promise.race([
193
187
  produce,
194
188
  deadline,
195
189
  aborted,
@@ -230,14 +224,9 @@ let QueryDataMartService = QueryDataMartService_1 = class QueryDataMartService {
230
224
  }
231
225
  return {
232
226
  columns,
233
- columnMetadata,
234
227
  rows: trimmed,
235
228
  truncated,
236
229
  totals,
237
- dataMart: {
238
- id: dataMart.id,
239
- title: dataMart.title,
240
- },
241
230
  executedSql: executionSqlQuery,
242
231
  };
243
232
  }
@@ -1,2 +1,2 @@
1
- export declare const MCP_SYSTEM_INSTRUCTIONS = "You have access to the current OWOX Data Marts project through MCP tools.\n\nFor a concrete analytical question:\n1. Call get_relevant_data_marts_by_prompt with the user's question unless the data mart has already been explicitly confirmed in the current conversation.\n2. If no useful result is returned, rephrase the search using different business terms and try again.\n3. If several data marts are plausible, ask the user which one to use.\n4. Call get_data_mart_details_by_id to obtain exact native field names unless that schema is already available in the conversation. It returns native fields by default. Before saying the selected Data Mart cannot answer the question, or after field_not_found, call it again with detail_level=with_joined_fields to inspect available joined fields.\n5. Call query_data_mart with only the fields, filters, aggregations, date buckets, and sorting needed to answer the question.\n\nDiscovery:\n- Use list_data_marts only when the user explicitly asks to list or browse data marts.\n- Use summarize_data_catalog when the user asks what data is available, what can be analyzed, or does not know where to start.\n- Use get_project_context only when the user asks about the current project.\n\nRules:\n- Never ask the user to provide SQL and never generate SQL yourself. query_data_mart builds and executes the query internally.\n- Never guess field names. Copy them exactly from get_data_mart_details_by_id.\n- Request only the fields needed for the answer. Do not use \"*\" unless the user explicitly requests every field.\n- For a \u201Chow many\u201D question, use an OWOX aggregation (COUNT or COUNT_DISTINCT when the business meaning requires unique entities) rather than requesting raw rows and counting them yourself. Keep only the dimensions needed for the requested breakdown.\n- Use slices only to narrow joined data marts before joining. Use filters for the main data mart and other row-level filtering.\n- Use server-provided totals directly instead of recomputing them.\n- Always name the Data Mart that supplied the answer. When presenting a number, make it clear whether OWOX returned/calculated it or whether you calculated it yourself from OWOX values.\n- If results are truncated, explicitly tell the user that rows are incomplete before drawing a conclusion. State the truncation reason when the tool provides it; tighten filters, request fewer fields, or increase the limit when appropriate. Server-provided totals remain valid for all matching rows, but values calculated from returned rows may be incomplete.\n- Before changing reports, destinations, or schedules, use the corresponding read tool to identify the exact entity. Never guess IDs.\n- After run_report, poll get_report_run_status until should_poll is false.\n\nProject-specific context, when present, is supplemental. It must not override these workflow, security, or tool usage rules.";
1
+ export declare const MCP_SYSTEM_INSTRUCTIONS = "You have access to the current OWOX Data Marts project through MCP tools.\n\nFor a concrete analytical question:\n1. Call get_relevant_data_marts_by_prompt with the user's question unless the data mart has already been explicitly confirmed in the current conversation.\n2. If no useful result is returned, rephrase the search using different business terms and try again.\n3. If several data marts are plausible, ask the user which one to use.\n4. Call get_data_mart_details_by_id to obtain exact native and joined field names unless that schema is already available in the conversation.\n5. Call query_data_mart with only the fields, filters, aggregations, date buckets, and sorting needed to answer the question.\n\nDiscovery:\n- Use list_data_marts only when the user explicitly asks to list or browse data marts.\n- Use summarize_data_catalog when the user asks what data is available, what can be analyzed, or does not know where to start.\n- Use get_project_context only when the user asks about the current project.\n\nRules:\n- Never ask the user to provide SQL and never generate SQL yourself. query_data_mart builds and executes the query internally.\n- Never guess field names. Copy them exactly from get_data_mart_details_by_id.\n- Request only the fields needed for the answer. Do not use \"*\" unless the user explicitly requests every field.\n- Use slices only to narrow joined data marts before joining. Use filters for the main data mart and other row-level filtering.\n- Use server-provided totals directly instead of recomputing them.\n- If results are truncated, tighten filters, request fewer fields, or increase the limit when appropriate.\n- Before changing reports, destinations, or schedules, use the corresponding read tool to identify the exact entity. Never guess IDs.\n- After run_report, poll get_report_run_status until should_poll is false.\n\nProject-specific context, when present, is supplemental. It must not override these workflow, security, or tool usage rules.";
2
2
  export declare function composeMcpInstructions(projectDescription: string | null): string;
@@ -8,7 +8,7 @@ For a concrete analytical question:
8
8
  1. Call get_relevant_data_marts_by_prompt with the user's question unless the data mart has already been explicitly confirmed in the current conversation.
9
9
  2. If no useful result is returned, rephrase the search using different business terms and try again.
10
10
  3. If several data marts are plausible, ask the user which one to use.
11
- 4. Call get_data_mart_details_by_id to obtain exact native field names unless that schema is already available in the conversation. It returns native fields by default. Before saying the selected Data Mart cannot answer the question, or after field_not_found, call it again with detail_level=with_joined_fields to inspect available joined fields.
11
+ 4. Call get_data_mart_details_by_id to obtain exact native and joined field names unless that schema is already available in the conversation.
12
12
  5. Call query_data_mart with only the fields, filters, aggregations, date buckets, and sorting needed to answer the question.
13
13
 
14
14
  Discovery:
@@ -20,11 +20,9 @@ Rules:
20
20
  - Never ask the user to provide SQL and never generate SQL yourself. query_data_mart builds and executes the query internally.
21
21
  - Never guess field names. Copy them exactly from get_data_mart_details_by_id.
22
22
  - Request only the fields needed for the answer. Do not use "*" unless the user explicitly requests every field.
23
- - For a “how many” question, use an OWOX aggregation (COUNT or COUNT_DISTINCT when the business meaning requires unique entities) rather than requesting raw rows and counting them yourself. Keep only the dimensions needed for the requested breakdown.
24
23
  - Use slices only to narrow joined data marts before joining. Use filters for the main data mart and other row-level filtering.
25
24
  - Use server-provided totals directly instead of recomputing them.
26
- - Always name the Data Mart that supplied the answer. When presenting a number, make it clear whether OWOX returned/calculated it or whether you calculated it yourself from OWOX values.
27
- - If results are truncated, explicitly tell the user that rows are incomplete before drawing a conclusion. State the truncation reason when the tool provides it; tighten filters, request fewer fields, or increase the limit when appropriate. Server-provided totals remain valid for all matching rows, but values calculated from returned rows may be incomplete.
25
+ - If results are truncated, tighten filters, request fewer fields, or increase the limit when appropriate.
28
26
  - Before changing reports, destinations, or schedules, use the corresponding read tool to identify the exact entity. Never guess IDs.
29
27
  - After run_report, poll get_report_run_status until should_poll is false.
30
28
 
@@ -32,7 +32,6 @@ export declare class AddDestinationTool implements McpToolDefinition<AddDestinat
32
32
  authorization_url: z.ZodOptional<z.ZodString>;
33
33
  instructions: z.ZodString;
34
34
  destination_id: z.ZodOptional<z.ZodString>;
35
- destination_url: z.ZodOptional<z.ZodString>;
36
35
  };
37
36
  readonly annotations: {
38
37
  title: string;
@@ -19,7 +19,6 @@ const public_origin_service_1 = require("../../../common/config/public-origin.se
19
19
  const mcp_data_destinations_facade_1 = require("../../../data-marts/facades/mcp-data-destinations.facade");
20
20
  const mcp_destination_type_1 = require("../../../data-marts/facades/mcp-destination-type");
21
21
  const mcp_tool_definition_1 = require("./mcp-tool.definition");
22
- const data_mart_ui_path_1 = require("./data-mart-ui-path");
23
22
  const mcp_flow_ui_path_1 = require("./mcp-flow-ui-path");
24
23
  const mcp_docs_urls_1 = require("./mcp-docs-urls");
25
24
  const mcp_public_url_util_1 = require("./mcp-public-url.util");
@@ -90,10 +89,6 @@ let AddDestinationTool = class AddDestinationTool {
90
89
  .describe('The new destination id. Present for every destination_type EXCEPT google_sheets ' +
91
90
  '(returned immediately, before any external action is needed). For google_sheets, ' +
92
91
  'this is absent — use list_destinations after the user confirms setup instead.'),
93
- destination_url: zod_1.z
94
- .string()
95
- .optional()
96
- .describe('Open the created destination in OWOX. Absent until Google Sheets OAuth creates it.'),
97
92
  };
98
93
  annotations = {
99
94
  title: 'Add Destination',
@@ -132,7 +127,6 @@ let AddDestinationTool = class AddDestinationTool {
132
127
  });
133
128
  return (0, mcp_tool_definition_1.jsonToolResult)({
134
129
  destination_id: created.id,
135
- destination_url: (0, mcp_public_url_util_1.joinPublicOrigin)(this.publicOriginService.getPublicOrigin(), (0, data_mart_ui_path_1.buildDataDestinationsUiPath)(context.projectId, created.id)),
136
130
  instructions: `Successfully connected ${humanType} destination "${created.name}" for report delivery.`,
137
131
  });
138
132
  }
@@ -149,7 +143,6 @@ Open Data Destinations in OWOX Data Marts and edit "${created.name}" to copy its
149
143
  Share the setup guide with the user — it walks through every step: ${mcp_docs_urls_1.LOOKER_STUDIO_DESTINATION_GUIDE_URL}`;
150
144
  return (0, mcp_tool_definition_1.jsonToolResult)({
151
145
  destination_id: created.id,
152
- destination_url: (0, mcp_public_url_util_1.joinPublicOrigin)(this.publicOriginService.getPublicOrigin(), (0, data_mart_ui_path_1.buildDataDestinationsUiPath)(context.projectId, created.id)),
153
146
  instructions,
154
147
  });
155
148
  }
@@ -1,6 +1,5 @@
1
1
  import { z } from 'zod';
2
2
  import type { McpScope } from '@owox/idp-protocol';
3
- import { PublicOriginService } from '../../../common/config/public-origin.service';
4
3
  import { type McpScheduledTriggersFacade } from '../../../data-marts/facades/mcp-scheduled-triggers.facade';
5
4
  import type { McpAuthContext } from '../auth/mcp-auth-context';
6
5
  import { type McpToolDefinition, type McpToolResult } from './mcp-tool.definition';
@@ -23,7 +22,6 @@ declare const inputSchema: z.ZodObject<{
23
22
  type CreateReportRunScheduleInput = z.infer<typeof inputSchema>;
24
23
  export declare class CreateReportRunScheduleTool implements McpToolDefinition<CreateReportRunScheduleInput> {
25
24
  private readonly facade;
26
- private readonly publicOriginService;
27
25
  readonly name = "create_report_run_schedule";
28
26
  readonly description = "Creates a new recurring run schedule for a report. Translate the user's natural-language schedule (\"every Monday at 9am\", \"daily at midnight\") into a standard 5-field cron expression before calling (e.g. \"0 9 * * 1\"). This creates an additional schedule and does not replace, delete, or update existing schedules for the same report. To change an existing schedule, first call list_report_run_schedules and then call update_report_run_schedule with the specific trigger_id. time_zone must be a valid IANA timezone (e.g. \"Europe/Kyiv\"); if the user does not specify one, default to UTC and confirm with them. is_active defaults to true.";
29
27
  readonly zodSchema: {
@@ -35,7 +33,6 @@ export declare class CreateReportRunScheduleTool implements McpToolDefinition<Cr
35
33
  readonly outputSchema: {
36
34
  trigger_id: z.ZodString;
37
35
  report_id: z.ZodString;
38
- schedules_url: z.ZodString;
39
36
  cron_expression: z.ZodString;
40
37
  time_zone: z.ZodString;
41
38
  is_active: z.ZodBoolean;
@@ -48,7 +45,7 @@ export declare class CreateReportRunScheduleTool implements McpToolDefinition<Cr
48
45
  openWorldHint: boolean;
49
46
  };
50
47
  readonly requiredScopes: McpScope[];
51
- constructor(facade: McpScheduledTriggersFacade, publicOriginService: PublicOriginService);
48
+ constructor(facade: McpScheduledTriggersFacade);
52
49
  parseInput(input: unknown): CreateReportRunScheduleInput;
53
50
  handler(input: CreateReportRunScheduleInput, context: McpAuthContext): Promise<McpToolResult>;
54
51
  }
@@ -15,11 +15,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.CreateReportRunScheduleTool = void 0;
16
16
  const common_1 = require("@nestjs/common");
17
17
  const zod_1 = require("zod");
18
- const public_origin_service_1 = require("../../../common/config/public-origin.service");
19
18
  const mcp_scheduled_triggers_facade_1 = require("../../../data-marts/facades/mcp-scheduled-triggers.facade");
20
19
  const mcp_tool_definition_1 = require("./mcp-tool.definition");
21
- const data_mart_ui_path_1 = require("./data-mart-ui-path");
22
- const mcp_public_url_util_1 = require("./mcp-public-url.util");
23
20
  const DEFAULT_TIME_ZONE = 'UTC';
24
21
  const inputSchema = zod_1.z
25
22
  .object({
@@ -31,14 +28,12 @@ const inputSchema = zod_1.z
31
28
  .strict();
32
29
  let CreateReportRunScheduleTool = class CreateReportRunScheduleTool {
33
30
  facade;
34
- publicOriginService;
35
31
  name = 'create_report_run_schedule';
36
32
  description = 'Creates a new recurring run schedule for a report. Translate the user\'s natural-language schedule ("every Monday at 9am", "daily at midnight") into a standard 5-field cron expression before calling (e.g. "0 9 * * 1"). This creates an additional schedule and does not replace, delete, or update existing schedules for the same report. To change an existing schedule, first call list_report_run_schedules and then call update_report_run_schedule with the specific trigger_id. time_zone must be a valid IANA timezone (e.g. "Europe/Kyiv"); if the user does not specify one, default to UTC and confirm with them. is_active defaults to true.';
37
33
  zodSchema = inputSchema.shape;
38
34
  outputSchema = {
39
35
  trigger_id: zod_1.z.string(),
40
36
  report_id: zod_1.z.string(),
41
- schedules_url: zod_1.z.string().describe('Open report schedules in OWOX.'),
42
37
  cron_expression: zod_1.z.string(),
43
38
  time_zone: zod_1.z.string(),
44
39
  is_active: zod_1.z.boolean(),
@@ -51,9 +46,8 @@ let CreateReportRunScheduleTool = class CreateReportRunScheduleTool {
51
46
  openWorldHint: false,
52
47
  };
53
48
  requiredScopes = ['mcp:read', 'mcp:write'];
54
- constructor(facade, publicOriginService) {
49
+ constructor(facade) {
55
50
  this.facade = facade;
56
- this.publicOriginService = publicOriginService;
57
51
  }
58
52
  parseInput(input) {
59
53
  return inputSchema.parse(input);
@@ -70,7 +64,6 @@ let CreateReportRunScheduleTool = class CreateReportRunScheduleTool {
70
64
  return (0, mcp_tool_definition_1.jsonToolResult)({
71
65
  trigger_id: result.triggerId,
72
66
  report_id: result.reportId,
73
- schedules_url: (0, mcp_public_url_util_1.joinPublicOrigin)(this.publicOriginService.getPublicOrigin(), (0, data_mart_ui_path_1.buildReportSchedulesUiPath)(context.projectId)),
74
67
  cron_expression: result.cronExpression,
75
68
  time_zone: result.timeZone,
76
69
  is_active: result.isActive,
@@ -82,6 +75,6 @@ exports.CreateReportRunScheduleTool = CreateReportRunScheduleTool;
82
75
  exports.CreateReportRunScheduleTool = CreateReportRunScheduleTool = __decorate([
83
76
  (0, common_1.Injectable)(),
84
77
  __param(0, (0, common_1.Inject)(mcp_scheduled_triggers_facade_1.MCP_SCHEDULED_TRIGGERS_FACADE)),
85
- __metadata("design:paramtypes", [Object, public_origin_service_1.PublicOriginService])
78
+ __metadata("design:paramtypes", [Object])
86
79
  ], CreateReportRunScheduleTool);
87
80
  //# sourceMappingURL=create-report-run-schedule.tool.js.map
@@ -1,38 +1,17 @@
1
1
  import { z } from 'zod';
2
2
  import type { McpScope } from '@owox/idp-protocol';
3
3
  import { PublicOriginService } from '../../../common/config/public-origin.service';
4
- import { type McpProjectContextFacade } from '../../../idp/facades/mcp-project-context.facade';
5
4
  import { type McpDataMartsFacade } from '../../../data-marts/facades/mcp-data-marts.facade';
6
5
  import type { McpAuthContext } from '../auth/mcp-auth-context';
7
6
  import { type McpToolDefinition, type McpToolResult } from './mcp-tool.definition';
8
- declare const inputSchema: z.ZodObject<{
9
- status: z.ZodOptional<z.ZodLiteral<"published">>;
10
- }, "strict", z.ZodTypeAny, {
11
- status?: "published" | undefined;
12
- }, {
13
- status?: "published" | undefined;
14
- }>;
15
- type ListDataMartsInput = z.infer<typeof inputSchema>;
7
+ type ListDataMartsInput = Record<string, never>;
16
8
  export declare class ListDataMartsTool implements McpToolDefinition<ListDataMartsInput> {
17
9
  private readonly dataMarts;
18
10
  private readonly publicOriginService;
19
- private readonly projectContext;
20
11
  readonly name = "list_data_marts";
21
12
  readonly description = "List data marts available to the current OWOX project member. Use only when the user explicitly asks to list or browse data marts; for a concrete analytical question use get_relevant_data_marts_by_prompt instead, and for open-ended orientation use summarize_data_catalog.";
22
- readonly zodSchema: {
23
- status: z.ZodOptional<z.ZodLiteral<"published">>;
24
- };
13
+ readonly zodSchema: {};
25
14
  readonly outputSchema: {
26
- project: z.ZodOptional<z.ZodObject<{
27
- id: z.ZodString;
28
- title: z.ZodString;
29
- }, "strip", z.ZodTypeAny, {
30
- id: string;
31
- title: string;
32
- }, {
33
- id: string;
34
- title: string;
35
- }>>;
36
15
  data_marts: z.ZodArray<z.ZodObject<{
37
16
  id: z.ZodString;
38
17
  title: z.ZodString;
@@ -63,7 +42,8 @@ export declare class ListDataMartsTool implements McpToolDefinition<ListDataMart
63
42
  openWorldHint: boolean;
64
43
  };
65
44
  readonly requiredScopes: McpScope[];
66
- constructor(dataMarts: McpDataMartsFacade, publicOriginService: PublicOriginService, projectContext: McpProjectContextFacade);
45
+ private readonly inputSchema;
46
+ constructor(dataMarts: McpDataMartsFacade, publicOriginService: PublicOriginService);
67
47
  parseInput(input: unknown): ListDataMartsInput;
68
48
  handler(input: ListDataMartsInput, context: McpAuthContext): Promise<McpToolResult>;
69
49
  }
@@ -16,29 +16,17 @@ exports.ListDataMartsTool = void 0;
16
16
  const common_1 = require("@nestjs/common");
17
17
  const zod_1 = require("zod");
18
18
  const public_origin_service_1 = require("../../../common/config/public-origin.service");
19
- const mcp_project_context_facade_1 = require("../../../idp/facades/mcp-project-context.facade");
20
19
  const mcp_data_marts_facade_1 = require("../../../data-marts/facades/mcp-data-marts.facade");
21
20
  const mcp_tool_definition_1 = require("./mcp-tool.definition");
22
21
  const data_mart_ui_path_1 = require("./data-mart-ui-path");
23
- const mcp_project_summary_util_1 = require("./mcp-project-summary.util");
24
22
  const mcp_public_url_util_1 = require("./mcp-public-url.util");
25
- const inputSchema = zod_1.z
26
- .object({
27
- status: zod_1.z
28
- .literal('published')
29
- .optional()
30
- .describe('Catalog state filter. Only published Data Marts are available through MCP.'),
31
- })
32
- .strict();
33
23
  let ListDataMartsTool = class ListDataMartsTool {
34
24
  dataMarts;
35
25
  publicOriginService;
36
- projectContext;
37
26
  name = 'list_data_marts';
38
27
  description = 'List data marts available to the current OWOX project member. Use only when the user explicitly asks to list or browse data marts; for a concrete analytical question use get_relevant_data_marts_by_prompt instead, and for open-ended orientation use summarize_data_catalog.';
39
- zodSchema = inputSchema.shape;
28
+ zodSchema = {};
40
29
  outputSchema = {
41
- project: zod_1.z.object({ id: zod_1.z.string(), title: zod_1.z.string() }).optional(),
42
30
  data_marts: zod_1.z.array(zod_1.z.object({
43
31
  id: zod_1.z.string(),
44
32
  title: zod_1.z.string(),
@@ -55,28 +43,23 @@ let ListDataMartsTool = class ListDataMartsTool {
55
43
  openWorldHint: false,
56
44
  };
57
45
  requiredScopes = ['mcp:read'];
58
- constructor(dataMarts, publicOriginService, projectContext) {
46
+ inputSchema = zod_1.z.object({}).strict();
47
+ constructor(dataMarts, publicOriginService) {
59
48
  this.dataMarts = dataMarts;
60
49
  this.publicOriginService = publicOriginService;
61
- this.projectContext = projectContext;
62
50
  }
63
51
  parseInput(input) {
64
- return inputSchema.parse(input);
52
+ return this.inputSchema.parse(input);
65
53
  }
66
54
  async handler(input, context) {
67
- const parsed = this.parseInput(input);
68
- const [result, projectContext] = await Promise.all([
69
- this.dataMarts.listDataMarts({
70
- projectId: context.projectId,
71
- userId: context.userId,
72
- roles: context.roles,
73
- status: parsed.status ?? 'published',
74
- }),
75
- (0, mcp_project_summary_util_1.tryGetMcpProjectSummary)(this.projectContext, context),
76
- ]);
55
+ this.parseInput(input);
56
+ const result = await this.dataMarts.listDataMarts({
57
+ projectId: context.projectId,
58
+ userId: context.userId,
59
+ roles: context.roles,
60
+ });
77
61
  const publicOrigin = this.publicOriginService.getPublicOrigin();
78
62
  const structuredContent = {
79
- ...(projectContext ? { project: projectContext } : {}),
80
63
  data_marts: result.dataMarts.map(dataMart => ({
81
64
  id: dataMart.id,
82
65
  title: dataMart.title,
@@ -93,7 +76,6 @@ exports.ListDataMartsTool = ListDataMartsTool;
93
76
  exports.ListDataMartsTool = ListDataMartsTool = __decorate([
94
77
  (0, common_1.Injectable)(),
95
78
  __param(0, (0, common_1.Inject)(mcp_data_marts_facade_1.MCP_DATA_MARTS_FACADE)),
96
- __param(2, (0, common_1.Inject)(mcp_project_context_facade_1.MCP_PROJECT_CONTEXT_FACADE)),
97
- __metadata("design:paramtypes", [Object, public_origin_service_1.PublicOriginService, Object])
79
+ __metadata("design:paramtypes", [Object, public_origin_service_1.PublicOriginService])
98
80
  ], ListDataMartsTool);
99
81
  //# sourceMappingURL=data-mart-catalog.tool.js.map