@jupiterone/jupiterone-mcp 0.0.3 → 0.0.6
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/README.md +2 -2
- package/dist/client/graphql/mutations.js +13 -10
- package/dist/client/graphql/mutations.js.map +1 -1
- package/dist/client/graphql/queries.d.ts +1 -1
- package/dist/client/graphql/queries.d.ts.map +1 -1
- package/dist/client/graphql/queries.js +22 -19
- package/dist/client/graphql/queries.js.map +1 -1
- package/dist/client/jupiterone-client.d.ts +3 -1
- package/dist/client/jupiterone-client.d.ts.map +1 -1
- package/dist/client/jupiterone-client.js +33 -20
- package/dist/client/jupiterone-client.js.map +1 -1
- package/dist/client/services/account-service.js +8 -4
- package/dist/client/services/account-service.js.map +1 -1
- package/dist/client/services/alert-service.js +7 -3
- package/dist/client/services/alert-service.js.map +1 -1
- package/dist/client/services/dashboard-service.js +12 -8
- package/dist/client/services/dashboard-service.js.map +1 -1
- package/dist/client/services/integration-service.js +11 -7
- package/dist/client/services/integration-service.js.map +1 -1
- package/dist/client/services/j1ql-service.d.ts.map +1 -1
- package/dist/client/services/j1ql-service.js +42 -7
- package/dist/client/services/j1ql-service.js.map +1 -1
- package/dist/client/services/rule-service.js +17 -13
- package/dist/client/services/rule-service.js.map +1 -1
- package/dist/generated/description-map.d.ts +2 -0
- package/dist/generated/description-map.d.ts.map +1 -0
- package/dist/generated/description-map.js +2107 -0
- package/dist/generated/description-map.js.map +1 -0
- package/dist/index.js +11 -12
- package/dist/index.js.map +1 -1
- package/dist/server/mcp-server.d.ts +9 -1
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +1557 -1360
- package/dist/server/mcp-server.js.map +1 -1
- package/dist/types/jupiterone.d.ts +3 -2
- package/dist/types/jupiterone.d.ts.map +1 -1
- package/dist/types/jupiterone.js +2 -1
- package/dist/utils/description-loader.js +8 -5
- package/dist/utils/description-loader.js.map +1 -1
- package/dist/utils/j1ql-validator.d.ts +34 -0
- package/dist/utils/j1ql-validator.d.ts.map +1 -0
- package/dist/utils/j1ql-validator.js +292 -0
- package/dist/utils/j1ql-validator.js.map +1 -0
- package/dist/utils/load-description.d.ts.map +1 -1
- package/dist/utils/load-description.js +7 -7
- package/dist/utils/load-description.js.map +1 -1
- package/package.json +5 -5
- package/dist/descriptions/create-dashboard-widget.md +0 -325
- package/dist/descriptions/create-dashboard.md +0 -12
- package/dist/descriptions/create-inline-question-rule.md +0 -374
- package/dist/descriptions/create-j1ql-from-natural-language.md +0 -7
- package/dist/descriptions/execute-j1ql-query.md +0 -426
- package/dist/descriptions/get-integration-definitions.md +0 -27
- package/dist/descriptions/get-integration-instances.md +0 -35
- package/dist/descriptions/list-alerts.md +0 -14
- package/dist/descriptions/list-rules.md +0 -53
- package/dist/descriptions/update-dashboard.md +0 -467
- package/dist/descriptions/update-inline-question-rule.md +0 -363
|
@@ -1,286 +1,447 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JupiterOneMcpServer = void 0;
|
|
4
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const jupiterone_client_js_1 = require("../client/jupiterone-client.js");
|
|
8
|
+
const load_description_js_1 = require("../utils/load-description.js");
|
|
9
|
+
const j1ql_validator_js_1 = require("../utils/j1ql-validator.js");
|
|
10
|
+
class JupiterOneMcpServer {
|
|
7
11
|
server;
|
|
8
12
|
client;
|
|
13
|
+
validator;
|
|
14
|
+
hasEnvironmentAccount;
|
|
9
15
|
constructor(config) {
|
|
10
|
-
this.client = new JupiterOneClient(config);
|
|
11
|
-
this.
|
|
16
|
+
this.client = new jupiterone_client_js_1.JupiterOneClient(config);
|
|
17
|
+
this.validator = new j1ql_validator_js_1.J1QLValidator(this.client.j1qlService);
|
|
18
|
+
this.server = new mcp_js_1.McpServer({
|
|
12
19
|
name: 'jupiterone-mcp',
|
|
13
20
|
version: '1.0.0',
|
|
14
21
|
});
|
|
22
|
+
this.hasEnvironmentAccount = !config.accountId;
|
|
15
23
|
this.setupTools();
|
|
16
24
|
}
|
|
25
|
+
registerTool(options) {
|
|
26
|
+
const { name, schema, handler, description } = options;
|
|
27
|
+
let finalSchema = schema;
|
|
28
|
+
if (this.hasEnvironmentAccount) {
|
|
29
|
+
finalSchema = {
|
|
30
|
+
...schema,
|
|
31
|
+
accountId: zod_1.z
|
|
32
|
+
.string()
|
|
33
|
+
.describe('JupiterOne Account ID for this request. This should be explicitly asked for with the first tool call.'),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
this.server.tool(name, description || '', finalSchema, async (params) => {
|
|
37
|
+
let client = this.client;
|
|
38
|
+
let toolParams = params;
|
|
39
|
+
let validator = this.validator;
|
|
40
|
+
if (this.hasEnvironmentAccount) {
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
42
|
+
const { accountId, ...otherParams } = params;
|
|
43
|
+
if (!accountId) {
|
|
44
|
+
return {
|
|
45
|
+
content: [
|
|
46
|
+
{
|
|
47
|
+
type: 'text',
|
|
48
|
+
text: 'Error: accountId is required for this operation because no default JUPITERONE_ACCOUNT_ID is configured.',
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
isError: true,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
client = this.client.cloneWithAccountId(accountId);
|
|
55
|
+
validator = new j1ql_validator_js_1.J1QLValidator(client.j1qlService);
|
|
56
|
+
toolParams = otherParams;
|
|
57
|
+
}
|
|
58
|
+
return handler(toolParams, client, validator);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
17
61
|
setupTools() {
|
|
18
62
|
// Tool: List all rules
|
|
19
|
-
this.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
this.registerTool({
|
|
64
|
+
name: 'list-rules',
|
|
65
|
+
description: (0, load_description_js_1.loadDescription)('list-rules.md'),
|
|
66
|
+
schema: {
|
|
67
|
+
limit: zod_1.z.number().min(1).max(1000).optional(),
|
|
68
|
+
cursor: zod_1.z.string().optional(),
|
|
69
|
+
},
|
|
70
|
+
handler: async ({ limit, cursor }, client) => {
|
|
71
|
+
try {
|
|
72
|
+
const response = await client.listRuleInstances(limit, cursor);
|
|
73
|
+
const instances = response.questionInstances || [];
|
|
74
|
+
return {
|
|
75
|
+
content: [
|
|
76
|
+
{
|
|
77
|
+
type: 'text',
|
|
78
|
+
text: JSON.stringify({
|
|
79
|
+
returned: instances.length,
|
|
80
|
+
rules: instances.map((instance) => ({
|
|
81
|
+
id: instance.id,
|
|
82
|
+
name: instance.name,
|
|
83
|
+
description: instance.description,
|
|
84
|
+
version: instance.version,
|
|
85
|
+
pollingInterval: instance.pollingInterval,
|
|
86
|
+
lastEvaluationStartOn: instance.lastEvaluationStartOn,
|
|
87
|
+
lastEvaluationEndOn: instance.lastEvaluationEndOn,
|
|
88
|
+
latestAlertId: instance.latestAlertId,
|
|
89
|
+
latestAlertIsActive: instance.latestAlertIsActive,
|
|
90
|
+
type: instance.type,
|
|
91
|
+
tags: instance.tags,
|
|
92
|
+
outputs: instance.outputs,
|
|
93
|
+
})),
|
|
94
|
+
pageInfo: response.pageInfo,
|
|
95
|
+
}, null, 2),
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
return {
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
type: 'text',
|
|
105
|
+
text: `Error listing rules: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
isError: true,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
},
|
|
63
112
|
});
|
|
64
113
|
// Tool: Get rule details
|
|
65
|
-
this.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
114
|
+
this.registerTool({
|
|
115
|
+
name: 'get-rule-details',
|
|
116
|
+
schema: {
|
|
117
|
+
ruleId: zod_1.z.string(),
|
|
118
|
+
},
|
|
119
|
+
handler: async ({ ruleId }, client) => {
|
|
120
|
+
try {
|
|
121
|
+
const instances = await client.getAllRuleInstances();
|
|
122
|
+
const rule = instances.find((instance) => instance.id === ruleId);
|
|
123
|
+
if (!rule) {
|
|
124
|
+
return {
|
|
125
|
+
content: [
|
|
126
|
+
{
|
|
127
|
+
type: 'text',
|
|
128
|
+
text: `Rule with ID ${ruleId} not found`,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
isError: true,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
72
134
|
return {
|
|
73
135
|
content: [
|
|
74
136
|
{
|
|
75
137
|
type: 'text',
|
|
76
|
-
text:
|
|
138
|
+
text: JSON.stringify({
|
|
139
|
+
id: rule.id,
|
|
140
|
+
resourceGroupId: rule.resourceGroupId,
|
|
141
|
+
accountId: rule.accountId,
|
|
142
|
+
name: rule.name,
|
|
143
|
+
description: rule.description,
|
|
144
|
+
version: rule.version,
|
|
145
|
+
lastEvaluationStartOn: rule.lastEvaluationStartOn,
|
|
146
|
+
lastEvaluationEndOn: rule.lastEvaluationEndOn,
|
|
147
|
+
evaluationStep: rule.evaluationStep,
|
|
148
|
+
specVersion: rule.specVersion,
|
|
149
|
+
notifyOnFailure: rule.notifyOnFailure,
|
|
150
|
+
triggerActionsOnNewEntitiesOnly: rule.triggerActionsOnNewEntitiesOnly,
|
|
151
|
+
ignorePreviousResults: rule.ignorePreviousResults,
|
|
152
|
+
pollingInterval: rule.pollingInterval,
|
|
153
|
+
templates: rule.templates,
|
|
154
|
+
outputs: rule.outputs,
|
|
155
|
+
labels: rule.labels?.map((label) => ({
|
|
156
|
+
labelName: label.labelName,
|
|
157
|
+
labelValue: label.labelValue,
|
|
158
|
+
})) || [],
|
|
159
|
+
question: rule.question
|
|
160
|
+
? {
|
|
161
|
+
queries: rule.question.queries?.map((query) => ({
|
|
162
|
+
query: query.query,
|
|
163
|
+
name: query.name,
|
|
164
|
+
includeDeleted: query.includeDeleted,
|
|
165
|
+
})) || [],
|
|
166
|
+
}
|
|
167
|
+
: null,
|
|
168
|
+
questionId: rule.questionId,
|
|
169
|
+
latest: rule.latest,
|
|
170
|
+
deleted: rule.deleted,
|
|
171
|
+
type: rule.type,
|
|
172
|
+
operations: rule.operations?.map((op) => ({
|
|
173
|
+
when: op.when,
|
|
174
|
+
actions: op.actions,
|
|
175
|
+
})) || [],
|
|
176
|
+
latestAlertId: rule.latestAlertId,
|
|
177
|
+
latestAlertIsActive: rule.latestAlertIsActive,
|
|
178
|
+
state: rule.state
|
|
179
|
+
? {
|
|
180
|
+
actions: rule.state.actions,
|
|
181
|
+
}
|
|
182
|
+
: null,
|
|
183
|
+
tags: rule.tags,
|
|
184
|
+
remediationSteps: rule.remediationSteps,
|
|
185
|
+
}, null, 2),
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
return {
|
|
192
|
+
content: [
|
|
193
|
+
{
|
|
194
|
+
type: 'text',
|
|
195
|
+
text: `Error getting rule details: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
77
196
|
},
|
|
78
197
|
],
|
|
79
198
|
isError: true,
|
|
80
199
|
};
|
|
81
200
|
}
|
|
82
|
-
|
|
83
|
-
content: [
|
|
84
|
-
{
|
|
85
|
-
type: 'text',
|
|
86
|
-
text: JSON.stringify({
|
|
87
|
-
id: rule.id,
|
|
88
|
-
resourceGroupId: rule.resourceGroupId,
|
|
89
|
-
accountId: rule.accountId,
|
|
90
|
-
name: rule.name,
|
|
91
|
-
description: rule.description,
|
|
92
|
-
version: rule.version,
|
|
93
|
-
lastEvaluationStartOn: rule.lastEvaluationStartOn,
|
|
94
|
-
lastEvaluationEndOn: rule.lastEvaluationEndOn,
|
|
95
|
-
evaluationStep: rule.evaluationStep,
|
|
96
|
-
specVersion: rule.specVersion,
|
|
97
|
-
notifyOnFailure: rule.notifyOnFailure,
|
|
98
|
-
triggerActionsOnNewEntitiesOnly: rule.triggerActionsOnNewEntitiesOnly,
|
|
99
|
-
ignorePreviousResults: rule.ignorePreviousResults,
|
|
100
|
-
pollingInterval: rule.pollingInterval,
|
|
101
|
-
templates: rule.templates,
|
|
102
|
-
outputs: rule.outputs,
|
|
103
|
-
labels: rule.labels?.map((label) => ({
|
|
104
|
-
labelName: label.labelName,
|
|
105
|
-
labelValue: label.labelValue,
|
|
106
|
-
})) || [],
|
|
107
|
-
question: rule.question
|
|
108
|
-
? {
|
|
109
|
-
queries: rule.question.queries?.map((query) => ({
|
|
110
|
-
query: query.query,
|
|
111
|
-
name: query.name,
|
|
112
|
-
includeDeleted: query.includeDeleted,
|
|
113
|
-
})) || [],
|
|
114
|
-
}
|
|
115
|
-
: null,
|
|
116
|
-
questionId: rule.questionId,
|
|
117
|
-
latest: rule.latest,
|
|
118
|
-
deleted: rule.deleted,
|
|
119
|
-
type: rule.type,
|
|
120
|
-
operations: rule.operations?.map((op) => ({
|
|
121
|
-
when: op.when,
|
|
122
|
-
actions: op.actions,
|
|
123
|
-
})) || [],
|
|
124
|
-
latestAlertId: rule.latestAlertId,
|
|
125
|
-
latestAlertIsActive: rule.latestAlertIsActive,
|
|
126
|
-
state: rule.state
|
|
127
|
-
? {
|
|
128
|
-
actions: rule.state.actions,
|
|
129
|
-
}
|
|
130
|
-
: null,
|
|
131
|
-
tags: rule.tags,
|
|
132
|
-
remediationSteps: rule.remediationSteps,
|
|
133
|
-
}, null, 2),
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
catch (error) {
|
|
139
|
-
return {
|
|
140
|
-
content: [
|
|
141
|
-
{
|
|
142
|
-
type: 'text',
|
|
143
|
-
text: `Error getting rule details: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
isError: true,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
201
|
+
},
|
|
149
202
|
});
|
|
150
203
|
// Tool: Test connection
|
|
151
|
-
this.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
204
|
+
this.registerTool({
|
|
205
|
+
name: 'test-connection',
|
|
206
|
+
schema: {},
|
|
207
|
+
handler: async (_, client) => {
|
|
208
|
+
try {
|
|
209
|
+
const isConnected = await client.testConnection();
|
|
210
|
+
const accountInfo = isConnected ? await client.getAccountInfo() : null;
|
|
211
|
+
return {
|
|
212
|
+
content: [
|
|
213
|
+
{
|
|
214
|
+
type: 'text',
|
|
215
|
+
text: JSON.stringify({
|
|
216
|
+
connected: isConnected,
|
|
217
|
+
account: accountInfo,
|
|
218
|
+
}, null, 2),
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
return {
|
|
225
|
+
content: [
|
|
226
|
+
{
|
|
227
|
+
type: 'text',
|
|
228
|
+
text: `Connection test failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
isError: true,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
},
|
|
178
235
|
});
|
|
179
236
|
// Tool: Evaluate rule
|
|
180
|
-
this.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
237
|
+
this.registerTool({
|
|
238
|
+
name: 'evaluate-rule',
|
|
239
|
+
schema: {
|
|
240
|
+
ruleId: zod_1.z.string(),
|
|
241
|
+
},
|
|
242
|
+
handler: async ({ ruleId }, client) => {
|
|
243
|
+
try {
|
|
244
|
+
const result = await client.evaluateRuleInstance(ruleId);
|
|
245
|
+
return {
|
|
246
|
+
content: [
|
|
247
|
+
{
|
|
248
|
+
type: 'text',
|
|
249
|
+
text: JSON.stringify({
|
|
250
|
+
ruleId,
|
|
251
|
+
id: result.id,
|
|
252
|
+
__typename: result.__typename,
|
|
253
|
+
}, null, 2),
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
return {
|
|
260
|
+
content: [
|
|
261
|
+
{
|
|
262
|
+
type: 'text',
|
|
263
|
+
text: `Error evaluating rule: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
isError: true,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
},
|
|
209
270
|
});
|
|
210
271
|
// Tool: Get active alerts
|
|
211
|
-
this.
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
272
|
+
this.registerTool({
|
|
273
|
+
name: 'get-active-alerts',
|
|
274
|
+
description: (0, load_description_js_1.loadDescription)('list-alerts.md'),
|
|
275
|
+
schema: {
|
|
276
|
+
limit: zod_1.z.number().min(1).max(1000).optional(),
|
|
277
|
+
},
|
|
278
|
+
handler: async ({ limit }, client) => {
|
|
279
|
+
try {
|
|
280
|
+
const instances = await client.getAllAlertInstances('ACTIVE');
|
|
281
|
+
if (!instances || !Array.isArray(instances)) {
|
|
282
|
+
throw new Error('Invalid response from JupiterOne API: instances is not an array');
|
|
283
|
+
}
|
|
284
|
+
const limitedInstances = limit ? instances.slice(0, limit) : instances;
|
|
285
|
+
return {
|
|
286
|
+
content: [
|
|
287
|
+
{
|
|
288
|
+
type: 'text',
|
|
289
|
+
text: JSON.stringify({
|
|
290
|
+
total: instances.length,
|
|
291
|
+
returned: limitedInstances.length,
|
|
292
|
+
activeAlerts: limitedInstances.map((instance) => ({
|
|
293
|
+
id: instance.id,
|
|
294
|
+
name: instance.questionRuleInstance?.name ||
|
|
295
|
+
instance.reportRuleInstance?.name ||
|
|
296
|
+
'Unknown',
|
|
297
|
+
description: instance.questionRuleInstance?.description ||
|
|
298
|
+
instance.reportRuleInstance?.description,
|
|
299
|
+
level: instance.level,
|
|
300
|
+
status: instance.status,
|
|
301
|
+
createdOn: instance.createdOn,
|
|
302
|
+
lastUpdatedOn: instance.lastUpdatedOn,
|
|
303
|
+
lastEvaluationBeginOn: instance.lastEvaluationBeginOn,
|
|
304
|
+
lastEvaluationEndOn: instance.lastEvaluationEndOn,
|
|
305
|
+
recordCount: instance.lastEvaluationResult?.rawDataDescriptors?.[0]?.recordCount || 0,
|
|
306
|
+
tags: instance.questionRuleInstance?.tags || [],
|
|
307
|
+
labels: instance.questionRuleInstance?.labels || [],
|
|
308
|
+
outputs: instance.lastEvaluationResult?.outputs || [],
|
|
309
|
+
users: instance.users,
|
|
310
|
+
ruleId: instance.ruleId,
|
|
311
|
+
ruleVersion: instance.ruleVersion,
|
|
312
|
+
endReason: instance.endReason,
|
|
313
|
+
dismissedOn: instance.dismissedOn,
|
|
314
|
+
})),
|
|
315
|
+
}, null, 2),
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
};
|
|
218
319
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
description: instance.questionRuleInstance?.description ||
|
|
233
|
-
instance.reportRuleInstance?.description,
|
|
234
|
-
level: instance.level,
|
|
235
|
-
status: instance.status,
|
|
236
|
-
createdOn: instance.createdOn,
|
|
237
|
-
lastUpdatedOn: instance.lastUpdatedOn,
|
|
238
|
-
lastEvaluationBeginOn: instance.lastEvaluationBeginOn,
|
|
239
|
-
lastEvaluationEndOn: instance.lastEvaluationEndOn,
|
|
240
|
-
recordCount: instance.lastEvaluationResult?.rawDataDescriptors?.[0]?.recordCount || 0,
|
|
241
|
-
tags: instance.questionRuleInstance?.tags || [],
|
|
242
|
-
labels: instance.questionRuleInstance?.labels || [],
|
|
243
|
-
outputs: instance.lastEvaluationResult?.outputs || [],
|
|
244
|
-
users: instance.users,
|
|
245
|
-
ruleId: instance.ruleId,
|
|
246
|
-
ruleVersion: instance.ruleVersion,
|
|
247
|
-
endReason: instance.endReason,
|
|
248
|
-
dismissedOn: instance.dismissedOn,
|
|
249
|
-
})),
|
|
250
|
-
}, null, 2),
|
|
251
|
-
},
|
|
252
|
-
],
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
catch (error) {
|
|
256
|
-
console.error('Error in get-active-alerts:', error);
|
|
257
|
-
return {
|
|
258
|
-
content: [
|
|
259
|
-
{
|
|
260
|
-
type: 'text',
|
|
261
|
-
text: `Error getting active alerts: ${error instanceof Error ? error.message : 'Unknown error'}. Please check your JupiterOne API credentials and connection.`,
|
|
262
|
-
},
|
|
263
|
-
],
|
|
264
|
-
isError: true,
|
|
265
|
-
};
|
|
266
|
-
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
console.error('Error in get-active-alerts:', error);
|
|
322
|
+
return {
|
|
323
|
+
content: [
|
|
324
|
+
{
|
|
325
|
+
type: 'text',
|
|
326
|
+
text: `Error getting active alerts: ${error instanceof Error ? error.message : 'Unknown error'}. Please check your JupiterOne API credentials and connection.`,
|
|
327
|
+
},
|
|
328
|
+
],
|
|
329
|
+
isError: true,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
},
|
|
267
333
|
});
|
|
268
334
|
// Tool: Get dashboards
|
|
269
|
-
this.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
335
|
+
this.registerTool({
|
|
336
|
+
name: 'get-dashboards',
|
|
337
|
+
schema: {},
|
|
338
|
+
handler: async (_, client) => {
|
|
339
|
+
try {
|
|
340
|
+
const dashboards = await client.getDashboards();
|
|
341
|
+
return {
|
|
342
|
+
content: [
|
|
343
|
+
{
|
|
344
|
+
type: 'text',
|
|
345
|
+
text: JSON.stringify({
|
|
346
|
+
total: dashboards.length,
|
|
347
|
+
dashboards: dashboards.map((dashboard) => ({
|
|
348
|
+
id: dashboard.id,
|
|
349
|
+
name: dashboard.name,
|
|
350
|
+
category: dashboard.category,
|
|
351
|
+
supportedUseCase: dashboard.supportedUseCase,
|
|
352
|
+
isJ1ManagedBoard: dashboard.isJ1ManagedBoard,
|
|
353
|
+
resourceGroupId: dashboard.resourceGroupId,
|
|
354
|
+
starred: dashboard.starred,
|
|
355
|
+
lastUpdated: dashboard._timeUpdated,
|
|
356
|
+
createdAt: dashboard._createdAt,
|
|
357
|
+
prerequisites: dashboard.prerequisites
|
|
358
|
+
? {
|
|
359
|
+
prerequisitesMet: dashboard.prerequisites.prerequisitesMet,
|
|
360
|
+
preRequisitesGroupsFulfilled: dashboard.prerequisites.preRequisitesGroupsFulfilled,
|
|
361
|
+
preRequisitesGroupsRequired: dashboard.prerequisites.preRequisitesGroupsRequired,
|
|
362
|
+
}
|
|
363
|
+
: null,
|
|
364
|
+
})),
|
|
365
|
+
}, null, 2),
|
|
366
|
+
},
|
|
367
|
+
],
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
return {
|
|
372
|
+
content: [
|
|
373
|
+
{
|
|
374
|
+
type: 'text',
|
|
375
|
+
text: `Error getting dashboards: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
376
|
+
},
|
|
377
|
+
],
|
|
378
|
+
isError: true,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
// Tool: Create dashboard
|
|
384
|
+
this.registerTool({
|
|
385
|
+
name: 'create-dashboard',
|
|
386
|
+
description: (0, load_description_js_1.loadDescription)('create-dashboard.md'),
|
|
387
|
+
schema: {
|
|
388
|
+
name: zod_1.z.string(),
|
|
389
|
+
type: zod_1.z.string(),
|
|
390
|
+
},
|
|
391
|
+
handler: async ({ name, type }, client) => {
|
|
392
|
+
try {
|
|
393
|
+
const result = await client.createDashboard({ name, type });
|
|
394
|
+
return {
|
|
395
|
+
content: [
|
|
396
|
+
{
|
|
397
|
+
type: 'text',
|
|
398
|
+
text: JSON.stringify({
|
|
399
|
+
id: result.id,
|
|
400
|
+
name,
|
|
401
|
+
type,
|
|
402
|
+
}, null, 2),
|
|
403
|
+
},
|
|
404
|
+
],
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
return {
|
|
409
|
+
content: [
|
|
410
|
+
{
|
|
411
|
+
type: 'text',
|
|
412
|
+
text: `Error creating dashboard: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
isError: true,
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
// Tool: Get dashboard details
|
|
421
|
+
this.registerTool({
|
|
422
|
+
name: 'get-dashboard-details',
|
|
423
|
+
schema: {
|
|
424
|
+
dashboardId: zod_1.z.string(),
|
|
425
|
+
},
|
|
426
|
+
handler: async ({ dashboardId }, client) => {
|
|
427
|
+
try {
|
|
428
|
+
const dashboard = await client.getDashboard(dashboardId);
|
|
429
|
+
return {
|
|
430
|
+
content: [
|
|
431
|
+
{
|
|
432
|
+
type: 'text',
|
|
433
|
+
text: JSON.stringify({
|
|
279
434
|
id: dashboard.id,
|
|
280
435
|
name: dashboard.name,
|
|
281
436
|
category: dashboard.category,
|
|
282
437
|
supportedUseCase: dashboard.supportedUseCase,
|
|
283
438
|
isJ1ManagedBoard: dashboard.isJ1ManagedBoard,
|
|
439
|
+
published: dashboard.published,
|
|
440
|
+
publishedToUserIds: dashboard.publishedToUserIds,
|
|
441
|
+
publishedToGroupIds: dashboard.publishedToGroupIds,
|
|
442
|
+
groupIds: dashboard.groupIds,
|
|
443
|
+
userIds: dashboard.userIds,
|
|
444
|
+
scopeFilters: dashboard.scopeFilters,
|
|
284
445
|
resourceGroupId: dashboard.resourceGroupId,
|
|
285
446
|
starred: dashboard.starred,
|
|
286
447
|
lastUpdated: dashboard._timeUpdated,
|
|
@@ -292,973 +453,948 @@ export class JupiterOneMcpServer {
|
|
|
292
453
|
preRequisitesGroupsRequired: dashboard.prerequisites.preRequisitesGroupsRequired,
|
|
293
454
|
}
|
|
294
455
|
: null,
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
type: 'text',
|
|
306
|
-
text: `Error getting dashboards: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
307
|
-
},
|
|
308
|
-
],
|
|
309
|
-
isError: true,
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
|
-
// Tool: Create dashboard
|
|
314
|
-
this.server.tool('create-dashboard', loadDescription('create-dashboard.md'), {
|
|
315
|
-
name: z.string(),
|
|
316
|
-
type: z.string(),
|
|
317
|
-
}, async ({ name, type }) => {
|
|
318
|
-
try {
|
|
319
|
-
const result = await this.client.createDashboard({ name, type });
|
|
320
|
-
return {
|
|
321
|
-
content: [
|
|
322
|
-
{
|
|
323
|
-
type: 'text',
|
|
324
|
-
text: JSON.stringify({
|
|
325
|
-
id: result.id,
|
|
326
|
-
name,
|
|
327
|
-
type,
|
|
328
|
-
}, null, 2),
|
|
329
|
-
},
|
|
330
|
-
],
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
catch (error) {
|
|
334
|
-
return {
|
|
335
|
-
content: [
|
|
336
|
-
{
|
|
337
|
-
type: 'text',
|
|
338
|
-
text: `Error creating dashboard: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
339
|
-
},
|
|
340
|
-
],
|
|
341
|
-
isError: true,
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
});
|
|
345
|
-
// Tool: Get dashboard details
|
|
346
|
-
this.server.tool('get-dashboard-details', {
|
|
347
|
-
dashboardId: z.string(),
|
|
348
|
-
}, async ({ dashboardId }) => {
|
|
349
|
-
try {
|
|
350
|
-
const dashboard = await this.client.getDashboard(dashboardId);
|
|
351
|
-
return {
|
|
352
|
-
content: [
|
|
353
|
-
{
|
|
354
|
-
type: 'text',
|
|
355
|
-
text: JSON.stringify({
|
|
356
|
-
id: dashboard.id,
|
|
357
|
-
name: dashboard.name,
|
|
358
|
-
category: dashboard.category,
|
|
359
|
-
supportedUseCase: dashboard.supportedUseCase,
|
|
360
|
-
isJ1ManagedBoard: dashboard.isJ1ManagedBoard,
|
|
361
|
-
published: dashboard.published,
|
|
362
|
-
publishedToUserIds: dashboard.publishedToUserIds,
|
|
363
|
-
publishedToGroupIds: dashboard.publishedToGroupIds,
|
|
364
|
-
groupIds: dashboard.groupIds,
|
|
365
|
-
userIds: dashboard.userIds,
|
|
366
|
-
scopeFilters: dashboard.scopeFilters,
|
|
367
|
-
resourceGroupId: dashboard.resourceGroupId,
|
|
368
|
-
starred: dashboard.starred,
|
|
369
|
-
lastUpdated: dashboard._timeUpdated,
|
|
370
|
-
createdAt: dashboard._createdAt,
|
|
371
|
-
prerequisites: dashboard.prerequisites
|
|
372
|
-
? {
|
|
373
|
-
prerequisitesMet: dashboard.prerequisites.prerequisitesMet,
|
|
374
|
-
preRequisitesGroupsFulfilled: dashboard.prerequisites.preRequisitesGroupsFulfilled,
|
|
375
|
-
preRequisitesGroupsRequired: dashboard.prerequisites.preRequisitesGroupsRequired,
|
|
376
|
-
}
|
|
377
|
-
: null,
|
|
378
|
-
parameters: dashboard.parameters.map((param) => ({
|
|
379
|
-
id: param.id,
|
|
380
|
-
label: param.label,
|
|
381
|
-
name: param.name,
|
|
382
|
-
type: param.type,
|
|
383
|
-
valueType: param.valueType,
|
|
384
|
-
default: param.default,
|
|
385
|
-
options: param.options,
|
|
386
|
-
requireValue: param.requireValue,
|
|
387
|
-
disableCustomInput: param.disableCustomInput,
|
|
388
|
-
})),
|
|
389
|
-
widgets: dashboard.widgets.map((widget) => ({
|
|
390
|
-
id: widget.id,
|
|
391
|
-
title: widget.title,
|
|
392
|
-
description: widget.description,
|
|
393
|
-
type: widget.type,
|
|
394
|
-
questionId: widget.questionId,
|
|
395
|
-
noResultMessage: widget.noResultMessage,
|
|
396
|
-
includeDeleted: widget.includeDeleted,
|
|
397
|
-
config: {
|
|
398
|
-
queries: widget.config.queries.map((query) => ({
|
|
399
|
-
id: query.id,
|
|
400
|
-
name: query.name,
|
|
401
|
-
query: query.query,
|
|
402
|
-
})),
|
|
403
|
-
settings: widget.config.settings,
|
|
404
|
-
postQueryFilters: widget.config.postQueryFilters,
|
|
405
|
-
disableQueryPolicyFilters: widget.config.disableQueryPolicyFilters,
|
|
406
|
-
},
|
|
407
|
-
})),
|
|
408
|
-
layouts: {
|
|
409
|
-
xs: dashboard.layouts.xs.map((item) => ({
|
|
410
|
-
i: item.i,
|
|
411
|
-
x: item.x,
|
|
412
|
-
y: item.y,
|
|
413
|
-
w: item.w,
|
|
414
|
-
h: item.h,
|
|
415
|
-
static: item.static,
|
|
416
|
-
moved: item.moved,
|
|
417
|
-
})),
|
|
418
|
-
sm: dashboard.layouts.sm.map((item) => ({
|
|
419
|
-
i: item.i,
|
|
420
|
-
x: item.x,
|
|
421
|
-
y: item.y,
|
|
422
|
-
w: item.w,
|
|
423
|
-
h: item.h,
|
|
424
|
-
static: item.static,
|
|
425
|
-
moved: item.moved,
|
|
426
|
-
})),
|
|
427
|
-
md: dashboard.layouts.md.map((item) => ({
|
|
428
|
-
i: item.i,
|
|
429
|
-
x: item.x,
|
|
430
|
-
y: item.y,
|
|
431
|
-
w: item.w,
|
|
432
|
-
h: item.h,
|
|
433
|
-
static: item.static,
|
|
434
|
-
moved: item.moved,
|
|
456
|
+
parameters: dashboard.parameters.map((param) => ({
|
|
457
|
+
id: param.id,
|
|
458
|
+
label: param.label,
|
|
459
|
+
name: param.name,
|
|
460
|
+
type: param.type,
|
|
461
|
+
valueType: param.valueType,
|
|
462
|
+
default: param.default,
|
|
463
|
+
options: param.options,
|
|
464
|
+
requireValue: param.requireValue,
|
|
465
|
+
disableCustomInput: param.disableCustomInput,
|
|
435
466
|
})),
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
467
|
+
widgets: dashboard.widgets.map((widget) => ({
|
|
468
|
+
id: widget.id,
|
|
469
|
+
title: widget.title,
|
|
470
|
+
description: widget.description,
|
|
471
|
+
type: widget.type,
|
|
472
|
+
questionId: widget.questionId,
|
|
473
|
+
noResultMessage: widget.noResultMessage,
|
|
474
|
+
includeDeleted: widget.includeDeleted,
|
|
475
|
+
config: {
|
|
476
|
+
queries: widget.config.queries.map((query) => ({
|
|
477
|
+
id: query.id,
|
|
478
|
+
name: query.name,
|
|
479
|
+
query: query.query,
|
|
480
|
+
})),
|
|
481
|
+
settings: widget.config.settings,
|
|
482
|
+
postQueryFilters: widget.config.postQueryFilters,
|
|
483
|
+
disableQueryPolicyFilters: widget.config.disableQueryPolicyFilters,
|
|
484
|
+
},
|
|
444
485
|
})),
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
486
|
+
layouts: {
|
|
487
|
+
xs: dashboard.layouts.xs.map((item) => ({
|
|
488
|
+
i: item.i,
|
|
489
|
+
x: item.x,
|
|
490
|
+
y: item.y,
|
|
491
|
+
w: item.w,
|
|
492
|
+
h: item.h,
|
|
493
|
+
static: item.static,
|
|
494
|
+
moved: item.moved,
|
|
495
|
+
})),
|
|
496
|
+
sm: dashboard.layouts.sm.map((item) => ({
|
|
497
|
+
i: item.i,
|
|
498
|
+
x: item.x,
|
|
499
|
+
y: item.y,
|
|
500
|
+
w: item.w,
|
|
501
|
+
h: item.h,
|
|
502
|
+
static: item.static,
|
|
503
|
+
moved: item.moved,
|
|
504
|
+
})),
|
|
505
|
+
md: dashboard.layouts.md.map((item) => ({
|
|
506
|
+
i: item.i,
|
|
507
|
+
x: item.x,
|
|
508
|
+
y: item.y,
|
|
509
|
+
w: item.w,
|
|
510
|
+
h: item.h,
|
|
511
|
+
static: item.static,
|
|
512
|
+
moved: item.moved,
|
|
513
|
+
})),
|
|
514
|
+
lg: dashboard.layouts.lg.map((item) => ({
|
|
515
|
+
i: item.i,
|
|
516
|
+
x: item.x,
|
|
517
|
+
y: item.y,
|
|
518
|
+
w: item.w,
|
|
519
|
+
h: item.h,
|
|
520
|
+
static: item.static,
|
|
521
|
+
moved: item.moved,
|
|
522
|
+
})),
|
|
523
|
+
xl: dashboard.layouts.xl.map((item) => ({
|
|
524
|
+
i: item.i,
|
|
525
|
+
x: item.x,
|
|
526
|
+
y: item.y,
|
|
527
|
+
w: item.w,
|
|
528
|
+
h: item.h,
|
|
529
|
+
static: item.static,
|
|
530
|
+
moved: item.moved,
|
|
531
|
+
})),
|
|
532
|
+
},
|
|
533
|
+
}, null, 2),
|
|
534
|
+
},
|
|
535
|
+
],
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
catch (error) {
|
|
539
|
+
return {
|
|
540
|
+
content: [
|
|
541
|
+
{
|
|
542
|
+
type: 'text',
|
|
543
|
+
text: `Error getting dashboard details: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
544
|
+
},
|
|
545
|
+
],
|
|
546
|
+
isError: true,
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
},
|
|
471
550
|
});
|
|
472
551
|
// Tool: Get integration definitions
|
|
473
|
-
this.
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
552
|
+
this.registerTool({
|
|
553
|
+
name: 'get-integration-definitions',
|
|
554
|
+
description: (0, load_description_js_1.loadDescription)('get-integration-definitions.md'),
|
|
555
|
+
schema: {
|
|
556
|
+
cursor: zod_1.z.string().optional().describe('Optional cursor for pagination'),
|
|
557
|
+
includeConfig: zod_1.z.boolean().optional().describe('Whether to include configuration fields'),
|
|
558
|
+
},
|
|
559
|
+
handler: async ({ cursor, includeConfig }, client) => {
|
|
560
|
+
try {
|
|
561
|
+
const definitions = await client.getIntegrationDefinitions(cursor, includeConfig);
|
|
562
|
+
return {
|
|
563
|
+
content: [
|
|
564
|
+
{
|
|
565
|
+
type: 'text',
|
|
566
|
+
text: JSON.stringify({
|
|
567
|
+
total: definitions.definitions.length,
|
|
568
|
+
definitions: definitions.definitions.map((def) => ({
|
|
569
|
+
id: def.id,
|
|
570
|
+
name: def.name,
|
|
571
|
+
type: def.type,
|
|
572
|
+
title: def.title,
|
|
573
|
+
displayMode: def.displayMode,
|
|
574
|
+
integrationType: def.integrationType,
|
|
575
|
+
integrationClass: def.integrationClass,
|
|
576
|
+
integrationCategory: def.integrationCategory,
|
|
577
|
+
beta: def.beta,
|
|
578
|
+
docsWebLink: def.docsWebLink,
|
|
579
|
+
repoWebLink: def.repoWebLink,
|
|
580
|
+
invocationPaused: def.invocationPaused,
|
|
581
|
+
managedExecutionDisabled: def.managedExecutionDisabled,
|
|
582
|
+
managedCreateDisabled: def.managedCreateDisabled,
|
|
583
|
+
managedDeleteDisabled: def.managedDeleteDisabled,
|
|
584
|
+
totalInstanceCount: def.totalInstanceCount,
|
|
585
|
+
description: def.description,
|
|
586
|
+
provisioningType: def.provisioningType,
|
|
587
|
+
customDefinitionType: def.customDefinitionType,
|
|
588
|
+
integrationPlatformFeatures: def.integrationPlatformFeatures,
|
|
589
|
+
configFields: def.configFields,
|
|
590
|
+
authSections: def.authSections,
|
|
591
|
+
configSections: def.configSections,
|
|
592
|
+
})),
|
|
593
|
+
pageInfo: definitions.pageInfo,
|
|
594
|
+
}, null, 2),
|
|
595
|
+
},
|
|
596
|
+
],
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
catch (error) {
|
|
600
|
+
return {
|
|
601
|
+
content: [
|
|
602
|
+
{
|
|
603
|
+
type: 'text',
|
|
604
|
+
text: `Error getting integration definitions: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
605
|
+
},
|
|
606
|
+
],
|
|
607
|
+
isError: true,
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
},
|
|
527
611
|
});
|
|
528
612
|
// Tool: Get integration instances
|
|
529
|
-
this.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
.
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
.
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
613
|
+
this.registerTool({
|
|
614
|
+
name: 'get-integration-instances',
|
|
615
|
+
description: (0, load_description_js_1.loadDescription)('get-integration-instances.md'),
|
|
616
|
+
schema: {
|
|
617
|
+
definitionId: zod_1.z
|
|
618
|
+
.string()
|
|
619
|
+
.optional()
|
|
620
|
+
.describe('Optional ID to filter instances by definition'),
|
|
621
|
+
limit: zod_1.z
|
|
622
|
+
.number()
|
|
623
|
+
.min(1)
|
|
624
|
+
.max(1000)
|
|
625
|
+
.optional()
|
|
626
|
+
.describe('Optional limit for number of instances to return'),
|
|
627
|
+
},
|
|
628
|
+
handler: async ({ definitionId, limit }, client) => {
|
|
629
|
+
try {
|
|
630
|
+
const instances = await client.getIntegrationInstances(definitionId, undefined, limit);
|
|
631
|
+
return {
|
|
632
|
+
content: [
|
|
633
|
+
{
|
|
634
|
+
type: 'text',
|
|
635
|
+
text: JSON.stringify({
|
|
636
|
+
total: instances.instances.length,
|
|
637
|
+
instances: instances.instances.map((instance) => ({
|
|
638
|
+
id: instance.id,
|
|
639
|
+
name: instance.name,
|
|
640
|
+
accountId: instance.accountId,
|
|
641
|
+
sourceIntegrationInstanceId: instance.sourceIntegrationInstanceId,
|
|
642
|
+
pollingInterval: instance.pollingInterval,
|
|
643
|
+
pollingIntervalCronExpression: instance.pollingIntervalCronExpression,
|
|
644
|
+
integrationDefinitionId: instance.integrationDefinitionId,
|
|
645
|
+
description: instance.description,
|
|
646
|
+
config: instance.config,
|
|
647
|
+
instanceRelationship: instance.instanceRelationship,
|
|
648
|
+
resourceGroupId: instance.resourceGroupId,
|
|
649
|
+
createdOn: instance.createdOn,
|
|
650
|
+
createdBy: instance.createdBy,
|
|
651
|
+
updatedOn: instance.updatedOn,
|
|
652
|
+
updatedBy: instance.updatedBy,
|
|
653
|
+
mostRecentJob: instance.mostRecentJob
|
|
654
|
+
? {
|
|
655
|
+
status: instance.mostRecentJob.status,
|
|
656
|
+
hasSkippedSteps: instance.mostRecentJob.hasSkippedSteps,
|
|
657
|
+
createDate: instance.mostRecentJob.createDate,
|
|
658
|
+
}
|
|
659
|
+
: null,
|
|
660
|
+
})),
|
|
661
|
+
pageInfo: instances.pageInfo,
|
|
662
|
+
}, null, 2),
|
|
663
|
+
},
|
|
664
|
+
],
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
catch (error) {
|
|
668
|
+
return {
|
|
669
|
+
content: [
|
|
670
|
+
{
|
|
671
|
+
type: 'text',
|
|
672
|
+
text: `Error getting integration instances: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
673
|
+
},
|
|
674
|
+
],
|
|
675
|
+
isError: true,
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
},
|
|
590
679
|
});
|
|
591
680
|
// Tool: Get integration jobs
|
|
592
|
-
this.
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
.
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
.
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
.
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
.
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
.
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
681
|
+
this.registerTool({
|
|
682
|
+
name: 'get-integration-jobs',
|
|
683
|
+
schema: {
|
|
684
|
+
status: zod_1.z
|
|
685
|
+
.enum(['PENDING', 'RUNNING', 'COMPLETED', 'FAILED', 'CANCELLED'])
|
|
686
|
+
.optional()
|
|
687
|
+
.describe('Optional status to filter jobs'),
|
|
688
|
+
integrationInstanceId: zod_1.z
|
|
689
|
+
.string()
|
|
690
|
+
.optional()
|
|
691
|
+
.describe('Optional ID to filter jobs by instance'),
|
|
692
|
+
integrationDefinitionId: zod_1.z
|
|
693
|
+
.string()
|
|
694
|
+
.optional()
|
|
695
|
+
.describe('Optional ID to filter jobs by definition'),
|
|
696
|
+
integrationInstanceIds: zod_1.z
|
|
697
|
+
.array(zod_1.z.string())
|
|
698
|
+
.optional()
|
|
699
|
+
.describe('Optional array of instance IDs to filter jobs'),
|
|
700
|
+
size: zod_1.z
|
|
701
|
+
.number()
|
|
702
|
+
.min(1)
|
|
703
|
+
.max(1000)
|
|
704
|
+
.optional()
|
|
705
|
+
.describe('Optional size limit for number of jobs to return'),
|
|
706
|
+
},
|
|
707
|
+
handler: async ({ status, integrationInstanceId, integrationDefinitionId, integrationInstanceIds, size }, client) => {
|
|
708
|
+
try {
|
|
709
|
+
const jobs = await client.getIntegrationJobs(status, integrationInstanceId, integrationDefinitionId, integrationInstanceIds, undefined, size);
|
|
710
|
+
return {
|
|
711
|
+
content: [
|
|
712
|
+
{
|
|
713
|
+
type: 'text',
|
|
714
|
+
text: JSON.stringify({
|
|
715
|
+
total: jobs.jobs.length,
|
|
716
|
+
jobs: jobs.jobs.map((job) => ({
|
|
717
|
+
id: job.id,
|
|
718
|
+
status: job.status,
|
|
719
|
+
integrationInstanceId: job.integrationInstanceId,
|
|
720
|
+
createDate: job.createDate,
|
|
721
|
+
endDate: job.endDate,
|
|
722
|
+
hasSkippedSteps: job.hasSkippedSteps,
|
|
723
|
+
integrationInstance: job.integrationInstance,
|
|
724
|
+
integrationDefinition: job.integrationDefinition,
|
|
725
|
+
})),
|
|
726
|
+
pageInfo: jobs.pageInfo,
|
|
727
|
+
}, null, 2),
|
|
728
|
+
},
|
|
729
|
+
],
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
catch (error) {
|
|
733
|
+
return {
|
|
734
|
+
content: [
|
|
735
|
+
{
|
|
736
|
+
type: 'text',
|
|
737
|
+
text: `Error getting integration jobs: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
738
|
+
},
|
|
739
|
+
],
|
|
740
|
+
isError: true,
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
},
|
|
744
|
+
});
|
|
745
|
+
// Tool: Create inline question rule instance
|
|
746
|
+
this.registerTool({
|
|
747
|
+
name: 'create-inline-question-rule',
|
|
748
|
+
description: (0, load_description_js_1.loadDescription)('create-inline-question-rule.md'),
|
|
749
|
+
schema: {
|
|
750
|
+
name: zod_1.z.string().describe('Name of the rule'),
|
|
751
|
+
description: zod_1.z.string().describe('Description of the rule'),
|
|
752
|
+
notifyOnFailure: zod_1.z.boolean().optional().describe('Whether to notify on failure'),
|
|
753
|
+
triggerActionsOnNewEntitiesOnly: zod_1.z
|
|
754
|
+
.boolean()
|
|
755
|
+
.optional()
|
|
756
|
+
.describe('Whether to trigger actions only on new entities'),
|
|
757
|
+
ignorePreviousResults: zod_1.z
|
|
758
|
+
.boolean()
|
|
759
|
+
.optional()
|
|
760
|
+
.describe('Whether to ignore previous results'),
|
|
761
|
+
pollingInterval: zod_1.z
|
|
762
|
+
.enum([
|
|
763
|
+
'DISABLED',
|
|
764
|
+
'THIRTY_MINUTES',
|
|
765
|
+
'ONE_HOUR',
|
|
766
|
+
'FOUR_HOURS',
|
|
767
|
+
'EIGHT_HOURS',
|
|
768
|
+
'TWELVE_HOURS',
|
|
769
|
+
'ONE_DAY',
|
|
770
|
+
'ONE_WEEK',
|
|
771
|
+
])
|
|
772
|
+
.describe('How frequently to evaluate the rule'),
|
|
773
|
+
outputs: zod_1.z.array(zod_1.z.string()).describe('Output fields from the rule evaluation'),
|
|
774
|
+
specVersion: zod_1.z.number().optional().describe('Specification version'),
|
|
775
|
+
tags: zod_1.z.array(zod_1.z.string()).optional().describe('Tags for categorizing the rule'),
|
|
776
|
+
templates: zod_1.z.record(zod_1.z.any()).optional().describe('Template variables'),
|
|
777
|
+
question: zod_1.z
|
|
778
|
+
.object({
|
|
779
|
+
queries: zod_1.z.array(zod_1.z.object({
|
|
780
|
+
query: zod_1.z.string().describe('J1QL query string'),
|
|
781
|
+
name: zod_1.z.string().describe('Name identifier for the query'),
|
|
782
|
+
version: zod_1.z.string().optional().describe('Version of the query'),
|
|
783
|
+
includeDeleted: zod_1.z.boolean().describe('Whether to include deleted entities'),
|
|
784
|
+
})),
|
|
785
|
+
})
|
|
786
|
+
.describe('Question configuration'),
|
|
787
|
+
labels: zod_1.z
|
|
788
|
+
.array(zod_1.z.object({
|
|
789
|
+
labelName: zod_1.z.string(),
|
|
790
|
+
labelValue: zod_1.z.string().nullable(),
|
|
791
|
+
}))
|
|
792
|
+
.describe('Labels for the rule'),
|
|
793
|
+
operations: zod_1.z
|
|
794
|
+
.array(zod_1.z.object({
|
|
795
|
+
when: zod_1.z
|
|
796
|
+
.object({
|
|
797
|
+
type: zod_1.z.literal('FILTER'),
|
|
798
|
+
condition: zod_1.z
|
|
799
|
+
.array(zod_1.z.union([zod_1.z.string(), zod_1.z.number(), zod_1.z.array(zod_1.z.union([zod_1.z.string(), zod_1.z.number()]))]))
|
|
800
|
+
.describe('Filter condition array (e.g., ["AND", ["queries.query0.total", ">", 0]])'),
|
|
801
|
+
})
|
|
802
|
+
.describe('Condition that triggers the actions'),
|
|
803
|
+
actions: zod_1.z
|
|
804
|
+
.array(zod_1.z.object({
|
|
805
|
+
id: zod_1.z.string().optional(),
|
|
806
|
+
type: zod_1.z
|
|
807
|
+
.string()
|
|
808
|
+
.describe('Action type (e.g., SET_PROPERTY, CREATE_ALERT, SEND_EMAIL)'),
|
|
809
|
+
targetProperty: zod_1.z
|
|
810
|
+
.string()
|
|
811
|
+
.optional()
|
|
812
|
+
.describe('Property to set (for SET_PROPERTY actions)'),
|
|
813
|
+
targetValue: zod_1.z
|
|
814
|
+
.any()
|
|
815
|
+
.optional()
|
|
816
|
+
.describe('Value to set (for SET_PROPERTY actions)'),
|
|
817
|
+
integrationInstanceId: zod_1.z
|
|
818
|
+
.string()
|
|
819
|
+
.optional()
|
|
820
|
+
.describe('ID of the integration instance for integration actions'),
|
|
821
|
+
recipients: zod_1.z
|
|
822
|
+
.array(zod_1.z.string())
|
|
823
|
+
.optional()
|
|
824
|
+
.describe('Email recipients for SEND_EMAIL action'),
|
|
825
|
+
body: zod_1.z.string().optional().describe('Message body for email/slack actions'),
|
|
826
|
+
channels: zod_1.z
|
|
827
|
+
.array(zod_1.z.string())
|
|
828
|
+
.optional()
|
|
829
|
+
.describe('Slack channels for SEND_SLACK_MESSAGE action'),
|
|
830
|
+
bucket: zod_1.z.string().optional().describe('S3 bucket name for SEND_TO_S3 action'),
|
|
831
|
+
region: zod_1.z.string().optional().describe('AWS region for SEND_TO_S3 action'),
|
|
832
|
+
data: zod_1.z.any().optional().describe('Additional data for actions'),
|
|
833
|
+
entityClass: zod_1.z
|
|
834
|
+
.string()
|
|
835
|
+
.optional()
|
|
836
|
+
.describe('Entity class for CREATE_JIRA_TICKET action'),
|
|
837
|
+
summary: zod_1.z
|
|
838
|
+
.string()
|
|
839
|
+
.optional()
|
|
840
|
+
.describe('Summary for CREATE_JIRA_TICKET action'),
|
|
841
|
+
issueType: zod_1.z
|
|
842
|
+
.string()
|
|
843
|
+
.optional()
|
|
844
|
+
.describe('Issue type for CREATE_JIRA_TICKET action'),
|
|
845
|
+
project: zod_1.z
|
|
846
|
+
.string()
|
|
847
|
+
.optional()
|
|
848
|
+
.describe('Project key for CREATE_JIRA_TICKET action'),
|
|
849
|
+
updateContentOnChanges: zod_1.z
|
|
850
|
+
.boolean()
|
|
851
|
+
.optional()
|
|
852
|
+
.describe('Whether to update content on changes for CREATE_JIRA_TICKET action'),
|
|
853
|
+
additionalFields: zod_1.z
|
|
854
|
+
.any()
|
|
855
|
+
.optional()
|
|
856
|
+
.describe('Additional fields for CREATE_JIRA_TICKET action'),
|
|
857
|
+
}))
|
|
858
|
+
.describe('Actions to take when condition is met'),
|
|
859
|
+
}))
|
|
860
|
+
.describe('Operations to perform when conditions are met'),
|
|
861
|
+
},
|
|
862
|
+
handler: async ({ name, description, notifyOnFailure, triggerActionsOnNewEntitiesOnly, ignorePreviousResults, pollingInterval, outputs, specVersion, labels, tags, templates, question, operations, }, client, validator) => {
|
|
863
|
+
try {
|
|
864
|
+
// Validate all queries before creating the rule
|
|
865
|
+
const validationResults = await this.validateQueries(question.queries, validator);
|
|
866
|
+
if (validationResults.length > 0) {
|
|
867
|
+
return this.createValidationErrorResponse(validationResults);
|
|
868
|
+
}
|
|
869
|
+
const instance = {
|
|
870
|
+
name,
|
|
871
|
+
description,
|
|
872
|
+
notifyOnFailure,
|
|
873
|
+
triggerActionsOnNewEntitiesOnly,
|
|
874
|
+
ignorePreviousResults,
|
|
875
|
+
pollingInterval,
|
|
876
|
+
outputs,
|
|
877
|
+
specVersion,
|
|
878
|
+
labels,
|
|
879
|
+
tags,
|
|
880
|
+
templates,
|
|
881
|
+
question,
|
|
882
|
+
operations,
|
|
883
|
+
};
|
|
884
|
+
const result = await client.createInlineQuestionRuleInstance(instance);
|
|
885
|
+
return {
|
|
886
|
+
content: [
|
|
887
|
+
{
|
|
888
|
+
type: 'text',
|
|
889
|
+
text: JSON.stringify({
|
|
890
|
+
success: true,
|
|
891
|
+
rule: {
|
|
892
|
+
id: result.id,
|
|
893
|
+
name: result.name,
|
|
894
|
+
description: result.description,
|
|
895
|
+
version: result.version,
|
|
896
|
+
pollingInterval: result.pollingInterval,
|
|
897
|
+
outputs: result.outputs,
|
|
898
|
+
specVersion: result.specVersion,
|
|
899
|
+
notifyOnFailure: result.notifyOnFailure,
|
|
900
|
+
triggerActionsOnNewEntitiesOnly: result.triggerActionsOnNewEntitiesOnly,
|
|
901
|
+
ignorePreviousResults: result.ignorePreviousResults,
|
|
902
|
+
tags: result.tags,
|
|
903
|
+
question: result.question,
|
|
904
|
+
operations: result.operations,
|
|
905
|
+
latestAlertId: result.latestAlertId,
|
|
906
|
+
latestAlertIsActive: result.latestAlertIsActive,
|
|
907
|
+
},
|
|
908
|
+
}, null, 2),
|
|
909
|
+
},
|
|
910
|
+
],
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
catch (error) {
|
|
914
|
+
return {
|
|
915
|
+
content: [
|
|
916
|
+
{
|
|
917
|
+
type: 'text',
|
|
918
|
+
text: `Error creating inline question rule: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
919
|
+
},
|
|
920
|
+
],
|
|
921
|
+
isError: true,
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
},
|
|
658
925
|
});
|
|
659
|
-
// Tool:
|
|
660
|
-
this.
|
|
661
|
-
name:
|
|
662
|
-
description:
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
.
|
|
666
|
-
.
|
|
667
|
-
.describe('Whether to
|
|
668
|
-
|
|
669
|
-
.boolean()
|
|
670
|
-
.optional()
|
|
671
|
-
.describe('Whether to ignore previous results'),
|
|
672
|
-
pollingInterval: z
|
|
673
|
-
.enum([
|
|
674
|
-
'DISABLED',
|
|
675
|
-
'THIRTY_MINUTES',
|
|
676
|
-
'ONE_HOUR',
|
|
677
|
-
'FOUR_HOURS',
|
|
678
|
-
'EIGHT_HOURS',
|
|
679
|
-
'TWELVE_HOURS',
|
|
680
|
-
'ONE_DAY',
|
|
681
|
-
'ONE_WEEK',
|
|
682
|
-
])
|
|
683
|
-
.describe('How frequently to evaluate the rule'),
|
|
684
|
-
outputs: z.array(z.string()).describe('Output fields from the rule evaluation'),
|
|
685
|
-
specVersion: z.number().optional().describe('Specification version'),
|
|
686
|
-
tags: z.array(z.string()).optional().describe('Tags for categorizing the rule'),
|
|
687
|
-
templates: z.record(z.any()).optional().describe('Template variables'),
|
|
688
|
-
queries: z
|
|
689
|
-
.array(z.object({
|
|
690
|
-
query: z.string().describe('J1QL query string'),
|
|
691
|
-
name: z.string().describe('Name identifier for the query'),
|
|
692
|
-
version: z.string().optional().describe('Version of the query'),
|
|
693
|
-
includeDeleted: z
|
|
926
|
+
// Tool: Update inline question rule instance
|
|
927
|
+
this.registerTool({
|
|
928
|
+
name: 'update-inline-question-rule',
|
|
929
|
+
description: (0, load_description_js_1.loadDescription)('update-inline-question-rule.md'),
|
|
930
|
+
schema: {
|
|
931
|
+
id: zod_1.z.string().describe('ID of the rule to update'),
|
|
932
|
+
name: zod_1.z.string().describe('Name of the rule'),
|
|
933
|
+
description: zod_1.z.string().describe('Description of the rule'),
|
|
934
|
+
notifyOnFailure: zod_1.z.boolean().describe('Whether to notify on failure'),
|
|
935
|
+
triggerActionsOnNewEntitiesOnly: zod_1.z
|
|
694
936
|
.boolean()
|
|
695
|
-
.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
.
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
targetValue: z
|
|
718
|
-
.any()
|
|
719
|
-
.optional()
|
|
720
|
-
.describe('Value to set (for SET_PROPERTY actions)'),
|
|
721
|
-
integrationInstanceId: z
|
|
722
|
-
.string()
|
|
723
|
-
.optional()
|
|
724
|
-
.describe('ID of the integration instance for integration actions'),
|
|
725
|
-
recipients: z
|
|
726
|
-
.array(z.string())
|
|
727
|
-
.optional()
|
|
728
|
-
.describe('Email recipients for SEND_EMAIL action'),
|
|
729
|
-
body: z.string().optional().describe('Message body for email/slack actions'),
|
|
730
|
-
channels: z
|
|
731
|
-
.array(z.string())
|
|
732
|
-
.optional()
|
|
733
|
-
.describe('Slack channels for SEND_SLACK_MESSAGE action'),
|
|
734
|
-
bucket: z.string().optional().describe('S3 bucket name for SEND_TO_S3 action'),
|
|
735
|
-
region: z.string().optional().describe('AWS region for SEND_TO_S3 action'),
|
|
736
|
-
data: z.any().optional().describe('Additional data for actions'),
|
|
737
|
-
entityClass: z
|
|
738
|
-
.string()
|
|
739
|
-
.optional()
|
|
740
|
-
.describe('Entity class for CREATE_JIRA_TICKET action'),
|
|
741
|
-
summary: z
|
|
742
|
-
.string()
|
|
743
|
-
.optional()
|
|
744
|
-
.describe('Summary for CREATE_JIRA_TICKET action'),
|
|
745
|
-
issueType: z
|
|
746
|
-
.string()
|
|
747
|
-
.optional()
|
|
748
|
-
.describe('Issue type for CREATE_JIRA_TICKET action'),
|
|
749
|
-
project: z
|
|
750
|
-
.string()
|
|
751
|
-
.optional()
|
|
752
|
-
.describe('Project key for CREATE_JIRA_TICKET action'),
|
|
753
|
-
updateContentOnChanges: z
|
|
754
|
-
.boolean()
|
|
755
|
-
.optional()
|
|
756
|
-
.describe('Whether to update content on changes for CREATE_JIRA_TICKET action'),
|
|
757
|
-
additionalFields: z
|
|
758
|
-
.any()
|
|
759
|
-
.optional()
|
|
760
|
-
.describe('Additional fields for CREATE_JIRA_TICKET action'),
|
|
937
|
+
.describe('Whether to trigger actions only on new entities'),
|
|
938
|
+
ignorePreviousResults: zod_1.z.boolean().describe('Whether to ignore previous results'),
|
|
939
|
+
pollingInterval: zod_1.z
|
|
940
|
+
.enum([
|
|
941
|
+
'DISABLED',
|
|
942
|
+
'THIRTY_MINUTES',
|
|
943
|
+
'ONE_HOUR',
|
|
944
|
+
'FOUR_HOURS',
|
|
945
|
+
'EIGHT_HOURS',
|
|
946
|
+
'TWELVE_HOURS',
|
|
947
|
+
'ONE_DAY',
|
|
948
|
+
'ONE_WEEK',
|
|
949
|
+
])
|
|
950
|
+
.describe('How frequently to evaluate the rule'),
|
|
951
|
+
outputs: zod_1.z.array(zod_1.z.string()).describe('Output fields from the rule evaluation'),
|
|
952
|
+
specVersion: zod_1.z.number().describe('Specification version'),
|
|
953
|
+
tags: zod_1.z.array(zod_1.z.string()).describe('Tags for categorizing the rule'),
|
|
954
|
+
templates: zod_1.z.record(zod_1.z.any()).describe('Template variables'),
|
|
955
|
+
labels: zod_1.z
|
|
956
|
+
.array(zod_1.z.object({
|
|
957
|
+
labelName: zod_1.z.string(),
|
|
958
|
+
labelValue: zod_1.z.string().nullable(),
|
|
761
959
|
}))
|
|
762
|
-
.describe('
|
|
763
|
-
|
|
764
|
-
.
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
description,
|
|
770
|
-
notifyOnFailure,
|
|
771
|
-
triggerActionsOnNewEntitiesOnly,
|
|
772
|
-
ignorePreviousResults,
|
|
773
|
-
pollingInterval,
|
|
774
|
-
outputs,
|
|
775
|
-
specVersion,
|
|
776
|
-
tags,
|
|
777
|
-
templates,
|
|
778
|
-
question: {
|
|
779
|
-
queries,
|
|
780
|
-
},
|
|
781
|
-
operations,
|
|
782
|
-
};
|
|
783
|
-
const result = await this.client.createInlineQuestionRuleInstance(instance);
|
|
784
|
-
return {
|
|
785
|
-
content: [
|
|
786
|
-
{
|
|
787
|
-
type: 'text',
|
|
788
|
-
text: JSON.stringify({
|
|
789
|
-
success: true,
|
|
790
|
-
rule: {
|
|
791
|
-
id: result.id,
|
|
792
|
-
name: result.name,
|
|
793
|
-
description: result.description,
|
|
794
|
-
version: result.version,
|
|
795
|
-
pollingInterval: result.pollingInterval,
|
|
796
|
-
outputs: result.outputs,
|
|
797
|
-
specVersion: result.specVersion,
|
|
798
|
-
notifyOnFailure: result.notifyOnFailure,
|
|
799
|
-
triggerActionsOnNewEntitiesOnly: result.triggerActionsOnNewEntitiesOnly,
|
|
800
|
-
ignorePreviousResults: result.ignorePreviousResults,
|
|
801
|
-
tags: result.tags,
|
|
802
|
-
question: result.question,
|
|
803
|
-
operations: result.operations,
|
|
804
|
-
latestAlertId: result.latestAlertId,
|
|
805
|
-
latestAlertIsActive: result.latestAlertIsActive,
|
|
806
|
-
},
|
|
807
|
-
}, null, 2),
|
|
808
|
-
},
|
|
809
|
-
],
|
|
810
|
-
};
|
|
811
|
-
}
|
|
812
|
-
catch (error) {
|
|
813
|
-
return {
|
|
814
|
-
content: [
|
|
815
|
-
{
|
|
816
|
-
type: 'text',
|
|
817
|
-
text: `Error creating inline question rule: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
818
|
-
},
|
|
819
|
-
],
|
|
820
|
-
isError: true,
|
|
821
|
-
};
|
|
822
|
-
}
|
|
823
|
-
});
|
|
824
|
-
// Tool: Update inline question rule instance
|
|
825
|
-
this.server.tool('update-inline-question-rule', loadDescription('update-inline-question-rule.md'), {
|
|
826
|
-
id: z.string().describe('ID of the rule to update'),
|
|
827
|
-
name: z.string().describe('Name of the rule'),
|
|
828
|
-
description: z.string().describe('Description of the rule'),
|
|
829
|
-
notifyOnFailure: z.boolean().describe('Whether to notify on failure'),
|
|
830
|
-
triggerActionsOnNewEntitiesOnly: z
|
|
831
|
-
.boolean()
|
|
832
|
-
.describe('Whether to trigger actions only on new entities'),
|
|
833
|
-
ignorePreviousResults: z.boolean().describe('Whether to ignore previous results'),
|
|
834
|
-
pollingInterval: z
|
|
835
|
-
.enum([
|
|
836
|
-
'DISABLED',
|
|
837
|
-
'THIRTY_MINUTES',
|
|
838
|
-
'ONE_HOUR',
|
|
839
|
-
'FOUR_HOURS',
|
|
840
|
-
'EIGHT_HOURS',
|
|
841
|
-
'TWELVE_HOURS',
|
|
842
|
-
'ONE_DAY',
|
|
843
|
-
'ONE_WEEK',
|
|
844
|
-
])
|
|
845
|
-
.describe('How frequently to evaluate the rule'),
|
|
846
|
-
outputs: z.array(z.string()).describe('Output fields from the rule evaluation'),
|
|
847
|
-
specVersion: z.number().describe('Specification version'),
|
|
848
|
-
version: z.number().describe('Version of the rule'),
|
|
849
|
-
tags: z.array(z.string()).describe('Tags for categorizing the rule'),
|
|
850
|
-
templates: z.record(z.any()).describe('Template variables'),
|
|
851
|
-
labels: z
|
|
852
|
-
.array(z.object({
|
|
853
|
-
labelName: z.string(),
|
|
854
|
-
labelValue: z.string().nullable(),
|
|
855
|
-
}))
|
|
856
|
-
.describe('Labels for the rule'),
|
|
857
|
-
resourceGroupId: z.string().nullable().describe('Resource group ID'),
|
|
858
|
-
remediationSteps: z
|
|
859
|
-
.string()
|
|
860
|
-
.nullable()
|
|
861
|
-
.describe('Steps to remediate issues found by the rule'),
|
|
862
|
-
question: z
|
|
863
|
-
.object({
|
|
864
|
-
queries: z.array(z.object({
|
|
865
|
-
query: z.string().describe('J1QL query string'),
|
|
866
|
-
name: z.string().describe('Name identifier for the query'),
|
|
867
|
-
version: z.string().optional().describe('Version of the query'),
|
|
868
|
-
includeDeleted: z.boolean().describe('Whether to include deleted entities'),
|
|
869
|
-
})),
|
|
870
|
-
})
|
|
871
|
-
.describe('Question configuration'),
|
|
872
|
-
operations: z
|
|
873
|
-
.array(z.object({
|
|
874
|
-
when: z
|
|
960
|
+
.describe('Labels for the rule'),
|
|
961
|
+
resourceGroupId: zod_1.z.string().nullable().describe('Resource group ID'),
|
|
962
|
+
remediationSteps: zod_1.z
|
|
963
|
+
.string()
|
|
964
|
+
.nullable()
|
|
965
|
+
.describe('Steps to remediate issues found by the rule'),
|
|
966
|
+
question: zod_1.z
|
|
875
967
|
.object({
|
|
876
|
-
|
|
877
|
-
|
|
968
|
+
queries: zod_1.z.array(zod_1.z.object({
|
|
969
|
+
query: zod_1.z.string().describe('J1QL query string'),
|
|
970
|
+
name: zod_1.z.string().describe('Name identifier for the query'),
|
|
971
|
+
version: zod_1.z.string().optional().describe('Version of the query'),
|
|
972
|
+
includeDeleted: zod_1.z.boolean().describe('Whether to include deleted entities'),
|
|
973
|
+
})),
|
|
878
974
|
})
|
|
879
|
-
.describe('
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
.
|
|
885
|
-
.
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
.
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
.string()
|
|
893
|
-
.
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
.
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
.
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
.optional()
|
|
910
|
-
.
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
.optional()
|
|
915
|
-
.describe('
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
.
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
.
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
.
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
975
|
+
.describe('Question configuration'),
|
|
976
|
+
operations: zod_1.z
|
|
977
|
+
.array(zod_1.z.object({
|
|
978
|
+
when: zod_1.z
|
|
979
|
+
.object({
|
|
980
|
+
type: zod_1.z.literal('FILTER'),
|
|
981
|
+
condition: zod_1.z
|
|
982
|
+
.array(zod_1.z.union([zod_1.z.string(), zod_1.z.number(), zod_1.z.array(zod_1.z.union([zod_1.z.string(), zod_1.z.number()]))]))
|
|
983
|
+
.describe('Filter condition array (e.g., ["AND", ["queries.query0.total", ">", 0]])'),
|
|
984
|
+
})
|
|
985
|
+
.describe('Condition that triggers the actions'),
|
|
986
|
+
actions: zod_1.z.array(zod_1.z.object({
|
|
987
|
+
id: zod_1.z.string().optional(),
|
|
988
|
+
type: zod_1.z.string().describe('Action type (e.g., SET_PROPERTY, CREATE_ALERT)'),
|
|
989
|
+
targetProperty: zod_1.z
|
|
990
|
+
.string()
|
|
991
|
+
.optional()
|
|
992
|
+
.describe('Property to set (for SET_PROPERTY actions)'),
|
|
993
|
+
targetValue: zod_1.z
|
|
994
|
+
.any()
|
|
995
|
+
.optional()
|
|
996
|
+
.describe('Value to set (for SET_PROPERTY actions)'),
|
|
997
|
+
integrationInstanceId: zod_1.z
|
|
998
|
+
.string()
|
|
999
|
+
.optional()
|
|
1000
|
+
.describe('ID of the integration instance for integration actions'),
|
|
1001
|
+
recipients: zod_1.z
|
|
1002
|
+
.array(zod_1.z.string())
|
|
1003
|
+
.optional()
|
|
1004
|
+
.describe('Email recipients for SEND_EMAIL action'),
|
|
1005
|
+
body: zod_1.z.string().optional().describe('Message body for email/slack actions'),
|
|
1006
|
+
channels: zod_1.z
|
|
1007
|
+
.array(zod_1.z.string())
|
|
1008
|
+
.optional()
|
|
1009
|
+
.describe('Slack channels for SEND_SLACK_MESSAGE action'),
|
|
1010
|
+
bucket: zod_1.z.string().optional().describe('S3 bucket name for SEND_TO_S3 action'),
|
|
1011
|
+
region: zod_1.z.string().optional().describe('AWS region for SEND_TO_S3 action'),
|
|
1012
|
+
data: zod_1.z.any().optional().describe('Additional data for actions'),
|
|
1013
|
+
entityClass: zod_1.z
|
|
1014
|
+
.string()
|
|
1015
|
+
.optional()
|
|
1016
|
+
.describe('Entity class for CREATE_JIRA_TICKET action'),
|
|
1017
|
+
summary: zod_1.z.string().optional().describe('Summary for CREATE_JIRA_TICKET action'),
|
|
1018
|
+
issueType: zod_1.z
|
|
1019
|
+
.string()
|
|
1020
|
+
.optional()
|
|
1021
|
+
.describe('Issue type for CREATE_JIRA_TICKET action'),
|
|
1022
|
+
project: zod_1.z.string().optional().describe('Project for CREATE_JIRA_TICKET action'),
|
|
1023
|
+
updateContentOnChanges: zod_1.z
|
|
1024
|
+
.boolean()
|
|
1025
|
+
.optional()
|
|
1026
|
+
.describe('Whether to update content on changes for CREATE_JIRA_TICKET action'),
|
|
1027
|
+
additionalFields: zod_1.z
|
|
1028
|
+
.any()
|
|
1029
|
+
.optional()
|
|
1030
|
+
.describe('Additional fields for CREATE_JIRA_TICKET action'),
|
|
1031
|
+
entities: zod_1.z.string().optional().describe('Entities for TAG_ENTITIES action'),
|
|
1032
|
+
tags: zod_1.z
|
|
1033
|
+
.array(zod_1.z.object({
|
|
1034
|
+
name: zod_1.z.string(),
|
|
1035
|
+
value: zod_1.z.string().nullable(),
|
|
1036
|
+
}))
|
|
1037
|
+
.optional()
|
|
1038
|
+
.describe('Tags for TAG_ENTITIES action'),
|
|
1039
|
+
})),
|
|
1040
|
+
}))
|
|
1041
|
+
.describe('Operations that define when and what actions to take'),
|
|
1042
|
+
},
|
|
1043
|
+
handler: async ({ id, name, description, notifyOnFailure, triggerActionsOnNewEntitiesOnly, ignorePreviousResults, pollingInterval, outputs, specVersion, tags, templates, labels, resourceGroupId, remediationSteps, question, operations, }, client, validator) => {
|
|
1044
|
+
try {
|
|
1045
|
+
// Validate all queries before updating the rule
|
|
1046
|
+
const validationResults = await this.validateQueries(question?.queries, validator);
|
|
1047
|
+
if (validationResults.length > 0) {
|
|
1048
|
+
return this.createValidationErrorResponse(validationResults);
|
|
1049
|
+
}
|
|
1050
|
+
const instance = {
|
|
1051
|
+
id,
|
|
1052
|
+
name,
|
|
1053
|
+
description,
|
|
1054
|
+
notifyOnFailure,
|
|
1055
|
+
triggerActionsOnNewEntitiesOnly,
|
|
1056
|
+
ignorePreviousResults,
|
|
1057
|
+
pollingInterval,
|
|
1058
|
+
outputs,
|
|
1059
|
+
specVersion,
|
|
1060
|
+
labels,
|
|
1061
|
+
tags,
|
|
1062
|
+
templates,
|
|
1063
|
+
resourceGroupId,
|
|
1064
|
+
remediationSteps,
|
|
1065
|
+
question,
|
|
1066
|
+
operations,
|
|
1067
|
+
};
|
|
1068
|
+
const result = await client.updateInlineQuestionRuleInstance(instance);
|
|
1069
|
+
return {
|
|
1070
|
+
content: [
|
|
1071
|
+
{
|
|
1072
|
+
type: 'text',
|
|
1073
|
+
text: JSON.stringify({
|
|
1074
|
+
success: true,
|
|
1075
|
+
rule: {
|
|
1076
|
+
id: result.id,
|
|
1077
|
+
name: result.name,
|
|
1078
|
+
description: result.description,
|
|
1079
|
+
version: result.version,
|
|
1080
|
+
pollingInterval: result.pollingInterval,
|
|
1081
|
+
outputs: result.outputs,
|
|
1082
|
+
specVersion: result.specVersion,
|
|
1083
|
+
notifyOnFailure: result.notifyOnFailure,
|
|
1084
|
+
triggerActionsOnNewEntitiesOnly: result.triggerActionsOnNewEntitiesOnly,
|
|
1085
|
+
ignorePreviousResults: result.ignorePreviousResults,
|
|
1086
|
+
tags: result.tags,
|
|
1087
|
+
labels: result.labels,
|
|
1088
|
+
question: result.question,
|
|
1089
|
+
operations: result.operations,
|
|
1090
|
+
latestAlertId: result.latestAlertId,
|
|
1091
|
+
latestAlertIsActive: result.latestAlertIsActive,
|
|
1092
|
+
resourceGroupId: result.resourceGroupId,
|
|
1093
|
+
remediationSteps: result.remediationSteps,
|
|
1094
|
+
},
|
|
1095
|
+
}, null, 2),
|
|
1096
|
+
},
|
|
1097
|
+
],
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
catch (error) {
|
|
1101
|
+
return {
|
|
1102
|
+
content: [
|
|
1103
|
+
{
|
|
1104
|
+
type: 'text',
|
|
1105
|
+
text: `Error updating inline question rule: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1106
|
+
},
|
|
1107
|
+
],
|
|
1108
|
+
isError: true,
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
},
|
|
1000
1112
|
});
|
|
1001
1113
|
// Add get-integration-job tool
|
|
1002
|
-
this.
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1114
|
+
this.registerTool({
|
|
1115
|
+
name: 'get-integration-job',
|
|
1116
|
+
schema: {
|
|
1117
|
+
integrationJobId: zod_1.z.string().describe('ID of the job to get'),
|
|
1118
|
+
integrationInstanceId: zod_1.z.string().describe('ID of the instance the job belongs to'),
|
|
1119
|
+
},
|
|
1120
|
+
handler: async ({ integrationJobId, integrationInstanceId }, client) => {
|
|
1121
|
+
try {
|
|
1122
|
+
const job = await client.getIntegrationJob(integrationJobId, integrationInstanceId);
|
|
1123
|
+
return {
|
|
1124
|
+
content: [
|
|
1125
|
+
{
|
|
1126
|
+
type: 'text',
|
|
1127
|
+
text: JSON.stringify({
|
|
1128
|
+
id: job.id,
|
|
1129
|
+
status: job.status,
|
|
1130
|
+
integrationInstanceId: job.integrationInstanceId,
|
|
1131
|
+
createDate: job.createDate,
|
|
1132
|
+
endDate: job.endDate,
|
|
1133
|
+
hasSkippedSteps: job.hasSkippedSteps,
|
|
1134
|
+
integrationInstance: job.integrationInstance,
|
|
1135
|
+
integrationDefinition: job.integrationDefinition,
|
|
1136
|
+
}, null, 2),
|
|
1137
|
+
},
|
|
1138
|
+
],
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
catch (error) {
|
|
1142
|
+
return {
|
|
1143
|
+
content: [
|
|
1144
|
+
{
|
|
1145
|
+
type: 'text',
|
|
1146
|
+
text: `Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}`,
|
|
1147
|
+
},
|
|
1148
|
+
],
|
|
1149
|
+
isError: true,
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
},
|
|
1037
1153
|
});
|
|
1038
1154
|
// Add get-integration-events tool
|
|
1039
|
-
this.
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
.
|
|
1045
|
-
.
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1155
|
+
this.registerTool({
|
|
1156
|
+
name: 'get-integration-events',
|
|
1157
|
+
schema: {
|
|
1158
|
+
jobId: zod_1.z.string().describe('ID of the job to get events for'),
|
|
1159
|
+
integrationInstanceId: zod_1.z.string().describe('ID of the instance the job belongs to'),
|
|
1160
|
+
cursor: zod_1.z.string().optional().describe('Optional cursor for pagination'),
|
|
1161
|
+
size: zod_1.z
|
|
1162
|
+
.number()
|
|
1163
|
+
.min(1)
|
|
1164
|
+
.max(1000)
|
|
1165
|
+
.optional()
|
|
1166
|
+
.describe('Optional size limit for number of events to return (1-1000)'),
|
|
1167
|
+
},
|
|
1168
|
+
handler: async ({ jobId, integrationInstanceId, cursor, size }, client) => {
|
|
1169
|
+
try {
|
|
1170
|
+
const events = await client.getIntegrationEvents(jobId, integrationInstanceId, cursor, size);
|
|
1171
|
+
return {
|
|
1172
|
+
content: [
|
|
1173
|
+
{
|
|
1174
|
+
type: 'text',
|
|
1175
|
+
text: JSON.stringify({
|
|
1176
|
+
events: events.events.map((event) => ({
|
|
1177
|
+
id: event.id,
|
|
1178
|
+
name: event.name,
|
|
1179
|
+
description: event.description,
|
|
1180
|
+
createDate: event.createDate,
|
|
1181
|
+
jobId: event.jobId,
|
|
1182
|
+
level: event.level,
|
|
1183
|
+
eventCode: event.eventCode,
|
|
1184
|
+
})),
|
|
1185
|
+
pageInfo: events.pageInfo,
|
|
1186
|
+
}, null, 2),
|
|
1187
|
+
},
|
|
1188
|
+
],
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
catch (error) {
|
|
1192
|
+
return {
|
|
1193
|
+
content: [
|
|
1194
|
+
{
|
|
1195
|
+
type: 'text',
|
|
1196
|
+
text: `Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}`,
|
|
1197
|
+
},
|
|
1198
|
+
],
|
|
1199
|
+
isError: true,
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
},
|
|
1083
1203
|
});
|
|
1084
1204
|
// Tool: List rule evaluations
|
|
1085
|
-
this.
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1205
|
+
this.registerTool({
|
|
1206
|
+
name: 'list-rule-evaluations',
|
|
1207
|
+
schema: {
|
|
1208
|
+
ruleId: zod_1.z.string(),
|
|
1209
|
+
beginTimestamp: zod_1.z.number().optional(),
|
|
1210
|
+
endTimestamp: zod_1.z.number().optional(),
|
|
1211
|
+
limit: zod_1.z.number().min(1).max(1000).optional(),
|
|
1212
|
+
tag: zod_1.z.string().optional(),
|
|
1213
|
+
},
|
|
1214
|
+
handler: async ({ ruleId, beginTimestamp, endTimestamp, limit, tag }, client) => {
|
|
1215
|
+
try {
|
|
1216
|
+
const evaluations = await client.getAllRuleEvaluations({
|
|
1217
|
+
collectionType: 'RULE_EVALUATION',
|
|
1218
|
+
collectionOwnerId: ruleId,
|
|
1219
|
+
beginTimestamp: beginTimestamp || 0,
|
|
1220
|
+
endTimestamp: endTimestamp || Date.now(),
|
|
1221
|
+
limit,
|
|
1222
|
+
tag,
|
|
1223
|
+
});
|
|
1224
|
+
return {
|
|
1225
|
+
content: [
|
|
1226
|
+
{
|
|
1227
|
+
type: 'text',
|
|
1228
|
+
text: JSON.stringify({
|
|
1229
|
+
total: evaluations.length,
|
|
1230
|
+
evaluations: evaluations.map((evaluation) => ({
|
|
1231
|
+
accountId: evaluation.accountId,
|
|
1232
|
+
collectionOwnerId: evaluation.collectionOwnerId,
|
|
1233
|
+
collectionOwnerVersion: evaluation.collectionOwnerVersion,
|
|
1234
|
+
collectionType: evaluation.collectionType,
|
|
1235
|
+
outputs: evaluation.outputs,
|
|
1236
|
+
rawDataDescriptors: evaluation.rawDataDescriptors,
|
|
1237
|
+
tag: evaluation.tag,
|
|
1238
|
+
timestamp: evaluation.timestamp,
|
|
1239
|
+
})),
|
|
1240
|
+
}, null, 2),
|
|
1241
|
+
},
|
|
1242
|
+
],
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
catch (error) {
|
|
1246
|
+
return {
|
|
1247
|
+
content: [
|
|
1248
|
+
{
|
|
1249
|
+
type: 'text',
|
|
1250
|
+
text: `Error listing rule evaluations: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1251
|
+
},
|
|
1252
|
+
],
|
|
1253
|
+
isError: true,
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
},
|
|
1133
1257
|
});
|
|
1134
1258
|
// Tool: Get rule evaluation details
|
|
1135
|
-
this.
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1259
|
+
this.registerTool({
|
|
1260
|
+
name: 'get-rule-evaluation-details',
|
|
1261
|
+
schema: {
|
|
1262
|
+
ruleId: zod_1.z.string(),
|
|
1263
|
+
timestamp: zod_1.z.number(),
|
|
1264
|
+
},
|
|
1265
|
+
handler: async ({ ruleId, timestamp }, client) => {
|
|
1266
|
+
try {
|
|
1267
|
+
const details = await client.getRuleEvaluationDetails({
|
|
1268
|
+
ruleInstanceId: ruleId,
|
|
1269
|
+
timestamp,
|
|
1270
|
+
});
|
|
1271
|
+
return {
|
|
1272
|
+
content: [
|
|
1273
|
+
{
|
|
1274
|
+
type: 'text',
|
|
1275
|
+
text: JSON.stringify({
|
|
1276
|
+
accountRuleId: details.accountRuleId,
|
|
1277
|
+
startedOn: details.startedOn,
|
|
1278
|
+
question: {
|
|
1279
|
+
totalDuration: details.question.totalDuration,
|
|
1280
|
+
queries: Array.isArray(details.question.queries)
|
|
1281
|
+
? details.question.queries.map((query) => ({
|
|
1282
|
+
status: query.status,
|
|
1283
|
+
queryEvaluationDetails: Array.isArray(query.queryEvaluationDetails)
|
|
1284
|
+
? query.queryEvaluationDetails.map((detail) => ({
|
|
1285
|
+
name: detail.name,
|
|
1286
|
+
duration: detail.duration,
|
|
1287
|
+
status: detail.status,
|
|
1288
|
+
error: detail.error,
|
|
1289
|
+
}))
|
|
1290
|
+
: [],
|
|
1291
|
+
}))
|
|
1292
|
+
: [],
|
|
1293
|
+
},
|
|
1294
|
+
conditions: Array.isArray(details.conditions)
|
|
1295
|
+
? details.conditions.map((condition) => ({
|
|
1296
|
+
status: condition.status,
|
|
1297
|
+
condition: condition.condition,
|
|
1298
|
+
}))
|
|
1299
|
+
: [],
|
|
1300
|
+
actions: Array.isArray(details.actions)
|
|
1301
|
+
? details.actions.map((action) => ({
|
|
1302
|
+
status: action.status,
|
|
1303
|
+
actionEvaluationDetails: Array.isArray(action.actionEvaluationDetails)
|
|
1304
|
+
? action.actionEvaluationDetails.map((detail) => ({
|
|
1305
|
+
actionId: detail.actionId,
|
|
1306
|
+
action: detail.action,
|
|
1160
1307
|
status: detail.status,
|
|
1161
|
-
|
|
1308
|
+
duration: detail.duration,
|
|
1309
|
+
finishedOn: detail.finishedOn,
|
|
1310
|
+
logs: detail.logs,
|
|
1162
1311
|
}))
|
|
1163
1312
|
: [],
|
|
1164
1313
|
}))
|
|
1165
1314
|
: [],
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
}))
|
|
1185
|
-
: [],
|
|
1186
|
-
}))
|
|
1187
|
-
: [],
|
|
1188
|
-
ruleEvaluationOrigin: details.ruleEvaluationOrigin,
|
|
1189
|
-
}, null, 2),
|
|
1190
|
-
},
|
|
1191
|
-
],
|
|
1192
|
-
};
|
|
1193
|
-
}
|
|
1194
|
-
catch (error) {
|
|
1195
|
-
return {
|
|
1196
|
-
content: [
|
|
1197
|
-
{
|
|
1198
|
-
type: 'text',
|
|
1199
|
-
text: `Error getting rule evaluation details: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1200
|
-
},
|
|
1201
|
-
],
|
|
1202
|
-
isError: true,
|
|
1203
|
-
};
|
|
1204
|
-
}
|
|
1315
|
+
ruleEvaluationOrigin: details.ruleEvaluationOrigin,
|
|
1316
|
+
}, null, 2),
|
|
1317
|
+
},
|
|
1318
|
+
],
|
|
1319
|
+
};
|
|
1320
|
+
}
|
|
1321
|
+
catch (error) {
|
|
1322
|
+
return {
|
|
1323
|
+
content: [
|
|
1324
|
+
{
|
|
1325
|
+
type: 'text',
|
|
1326
|
+
text: `Error getting rule evaluation details: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1327
|
+
},
|
|
1328
|
+
],
|
|
1329
|
+
isError: true,
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
},
|
|
1205
1333
|
});
|
|
1206
1334
|
// Tool: Get raw data download URL
|
|
1207
|
-
this.
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1335
|
+
this.registerTool({
|
|
1336
|
+
name: 'get-raw-data-download-url',
|
|
1337
|
+
schema: {
|
|
1338
|
+
rawDataKey: zod_1.z.string(),
|
|
1339
|
+
},
|
|
1340
|
+
handler: async ({ rawDataKey }, client) => {
|
|
1341
|
+
try {
|
|
1342
|
+
const downloadUrl = await client.getRawDataDownloadUrl(rawDataKey);
|
|
1343
|
+
return {
|
|
1344
|
+
content: [
|
|
1345
|
+
{
|
|
1346
|
+
type: 'text',
|
|
1347
|
+
text: JSON.stringify({
|
|
1348
|
+
rawDataKey,
|
|
1349
|
+
downloadUrl,
|
|
1350
|
+
}, null, 2),
|
|
1351
|
+
},
|
|
1352
|
+
],
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
catch (error) {
|
|
1356
|
+
return {
|
|
1357
|
+
content: [
|
|
1358
|
+
{
|
|
1359
|
+
type: 'text',
|
|
1360
|
+
text: `Error getting raw data download URL: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1361
|
+
},
|
|
1362
|
+
],
|
|
1363
|
+
isError: true,
|
|
1364
|
+
};
|
|
1365
|
+
}
|
|
1366
|
+
},
|
|
1235
1367
|
});
|
|
1236
1368
|
// Tool: Get rule evaluation query results
|
|
1237
|
-
this.
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1369
|
+
this.registerTool({
|
|
1370
|
+
name: 'get-rule-evaluation-query-results',
|
|
1371
|
+
schema: {
|
|
1372
|
+
rawDataKey: zod_1.z.string(),
|
|
1373
|
+
},
|
|
1374
|
+
handler: async ({ rawDataKey }, client) => {
|
|
1375
|
+
try {
|
|
1376
|
+
const results = await client.getRawDataResults(rawDataKey);
|
|
1377
|
+
return {
|
|
1378
|
+
content: [
|
|
1379
|
+
{
|
|
1380
|
+
type: 'text',
|
|
1381
|
+
text: JSON.stringify(results, null, 2),
|
|
1382
|
+
},
|
|
1383
|
+
],
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
catch (error) {
|
|
1387
|
+
return {
|
|
1388
|
+
content: [
|
|
1389
|
+
{
|
|
1390
|
+
type: 'text',
|
|
1391
|
+
text: `Error getting rule evaluation query results: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1392
|
+
},
|
|
1393
|
+
],
|
|
1394
|
+
isError: true,
|
|
1395
|
+
};
|
|
1396
|
+
}
|
|
1397
|
+
},
|
|
1262
1398
|
});
|
|
1263
1399
|
// The server is not doing a great job of this, will uncomment when we have better support for this
|
|
1264
1400
|
// Tool: Create J1QL from natural language
|
|
@@ -1304,195 +1440,256 @@ export class JupiterOneMcpServer {
|
|
|
1304
1440
|
// }
|
|
1305
1441
|
// );
|
|
1306
1442
|
// Tool: Create dashboard widget
|
|
1307
|
-
this.
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1443
|
+
this.registerTool({
|
|
1444
|
+
name: 'create-dashboard-widget',
|
|
1445
|
+
description: (0, load_description_js_1.loadDescription)('create-dashboard-widget.md'),
|
|
1446
|
+
schema: {
|
|
1447
|
+
dashboardId: zod_1.z.string().describe('ID of the dashboard to add the widget to'),
|
|
1448
|
+
input: zod_1.z.any().describe('Widget input object (CreateInsightsWidgetInput)'),
|
|
1449
|
+
},
|
|
1450
|
+
handler: async ({ dashboardId, input }, client, validator) => {
|
|
1451
|
+
try {
|
|
1452
|
+
let widgetInput = input;
|
|
1453
|
+
if (typeof input === 'string') {
|
|
1454
|
+
try {
|
|
1455
|
+
widgetInput = JSON.parse(input);
|
|
1456
|
+
}
|
|
1457
|
+
catch (e) {
|
|
1458
|
+
throw new Error('Input must be a valid object or JSON string');
|
|
1459
|
+
}
|
|
1316
1460
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1461
|
+
// Validate queries before creating widget
|
|
1462
|
+
const validationResults = await this.validateWidgetQueries(widgetInput.config?.queries, validator);
|
|
1463
|
+
if (validationResults.length > 0) {
|
|
1464
|
+
return this.createValidationErrorResponse(validationResults);
|
|
1319
1465
|
}
|
|
1466
|
+
const widget = await client.createDashboardWidget(dashboardId, widgetInput);
|
|
1467
|
+
return {
|
|
1468
|
+
content: [
|
|
1469
|
+
{
|
|
1470
|
+
type: 'text',
|
|
1471
|
+
text: JSON.stringify(widget, null, 2),
|
|
1472
|
+
},
|
|
1473
|
+
],
|
|
1474
|
+
};
|
|
1320
1475
|
}
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
content: [
|
|
1334
|
-
{
|
|
1335
|
-
type: 'text',
|
|
1336
|
-
text: `Error creating dashboard widget: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1337
|
-
},
|
|
1338
|
-
],
|
|
1339
|
-
isError: true,
|
|
1340
|
-
};
|
|
1341
|
-
}
|
|
1476
|
+
catch (error) {
|
|
1477
|
+
return {
|
|
1478
|
+
content: [
|
|
1479
|
+
{
|
|
1480
|
+
type: 'text',
|
|
1481
|
+
text: `Error creating dashboard widget: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1482
|
+
},
|
|
1483
|
+
],
|
|
1484
|
+
isError: true,
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1487
|
+
},
|
|
1342
1488
|
});
|
|
1343
1489
|
// Tool: Update dashboard
|
|
1344
|
-
this.
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1490
|
+
this.registerTool({
|
|
1491
|
+
name: 'update-dashboard',
|
|
1492
|
+
description: (0, load_description_js_1.loadDescription)('update-dashboard.md'),
|
|
1493
|
+
schema: {
|
|
1494
|
+
dashboardId: zod_1.z.string().describe('ID of the dashboard to update'),
|
|
1495
|
+
layouts: zod_1.z
|
|
1496
|
+
.object({
|
|
1497
|
+
xs: zod_1.z
|
|
1498
|
+
.array(zod_1.z.object({
|
|
1499
|
+
w: zod_1.z.number(),
|
|
1500
|
+
h: zod_1.z.number(),
|
|
1501
|
+
x: zod_1.z.number(),
|
|
1502
|
+
y: zod_1.z.number(),
|
|
1503
|
+
i: zod_1.z.string(),
|
|
1504
|
+
moved: zod_1.z.boolean(),
|
|
1505
|
+
static: zod_1.z.boolean(),
|
|
1506
|
+
}))
|
|
1507
|
+
.optional(),
|
|
1508
|
+
sm: zod_1.z
|
|
1509
|
+
.array(zod_1.z.object({
|
|
1510
|
+
w: zod_1.z.number(),
|
|
1511
|
+
h: zod_1.z.number(),
|
|
1512
|
+
x: zod_1.z.number(),
|
|
1513
|
+
y: zod_1.z.number(),
|
|
1514
|
+
i: zod_1.z.string(),
|
|
1515
|
+
moved: zod_1.z.boolean(),
|
|
1516
|
+
static: zod_1.z.boolean(),
|
|
1517
|
+
}))
|
|
1518
|
+
.optional(),
|
|
1519
|
+
md: zod_1.z
|
|
1520
|
+
.array(zod_1.z.object({
|
|
1521
|
+
w: zod_1.z.number(),
|
|
1522
|
+
h: zod_1.z.number(),
|
|
1523
|
+
x: zod_1.z.number(),
|
|
1524
|
+
y: zod_1.z.number(),
|
|
1525
|
+
i: zod_1.z.string(),
|
|
1526
|
+
moved: zod_1.z.boolean(),
|
|
1527
|
+
static: zod_1.z.boolean(),
|
|
1528
|
+
}))
|
|
1529
|
+
.optional(),
|
|
1530
|
+
lg: zod_1.z
|
|
1531
|
+
.array(zod_1.z.object({
|
|
1532
|
+
w: zod_1.z.number(),
|
|
1533
|
+
h: zod_1.z.number(),
|
|
1534
|
+
x: zod_1.z.number(),
|
|
1535
|
+
y: zod_1.z.number(),
|
|
1536
|
+
i: zod_1.z.string(),
|
|
1537
|
+
moved: zod_1.z.boolean(),
|
|
1538
|
+
static: zod_1.z.boolean(),
|
|
1539
|
+
}))
|
|
1540
|
+
.optional(),
|
|
1541
|
+
xl: zod_1.z
|
|
1542
|
+
.array(zod_1.z.object({
|
|
1543
|
+
w: zod_1.z.number(),
|
|
1544
|
+
h: zod_1.z.number(),
|
|
1545
|
+
x: zod_1.z.number(),
|
|
1546
|
+
y: zod_1.z.number(),
|
|
1547
|
+
i: zod_1.z.string(),
|
|
1548
|
+
moved: zod_1.z.boolean(),
|
|
1549
|
+
static: zod_1.z.boolean(),
|
|
1550
|
+
}))
|
|
1551
|
+
.optional(),
|
|
1552
|
+
})
|
|
1553
|
+
.describe('Layouts object for the dashboard'),
|
|
1554
|
+
},
|
|
1555
|
+
handler: async ({ dashboardId, layouts }, client) => {
|
|
1556
|
+
try {
|
|
1557
|
+
const updated = await client.updateDashboard({ dashboardId, layouts });
|
|
1558
|
+
return {
|
|
1559
|
+
content: [
|
|
1560
|
+
{
|
|
1561
|
+
type: 'text',
|
|
1562
|
+
text: JSON.stringify(updated, null, 2),
|
|
1563
|
+
},
|
|
1564
|
+
],
|
|
1565
|
+
};
|
|
1566
|
+
}
|
|
1567
|
+
catch (error) {
|
|
1568
|
+
return {
|
|
1569
|
+
content: [
|
|
1570
|
+
{
|
|
1571
|
+
type: 'text',
|
|
1572
|
+
text: `Error updating dashboard: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1573
|
+
},
|
|
1574
|
+
],
|
|
1575
|
+
isError: true,
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1578
|
+
},
|
|
1428
1579
|
});
|
|
1429
1580
|
// Tool: Execute J1QL query
|
|
1430
|
-
this.
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
.
|
|
1435
|
-
.
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
.
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
.
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
.
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
.optional()
|
|
1452
|
-
.
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
queryFlags
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
isError: true,
|
|
1486
|
-
};
|
|
1487
|
-
}
|
|
1581
|
+
this.registerTool({
|
|
1582
|
+
name: 'execute-j1ql-query',
|
|
1583
|
+
description: (0, load_description_js_1.loadDescription)('execute-j1ql-query.md'),
|
|
1584
|
+
schema: {
|
|
1585
|
+
query: zod_1.z.string().describe('A J1QL query string that describes what data to return'),
|
|
1586
|
+
variables: zod_1.z
|
|
1587
|
+
.record(zod_1.z.any())
|
|
1588
|
+
.optional()
|
|
1589
|
+
.describe('A JSON map of values to be used as parameters for the query'),
|
|
1590
|
+
cursor: zod_1.z
|
|
1591
|
+
.string()
|
|
1592
|
+
.optional()
|
|
1593
|
+
.describe('A token that can be exchanged to fetch the next page of information'),
|
|
1594
|
+
includeDeleted: zod_1.z
|
|
1595
|
+
.boolean()
|
|
1596
|
+
.optional()
|
|
1597
|
+
.describe('Include recently deleted information in the results'),
|
|
1598
|
+
deferredResponse: zod_1.z
|
|
1599
|
+
.enum(['DISABLED', 'FORCE'])
|
|
1600
|
+
.optional()
|
|
1601
|
+
.describe('Allows for a deferred response to be returned'),
|
|
1602
|
+
flags: zod_1.z.record(zod_1.z.any()).optional().describe('Flags for query execution'),
|
|
1603
|
+
scopeFilters: zod_1.z
|
|
1604
|
+
.array(zod_1.z.record(zod_1.z.any()))
|
|
1605
|
+
.optional()
|
|
1606
|
+
.describe('Array of filters that define the desired vertex'),
|
|
1607
|
+
},
|
|
1608
|
+
handler: async ({ query, variables, cursor, includeDeleted, deferredResponse, flags, scopeFilters }, client, validator) => {
|
|
1609
|
+
try {
|
|
1610
|
+
// Build flags object
|
|
1611
|
+
const queryFlags = { ...flags };
|
|
1612
|
+
if (typeof includeDeleted === 'boolean')
|
|
1613
|
+
queryFlags.includeDeleted = includeDeleted;
|
|
1614
|
+
if (deferredResponse)
|
|
1615
|
+
queryFlags.deferredResponse = deferredResponse;
|
|
1616
|
+
const result = await client.executeJ1qlQuery({
|
|
1617
|
+
query,
|
|
1618
|
+
variables,
|
|
1619
|
+
cursor,
|
|
1620
|
+
scopeFilters,
|
|
1621
|
+
flags: Object.keys(queryFlags).length > 0 ? queryFlags : undefined,
|
|
1622
|
+
});
|
|
1623
|
+
return {
|
|
1624
|
+
content: [
|
|
1625
|
+
{
|
|
1626
|
+
type: 'text',
|
|
1627
|
+
text: JSON.stringify(result, null, 2),
|
|
1628
|
+
},
|
|
1629
|
+
],
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1632
|
+
catch (error) {
|
|
1633
|
+
return this.createQueryErrorResponse(error, query, validator);
|
|
1634
|
+
}
|
|
1635
|
+
},
|
|
1488
1636
|
});
|
|
1489
1637
|
}
|
|
1638
|
+
// Helper methods for validation
|
|
1639
|
+
async validateQueries(queries, validator) {
|
|
1640
|
+
if (!queries || !Array.isArray(queries))
|
|
1641
|
+
return [];
|
|
1642
|
+
const validationResults = [];
|
|
1643
|
+
for (const queryObj of queries) {
|
|
1644
|
+
if (queryObj.query) {
|
|
1645
|
+
const validation = await validator.validateQuery(queryObj.query);
|
|
1646
|
+
if (!validation.isValid) {
|
|
1647
|
+
validationResults.push({
|
|
1648
|
+
queryName: queryObj.name || 'Unnamed query',
|
|
1649
|
+
error: validation.error || 'Query validation failed',
|
|
1650
|
+
suggestion: validation.suggestion || 'Please check the query syntax and try again',
|
|
1651
|
+
});
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
return validationResults;
|
|
1656
|
+
}
|
|
1657
|
+
async validateWidgetQueries(queries, validator) {
|
|
1658
|
+
// Use the same validation logic as rules - actually execute the queries
|
|
1659
|
+
return this.validateQueries(queries, validator);
|
|
1660
|
+
}
|
|
1661
|
+
createValidationErrorResponse(validationResults) {
|
|
1662
|
+
return {
|
|
1663
|
+
content: [
|
|
1664
|
+
{
|
|
1665
|
+
type: 'text',
|
|
1666
|
+
text: `Query validation failed. Please fix the following issues:\n\n${validationResults
|
|
1667
|
+
.map((r) => `Query: ${r.queryName}\nError: ${r.error}\nSuggestion: ${r.suggestion}`)
|
|
1668
|
+
.join('\n\n')}\n\nUse the execute-j1ql-query tool to test and refine your queries first.`,
|
|
1669
|
+
},
|
|
1670
|
+
],
|
|
1671
|
+
isError: true,
|
|
1672
|
+
};
|
|
1673
|
+
}
|
|
1674
|
+
createQueryErrorResponse(error, query, validator) {
|
|
1675
|
+
const errorResult = validator.handleQueryError(error, query);
|
|
1676
|
+
return {
|
|
1677
|
+
content: [
|
|
1678
|
+
{
|
|
1679
|
+
type: 'text',
|
|
1680
|
+
text: `Error executing J1QL query:\n\n${errorResult.error}\n\nSuggestion: ${errorResult.suggestion}\n\nDebugging tips:\n1. Modify existing queries that are already working as expected.\n2. Use discovery queries to understand available data\n3. Verify entity classes exist (use proper capitalization)\n4. Check property names match exactly\n5. Use single quotes for strings, not double quotes\n6. Place aliases after WITH statements\n7. Add LIMIT clause to prevent timeouts`,
|
|
1681
|
+
},
|
|
1682
|
+
],
|
|
1683
|
+
isError: true,
|
|
1684
|
+
};
|
|
1685
|
+
}
|
|
1490
1686
|
async start() {
|
|
1491
|
-
const transport = new StdioServerTransport();
|
|
1687
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
1492
1688
|
await this.server.connect(transport);
|
|
1493
1689
|
}
|
|
1494
1690
|
async stop() {
|
|
1495
1691
|
// Cleanup if needed
|
|
1496
1692
|
}
|
|
1497
1693
|
}
|
|
1694
|
+
exports.JupiterOneMcpServer = JupiterOneMcpServer;
|
|
1498
1695
|
//# sourceMappingURL=mcp-server.js.map
|