@jupiterone/jupiterone-mcp 0.0.4 → 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.js +17 -14
- package/dist/client/graphql/queries.js.map +1 -1
- package/dist/client/jupiterone-client.d.ts +2 -0
- 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.js +9 -5
- 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 +4 -1
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +1505 -1366
- 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.js +5 -1
- package/dist/utils/j1ql-validator.js.map +1 -1
- 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 -379
- 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,289 +1,447 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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 {
|
|
8
11
|
server;
|
|
9
12
|
client;
|
|
10
13
|
validator;
|
|
14
|
+
hasEnvironmentAccount;
|
|
11
15
|
constructor(config) {
|
|
12
|
-
this.client = new JupiterOneClient(config);
|
|
13
|
-
this.validator = new J1QLValidator(this.client.j1qlService);
|
|
14
|
-
this.server = new McpServer({
|
|
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({
|
|
15
19
|
name: 'jupiterone-mcp',
|
|
16
20
|
version: '1.0.0',
|
|
17
21
|
});
|
|
22
|
+
this.hasEnvironmentAccount = !config.accountId;
|
|
18
23
|
this.setupTools();
|
|
19
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
|
+
}
|
|
20
61
|
setupTools() {
|
|
21
62
|
// Tool: List all rules
|
|
22
|
-
this.
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
+
},
|
|
66
112
|
});
|
|
67
113
|
// Tool: Get rule details
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
+
}
|
|
75
134
|
return {
|
|
76
135
|
content: [
|
|
77
136
|
{
|
|
78
137
|
type: 'text',
|
|
79
|
-
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'}`,
|
|
80
196
|
},
|
|
81
197
|
],
|
|
82
198
|
isError: true,
|
|
83
199
|
};
|
|
84
200
|
}
|
|
85
|
-
|
|
86
|
-
content: [
|
|
87
|
-
{
|
|
88
|
-
type: 'text',
|
|
89
|
-
text: JSON.stringify({
|
|
90
|
-
id: rule.id,
|
|
91
|
-
resourceGroupId: rule.resourceGroupId,
|
|
92
|
-
accountId: rule.accountId,
|
|
93
|
-
name: rule.name,
|
|
94
|
-
description: rule.description,
|
|
95
|
-
version: rule.version,
|
|
96
|
-
lastEvaluationStartOn: rule.lastEvaluationStartOn,
|
|
97
|
-
lastEvaluationEndOn: rule.lastEvaluationEndOn,
|
|
98
|
-
evaluationStep: rule.evaluationStep,
|
|
99
|
-
specVersion: rule.specVersion,
|
|
100
|
-
notifyOnFailure: rule.notifyOnFailure,
|
|
101
|
-
triggerActionsOnNewEntitiesOnly: rule.triggerActionsOnNewEntitiesOnly,
|
|
102
|
-
ignorePreviousResults: rule.ignorePreviousResults,
|
|
103
|
-
pollingInterval: rule.pollingInterval,
|
|
104
|
-
templates: rule.templates,
|
|
105
|
-
outputs: rule.outputs,
|
|
106
|
-
labels: rule.labels?.map((label) => ({
|
|
107
|
-
labelName: label.labelName,
|
|
108
|
-
labelValue: label.labelValue,
|
|
109
|
-
})) || [],
|
|
110
|
-
question: rule.question
|
|
111
|
-
? {
|
|
112
|
-
queries: rule.question.queries?.map((query) => ({
|
|
113
|
-
query: query.query,
|
|
114
|
-
name: query.name,
|
|
115
|
-
includeDeleted: query.includeDeleted,
|
|
116
|
-
})) || [],
|
|
117
|
-
}
|
|
118
|
-
: null,
|
|
119
|
-
questionId: rule.questionId,
|
|
120
|
-
latest: rule.latest,
|
|
121
|
-
deleted: rule.deleted,
|
|
122
|
-
type: rule.type,
|
|
123
|
-
operations: rule.operations?.map((op) => ({
|
|
124
|
-
when: op.when,
|
|
125
|
-
actions: op.actions,
|
|
126
|
-
})) || [],
|
|
127
|
-
latestAlertId: rule.latestAlertId,
|
|
128
|
-
latestAlertIsActive: rule.latestAlertIsActive,
|
|
129
|
-
state: rule.state
|
|
130
|
-
? {
|
|
131
|
-
actions: rule.state.actions,
|
|
132
|
-
}
|
|
133
|
-
: null,
|
|
134
|
-
tags: rule.tags,
|
|
135
|
-
remediationSteps: rule.remediationSteps,
|
|
136
|
-
}, null, 2),
|
|
137
|
-
},
|
|
138
|
-
],
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
return {
|
|
143
|
-
content: [
|
|
144
|
-
{
|
|
145
|
-
type: 'text',
|
|
146
|
-
text: `Error getting rule details: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
147
|
-
},
|
|
148
|
-
],
|
|
149
|
-
isError: true,
|
|
150
|
-
};
|
|
151
|
-
}
|
|
201
|
+
},
|
|
152
202
|
});
|
|
153
203
|
// Tool: Test connection
|
|
154
|
-
this.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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
|
+
},
|
|
181
235
|
});
|
|
182
236
|
// Tool: Evaluate rule
|
|
183
|
-
this.
|
|
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
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
+
},
|
|
212
270
|
});
|
|
213
271
|
// Tool: Get active alerts
|
|
214
|
-
this.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
+
};
|
|
221
319
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
description: instance.questionRuleInstance?.description ||
|
|
236
|
-
instance.reportRuleInstance?.description,
|
|
237
|
-
level: instance.level,
|
|
238
|
-
status: instance.status,
|
|
239
|
-
createdOn: instance.createdOn,
|
|
240
|
-
lastUpdatedOn: instance.lastUpdatedOn,
|
|
241
|
-
lastEvaluationBeginOn: instance.lastEvaluationBeginOn,
|
|
242
|
-
lastEvaluationEndOn: instance.lastEvaluationEndOn,
|
|
243
|
-
recordCount: instance.lastEvaluationResult?.rawDataDescriptors?.[0]?.recordCount || 0,
|
|
244
|
-
tags: instance.questionRuleInstance?.tags || [],
|
|
245
|
-
labels: instance.questionRuleInstance?.labels || [],
|
|
246
|
-
outputs: instance.lastEvaluationResult?.outputs || [],
|
|
247
|
-
users: instance.users,
|
|
248
|
-
ruleId: instance.ruleId,
|
|
249
|
-
ruleVersion: instance.ruleVersion,
|
|
250
|
-
endReason: instance.endReason,
|
|
251
|
-
dismissedOn: instance.dismissedOn,
|
|
252
|
-
})),
|
|
253
|
-
}, null, 2),
|
|
254
|
-
},
|
|
255
|
-
],
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
catch (error) {
|
|
259
|
-
console.error('Error in get-active-alerts:', error);
|
|
260
|
-
return {
|
|
261
|
-
content: [
|
|
262
|
-
{
|
|
263
|
-
type: 'text',
|
|
264
|
-
text: `Error getting active alerts: ${error instanceof Error ? error.message : 'Unknown error'}. Please check your JupiterOne API credentials and connection.`,
|
|
265
|
-
},
|
|
266
|
-
],
|
|
267
|
-
isError: true,
|
|
268
|
-
};
|
|
269
|
-
}
|
|
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
|
+
},
|
|
270
333
|
});
|
|
271
334
|
// Tool: Get dashboards
|
|
272
|
-
this.
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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({
|
|
282
434
|
id: dashboard.id,
|
|
283
435
|
name: dashboard.name,
|
|
284
436
|
category: dashboard.category,
|
|
285
437
|
supportedUseCase: dashboard.supportedUseCase,
|
|
286
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,
|
|
287
445
|
resourceGroupId: dashboard.resourceGroupId,
|
|
288
446
|
starred: dashboard.starred,
|
|
289
447
|
lastUpdated: dashboard._timeUpdated,
|
|
@@ -295,983 +453,948 @@ export class JupiterOneMcpServer {
|
|
|
295
453
|
preRequisitesGroupsRequired: dashboard.prerequisites.preRequisitesGroupsRequired,
|
|
296
454
|
}
|
|
297
455
|
: null,
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
type: 'text',
|
|
309
|
-
text: `Error getting dashboards: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
310
|
-
},
|
|
311
|
-
],
|
|
312
|
-
isError: true,
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
});
|
|
316
|
-
// Tool: Create dashboard
|
|
317
|
-
this.server.tool('create-dashboard', loadDescription('create-dashboard.md'), {
|
|
318
|
-
name: z.string(),
|
|
319
|
-
type: z.string(),
|
|
320
|
-
}, async ({ name, type }) => {
|
|
321
|
-
try {
|
|
322
|
-
const result = await this.client.createDashboard({ name, type });
|
|
323
|
-
return {
|
|
324
|
-
content: [
|
|
325
|
-
{
|
|
326
|
-
type: 'text',
|
|
327
|
-
text: JSON.stringify({
|
|
328
|
-
id: result.id,
|
|
329
|
-
name,
|
|
330
|
-
type,
|
|
331
|
-
}, null, 2),
|
|
332
|
-
},
|
|
333
|
-
],
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
catch (error) {
|
|
337
|
-
return {
|
|
338
|
-
content: [
|
|
339
|
-
{
|
|
340
|
-
type: 'text',
|
|
341
|
-
text: `Error creating dashboard: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
342
|
-
},
|
|
343
|
-
],
|
|
344
|
-
isError: true,
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
// Tool: Get dashboard details
|
|
349
|
-
this.server.tool('get-dashboard-details', {
|
|
350
|
-
dashboardId: z.string(),
|
|
351
|
-
}, async ({ dashboardId }) => {
|
|
352
|
-
try {
|
|
353
|
-
const dashboard = await this.client.getDashboard(dashboardId);
|
|
354
|
-
return {
|
|
355
|
-
content: [
|
|
356
|
-
{
|
|
357
|
-
type: 'text',
|
|
358
|
-
text: JSON.stringify({
|
|
359
|
-
id: dashboard.id,
|
|
360
|
-
name: dashboard.name,
|
|
361
|
-
category: dashboard.category,
|
|
362
|
-
supportedUseCase: dashboard.supportedUseCase,
|
|
363
|
-
isJ1ManagedBoard: dashboard.isJ1ManagedBoard,
|
|
364
|
-
published: dashboard.published,
|
|
365
|
-
publishedToUserIds: dashboard.publishedToUserIds,
|
|
366
|
-
publishedToGroupIds: dashboard.publishedToGroupIds,
|
|
367
|
-
groupIds: dashboard.groupIds,
|
|
368
|
-
userIds: dashboard.userIds,
|
|
369
|
-
scopeFilters: dashboard.scopeFilters,
|
|
370
|
-
resourceGroupId: dashboard.resourceGroupId,
|
|
371
|
-
starred: dashboard.starred,
|
|
372
|
-
lastUpdated: dashboard._timeUpdated,
|
|
373
|
-
createdAt: dashboard._createdAt,
|
|
374
|
-
prerequisites: dashboard.prerequisites
|
|
375
|
-
? {
|
|
376
|
-
prerequisitesMet: dashboard.prerequisites.prerequisitesMet,
|
|
377
|
-
preRequisitesGroupsFulfilled: dashboard.prerequisites.preRequisitesGroupsFulfilled,
|
|
378
|
-
preRequisitesGroupsRequired: dashboard.prerequisites.preRequisitesGroupsRequired,
|
|
379
|
-
}
|
|
380
|
-
: null,
|
|
381
|
-
parameters: dashboard.parameters.map((param) => ({
|
|
382
|
-
id: param.id,
|
|
383
|
-
label: param.label,
|
|
384
|
-
name: param.name,
|
|
385
|
-
type: param.type,
|
|
386
|
-
valueType: param.valueType,
|
|
387
|
-
default: param.default,
|
|
388
|
-
options: param.options,
|
|
389
|
-
requireValue: param.requireValue,
|
|
390
|
-
disableCustomInput: param.disableCustomInput,
|
|
391
|
-
})),
|
|
392
|
-
widgets: dashboard.widgets.map((widget) => ({
|
|
393
|
-
id: widget.id,
|
|
394
|
-
title: widget.title,
|
|
395
|
-
description: widget.description,
|
|
396
|
-
type: widget.type,
|
|
397
|
-
questionId: widget.questionId,
|
|
398
|
-
noResultMessage: widget.noResultMessage,
|
|
399
|
-
includeDeleted: widget.includeDeleted,
|
|
400
|
-
config: {
|
|
401
|
-
queries: widget.config.queries.map((query) => ({
|
|
402
|
-
id: query.id,
|
|
403
|
-
name: query.name,
|
|
404
|
-
query: query.query,
|
|
405
|
-
})),
|
|
406
|
-
settings: widget.config.settings,
|
|
407
|
-
postQueryFilters: widget.config.postQueryFilters,
|
|
408
|
-
disableQueryPolicyFilters: widget.config.disableQueryPolicyFilters,
|
|
409
|
-
},
|
|
410
|
-
})),
|
|
411
|
-
layouts: {
|
|
412
|
-
xs: dashboard.layouts.xs.map((item) => ({
|
|
413
|
-
i: item.i,
|
|
414
|
-
x: item.x,
|
|
415
|
-
y: item.y,
|
|
416
|
-
w: item.w,
|
|
417
|
-
h: item.h,
|
|
418
|
-
static: item.static,
|
|
419
|
-
moved: item.moved,
|
|
420
|
-
})),
|
|
421
|
-
sm: dashboard.layouts.sm.map((item) => ({
|
|
422
|
-
i: item.i,
|
|
423
|
-
x: item.x,
|
|
424
|
-
y: item.y,
|
|
425
|
-
w: item.w,
|
|
426
|
-
h: item.h,
|
|
427
|
-
static: item.static,
|
|
428
|
-
moved: item.moved,
|
|
429
|
-
})),
|
|
430
|
-
md: dashboard.layouts.md.map((item) => ({
|
|
431
|
-
i: item.i,
|
|
432
|
-
x: item.x,
|
|
433
|
-
y: item.y,
|
|
434
|
-
w: item.w,
|
|
435
|
-
h: item.h,
|
|
436
|
-
static: item.static,
|
|
437
|
-
moved: item.moved,
|
|
438
|
-
})),
|
|
439
|
-
lg: dashboard.layouts.lg.map((item) => ({
|
|
440
|
-
i: item.i,
|
|
441
|
-
x: item.x,
|
|
442
|
-
y: item.y,
|
|
443
|
-
w: item.w,
|
|
444
|
-
h: item.h,
|
|
445
|
-
static: item.static,
|
|
446
|
-
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,
|
|
447
466
|
})),
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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
|
+
},
|
|
456
485
|
})),
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
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
|
+
},
|
|
474
550
|
});
|
|
475
551
|
// Tool: Get integration definitions
|
|
476
|
-
this.
|
|
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
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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
|
+
},
|
|
530
611
|
});
|
|
531
612
|
// Tool: Get integration instances
|
|
532
|
-
this.
|
|
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
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
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
|
+
},
|
|
593
679
|
});
|
|
594
680
|
// Tool: Get integration jobs
|
|
595
|
-
this.
|
|
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
|
-
|
|
658
|
-
isError: true,
|
|
659
|
-
};
|
|
660
|
-
}
|
|
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
|
+
},
|
|
661
744
|
});
|
|
662
745
|
// Tool: Create inline question rule instance
|
|
663
|
-
this.
|
|
664
|
-
name:
|
|
665
|
-
description:
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
.
|
|
669
|
-
.optional()
|
|
670
|
-
.
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
.
|
|
675
|
-
pollingInterval: z
|
|
676
|
-
.enum([
|
|
677
|
-
'DISABLED',
|
|
678
|
-
'THIRTY_MINUTES',
|
|
679
|
-
'ONE_HOUR',
|
|
680
|
-
'FOUR_HOURS',
|
|
681
|
-
'EIGHT_HOURS',
|
|
682
|
-
'TWELVE_HOURS',
|
|
683
|
-
'ONE_DAY',
|
|
684
|
-
'ONE_WEEK',
|
|
685
|
-
])
|
|
686
|
-
.describe('How frequently to evaluate the rule'),
|
|
687
|
-
outputs: z.array(z.string()).describe('Output fields from the rule evaluation'),
|
|
688
|
-
specVersion: z.number().optional().describe('Specification version'),
|
|
689
|
-
tags: z.array(z.string()).optional().describe('Tags for categorizing the rule'),
|
|
690
|
-
templates: z.record(z.any()).optional().describe('Template variables'),
|
|
691
|
-
queries: z
|
|
692
|
-
.array(z.object({
|
|
693
|
-
query: z.string().describe('J1QL query string'),
|
|
694
|
-
name: z.string().describe('Name identifier for the query'),
|
|
695
|
-
version: z.string().optional().describe('Version of the query'),
|
|
696
|
-
includeDeleted: z
|
|
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
|
|
697
758
|
.boolean()
|
|
698
759
|
.optional()
|
|
699
|
-
.describe('Whether to
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
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
|
|
705
778
|
.object({
|
|
706
|
-
|
|
707
|
-
|
|
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
|
+
})),
|
|
708
785
|
})
|
|
709
|
-
.describe('
|
|
710
|
-
|
|
711
|
-
.array(z.object({
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
.
|
|
720
|
-
|
|
721
|
-
.
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
.
|
|
726
|
-
|
|
727
|
-
.
|
|
728
|
-
|
|
729
|
-
.
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
.
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
.
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
.string()
|
|
754
|
-
.optional()
|
|
755
|
-
.describe('
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
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'),
|
|
764
859
|
}))
|
|
765
|
-
.describe('
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
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
|
+
};
|
|
774
912
|
}
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
queries,
|
|
788
|
-
},
|
|
789
|
-
operations,
|
|
790
|
-
};
|
|
791
|
-
const result = await this.client.createInlineQuestionRuleInstance(instance);
|
|
792
|
-
return {
|
|
793
|
-
content: [
|
|
794
|
-
{
|
|
795
|
-
type: 'text',
|
|
796
|
-
text: JSON.stringify({
|
|
797
|
-
success: true,
|
|
798
|
-
rule: {
|
|
799
|
-
id: result.id,
|
|
800
|
-
name: result.name,
|
|
801
|
-
description: result.description,
|
|
802
|
-
version: result.version,
|
|
803
|
-
pollingInterval: result.pollingInterval,
|
|
804
|
-
outputs: result.outputs,
|
|
805
|
-
specVersion: result.specVersion,
|
|
806
|
-
notifyOnFailure: result.notifyOnFailure,
|
|
807
|
-
triggerActionsOnNewEntitiesOnly: result.triggerActionsOnNewEntitiesOnly,
|
|
808
|
-
ignorePreviousResults: result.ignorePreviousResults,
|
|
809
|
-
tags: result.tags,
|
|
810
|
-
question: result.question,
|
|
811
|
-
operations: result.operations,
|
|
812
|
-
latestAlertId: result.latestAlertId,
|
|
813
|
-
latestAlertIsActive: result.latestAlertIsActive,
|
|
814
|
-
},
|
|
815
|
-
}, null, 2),
|
|
816
|
-
},
|
|
817
|
-
],
|
|
818
|
-
};
|
|
819
|
-
}
|
|
820
|
-
catch (error) {
|
|
821
|
-
return {
|
|
822
|
-
content: [
|
|
823
|
-
{
|
|
824
|
-
type: 'text',
|
|
825
|
-
text: `Error creating inline question rule: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
826
|
-
},
|
|
827
|
-
],
|
|
828
|
-
isError: true,
|
|
829
|
-
};
|
|
830
|
-
}
|
|
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
|
+
},
|
|
831
925
|
});
|
|
832
926
|
// Tool: Update inline question rule instance
|
|
833
|
-
this.
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
.
|
|
840
|
-
.describe('Whether to
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
'
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
.
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
.string()
|
|
868
|
-
.
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
query: z.string().describe('J1QL query string'),
|
|
874
|
-
name: z.string().describe('Name identifier for the query'),
|
|
875
|
-
version: z.string().optional().describe('Version of the query'),
|
|
876
|
-
includeDeleted: z.boolean().describe('Whether to include deleted entities'),
|
|
877
|
-
})),
|
|
878
|
-
})
|
|
879
|
-
.describe('Question configuration'),
|
|
880
|
-
operations: z
|
|
881
|
-
.array(z.object({
|
|
882
|
-
when: z
|
|
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
|
|
936
|
+
.boolean()
|
|
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(),
|
|
959
|
+
}))
|
|
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
|
|
883
967
|
.object({
|
|
884
|
-
|
|
885
|
-
|
|
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
|
+
})),
|
|
886
974
|
})
|
|
887
|
-
.describe('
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
.
|
|
893
|
-
.
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
.
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
.string()
|
|
901
|
-
.
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
.
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
.
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
.optional()
|
|
918
|
-
.
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
.optional()
|
|
923
|
-
.describe('
|
|
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
|
-
|
|
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
|
+
};
|
|
950
1099
|
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
templates,
|
|
964
|
-
labels,
|
|
965
|
-
resourceGroupId,
|
|
966
|
-
remediationSteps,
|
|
967
|
-
question,
|
|
968
|
-
operations,
|
|
969
|
-
};
|
|
970
|
-
const result = await this.client.updateInlineQuestionRuleInstance(instance);
|
|
971
|
-
return {
|
|
972
|
-
content: [
|
|
973
|
-
{
|
|
974
|
-
type: 'text',
|
|
975
|
-
text: JSON.stringify({
|
|
976
|
-
success: true,
|
|
977
|
-
rule: {
|
|
978
|
-
id: result.id,
|
|
979
|
-
name: result.name,
|
|
980
|
-
description: result.description,
|
|
981
|
-
version: result.version,
|
|
982
|
-
pollingInterval: result.pollingInterval,
|
|
983
|
-
outputs: result.outputs,
|
|
984
|
-
specVersion: result.specVersion,
|
|
985
|
-
notifyOnFailure: result.notifyOnFailure,
|
|
986
|
-
triggerActionsOnNewEntitiesOnly: result.triggerActionsOnNewEntitiesOnly,
|
|
987
|
-
ignorePreviousResults: result.ignorePreviousResults,
|
|
988
|
-
tags: result.tags,
|
|
989
|
-
labels: result.labels,
|
|
990
|
-
question: result.question,
|
|
991
|
-
operations: result.operations,
|
|
992
|
-
latestAlertId: result.latestAlertId,
|
|
993
|
-
latestAlertIsActive: result.latestAlertIsActive,
|
|
994
|
-
resourceGroupId: result.resourceGroupId,
|
|
995
|
-
remediationSteps: result.remediationSteps,
|
|
996
|
-
},
|
|
997
|
-
}, null, 2),
|
|
998
|
-
},
|
|
999
|
-
],
|
|
1000
|
-
};
|
|
1001
|
-
}
|
|
1002
|
-
catch (error) {
|
|
1003
|
-
return {
|
|
1004
|
-
content: [
|
|
1005
|
-
{
|
|
1006
|
-
type: 'text',
|
|
1007
|
-
text: `Error updating inline question rule: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1008
|
-
},
|
|
1009
|
-
],
|
|
1010
|
-
isError: true,
|
|
1011
|
-
};
|
|
1012
|
-
}
|
|
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
|
+
},
|
|
1013
1112
|
});
|
|
1014
1113
|
// Add get-integration-job tool
|
|
1015
|
-
this.
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
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
|
+
},
|
|
1050
1153
|
});
|
|
1051
1154
|
// Add get-integration-events tool
|
|
1052
|
-
this.
|
|
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
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
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
|
+
},
|
|
1096
1203
|
});
|
|
1097
1204
|
// Tool: List rule evaluations
|
|
1098
|
-
this.
|
|
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
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
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
|
+
},
|
|
1146
1257
|
});
|
|
1147
1258
|
// Tool: Get rule evaluation details
|
|
1148
|
-
this.
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
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,
|
|
1173
1307
|
status: detail.status,
|
|
1174
|
-
|
|
1308
|
+
duration: detail.duration,
|
|
1309
|
+
finishedOn: detail.finishedOn,
|
|
1310
|
+
logs: detail.logs,
|
|
1175
1311
|
}))
|
|
1176
1312
|
: [],
|
|
1177
1313
|
}))
|
|
1178
1314
|
: [],
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
}))
|
|
1198
|
-
: [],
|
|
1199
|
-
}))
|
|
1200
|
-
: [],
|
|
1201
|
-
ruleEvaluationOrigin: details.ruleEvaluationOrigin,
|
|
1202
|
-
}, null, 2),
|
|
1203
|
-
},
|
|
1204
|
-
],
|
|
1205
|
-
};
|
|
1206
|
-
}
|
|
1207
|
-
catch (error) {
|
|
1208
|
-
return {
|
|
1209
|
-
content: [
|
|
1210
|
-
{
|
|
1211
|
-
type: 'text',
|
|
1212
|
-
text: `Error getting rule evaluation details: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1213
|
-
},
|
|
1214
|
-
],
|
|
1215
|
-
isError: true,
|
|
1216
|
-
};
|
|
1217
|
-
}
|
|
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
|
+
},
|
|
1218
1333
|
});
|
|
1219
1334
|
// Tool: Get raw data download URL
|
|
1220
|
-
this.
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
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
|
+
},
|
|
1248
1367
|
});
|
|
1249
1368
|
// Tool: Get rule evaluation query results
|
|
1250
|
-
this.
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
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
|
+
},
|
|
1275
1398
|
});
|
|
1276
1399
|
// The server is not doing a great job of this, will uncomment when we have better support for this
|
|
1277
1400
|
// Tool: Create J1QL from natural language
|
|
@@ -1317,194 +1440,209 @@ export class JupiterOneMcpServer {
|
|
|
1317
1440
|
// }
|
|
1318
1441
|
// );
|
|
1319
1442
|
// Tool: Create dashboard widget
|
|
1320
|
-
this.
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
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
|
+
}
|
|
1329
1460
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
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);
|
|
1332
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
|
+
};
|
|
1333
1475
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
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
|
+
};
|
|
1338
1486
|
}
|
|
1339
|
-
|
|
1340
|
-
return {
|
|
1341
|
-
content: [
|
|
1342
|
-
{
|
|
1343
|
-
type: 'text',
|
|
1344
|
-
text: JSON.stringify(widget, null, 2),
|
|
1345
|
-
},
|
|
1346
|
-
],
|
|
1347
|
-
};
|
|
1348
|
-
}
|
|
1349
|
-
catch (error) {
|
|
1350
|
-
return {
|
|
1351
|
-
content: [
|
|
1352
|
-
{
|
|
1353
|
-
type: 'text',
|
|
1354
|
-
text: `Error creating dashboard widget: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1355
|
-
},
|
|
1356
|
-
],
|
|
1357
|
-
isError: true,
|
|
1358
|
-
};
|
|
1359
|
-
}
|
|
1487
|
+
},
|
|
1360
1488
|
});
|
|
1361
1489
|
// Tool: Update dashboard
|
|
1362
|
-
this.
|
|
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
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
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
|
+
},
|
|
1446
1579
|
});
|
|
1447
1580
|
// Tool: Execute J1QL query
|
|
1448
|
-
this.
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
.
|
|
1453
|
-
.
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
.
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
.
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
.
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
.optional()
|
|
1470
|
-
.
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
queryFlags
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
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
|
+
},
|
|
1498
1636
|
});
|
|
1499
1637
|
}
|
|
1500
1638
|
// Helper methods for validation
|
|
1501
|
-
async validateQueries(queries) {
|
|
1639
|
+
async validateQueries(queries, validator) {
|
|
1502
1640
|
if (!queries || !Array.isArray(queries))
|
|
1503
1641
|
return [];
|
|
1504
1642
|
const validationResults = [];
|
|
1505
1643
|
for (const queryObj of queries) {
|
|
1506
1644
|
if (queryObj.query) {
|
|
1507
|
-
const validation = await
|
|
1645
|
+
const validation = await validator.validateQuery(queryObj.query);
|
|
1508
1646
|
if (!validation.isValid) {
|
|
1509
1647
|
validationResults.push({
|
|
1510
1648
|
queryName: queryObj.name || 'Unnamed query',
|
|
@@ -1516,9 +1654,9 @@ export class JupiterOneMcpServer {
|
|
|
1516
1654
|
}
|
|
1517
1655
|
return validationResults;
|
|
1518
1656
|
}
|
|
1519
|
-
async validateWidgetQueries(queries) {
|
|
1657
|
+
async validateWidgetQueries(queries, validator) {
|
|
1520
1658
|
// Use the same validation logic as rules - actually execute the queries
|
|
1521
|
-
return this.validateQueries(queries);
|
|
1659
|
+
return this.validateQueries(queries, validator);
|
|
1522
1660
|
}
|
|
1523
1661
|
createValidationErrorResponse(validationResults) {
|
|
1524
1662
|
return {
|
|
@@ -1533,8 +1671,8 @@ export class JupiterOneMcpServer {
|
|
|
1533
1671
|
isError: true,
|
|
1534
1672
|
};
|
|
1535
1673
|
}
|
|
1536
|
-
createQueryErrorResponse(error, query) {
|
|
1537
|
-
const errorResult =
|
|
1674
|
+
createQueryErrorResponse(error, query, validator) {
|
|
1675
|
+
const errorResult = validator.handleQueryError(error, query);
|
|
1538
1676
|
return {
|
|
1539
1677
|
content: [
|
|
1540
1678
|
{
|
|
@@ -1546,11 +1684,12 @@ export class JupiterOneMcpServer {
|
|
|
1546
1684
|
};
|
|
1547
1685
|
}
|
|
1548
1686
|
async start() {
|
|
1549
|
-
const transport = new StdioServerTransport();
|
|
1687
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
1550
1688
|
await this.server.connect(transport);
|
|
1551
1689
|
}
|
|
1552
1690
|
async stop() {
|
|
1553
1691
|
// Cleanup if needed
|
|
1554
1692
|
}
|
|
1555
1693
|
}
|
|
1694
|
+
exports.JupiterOneMcpServer = JupiterOneMcpServer;
|
|
1556
1695
|
//# sourceMappingURL=mcp-server.js.map
|