@loadmill/mcp 0.0.2 → 0.1.0
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 +40 -2
- package/dist/constants.d.ts +10 -0
- package/dist/constants.js +16 -1
- package/dist/constants.js.map +1 -1
- package/dist/handlers/prompts/index.d.ts +2 -0
- package/dist/handlers/prompts/index.js +89 -0
- package/dist/handlers/prompts/index.js.map +1 -0
- package/dist/handlers/resources/index.d.ts +2 -0
- package/dist/handlers/resources/index.js +62 -0
- package/dist/handlers/resources/index.js.map +1 -0
- package/dist/handlers/shared.d.ts +4 -0
- package/dist/handlers/shared.js +45 -0
- package/dist/handlers/shared.js.map +1 -0
- package/dist/handlers/tools/index.d.ts +2 -0
- package/dist/handlers/tools/index.js +199 -0
- package/dist/handlers/tools/index.js.map +1 -0
- package/dist/handlers/tools/tasks.js +303 -0
- package/dist/handlers/tools/tasks.js.map +1 -0
- package/dist/http-request.js +0 -2
- package/dist/http-request.js.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp-handler.js +6 -252
- package/dist/mcp-handler.js.map +1 -1
- package/package.json +15 -2
- package/dist/tools.js +0 -182
- package/dist/tools.js.map +0 -1
- /package/dist/{tools.d.ts → handlers/tools/tasks.d.ts} +0 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.toolsTasks = void 0;
|
|
7
|
+
const _2020_1 = __importDefault(require("ajv/dist/2020"));
|
|
8
|
+
const json_schema_draft_07_json_1 = __importDefault(require("ajv/dist/refs/json-schema-draft-07.json"));
|
|
9
|
+
const ajv_formats_1 = __importDefault(require("ajv-formats"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const http_request_js_1 = require("../../http-request.js");
|
|
13
|
+
const constants_js_1 = require("../../constants.js");
|
|
14
|
+
const utils_js_1 = require("../../utils.js");
|
|
15
|
+
const shared_js_1 = require("../shared.js");
|
|
16
|
+
// todo make sure all return in the same allowed pattern
|
|
17
|
+
exports.toolsTasks = {
|
|
18
|
+
[constants_js_1.SEARCH_TEST_SUITES]: async (params) => {
|
|
19
|
+
const args = params.arguments;
|
|
20
|
+
console.log('Searching test suites with args:', args);
|
|
21
|
+
const response = await (0, http_request_js_1.sendHttpRequest)({
|
|
22
|
+
method: http_request_js_1.HttpMethods.GET,
|
|
23
|
+
url: `${constants_js_1.API_URL}/test-suites`,
|
|
24
|
+
query: {
|
|
25
|
+
search: args.search || '',
|
|
26
|
+
filter: args.filter || 'All',
|
|
27
|
+
fromDateFilter: args.fromDateFilter || '',
|
|
28
|
+
toDateFilter: args.toDateFilter || '',
|
|
29
|
+
labels: args.labels || [],
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
content: [{
|
|
34
|
+
type: 'text',
|
|
35
|
+
text: JSON.stringify(response, null, 2),
|
|
36
|
+
}],
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
[constants_js_1.SEARCH_TEST_SUITE_RUNS]: async (params) => {
|
|
40
|
+
const args = params.arguments;
|
|
41
|
+
console.log('Searching test suite runs with args:', args);
|
|
42
|
+
const response = await (0, http_request_js_1.sendHttpRequest)({
|
|
43
|
+
method: http_request_js_1.HttpMethods.GET,
|
|
44
|
+
url: `${constants_js_1.API_URL}/test-suites-runs/flows`,
|
|
45
|
+
query: {
|
|
46
|
+
search: args.search || '',
|
|
47
|
+
filter: args.filter || 'All',
|
|
48
|
+
fromDateFilter: args.fromDateFilter || '',
|
|
49
|
+
toDateFilter: args.toDateFilter || '',
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
return {
|
|
53
|
+
content: [{
|
|
54
|
+
type: 'text',
|
|
55
|
+
text: JSON.stringify(response, null, 2),
|
|
56
|
+
}],
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
[constants_js_1.RUN_TEST_SUITE]: async (params) => {
|
|
60
|
+
const args = params.arguments;
|
|
61
|
+
console.log('Running test suite with args:', args);
|
|
62
|
+
const response = await (0, http_request_js_1.sendHttpRequest)({
|
|
63
|
+
method: http_request_js_1.HttpMethods.POST,
|
|
64
|
+
url: `${constants_js_1.API_URL}/test-suites/${args.id}/run`,
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
content: [{
|
|
68
|
+
type: 'text',
|
|
69
|
+
text: JSON.stringify(response, null, 2),
|
|
70
|
+
}],
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
[constants_js_1.GET_TEST_SUITE_RUN]: async (params) => {
|
|
74
|
+
const args = params.arguments;
|
|
75
|
+
console.log('Getting test suite run with args:', args);
|
|
76
|
+
const response = await (0, http_request_js_1.sendHttpRequest)({
|
|
77
|
+
method: http_request_js_1.HttpMethods.GET,
|
|
78
|
+
url: `${constants_js_1.API_URL}/test-suites-runs/${args.id}`,
|
|
79
|
+
});
|
|
80
|
+
return {
|
|
81
|
+
content: [{
|
|
82
|
+
type: 'text',
|
|
83
|
+
text: JSON.stringify(response, null, 2),
|
|
84
|
+
}],
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
[constants_js_1.GET_TEST_SUITE_FLOW_RUN]: async (params) => {
|
|
88
|
+
const args = params.arguments;
|
|
89
|
+
console.log('Getting test suite flow run with args:', args);
|
|
90
|
+
const response = await (0, http_request_js_1.sendHttpRequest)({
|
|
91
|
+
method: http_request_js_1.HttpMethods.GET,
|
|
92
|
+
url: `${constants_js_1.API_URL}/test-suites-runs/flows/${args.flowRunId}`,
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
content: [{
|
|
96
|
+
type: 'text',
|
|
97
|
+
text: JSON.stringify(response, null, 2),
|
|
98
|
+
}],
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
[constants_js_1.SEARCH_TEST_PLAN]: async (params) => {
|
|
102
|
+
const args = params.arguments;
|
|
103
|
+
console.log('Searching test plans with args:', args);
|
|
104
|
+
const response = await (0, http_request_js_1.sendHttpRequest)({
|
|
105
|
+
method: http_request_js_1.HttpMethods.GET,
|
|
106
|
+
url: `${constants_js_1.API_URL}/test-plans`,
|
|
107
|
+
query: {
|
|
108
|
+
search: args.search || '',
|
|
109
|
+
filter: args.filter || 'All',
|
|
110
|
+
fromDateFilter: args.fromDateFilter || '',
|
|
111
|
+
toDateFilter: args.toDateFilter || '',
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
content: [{
|
|
116
|
+
type: 'text',
|
|
117
|
+
text: JSON.stringify(response, null, 2),
|
|
118
|
+
}],
|
|
119
|
+
};
|
|
120
|
+
},
|
|
121
|
+
[constants_js_1.RUN_TEST_PLAN]: async (params) => {
|
|
122
|
+
const args = params.arguments;
|
|
123
|
+
console.log('Running test plan with args:', args);
|
|
124
|
+
// AI decides to use both for some reason
|
|
125
|
+
const overrideParameters = args.overrideParameters && (0, utils_js_1.toLoadmillParams)(args.overrideParameters);
|
|
126
|
+
const parameters = args.parameters && (0, utils_js_1.toLoadmillParams)(args.parameters);
|
|
127
|
+
const response = await (0, http_request_js_1.sendHttpRequest)({
|
|
128
|
+
method: http_request_js_1.HttpMethods.POST,
|
|
129
|
+
url: `${constants_js_1.API_URL}/test-plans/${args.id}/run`,
|
|
130
|
+
body: {
|
|
131
|
+
labels: args.labels || [],
|
|
132
|
+
overrideParameters: overrideParameters || parameters || {},
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
return {
|
|
136
|
+
content: [{
|
|
137
|
+
type: 'text',
|
|
138
|
+
text: JSON.stringify(response, null, 2),
|
|
139
|
+
}],
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
[constants_js_1.GET_TEST_PLAN_RUN]: async (params) => {
|
|
143
|
+
const args = params.arguments;
|
|
144
|
+
console.log('Getting test plan run with args:', args);
|
|
145
|
+
const response = await (0, http_request_js_1.sendHttpRequest)({
|
|
146
|
+
method: http_request_js_1.HttpMethods.GET,
|
|
147
|
+
url: `${constants_js_1.API_URL}/test-plans-runs/${args.id}`,
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
content: [{
|
|
151
|
+
type: 'text',
|
|
152
|
+
text: JSON.stringify(response, null, 2),
|
|
153
|
+
}],
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
[constants_js_1.GET_LABELS]: async (params) => {
|
|
157
|
+
const args = params.arguments;
|
|
158
|
+
console.log('Getting labels with args:', args);
|
|
159
|
+
const response = await (0, http_request_js_1.sendHttpRequest)({
|
|
160
|
+
method: http_request_js_1.HttpMethods.GET,
|
|
161
|
+
url: `${constants_js_1.API_URL}/labels`,
|
|
162
|
+
});
|
|
163
|
+
// drop the colors
|
|
164
|
+
const res = JSON.parse(response.text);
|
|
165
|
+
const labels = res.teamLabels.map(tl => {
|
|
166
|
+
return {
|
|
167
|
+
id: tl.id,
|
|
168
|
+
description: tl.description,
|
|
169
|
+
};
|
|
170
|
+
});
|
|
171
|
+
return {
|
|
172
|
+
content: [{
|
|
173
|
+
type: 'text',
|
|
174
|
+
text: JSON.stringify(labels, null, 2),
|
|
175
|
+
}],
|
|
176
|
+
};
|
|
177
|
+
},
|
|
178
|
+
[constants_js_1.VALIDATE_TEST_SUITE]: async (params) => {
|
|
179
|
+
const args = params.arguments || {};
|
|
180
|
+
const filePath = args.path;
|
|
181
|
+
if (!filePath || typeof filePath !== 'string') {
|
|
182
|
+
return {
|
|
183
|
+
content: [
|
|
184
|
+
{
|
|
185
|
+
type: 'text',
|
|
186
|
+
text: JSON.stringify({
|
|
187
|
+
valid: false,
|
|
188
|
+
error: 'Missing or invalid "path" argument',
|
|
189
|
+
}, null, 2),
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
const absPath = path_1.default.isAbsolute(filePath)
|
|
196
|
+
? filePath
|
|
197
|
+
: path_1.default.resolve(process.cwd(), filePath);
|
|
198
|
+
const raw = await fs_1.default.readFileSync(absPath);
|
|
199
|
+
let suite;
|
|
200
|
+
try {
|
|
201
|
+
suite = JSON.parse(raw.toString());
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
return {
|
|
205
|
+
content: [
|
|
206
|
+
{
|
|
207
|
+
type: 'text',
|
|
208
|
+
text: JSON.stringify({
|
|
209
|
+
valid: false,
|
|
210
|
+
error: `Failed parsing JSON: ${e?.message || e}`,
|
|
211
|
+
}, null, 2),
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
const schemaText = await (0, shared_js_1.getSchema)(constants_js_1.SCHEMA_TYPE.TEST_SUITE);
|
|
217
|
+
console.log('Fetched schema for test suite:', typeof schemaText);
|
|
218
|
+
let schema;
|
|
219
|
+
try {
|
|
220
|
+
schema = JSON.parse(schemaText);
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
console.error('Failed parsing schema JSON:', e);
|
|
224
|
+
return {
|
|
225
|
+
content: [
|
|
226
|
+
{
|
|
227
|
+
type: 'text',
|
|
228
|
+
text: JSON.stringify({
|
|
229
|
+
valid: false,
|
|
230
|
+
error: `Failed parsing schema JSON: ${e?.message || e}`,
|
|
231
|
+
}, null, 2),
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
console.log('Compiling schema for validation');
|
|
237
|
+
console.log('Schema:', schema);
|
|
238
|
+
const ajv = new _2020_1.default({ allErrors: true, strict: false });
|
|
239
|
+
(0, ajv_formats_1.default)(ajv);
|
|
240
|
+
// IMPORTANT: call on the INSTANCE
|
|
241
|
+
ajv.addMetaSchema(json_schema_draft_07_json_1.default);
|
|
242
|
+
let validateFn;
|
|
243
|
+
try {
|
|
244
|
+
validateFn = ajv.compile(schema);
|
|
245
|
+
}
|
|
246
|
+
catch (e) {
|
|
247
|
+
console.error('Failed compiling schema:', e);
|
|
248
|
+
return {
|
|
249
|
+
content: [
|
|
250
|
+
{
|
|
251
|
+
type: 'text',
|
|
252
|
+
text: JSON.stringify({
|
|
253
|
+
valid: false,
|
|
254
|
+
error: `Failed compiling schema: ${e?.message || e}`,
|
|
255
|
+
}, null, 2),
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
const valid = validateFn(suite);
|
|
261
|
+
if (valid) {
|
|
262
|
+
return {
|
|
263
|
+
content: [
|
|
264
|
+
{
|
|
265
|
+
type: 'text',
|
|
266
|
+
text: JSON.stringify({ valid: true }, null, 2),
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
const errors = (validateFn.errors || []).map((err) => ({
|
|
272
|
+
instancePath: err.instancePath,
|
|
273
|
+
keyword: err.keyword,
|
|
274
|
+
message: err.message,
|
|
275
|
+
params: err.params,
|
|
276
|
+
schemaPath: err.schemaPath,
|
|
277
|
+
}));
|
|
278
|
+
console.log('Validation errors found:', errors);
|
|
279
|
+
return {
|
|
280
|
+
content: [
|
|
281
|
+
{
|
|
282
|
+
type: 'text',
|
|
283
|
+
text: JSON.stringify({ valid: false, errors }, null, 2),
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
catch (err) {
|
|
289
|
+
return {
|
|
290
|
+
content: [
|
|
291
|
+
{
|
|
292
|
+
type: 'text',
|
|
293
|
+
text: JSON.stringify({
|
|
294
|
+
valid: false,
|
|
295
|
+
error: err?.message || String(err),
|
|
296
|
+
}, null, 2),
|
|
297
|
+
},
|
|
298
|
+
],
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/handlers/tools/tasks.ts"],"names":[],"mappings":";;;;;;AAAA,0DAAoC;AACpC,wGAA6D;AAC7D,8DAAqC;AAGrC,4CAAoB;AACpB,gDAAwB;AAExB,2DAAqE;AACrE,qDAa4B;AAC5B,6CAAkD;AAClD,4CAAyC;AAOzC,wDAAwD;AAC3C,QAAA,UAAU,GAAc;IACnC,CAAC,iCAAkB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,IAAI,CAAC,CAAC;QAEtD,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAe,EAAC;YACrC,MAAM,EAAE,6BAAW,CAAC,GAAG;YACvB,GAAG,EAAE,GAAG,sBAAO,cAAc;YAC7B,KAAK,EAAE;gBACL,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;gBACzB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;gBAC5B,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,EAAE;gBACzC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE;gBACrC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;aAC1B;SACF,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC,CAAC;SACH,CAAC;IACJ,CAAC;IACD,CAAC,qCAAsB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACzC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,sCAAsC,EAAE,IAAI,CAAC,CAAC;QAE1D,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAe,EAAC;YACrC,MAAM,EAAE,6BAAW,CAAC,GAAG;YACvB,GAAG,EAAE,GAAG,sBAAO,yBAAyB;YACxC,KAAK,EAAE;gBACL,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;gBACzB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;gBAC5B,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,EAAE;gBACzC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE;aACtC;SACF,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC,CAAC;SACH,CAAC;IACJ,CAAC;IACD,CAAC,6BAAc,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,IAAI,CAAC,CAAC;QAEnD,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAe,EAAC;YACrC,MAAM,EAAE,6BAAW,CAAC,IAAI;YACxB,GAAG,EAAE,GAAG,sBAAO,gBAAgB,IAAI,CAAC,EAAE,MAAM;SAC7C,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC,CAAC;SACH,CAAC;IACJ,CAAC;IACD,CAAC,iCAAkB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,IAAI,CAAC,CAAC;QAEvD,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAe,EAAC;YACrC,MAAM,EAAE,6BAAW,CAAC,GAAG;YACvB,GAAG,EAAE,GAAG,sBAAO,qBAAqB,IAAI,CAAC,EAAE,EAAE;SAC9C,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC,CAAC;SACH,CAAC;IACJ,CAAC;IACD,CAAC,sCAAuB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE,IAAI,CAAC,CAAC;QAE5D,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAe,EAAC;YACrC,MAAM,EAAE,6BAAW,CAAC,GAAG;YACvB,GAAG,EAAE,GAAG,sBAAO,2BAA2B,IAAI,CAAC,SAAS,EAAE;SAC3D,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC,CAAC;SACH,CAAC;IACJ,CAAC;IACD,CAAC,+BAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,IAAI,CAAC,CAAC;QAErD,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAe,EAAC;YACrC,MAAM,EAAE,6BAAW,CAAC,GAAG;YACvB,GAAG,EAAE,GAAG,sBAAO,aAAa;YAC5B,KAAK,EAAE;gBACL,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;gBACzB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;gBAC5B,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,EAAE;gBACzC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE;aACtC;SACF,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC,CAAC;SACH,CAAC;IACJ,CAAC;IACD,CAAC,4BAAa,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,IAAI,CAAC,CAAC;QAElD,yCAAyC;QACzC,MAAM,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,IAAI,IAAA,2BAAgB,EAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAChG,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,IAAA,2BAAgB,EAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAExE,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAe,EAAC;YACrC,MAAM,EAAE,6BAAW,CAAC,IAAI;YACxB,GAAG,EAAE,GAAG,sBAAO,eAAe,IAAI,CAAC,EAAE,MAAM;YAC3C,IAAI,EAAE;gBACJ,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;gBACzB,kBAAkB,EAAE,kBAAkB,IAAI,UAAU,IAAI,EAAE;aAC3D;SACF,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC,CAAC;SACH,CAAC;IACJ,CAAC;IACD,CAAC,gCAAiB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACpC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,IAAI,CAAC,CAAC;QAEtD,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAe,EAAC;YACrC,MAAM,EAAE,6BAAW,CAAC,GAAG;YACvB,GAAG,EAAE,GAAG,sBAAO,oBAAoB,IAAI,CAAC,EAAE,EAAE;SAC7C,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC,CAAC;SACH,CAAC;IACJ,CAAC;IACD,CAAC,yBAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,IAAI,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAe,EAAC;YACrC,MAAM,EAAE,6BAAW,CAAC,GAAG;YACvB,GAAG,EAAE,GAAG,sBAAO,SAAS;SACzB,CAAC,CAAC;QAEH,kBAAkB;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YACrC,OAAO;gBACL,EAAE,EAAE,EAAE,CAAC,EAAE;gBACT,WAAW,EAAE,EAAE,CAAC,WAAW;aAC5B,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBACtC,CAAC;SACH,CAAC;IACJ,CAAC;IACD,CAAC,kCAAmB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAA0B,CAAC;QAEjD,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;YAC7C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,KAAK,EAAE,KAAK;4BACZ,KAAK,EAAE,oCAAoC;yBAC5C,EAAE,IAAI,EAAE,CAAC,CAAC;qBACZ;iBACF;aACF,CAAC;SACH;QAED,IAAI;YACF,MAAM,OAAO,GAAG,cAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBACvC,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;YAE1C,MAAM,GAAG,GAAG,MAAM,YAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,KAAU,CAAC;YACf,IAAI;gBACF,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;aACpC;YAAC,OAAO,CAAM,EAAE;gBACf,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,KAAK,EAAE,KAAK;gCACZ,KAAK,EAAE,wBAAwB,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE;6BACjD,EAAE,IAAI,EAAE,CAAC,CAAC;yBACZ;qBACF;iBACF,CAAC;aACH;YAED,MAAM,UAAU,GAAG,MAAM,IAAA,qBAAS,EAAC,0BAAW,CAAC,UAAU,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,OAAO,UAAU,CAAC,CAAC;YACjE,IAAI,MAAW,CAAC;YAChB,IAAI;gBACF,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;aACjC;YAAC,OAAO,CAAM,EAAE;gBACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC,CAAC,CAAC;gBAChD,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,KAAK,EAAE,KAAK;gCACZ,KAAK,EAAE,+BAA+B,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE;6BACxD,EAAE,IAAI,EAAE,CAAC,CAAC;yBACZ;qBACF;iBACF,CAAC;aACH;YAED,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,eAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5D,IAAA,qBAAU,EAAC,GAAG,CAAC,CAAC;YAEhB,kCAAkC;YAClC,GAAG,CAAC,aAAa,CAAC,mCAAa,CAAC,CAAC;YAEjC,IAAI,UAAU,CAAC;YACf,IAAI;gBACF,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;aAClC;YAAC,OAAO,CAAM,EAAE;gBACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,CAAC,CAAC,CAAC;gBAC7C,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,KAAK,EAAE,KAAK;gCACZ,KAAK,EAAE,4BAA4B,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE;6BACrD,EAAE,IAAI,EAAE,CAAC,CAAC;yBACZ;qBACF;iBACF,CAAC;aACH;YAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAY,CAAC;YAC3C,IAAI,KAAK,EAAE;gBACT,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;yBAC/C;qBACF;iBACF,CAAC;aACH;YAED,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBACrD,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,UAAU,EAAE,GAAG,CAAC,UAAU;aAC3B,CAAC,CAAC,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAC;YAEhD,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;qBACxD;iBACF;aACF,CAAC;SACH;QAAC,OAAO,GAAQ,EAAE;YACjB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,KAAK,EAAE,KAAK;4BACZ,KAAK,EAAE,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC;yBACnC,EAAE,IAAI,EAAE,CAAC,CAAC;qBACZ;iBACF;aACF,CAAC;SACH;IACH,CAAC;CACF,CAAC"}
|
package/dist/http-request.js
CHANGED
|
@@ -13,10 +13,8 @@ const sendHttpRequest = async (options) => {
|
|
|
13
13
|
return await _executeRequest(options);
|
|
14
14
|
}
|
|
15
15
|
catch (err) {
|
|
16
|
-
// eslint-disable-next-line no-console
|
|
17
16
|
console.error(`Error during ${(options.method || HttpMethods.GET).toUpperCase()} request to ${options.url}:`, err);
|
|
18
17
|
if (_shouldRetry(err)) {
|
|
19
|
-
// eslint-disable-next-line no-console
|
|
20
18
|
console.log(`Retrying ${(options.method || HttpMethods.GET).toUpperCase()} request to ${options.url}...`);
|
|
21
19
|
await _delay(RETRY_DELAY_MS);
|
|
22
20
|
return await _executeRequest(options);
|
package/dist/http-request.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-request.js","sourceRoot":"","sources":["../src/http-request.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAoC;AAEpC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,KAAK,CAAC,CAAC,aAAa;AAC/E,MAAM,cAAc,GAAG,IAAI,CAAC,CAAC,WAAW;AACxC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;AAEnD,MAAM,eAAe,GAAG,KAAK,EAAE,OAA2B,EAAE,EAAE;IACnE,IAAI;QACF,OAAO,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;KACvC;IACD,OAAO,GAAG,EAAE;QACV,
|
|
1
|
+
{"version":3,"file":"http-request.js","sourceRoot":"","sources":["../src/http-request.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAoC;AAEpC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,KAAK,CAAC,CAAC,aAAa;AAC/E,MAAM,cAAc,GAAG,IAAI,CAAC,CAAC,WAAW;AACxC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;AAEnD,MAAM,eAAe,GAAG,KAAK,EAAE,OAA2B,EAAE,EAAE;IACnE,IAAI;QACF,OAAO,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;KACvC;IACD,OAAO,GAAG,EAAE;QACV,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,eAAe,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;QACnH,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE;YACrB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,eAAe,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;YAC1G,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAC7B,OAAO,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;SACvC;QACD,MAAM,GAAG,CAAC;KACX;AACH,CAAC,CAAC;AAbW,QAAA,eAAe,mBAa1B;AAEF,MAAM,eAAe,GAAG,KAAK,EAAE,OAA2B,EAAE,EAAE;IAC5D,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAC/D,IAAI,OAAO,GAAG,oBAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC;SAClC,IAAI,CAAC,kBAAkB,CAAC;SACxB,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/B,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAE/D,IAAI,IAAI,EAAE;QACR,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC9B;IAED,OAAO,MAAM,OAAO,CAAC;AACvB,CAAC,CAAC;AAEF,0BAA0B;AAC1B,MAAM,YAAY,GAAG,CAAC,GAAG,EAAW,EAAE;IACpC,OAAO,GAAG,CAAC,OAAO;QAChB,GAAG,CAAC,IAAI,KAAK,cAAc;QAC3B,GAAG,CAAC,IAAI,KAAK,cAAc;QAC3B,GAAG,CAAC,IAAI,KAAK,WAAW;QACxB,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC;AAC9B,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAS/E,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,0BAAW,CAAA;IACX,4BAAa,CAAA;IACb,0BAAW,CAAA;IACX,gCAAiB,CAAA;IACjB,8BAAe,CAAA;AACjB,CAAC,EANW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAMtB"}
|
package/dist/index.js
CHANGED
|
@@ -4,11 +4,9 @@ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
|
4
4
|
const mcp_server_1 = require("./mcp-server");
|
|
5
5
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
6
6
|
transport.onmessage = async (message) => {
|
|
7
|
-
// eslint-disable-next-line no-console
|
|
8
7
|
console.error('Loadmill MCP:\n' + JSON.stringify(message, null, 2));
|
|
9
8
|
};
|
|
10
9
|
transport.onerror = async (error) => {
|
|
11
|
-
// eslint-disable-next-line no-console
|
|
12
10
|
console.error('Loadmill MCP Error:\n' + JSON.stringify(error, null, 2));
|
|
13
11
|
};
|
|
14
12
|
exports.default = async () => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AACA,wEAAiF;AACjF,6CAAyC;AAEzC,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;AAE7C,SAAS,CAAC,SAAS,GAAG,KAAK,EAAE,OAAO,EAAE,EAAE;IACtC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AACA,wEAAiF;AACjF,6CAAyC;AAEzC,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;AAE7C,SAAS,CAAC,SAAS,GAAG,KAAK,EAAE,OAAO,EAAE,EAAE;IACtC,OAAO,CAAC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF,SAAS,CAAC,OAAO,GAAG,KAAK,EAAE,KAAK,EAAE,EAAE;IAClC,OAAO,CAAC,KAAK,CAAC,uBAAuB,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC,CAAC;AAGF,kBAAe,KAAK,IAAI,EAAE;IACxB,MAAM,sBAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACrC,CAAC,CAAC"}
|
package/dist/mcp-handler.js
CHANGED
|
@@ -1,258 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handlers = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const utils_js_1 = require("./utils.js");
|
|
4
|
+
const tools_1 = require("./handlers/tools");
|
|
5
|
+
const prompts_1 = require("./handlers/prompts");
|
|
6
|
+
const resources_1 = require("./handlers/resources");
|
|
8
7
|
exports.handlers = [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const tools = [
|
|
13
|
-
{
|
|
14
|
-
name: constants_js_1.SEARCH_TEST_SUITES,
|
|
15
|
-
title: 'Search Test Suites',
|
|
16
|
-
description: 'A tool to search for Loadmill test suites. Returns a list of test suites',
|
|
17
|
-
inputSchema: {
|
|
18
|
-
type: 'object',
|
|
19
|
-
properties: {
|
|
20
|
-
search: {
|
|
21
|
-
type: 'string',
|
|
22
|
-
description: 'free text filter to search for test suites',
|
|
23
|
-
},
|
|
24
|
-
page: {
|
|
25
|
-
type: 'integer',
|
|
26
|
-
description: 'page number for pagination',
|
|
27
|
-
},
|
|
28
|
-
labels: {
|
|
29
|
-
type: 'array',
|
|
30
|
-
items: {
|
|
31
|
-
type: 'string',
|
|
32
|
-
description: 'filter suites that have flows with these labels',
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: constants_js_1.SEARCH_TEST_SUITE_RUNS,
|
|
40
|
-
title: 'Search Test Suite Runs',
|
|
41
|
-
description: 'A tool to search for Loadmill test suite runs. Returns a list of test suite runs',
|
|
42
|
-
inputSchema: {
|
|
43
|
-
type: 'object',
|
|
44
|
-
properties: {
|
|
45
|
-
search: {
|
|
46
|
-
type: 'string',
|
|
47
|
-
description: 'free text filter to search for test suites',
|
|
48
|
-
},
|
|
49
|
-
page: {
|
|
50
|
-
type: 'integer',
|
|
51
|
-
description: 'page number for pagination',
|
|
52
|
-
},
|
|
53
|
-
labels: {
|
|
54
|
-
type: 'array',
|
|
55
|
-
items: {
|
|
56
|
-
type: 'string',
|
|
57
|
-
description: 'filter suites that have flows with these labels',
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
name: constants_js_1.RUN_TEST_SUITE,
|
|
65
|
-
title: 'Run Test Suite',
|
|
66
|
-
description: 'A tool to run a Loadmill test suite. Returns the id of the running suite',
|
|
67
|
-
inputSchema: {
|
|
68
|
-
type: 'object',
|
|
69
|
-
properties: {
|
|
70
|
-
id: {
|
|
71
|
-
type: 'string',
|
|
72
|
-
description: 'ID of the test suite to run',
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
name: constants_js_1.GET_TEST_SUITE_RUN,
|
|
79
|
-
title: 'Get Test Suite Run',
|
|
80
|
-
description: `A tool to get a Loadmill test suite run by its ID.
|
|
81
|
-
Returns the run details including the testSuiteFlowRuns list that can be fetched later and is useful for understanding the flow of the test run.`,
|
|
82
|
-
inputSchema: {
|
|
83
|
-
type: 'object',
|
|
84
|
-
properties: {
|
|
85
|
-
id: {
|
|
86
|
-
type: 'string',
|
|
87
|
-
description: 'ID of the test suite run to fetch',
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
name: constants_js_1.GET_TEST_SUITE_FLOW_RUN,
|
|
94
|
-
title: 'Get Test Suite Flow Run',
|
|
95
|
-
description: `A tool to get a Loadmill test suite flow run by its ID.
|
|
96
|
-
Returns the run details. Use this when investigating the test run results.`,
|
|
97
|
-
inputSchema: {
|
|
98
|
-
type: 'object',
|
|
99
|
-
properties: {
|
|
100
|
-
flowRunId: {
|
|
101
|
-
type: 'string',
|
|
102
|
-
description: 'ID of the test suite flow run to fetch',
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
name: constants_js_1.SEARCH_TEST_PLAN,
|
|
109
|
-
title: 'Search Test Plans',
|
|
110
|
-
description: 'A tool to search for Loadmill test plans. Returns a list of test plans with their descriptions (names) and the author\'s information.',
|
|
111
|
-
inputSchema: {
|
|
112
|
-
type: 'object',
|
|
113
|
-
properties: {
|
|
114
|
-
search: {
|
|
115
|
-
type: 'string',
|
|
116
|
-
description: 'free text filter to search for test suites',
|
|
117
|
-
},
|
|
118
|
-
page: {
|
|
119
|
-
type: 'integer',
|
|
120
|
-
description: 'page number for pagination',
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
name: constants_js_1.RUN_TEST_PLAN,
|
|
127
|
-
title: 'Run a Test Plan',
|
|
128
|
-
description: 'A tool to run a Loadmill test plan. Returns the id of the running plan',
|
|
129
|
-
inputSchema: {
|
|
130
|
-
type: 'object',
|
|
131
|
-
properties: {
|
|
132
|
-
id: {
|
|
133
|
-
type: 'string',
|
|
134
|
-
description: 'ID of the test plan to run',
|
|
135
|
-
},
|
|
136
|
-
labels: {
|
|
137
|
-
type: 'array',
|
|
138
|
-
items: {
|
|
139
|
-
type: 'string',
|
|
140
|
-
description: 'filter suites that have flows with these labels',
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
overrideParameters: {
|
|
144
|
-
type: 'string',
|
|
145
|
-
description: `Parameters to override in the test plan.
|
|
146
|
-
A string of comma separated list of key-value pairs, e.g. "param1=value1,param2=value2".`,
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
name: constants_js_1.GET_TEST_PLAN_RUN,
|
|
153
|
-
title: 'Get Test Plan Run',
|
|
154
|
-
description: 'A tool to get a Loadmill test plan run by its ID. Returns the run details.',
|
|
155
|
-
inputSchema: {
|
|
156
|
-
type: 'object',
|
|
157
|
-
properties: {
|
|
158
|
-
id: {
|
|
159
|
-
type: 'string',
|
|
160
|
-
description: 'ID of the test plan run to fetch',
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
name: constants_js_1.GET_LABELS,
|
|
167
|
-
title: 'Get Labels',
|
|
168
|
-
description: 'A tool to fetch all available labels in Loadmill.',
|
|
169
|
-
inputSchema: {
|
|
170
|
-
type: 'object',
|
|
171
|
-
properties: {},
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
];
|
|
175
|
-
return { tools };
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
schema: types_js_1.CallToolRequestSchema,
|
|
180
|
-
handler: async (request) => {
|
|
181
|
-
if (!constants_js_1.AVALIABLE_TOOLS.includes(request.params.name)) {
|
|
182
|
-
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
|
|
183
|
-
}
|
|
184
|
-
const tool = tools_js_1.toolsTasks[request.params.name];
|
|
185
|
-
if (!tool) {
|
|
186
|
-
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
|
|
187
|
-
}
|
|
188
|
-
return await tool(request.params);
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
schema: types_js_1.ListPromptsRequestSchema,
|
|
193
|
-
handler: async (_request) => {
|
|
194
|
-
return { prompts };
|
|
195
|
-
},
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
schema: types_js_1.GetPromptRequestSchema,
|
|
199
|
-
handler: async (req) => {
|
|
200
|
-
const { name, arguments: args = {} } = req.params;
|
|
201
|
-
const prompt = prompts.find((p) => p.name === name);
|
|
202
|
-
if (!prompt) {
|
|
203
|
-
throw new Error(`Unknown prompt: ${name}`);
|
|
204
|
-
}
|
|
205
|
-
const required = (prompt.inputSchema?.required ?? []);
|
|
206
|
-
const missing = required.filter((k) => args[k] === undefined);
|
|
207
|
-
if (missing.length) {
|
|
208
|
-
throw new Error(`Missing required prompt arguments: ${missing.join(', ')}`);
|
|
209
|
-
}
|
|
210
|
-
const messages = prompt.messages.map((m) => ({
|
|
211
|
-
role: m.role,
|
|
212
|
-
content: (0, utils_js_1.fillTemplate)(m.content, args),
|
|
213
|
-
}));
|
|
214
|
-
return { messages };
|
|
215
|
-
},
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
schema: types_js_1.ListResourcesRequestSchema,
|
|
219
|
-
handler: async (_request) => {
|
|
220
|
-
// Handle the request
|
|
221
|
-
},
|
|
222
|
-
},
|
|
223
|
-
{
|
|
224
|
-
schema: types_js_1.ReadResourceRequestSchema,
|
|
225
|
-
handler: async (_request) => {
|
|
226
|
-
// Handle the request
|
|
227
|
-
},
|
|
228
|
-
},
|
|
229
|
-
];
|
|
230
|
-
const prompts = [
|
|
231
|
-
{
|
|
232
|
-
name: 'investigate_failed_test',
|
|
233
|
-
description: 'Analyze failed test results and suggest next steps',
|
|
234
|
-
messages: [
|
|
235
|
-
{
|
|
236
|
-
role: 'system',
|
|
237
|
-
content: 'You are a QA investigator. Explain failures clearly and suggest next steps.',
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
role: 'user',
|
|
241
|
-
content: `The test '{{test_description}}' has failed.\n\n
|
|
242
|
-
Result:\n{{result}}\n\n
|
|
243
|
-
RedactableResult (extended data):\n{{redactableResult}}\n\n
|
|
244
|
-
Please explain the cause and suggest how to fix it.`,
|
|
245
|
-
},
|
|
246
|
-
],
|
|
247
|
-
inputSchema: {
|
|
248
|
-
type: 'object',
|
|
249
|
-
properties: {
|
|
250
|
-
test_description: { type: 'string' },
|
|
251
|
-
result: { type: 'string' },
|
|
252
|
-
redactableResult: { type: 'string' },
|
|
253
|
-
},
|
|
254
|
-
required: ['test_description', 'result', 'redactableResult'],
|
|
255
|
-
},
|
|
256
|
-
},
|
|
8
|
+
...tools_1.handlers,
|
|
9
|
+
...prompts_1.handlers,
|
|
10
|
+
...resources_1.handlers,
|
|
257
11
|
];
|
|
258
12
|
//# sourceMappingURL=mcp-handler.js.map
|
package/dist/mcp-handler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-handler.js","sourceRoot":"","sources":["../src/mcp-handler.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"mcp-handler.js","sourceRoot":"","sources":["../src/mcp-handler.ts"],"names":[],"mappings":";;;AAAA,4CAA6D;AAC7D,gDAAiE;AACjE,oDAAqE;AAOxD,QAAA,QAAQ,GAAiB;IACpC,GAAG,gBAAa;IAChB,GAAG,kBAAe;IAClB,GAAG,oBAAiB;CACrB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loadmill/mcp",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Loadmill mcp library",
|
|
5
5
|
"main": "dist/",
|
|
6
6
|
"module": "src/",
|
|
@@ -19,6 +19,19 @@
|
|
|
19
19
|
"license": "Apache-2.0",
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@modelcontextprotocol/sdk": "^1.17.2",
|
|
22
|
+
"ajv": "^8.17.1",
|
|
23
|
+
"ajv-formats": "^3.0.1",
|
|
22
24
|
"superagent": "^10.0.1"
|
|
23
|
-
}
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"mcp",
|
|
28
|
+
"loadmill",
|
|
29
|
+
"model-context-protocol",
|
|
30
|
+
"testing",
|
|
31
|
+
"automation",
|
|
32
|
+
"ai",
|
|
33
|
+
"llm",
|
|
34
|
+
"agent",
|
|
35
|
+
"cli"
|
|
36
|
+
]
|
|
24
37
|
}
|