@qualitas-id/mcp 1.0.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/LICENSE +21 -0
- package/README.md +262 -0
- package/dist/constants.d.ts +18 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +18 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/common.d.ts +20 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +10 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/flow.d.ts +358 -0
- package/dist/schemas/flow.d.ts.map +1 -0
- package/dist/schemas/flow.js +72 -0
- package/dist/schemas/flow.js.map +1 -0
- package/dist/schemas/project.d.ts +70 -0
- package/dist/schemas/project.d.ts.map +1 -0
- package/dist/schemas/project.js +26 -0
- package/dist/schemas/project.js.map +1 -0
- package/dist/schemas/run.d.ts +54 -0
- package/dist/schemas/run.d.ts.map +1 -0
- package/dist/schemas/run.js +20 -0
- package/dist/schemas/run.js.map +1 -0
- package/dist/schemas/variable.d.ts +91 -0
- package/dist/schemas/variable.d.ts.map +1 -0
- package/dist/schemas/variable.js +30 -0
- package/dist/schemas/variable.js.map +1 -0
- package/dist/services/api-client.d.ts +101 -0
- package/dist/services/api-client.d.ts.map +1 -0
- package/dist/services/api-client.js +184 -0
- package/dist/services/api-client.js.map +1 -0
- package/dist/services/flow-generator.d.ts +31 -0
- package/dist/services/flow-generator.d.ts.map +1 -0
- package/dist/services/flow-generator.js +638 -0
- package/dist/services/flow-generator.js.map +1 -0
- package/dist/shared-types.d.ts +579 -0
- package/dist/shared-types.d.ts.map +1 -0
- package/dist/shared-types.js +12 -0
- package/dist/shared-types.js.map +1 -0
- package/dist/tools/flows.d.ts +13 -0
- package/dist/tools/flows.d.ts.map +1 -0
- package/dist/tools/flows.js +458 -0
- package/dist/tools/flows.js.map +1 -0
- package/dist/tools/projects.d.ts +13 -0
- package/dist/tools/projects.d.ts.map +1 -0
- package/dist/tools/projects.js +381 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/runs.d.ts +9 -0
- package/dist/tools/runs.d.ts.map +1 -0
- package/dist/tools/runs.js +342 -0
- package/dist/tools/runs.js.map +1 -0
- package/dist/tools/utils.d.ts +12 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +144 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/tools/variables.d.ts +9 -0
- package/dist/tools/variables.d.ts.map +1 -0
- package/dist/tools/variables.js +316 -0
- package/dist/tools/variables.js.map +1 -0
- package/dist/types.d.ts +117 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/flow-layout.d.ts +34 -0
- package/dist/utils/flow-layout.d.ts.map +1 -0
- package/dist/utils/flow-layout.js +109 -0
- package/dist/utils/flow-layout.js.map +1 -0
- package/dist/utils/flow-validation.d.ts +74 -0
- package/dist/utils/flow-validation.d.ts.map +1 -0
- package/dist/utils/flow-validation.js +386 -0
- package/dist/utils/flow-validation.js.map +1 -0
- package/dist/utils/ocr.d.ts +25 -0
- package/dist/utils/ocr.d.ts.map +1 -0
- package/dist/utils/ocr.js +88 -0
- package/dist/utils/ocr.js.map +1 -0
- package/package.json +65 -0
- package/skills/qualitas.md +253 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qualitas MCP Server - Run Tools
|
|
3
|
+
*
|
|
4
|
+
* Tools for triggering flow execution, checking run status, and listing run history.
|
|
5
|
+
*/
|
|
6
|
+
import { handleApiError } from "../services/api-client.js";
|
|
7
|
+
import { RunFlowSchema, GetRunStatusSchema, ListRunsSchema, } from "../schemas/run.js";
|
|
8
|
+
import { APP_URL } from "../constants.js";
|
|
9
|
+
// ===========================================
|
|
10
|
+
// Helpers
|
|
11
|
+
// ===========================================
|
|
12
|
+
const STATUS_ICON = {
|
|
13
|
+
passed: "✅",
|
|
14
|
+
failed: "❌",
|
|
15
|
+
running: "🔄",
|
|
16
|
+
pending: "⏳",
|
|
17
|
+
error: "⚠️",
|
|
18
|
+
cancelled: "🚫",
|
|
19
|
+
};
|
|
20
|
+
function statusIcon(status) {
|
|
21
|
+
return STATUS_ICON[status] ?? "❓";
|
|
22
|
+
}
|
|
23
|
+
function formatDuration(ms) {
|
|
24
|
+
if (ms == null)
|
|
25
|
+
return "N/A";
|
|
26
|
+
if (ms < 1000)
|
|
27
|
+
return `${ms}ms`;
|
|
28
|
+
const seconds = (ms / 1000).toFixed(1);
|
|
29
|
+
return `${seconds}s`;
|
|
30
|
+
}
|
|
31
|
+
function formatRunMarkdown(run) {
|
|
32
|
+
const icon = statusIcon(run.status);
|
|
33
|
+
const lines = [];
|
|
34
|
+
lines.push(`## ${icon} Run \`${run.id}\``);
|
|
35
|
+
lines.push("");
|
|
36
|
+
lines.push(`- **Status:** ${run.status}`);
|
|
37
|
+
lines.push(`- **Flow ID:** \`${run.flow_id}\``);
|
|
38
|
+
if (run.environment)
|
|
39
|
+
lines.push(`- **Environment:** ${run.environment}`);
|
|
40
|
+
lines.push(`- **Duration:** ${formatDuration(run.duration_ms)}`);
|
|
41
|
+
lines.push(`- **Executed at:** ${run.executed_at}`);
|
|
42
|
+
if (run.executed_by)
|
|
43
|
+
lines.push(`- **Executed by:** ${run.executed_by}`);
|
|
44
|
+
if (run.steps_total != null) {
|
|
45
|
+
lines.push("");
|
|
46
|
+
lines.push("### Step Results");
|
|
47
|
+
lines.push("");
|
|
48
|
+
lines.push(`- **Total:** ${run.steps_total}`);
|
|
49
|
+
lines.push(`- **Passed:** ${run.steps_passed ?? 0}`);
|
|
50
|
+
lines.push(`- **Failed:** ${run.steps_failed ?? 0}`);
|
|
51
|
+
}
|
|
52
|
+
// Display step details from run_steps table (preferred) or steps_result (fallback)
|
|
53
|
+
const steps = run.steps && run.steps.length > 0
|
|
54
|
+
? run.steps
|
|
55
|
+
: (run.steps_result && Array.isArray(run.steps_result) && run.steps_result.length > 0)
|
|
56
|
+
? run.steps_result
|
|
57
|
+
: [];
|
|
58
|
+
if (steps.length > 0) {
|
|
59
|
+
lines.push("");
|
|
60
|
+
lines.push("### Step Details");
|
|
61
|
+
lines.push("");
|
|
62
|
+
lines.push("| # | Step | Type | Status | Duration | Log |");
|
|
63
|
+
lines.push("|---|------|------|--------|----------|-----|");
|
|
64
|
+
for (const step of steps) {
|
|
65
|
+
const idx = step.sequenceOrder ?? "?";
|
|
66
|
+
const name = step.nodeId ?? "unknown";
|
|
67
|
+
const type = step.type ?? "unknown";
|
|
68
|
+
const stepStatus = statusIcon(step.status);
|
|
69
|
+
const dur = formatDuration(step.durationMs);
|
|
70
|
+
const log = step.logs
|
|
71
|
+
? (step.logs.length > 60 ? step.logs.substring(0, 57) + "..." : step.logs)
|
|
72
|
+
: (step.errorMessage ? `❌ ${step.errorMessage}` : "-");
|
|
73
|
+
lines.push(`| ${idx} | ${name} | ${type} | ${stepStatus} | ${dur} | ${log} |`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (run.video_url) {
|
|
77
|
+
lines.push("");
|
|
78
|
+
lines.push(`- **Video:** ${run.video_url}`);
|
|
79
|
+
}
|
|
80
|
+
return lines.join("\n");
|
|
81
|
+
}
|
|
82
|
+
function formatRunsTableMarkdown(runs, projectId, flowId) {
|
|
83
|
+
if (runs.length === 0) {
|
|
84
|
+
return "No runs found for this flow.";
|
|
85
|
+
}
|
|
86
|
+
const lines = [];
|
|
87
|
+
lines.push("## Run History");
|
|
88
|
+
lines.push("");
|
|
89
|
+
lines.push("| Status | Run ID | Environment | Duration | Executed At |");
|
|
90
|
+
lines.push("|--------|--------|-------------|----------|-------------|");
|
|
91
|
+
for (const run of runs) {
|
|
92
|
+
const icon = statusIcon(run.status);
|
|
93
|
+
const env = run.environment ?? "-";
|
|
94
|
+
const dur = formatDuration(run.duration_ms);
|
|
95
|
+
const shortId = run.id.length > 8 ? run.id.slice(0, 8) + "…" : run.id;
|
|
96
|
+
lines.push(`| ${icon} ${run.status} | \`${shortId}\` | ${env} | ${dur} | ${run.executed_at} |`);
|
|
97
|
+
}
|
|
98
|
+
lines.push("");
|
|
99
|
+
lines.push(`> View full run history: [${APP_URL}/projects/${projectId}/flows/${flowId}](${APP_URL}/projects/${projectId}/flows/${flowId})`);
|
|
100
|
+
return lines.join("\n");
|
|
101
|
+
}
|
|
102
|
+
// ===========================================
|
|
103
|
+
// Tool Registration
|
|
104
|
+
// ===========================================
|
|
105
|
+
export function registerRunTools(server, apiClient) {
|
|
106
|
+
// ------------------------------------------
|
|
107
|
+
// 1. qualitas_run_flow
|
|
108
|
+
// ------------------------------------------
|
|
109
|
+
server.registerTool("run_flow", {
|
|
110
|
+
title: "Run Flow",
|
|
111
|
+
description: [
|
|
112
|
+
"Trigger a flow execution on the Qualitas test automation platform.",
|
|
113
|
+
"",
|
|
114
|
+
"**Arguments:**",
|
|
115
|
+
"- `project_id` (UUID, required): The project containing the flow.",
|
|
116
|
+
"- `flow_id` (UUID, required): The flow to execute.",
|
|
117
|
+
"- `environment` (\"dev\" | \"staging\" | \"prod\", optional): Override the flow's default environment for this run.",
|
|
118
|
+
"- `headless` (boolean, default `true`): Whether to run the browser in headless mode.",
|
|
119
|
+
"",
|
|
120
|
+
"**Returns:**",
|
|
121
|
+
"- Markdown with the run ID, initial status, and a link to monitor execution.",
|
|
122
|
+
"- The run executes asynchronously — use `get_run_status` to poll for completion.",
|
|
123
|
+
"",
|
|
124
|
+
"**Example:**",
|
|
125
|
+
"```",
|
|
126
|
+
'qualitas_run_flow({ project_id: "abc-123", flow_id: "def-456", environment: "staging" })',
|
|
127
|
+
"```",
|
|
128
|
+
"",
|
|
129
|
+
"**Errors:**",
|
|
130
|
+
"- 404: Project or flow not found.",
|
|
131
|
+
"- 422: Flow has no nodes or is misconfigured.",
|
|
132
|
+
"- 401: Invalid or expired API key.",
|
|
133
|
+
].join("\n"),
|
|
134
|
+
inputSchema: RunFlowSchema.shape,
|
|
135
|
+
annotations: {
|
|
136
|
+
title: "Run Flow",
|
|
137
|
+
readOnlyHint: false,
|
|
138
|
+
destructiveHint: false,
|
|
139
|
+
idempotentHint: false,
|
|
140
|
+
openWorldHint: true,
|
|
141
|
+
},
|
|
142
|
+
}, async (args) => {
|
|
143
|
+
try {
|
|
144
|
+
const response = await apiClient.runFlow(args.project_id, args.flow_id, {
|
|
145
|
+
environment: args.environment,
|
|
146
|
+
headless: args.headless,
|
|
147
|
+
});
|
|
148
|
+
const run = response.data;
|
|
149
|
+
const lines = [];
|
|
150
|
+
lines.push(`## 🚀 Flow Execution Started`);
|
|
151
|
+
lines.push("");
|
|
152
|
+
lines.push(`- **Run ID:** \`${run.id}\``);
|
|
153
|
+
lines.push(`- **Flow ID:** \`${run.flow_id}\``);
|
|
154
|
+
lines.push(`- **Status:** ${statusIcon(run.status)} ${run.status}`);
|
|
155
|
+
if (run.environment)
|
|
156
|
+
lines.push(`- **Environment:** ${run.environment}`);
|
|
157
|
+
lines.push("");
|
|
158
|
+
lines.push(`> Monitor progress: [${APP_URL}/projects/${args.project_id}/flows/${args.flow_id}/runs/${run.id}](${APP_URL}/projects/${args.project_id}/flows/${args.flow_id}/runs/${run.id})`);
|
|
159
|
+
lines.push("");
|
|
160
|
+
lines.push("Use `get_run_status` with this run ID to check execution results.");
|
|
161
|
+
return {
|
|
162
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
return {
|
|
167
|
+
content: [{ type: "text", text: handleApiError(error) }],
|
|
168
|
+
isError: true,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
// ------------------------------------------
|
|
173
|
+
// 2. qualitas_get_run_status
|
|
174
|
+
// ------------------------------------------
|
|
175
|
+
server.registerTool("get_run_status", {
|
|
176
|
+
title: "Get Run Status",
|
|
177
|
+
description: [
|
|
178
|
+
"Get the status and results of a flow run.",
|
|
179
|
+
"",
|
|
180
|
+
"**Arguments:**",
|
|
181
|
+
"- `project_id` (UUID, required): The project containing the flow.",
|
|
182
|
+
"- `flow_id` (UUID, required): The flow that was executed.",
|
|
183
|
+
"- `run_id` (UUID, required): The run to check.",
|
|
184
|
+
"- `response_format` (\"markdown\" | \"json\", default \"markdown\"): Output format.",
|
|
185
|
+
"",
|
|
186
|
+
"**Returns (markdown):**",
|
|
187
|
+
"- Run status, duration, step pass/fail counts, and a detailed step results table.",
|
|
188
|
+
"",
|
|
189
|
+
"**Returns (json):**",
|
|
190
|
+
"```json",
|
|
191
|
+
'{',
|
|
192
|
+
' "id": "run-uuid",',
|
|
193
|
+
' "flow_id": "flow-uuid",',
|
|
194
|
+
' "status": "passed",',
|
|
195
|
+
' "environment": "dev",',
|
|
196
|
+
' "duration_ms": 4523,',
|
|
197
|
+
' "steps_total": 5,',
|
|
198
|
+
' "steps_passed": 5,',
|
|
199
|
+
' "steps_failed": 0,',
|
|
200
|
+
' "steps_result": [...],',
|
|
201
|
+
' "video_url": "https://...",',
|
|
202
|
+
' "executed_at": "2025-01-15T10:30:00Z"',
|
|
203
|
+
'}',
|
|
204
|
+
"```",
|
|
205
|
+
"",
|
|
206
|
+
"**Example:**",
|
|
207
|
+
"```",
|
|
208
|
+
'qualitas_get_run_status({ project_id: "abc-123", flow_id: "def-456", run_id: "ghi-789" })',
|
|
209
|
+
"```",
|
|
210
|
+
"",
|
|
211
|
+
"**Errors:**",
|
|
212
|
+
"- 404: Project, flow, or run not found.",
|
|
213
|
+
"- 401: Invalid or expired API key.",
|
|
214
|
+
].join("\n"),
|
|
215
|
+
inputSchema: GetRunStatusSchema.shape,
|
|
216
|
+
annotations: {
|
|
217
|
+
title: "Get Run Status",
|
|
218
|
+
readOnlyHint: true,
|
|
219
|
+
destructiveHint: false,
|
|
220
|
+
idempotentHint: true,
|
|
221
|
+
openWorldHint: true,
|
|
222
|
+
},
|
|
223
|
+
}, async (args) => {
|
|
224
|
+
try {
|
|
225
|
+
// Fetch run details and step details in parallel
|
|
226
|
+
const [runResponse, stepsResponse] = await Promise.all([
|
|
227
|
+
apiClient.getRunStatus(args.project_id, args.flow_id, args.run_id),
|
|
228
|
+
apiClient.getRunSteps(args.run_id),
|
|
229
|
+
]);
|
|
230
|
+
const run = runResponse.data;
|
|
231
|
+
const steps = stepsResponse.data || [];
|
|
232
|
+
// Merge steps into run object
|
|
233
|
+
const enrichedRun = {
|
|
234
|
+
...run,
|
|
235
|
+
steps,
|
|
236
|
+
};
|
|
237
|
+
if (args.response_format === "json") {
|
|
238
|
+
return {
|
|
239
|
+
content: [{ type: "text", text: JSON.stringify(enrichedRun, null, 2) }],
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
content: [{ type: "text", text: formatRunMarkdown(enrichedRun) }],
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
return {
|
|
248
|
+
content: [{ type: "text", text: handleApiError(error) }],
|
|
249
|
+
isError: true,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
// ------------------------------------------
|
|
254
|
+
// 3. qualitas_list_runs
|
|
255
|
+
// ------------------------------------------
|
|
256
|
+
server.registerTool("list_runs", {
|
|
257
|
+
title: "List Runs",
|
|
258
|
+
description: [
|
|
259
|
+
"List the execution history for a flow, ordered by most recent first.",
|
|
260
|
+
"",
|
|
261
|
+
"**Arguments:**",
|
|
262
|
+
"- `project_id` (UUID, required): The project containing the flow.",
|
|
263
|
+
"- `flow_id` (UUID, required): The flow whose runs to list.",
|
|
264
|
+
"- `limit` (1–100, default 20): Maximum number of runs to return.",
|
|
265
|
+
"- `offset` (default 0): Number of runs to skip for pagination.",
|
|
266
|
+
"- `response_format` (\"markdown\" | \"json\", default \"markdown\"): Output format.",
|
|
267
|
+
"",
|
|
268
|
+
"**Returns (markdown):**",
|
|
269
|
+
"- A table with status indicators, run IDs, environment, duration, and execution time.",
|
|
270
|
+
"",
|
|
271
|
+
"**Returns (json):**",
|
|
272
|
+
"```json",
|
|
273
|
+
'{',
|
|
274
|
+
' "runs": [',
|
|
275
|
+
' {',
|
|
276
|
+
' "id": "run-uuid",',
|
|
277
|
+
' "flow_id": "flow-uuid",',
|
|
278
|
+
' "status": "passed",',
|
|
279
|
+
' "environment": "dev",',
|
|
280
|
+
' "duration_ms": 4523,',
|
|
281
|
+
' "executed_at": "2025-01-15T10:30:00Z"',
|
|
282
|
+
' }',
|
|
283
|
+
' ],',
|
|
284
|
+
' "meta": { "page": 1, "limit": 20, "total": 42 }',
|
|
285
|
+
'}',
|
|
286
|
+
"```",
|
|
287
|
+
"",
|
|
288
|
+
"**Example:**",
|
|
289
|
+
"```",
|
|
290
|
+
'qualitas_list_runs({ project_id: "abc-123", flow_id: "def-456", limit: 10 })',
|
|
291
|
+
"```",
|
|
292
|
+
"",
|
|
293
|
+
"**Errors:**",
|
|
294
|
+
"- 404: Project or flow not found.",
|
|
295
|
+
"- 401: Invalid or expired API key.",
|
|
296
|
+
].join("\n"),
|
|
297
|
+
inputSchema: ListRunsSchema.shape,
|
|
298
|
+
annotations: {
|
|
299
|
+
title: "List Runs",
|
|
300
|
+
readOnlyHint: true,
|
|
301
|
+
destructiveHint: false,
|
|
302
|
+
idempotentHint: true,
|
|
303
|
+
openWorldHint: true,
|
|
304
|
+
},
|
|
305
|
+
}, async (args) => {
|
|
306
|
+
try {
|
|
307
|
+
const limit = args.limit ?? 20;
|
|
308
|
+
const offset = args.offset ?? 0;
|
|
309
|
+
const page = Math.floor(offset / limit) + 1;
|
|
310
|
+
const response = await apiClient.listRuns(args.project_id, args.flow_id, {
|
|
311
|
+
limit,
|
|
312
|
+
page,
|
|
313
|
+
});
|
|
314
|
+
const runs = response.data;
|
|
315
|
+
if (args.response_format === "json") {
|
|
316
|
+
return {
|
|
317
|
+
content: [
|
|
318
|
+
{
|
|
319
|
+
type: "text",
|
|
320
|
+
text: JSON.stringify({ runs, meta: response.meta }, null, 2),
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
content: [
|
|
327
|
+
{
|
|
328
|
+
type: "text",
|
|
329
|
+
text: formatRunsTableMarkdown(runs, args.project_id, args.flow_id),
|
|
330
|
+
},
|
|
331
|
+
],
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
return {
|
|
336
|
+
content: [{ type: "text", text: handleApiError(error) }],
|
|
337
|
+
isError: true,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/tools/runs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility Tools
|
|
3
|
+
*
|
|
4
|
+
* MCP tools for utility functions like OCR, screenshots, etc.
|
|
5
|
+
*/
|
|
6
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
import type { QualitasApiClient } from "../services/api-client.js";
|
|
8
|
+
/**
|
|
9
|
+
* Register utility tools with the MCP server
|
|
10
|
+
*/
|
|
11
|
+
export declare function registerUtilityTools(server: McpServer, apiClient: QualitasApiClient): void;
|
|
12
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAInE;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,iBAAiB,GAC3B,IAAI,CA2JN"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility Tools
|
|
3
|
+
*
|
|
4
|
+
* MCP tools for utility functions like OCR, screenshots, etc.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { handleApiError } from "../services/api-client.js";
|
|
8
|
+
import { extractTextFromImageUrl, extractErrorMessage } from "../utils/ocr.js";
|
|
9
|
+
/**
|
|
10
|
+
* Register utility tools with the MCP server
|
|
11
|
+
*/
|
|
12
|
+
export function registerUtilityTools(server, apiClient) {
|
|
13
|
+
// ===========================================
|
|
14
|
+
// 1. extract_screenshot_text
|
|
15
|
+
// ===========================================
|
|
16
|
+
server.tool("extract_screenshot_text", `Extract text from a screenshot image using OCR. Useful for reading error messages from test failure screenshots.
|
|
17
|
+
|
|
18
|
+
**Use cases:**
|
|
19
|
+
- Read error messages from failed test screenshots
|
|
20
|
+
- Extract text from any image URL
|
|
21
|
+
- Debug test failures by understanding what's shown on screen
|
|
22
|
+
|
|
23
|
+
**Arguments:**
|
|
24
|
+
- \`image_url\` (string, required): URL of the image to extract text from
|
|
25
|
+
- \`extract_error\` (boolean, optional, default true): Try to extract error message from the text
|
|
26
|
+
|
|
27
|
+
**Returns:**
|
|
28
|
+
- Extracted text from the image
|
|
29
|
+
- Confidence score (0-100)
|
|
30
|
+
- Error message if extract_error is true`, {
|
|
31
|
+
image_url: z.string().url("Invalid image URL").describe("URL of the image to extract text from"),
|
|
32
|
+
extract_error: z.boolean().default(true).describe("Try to extract error message from the text"),
|
|
33
|
+
}, async (params) => {
|
|
34
|
+
try {
|
|
35
|
+
const result = await extractTextFromImageUrl(params.image_url);
|
|
36
|
+
if (result.error) {
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: "text",
|
|
41
|
+
text: [
|
|
42
|
+
`# OCR Failed`,
|
|
43
|
+
"",
|
|
44
|
+
`**Error:** ${result.error}`,
|
|
45
|
+
"",
|
|
46
|
+
`The image could not be processed. Make sure the URL is accessible.`,
|
|
47
|
+
].join("\n"),
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
isError: true,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const lines = [];
|
|
54
|
+
lines.push(`# Screenshot Text Extracted`);
|
|
55
|
+
lines.push("");
|
|
56
|
+
lines.push(`**Confidence:** ${result.confidence.toFixed(1)}%`);
|
|
57
|
+
lines.push("");
|
|
58
|
+
if (params.extract_error && result.text) {
|
|
59
|
+
const errorMessage = extractErrorMessage(result.text);
|
|
60
|
+
if (errorMessage) {
|
|
61
|
+
lines.push(`**Error Message:**`);
|
|
62
|
+
lines.push(`\`\`\``);
|
|
63
|
+
lines.push(errorMessage);
|
|
64
|
+
lines.push(`\`\`\``);
|
|
65
|
+
lines.push("");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
lines.push(`**Full Text:**`);
|
|
69
|
+
lines.push(`\`\`\``);
|
|
70
|
+
lines.push(result.text || "(No text detected)");
|
|
71
|
+
lines.push(`\`\`\``);
|
|
72
|
+
return {
|
|
73
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return {
|
|
78
|
+
content: [{ type: "text", text: handleApiError(error) }],
|
|
79
|
+
isError: true,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
// ===========================================
|
|
84
|
+
// 2. get_run_screenshot
|
|
85
|
+
// ===========================================
|
|
86
|
+
server.tool("get_run_screenshot", `Get the screenshot URL for a specific step in a test run. Useful for debugging failed steps.
|
|
87
|
+
|
|
88
|
+
**Arguments:**
|
|
89
|
+
- \`run_id\` (UUID, required): The run ID
|
|
90
|
+
- \`node_id\` (string, optional): The node ID to get screenshot for. If not specified, returns all screenshots.
|
|
91
|
+
|
|
92
|
+
**Returns:**
|
|
93
|
+
- Screenshot URL(s) for the specified step or all failed steps`, {
|
|
94
|
+
run_id: z.string().uuid("Invalid run ID").describe("The run ID"),
|
|
95
|
+
node_id: z.string().optional().describe("The node ID to get screenshot for"),
|
|
96
|
+
}, async (params) => {
|
|
97
|
+
try {
|
|
98
|
+
// Fetch run steps
|
|
99
|
+
const stepsResponse = await apiClient.getRunSteps(params.run_id);
|
|
100
|
+
const steps = stepsResponse.data || [];
|
|
101
|
+
// Filter steps with screenshots
|
|
102
|
+
let stepsWithScreenshots = steps.filter((s) => s.screenshotUrl);
|
|
103
|
+
// Filter by node_id if specified
|
|
104
|
+
if (params.node_id) {
|
|
105
|
+
stepsWithScreenshots = stepsWithScreenshots.filter((s) => s.nodeId === params.node_id);
|
|
106
|
+
}
|
|
107
|
+
if (stepsWithScreenshots.length === 0) {
|
|
108
|
+
return {
|
|
109
|
+
content: [
|
|
110
|
+
{
|
|
111
|
+
type: "text",
|
|
112
|
+
text: `No screenshots found for run \`${params.run_id}\`${params.node_id ? ` and node \`${params.node_id}\`` : ""}.`,
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const lines = [];
|
|
118
|
+
lines.push(`# Run Screenshots`);
|
|
119
|
+
lines.push("");
|
|
120
|
+
lines.push(`**Run ID:** \`${params.run_id}\``);
|
|
121
|
+
lines.push("");
|
|
122
|
+
for (const step of stepsWithScreenshots) {
|
|
123
|
+
lines.push(`### Step: ${step.nodeId} (${step.type})`);
|
|
124
|
+
lines.push(`- **Status:** ${step.status}`);
|
|
125
|
+
lines.push(`- **Sequence:** ${step.sequenceOrder}`);
|
|
126
|
+
if (step.errorMessage) {
|
|
127
|
+
lines.push(`- **Error:** ${step.errorMessage}`);
|
|
128
|
+
}
|
|
129
|
+
lines.push(`- **Screenshot:** ${step.screenshotUrl}`);
|
|
130
|
+
lines.push("");
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
return {
|
|
138
|
+
content: [{ type: "text", text: handleApiError(error) }],
|
|
139
|
+
isError: true,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qualitas MCP Server - Variable Tools
|
|
3
|
+
*
|
|
4
|
+
* Tools for managing project-level environment variables (CRUD).
|
|
5
|
+
*/
|
|
6
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
import type { QualitasApiClient } from "../services/api-client.js";
|
|
8
|
+
export declare function registerVariableTools(server: McpServer, apiClient: QualitasApiClient): void;
|
|
9
|
+
//# sourceMappingURL=variables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../src/tools/variables.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAoEnE,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,iBAAiB,GAC3B,IAAI,CAgSN"}
|