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