@mablhq/mabl-cli 2.70.1 → 2.70.4

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.
@@ -11,6 +11,7 @@ const loggingProvider_1 = require("../../../providers/logging/loggingProvider");
11
11
  const tools_1 = __importDefault(require("./tools"));
12
12
  const constants_1 = require("../../constants");
13
13
  const createMablTestForCurrentWork_1 = require("./prompts/createMablTestForCurrentWork");
14
+ const common_1 = require("./tools/common");
14
15
  exports.command = 'start [options]';
15
16
  exports.describe = 'Start the MCP server';
16
17
  exports.builder = (yargs) => {
@@ -40,10 +41,8 @@ async function startServer(parsed) {
40
41
  },
41
42
  });
42
43
  server.setRequestHandler(types_js_1.ListToolsRequestSchema, () => ({
43
- tools: tools_1.default.map((tool) => ({
44
- name: tool.schema.name,
45
- description: tool.schema.description,
46
- inputSchema: tool.schema.inputSchema.safeParse({}).success
44
+ tools: tools_1.default.map((tool) => {
45
+ const inputSchema = tool.schema.inputSchema.safeParse({}).success
47
46
  ? { type: 'object', properties: {} }
48
47
  : {
49
48
  type: 'object',
@@ -57,8 +56,16 @@ async function startServer(parsed) {
57
56
  },
58
57
  ];
59
58
  })),
60
- },
61
- })),
59
+ };
60
+ return {
61
+ name: tool.schema.name,
62
+ description: tool.schema.description,
63
+ inputSchema,
64
+ ...(tool.schema.outputSchema
65
+ ? { outputSchema: (0, common_1.zodSchemaToOpenApiSchema)(tool.schema.outputSchema) }
66
+ : {}),
67
+ };
68
+ }),
62
69
  }));
