@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.
- package/dist/src/data-marts/dto/domain/list-data-marts.command.d.ts +1 -3
- package/dist/src/data-marts/dto/domain/list-data-marts.command.js +1 -3
- package/dist/src/data-marts/facades/mcp-data-marts.facade.d.ts +0 -13
- package/dist/src/data-marts/facades/mcp-data-marts.facade.impl.d.ts +1 -2
- package/dist/src/data-marts/facades/mcp-data-marts.facade.impl.js +7 -31
- package/dist/src/data-marts/services/blended-report-data.service.js +1 -2
- package/dist/src/data-marts/services/data-mart.service.d.ts +0 -2
- package/dist/src/data-marts/services/data-mart.service.js +0 -3
- package/dist/src/data-marts/services/report-sql-composer.service.js +1 -2
- package/dist/src/data-marts/use-cases/list-data-marts.service.js +0 -1
- package/dist/src/data-marts/use-cases/query-data-mart.service.js +2 -13
- package/dist/src/ee/mcp/instructions/mcp-system-instructions.d.ts +1 -1
- package/dist/src/ee/mcp/instructions/mcp-system-instructions.js +2 -4
- package/dist/src/ee/mcp/tools/add-destination.tool.d.ts +0 -1
- package/dist/src/ee/mcp/tools/add-destination.tool.js +0 -7
- package/dist/src/ee/mcp/tools/create-report-run-schedule.tool.d.ts +1 -4
- package/dist/src/ee/mcp/tools/create-report-run-schedule.tool.js +2 -9
- package/dist/src/ee/mcp/tools/data-mart-catalog.tool.d.ts +4 -24
- package/dist/src/ee/mcp/tools/data-mart-catalog.tool.js +11 -29
- package/dist/src/ee/mcp/tools/data-mart-details.tool.d.ts +2 -16
- package/dist/src/ee/mcp/tools/data-mart-details.tool.js +4 -25
- package/dist/src/ee/mcp/tools/data-mart-ui-path.d.ts +0 -2
- package/dist/src/ee/mcp/tools/data-mart-ui-path.js +0 -9
- package/dist/src/ee/mcp/tools/delete-report-run-schedule.tool.d.ts +1 -4
- package/dist/src/ee/mcp/tools/delete-report-run-schedule.tool.js +2 -9
- package/dist/src/ee/mcp/tools/get-data-mart-reports.tool.d.ts +1 -9
- package/dist/src/ee/mcp/tools/get-data-mart-reports.tool.js +3 -18
- package/dist/src/ee/mcp/tools/list-destinations.tool.d.ts +1 -6
- package/dist/src/ee/mcp/tools/list-destinations.tool.js +3 -15
- package/dist/src/ee/mcp/tools/list-report-run-schedules.tool.d.ts +1 -16
- package/dist/src/ee/mcp/tools/list-report-run-schedules.tool.js +6 -21
- package/dist/src/ee/mcp/tools/query-data-mart.tool.d.ts +2 -65
- package/dist/src/ee/mcp/tools/query-data-mart.tool.js +8 -72
- package/dist/src/ee/mcp/tools/search-data-marts.tool.d.ts +1 -13
- package/dist/src/ee/mcp/tools/search-data-marts.tool.js +11 -21
- package/dist/src/ee/mcp/tools/summarize-data-catalog.tool.d.ts +1 -13
- package/dist/src/ee/mcp/tools/summarize-data-catalog.tool.js +7 -17
- package/dist/src/ee/mcp/tools/tabular-serializer.d.ts +0 -6
- package/dist/src/ee/mcp/tools/tabular-serializer.js +3 -32
- package/dist/src/ee/mcp/tools/update-report-run-schedule.tool.d.ts +1 -4
- package/dist/src/ee/mcp/tools/update-report-run-schedule.tool.js +2 -9
- package/package.json +5 -5
- package/dist/src/data-marts/services/blended-field-display-name.d.ts +0 -7
- package/dist/src/data-marts/services/blended-field-display-name.js +0 -8
- package/dist/src/ee/mcp/tools/mcp-project-summary.util.d.ts +0 -7
- 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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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.
|
|
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:
|
|
76
|
-
joinedFields:
|
|
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
|
|
117
|
-
|
|
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,
|
|
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,
|
|
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
|
}
|
|
@@ -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,
|
|
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,
|
|
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
|
|
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.
|
|
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
|
-
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
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
|