63
70
  server.setRequestHandler(types_js_1.ListPromptsRequestSchema, () => ({
64
71
  prompts: [createMablTestForCurrentWork_1.createMablTestPrompt],
@@ -16,6 +16,17 @@ const analyzeFailure = (0, mcpMablTool_1.defineTool)({
16
16
  },
17
17
  handle: async (params, apiKey, server) => {
18
18
  const runId = params.runId;
19
+ if (runId.endsWith('-j')) {
20
+ return {
21
+ content: [
22
+ {
23
+ type: 'text',
24
+ text: `The runId ${runId} appears to be a test id. Please call the getResults tool with this id first, then call analyze-failure again with the resulting first runId with status "Failed".`,
25
+ isError: false,
26
+ },
27
+ ],
28
+ };
29
+ }
19
30
  const mablApiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClientFromOptionalApiKey(apiKey);
20
31
  const workspaceId = (await mablApiClient.getApiKeyDetails()).workspace_id;
21
32
  if (!workspaceId) {
@@ -1,13 +1,74 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.stringToToolResult = stringToToolResult;
4
- function stringToToolResult(value) {
4
+ exports.zodSchemaToOpenApiSchema = zodSchemaToOpenApiSchema;
5
+ const zod_1 = require("zod");
6
+ function stringToToolResult(value, isError = false) {
5
7
  return {
6
8
  content: [
7
9
  {
8
10
  type: 'text',
9
11
  text: value,
12
+ isError,
10
13
  },
11
14
  ],
12
15
  };
13
16
  }
17
+ function zodSchemaToOpenApiSchema(schema) {
18
+ if (schema instanceof zod_1.z.ZodArray) {
19
+ const element = schema.element;
20
+ if (element instanceof zod_1.z.ZodObject) {
21
+ const itemShape = element.shape;
22
+ return {
23
+ type: 'array',
24
+ items: {
25
+ type: 'object',
26
+ properties: Object.fromEntries(Object.entries(itemShape).map(([key, value]) => {
27
+ const description = value._def.description;
28
+ return [
29
+ key,
30
+ {
31
+ type: (() => {
32
+ if (value instanceof zod_1.z.ZodString) {
33
+ return 'string';
34
+ }
35
+ if (value instanceof zod_1.z.ZodNumber) {
36
+ return 'number';
37
+ }
38
+ if (value instanceof zod_1.z.ZodBoolean) {
39
+ return 'boolean';
40
+ }
41
+ if (value instanceof zod_1.z.ZodArray) {
42
+ return 'array';
43
+ }
44
+ if (value instanceof zod_1.z.ZodObject) {
45
+ return 'object';
46
+ }
47
+ return 'string';
48
+ })(),
49
+ description: description || '',
50
+ },
51
+ ];
52
+ })),
53
+ },
54
+ };
55
+ }
56
+ }
57
+ else if (schema instanceof zod_1.z.ZodObject) {
58
+ const shape = schema.shape;
59
+ return {
60
+ type: 'object',
61
+ properties: Object.fromEntries(Object.entries(shape).map(([key, value]) => {
62
+ const description = value._def.description;
63
+ return [
64
+ key,
65
+ {
66
+ type: 'string',
67
+ description: description || '',
68
+ },
69
+ ];
70
+ })),
71
+ };
72
+ }
73
+ return undefined;
74
+ }
@@ -15,15 +15,15 @@ exports.environmentRequiredToolResult = (0, common_1.stringToToolResult)(`
15
15
  Tell the user that the environmentId is required to export the test to Playwright with good locators.
16
16
  Call the get-environments tool to get the list of environments for the test.
17
17
  Ask them to select the environmentId from the list of environments and then call this tool again with the environmentId.
18
- `);
18
+ `, true);
19
19
  exports.performanceTestToolResult = (0, common_1.stringToToolResult)(`
20
20
  ## Instructions
21
21
  Tell the user that the test provided is a performance test and it can't be exported to playwright.
22
- `);
22
+ `, true);
23
23
  exports.defaultTestToolResult = (0, common_1.stringToToolResult)(`
24
24
  ## Instructions
25
25
  Tell the user that default tests can not be exported to playwright.
26
- `);
26
+ `, true);
27
27
  const exportToPlaywrightSchema = zod_1.z.object({
28
28
  testId: zod_1.z
29
29
  .string()
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const mcpMablTool_1 = require("./mcpMablTool");
4
4
  const zod_1 = require("zod");
5
5
  const mablApiClientFactory_1 = require("../../../../api/mablApiClientFactory");
6
+ const mablApi_1 = require("../../../../mablApi");
7
+ const common_1 = require("./common");
6
8
  const getResults = (0, mcpMablTool_1.defineTool)({
7
9
  schema: {
8
10
  name: 'get-results',
@@ -14,28 +16,71 @@ const getResults = (0, mcpMablTool_1.defineTool)({
14
16
  .describe('The id of the mabl test to get recent results of'),
15
17
  }),
16
18
  type: 'readOnly',
19
+ outputSchema: zod_1.z.array(zod_1.z.object({
20
+ testRunId: zod_1.z.string().nullable(),
21
+ environmentId: zod_1.z.string().nullable(),
22
+ status: zod_1.z.string().nullable(),
23
+ completedTimeMs: zod_1.z.number().nullable(),
24
+ errorMessage: zod_1.z.string(),
25
+ })),
17
26
  },
18
27
  handle: async (params, apiKey) => {
19
28
  const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClientFromOptionalApiKey(apiKey);
20
29
  const testId = params.testId;
21
30
  const testRunResults = (await apiClient.getRecentTestRunsForTest(testId))
22
31
  .test_script_executions || [];
32
+ const workspaceIdMaybe = (await apiClient.getApiKeyDetails()).workspace_id;
33
+ if (!workspaceIdMaybe) {
34
+ return (0, common_1.stringToToolResult)('Workspace ID not found', true);
35
+ }
36
+ const workspaceId = workspaceIdMaybe;
37
+ const processedResults = await Promise.all(testRunResults.map(async (testRun) => {
38
+ let errorMessage = '';
39
+ if (testRun.status === mablApi_1.TestRun.StatusEnum.Failed &&
40
+ testRun.failure_categorization?.is_failure_category_generated !== true) {
41
+ try {
42
+ const analysis = await apiClient.analyzeTestRun(workspaceId, {
43
+ test_run_id: testRun.id,
44
+ });
45
+ testRun.failure_categorization = {
46
+ ...testRun.failure_categorization,
47
+ ...analysis,
48
+ };
49
+ }
50
+ catch (e) {
51
+ console.error('Error analyzing test run:', e);
52
+ errorMessage = `Analysis error: ${e instanceof Error ? e.message : String(e)}`;
53
+ }
54
+ }
55
+ if (testRun.failure_categorization) {
56
+ errorMessage =
57
+ testRun.failure_categorization.failure_summary_text ??
58
+ testRun.failure_summary?.error ??
59
+ '';
60
+ }
61
+ if (!errorMessage) {
62
+ errorMessage = 'No categorized error available.';
63
+ }
64
+ const id = testRun.id;
65
+ const completedTimeMs = testRun.completed_time;
66
+ const status = testRun.status;
67
+ const envId = testRun.journey_parameters?.deployment?.environment_id;
68
+ return {
69
+ testRunId: id,
70
+ environmentId: envId,
71
+ status,
72
+ completedTimeMs,
73
+ errorMessage,
74
+ };
75
+ }));
23
76
  return {
24
77
  content: [
25
78
  {
26
79
  type: 'text',
27
- text: testRunResults
28
- .map((testRun) => {
29
- const id = testRun.id;
30
- const completedTimeMs = testRun.completed_time;
31
- const status = testRun.status;
32
- const envId = testRun.journey_parameters?.deployment?.environment_id;
33
- const errorMessage = testRun.failure_summary?.error;
34
- return `TestRunId: ${id} EnvironmentId: ${envId} Status: ${status} CompletedTimeMs: ${completedTimeMs} ErrorMessage: ${errorMessage}`;
35
- })
36
- .join('\n'),
80
+ text: JSON.stringify(processedResults),
37
81
  },
38
82
  ],
83
+ structuredContent: processedResults,
39
84
  };
40
85
  },
41
86
  });
@@ -1498,6 +1498,8 @@ function postmanAuthToApiTestAuth(auth) {
1498
1498
  verifier: getValueFromVariablesForAuthType('verifier'),
1499
1499
  };
1500
1500
  break;
1501
+ default:
1502
+ return undefined;
1501
1503
  }
1502
1504
  return apiTestAuth;
1503
1505
  }