@mablhq/mabl-cli 2.72.12 → 2.72.18

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.
@@ -87,7 +87,6 @@ async function startServer(parsed) {
87
87
  throw new Error(`Unknown prompt: ${name}`);
88
88
  });
89
89
  let mablApiClient;
90
- let workspaceId;
91
90
  server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
92
91
  const { name } = request.params;
93
92
  const tool = tools_1.default.find((t) => t.schema.name === name);
@@ -126,6 +125,7 @@ async function startServer(parsed) {
126
125
  },
127
126
  ],
128
127
  };
128
+ let workspaceId;
129
129
  try {
130
130
  workspaceId = await getWorkspaceId(parsed[constants_1.CommandArgWorkspaceId], parsed[constants_1.CommandArgApiKey], mablApiClient);
131
131
  if (!workspaceId) {
@@ -153,7 +153,14 @@ async function getWorkspaceId(workspaceId, apiKey, mablApiClient) {
153
153
  return workspaceId;
154
154
  }
155
155
  if (apiKey) {
156
- return (await mablApiClient.getApiKeyDetails()).workspace_id;
156
+ const apiKeyDetails = await mablApiClient.getApiKeyDetails();
157
+ return apiKeyDetails.workspace_id;
157
158
  }
158
- return (await cliConfigProvider_1.CliConfigProvider.getWorkspace()).id;
159
+ const currentWorkspace = await cliConfigProvider_1.CliConfigProvider.getWorkspace();
160
+ if (currentWorkspace?.id) {
161
+ return currentWorkspace.id;
162
+ }
163
+ await mablApiClient.getSelf();
164
+ const workspace = await cliConfigProvider_1.CliConfigProvider.getWorkspace();
165
+ return workspace?.id;
159
166
  }
@@ -23,6 +23,14 @@ const runTest = (0, mcpMablTool_1.defineTool)({
23
23
  On API tests this will be the endpoint to test.
24
24
  Try to validate that the url is correct.
25
25
  `),
26
+ credentialsId: zod_1.z
27
+ .string()
28
+ .describe('Optional. The id of the credentials to use for training the test. Cloud type credentials are not valid here. If not provided, the user will be prompted to select from available non-cloud credentials.')
29
+ .optional(),
30
+ withoutCredentials: zod_1.z
31
+ .boolean()
32
+ .describe('Optional. If true, the test will be created without credentials. If false, the user will be prompted to select from available non-cloud credentials.')
33
+ .optional(),
26
34
  name: zod_1.z.string().describe('The name of the test'),
27
35
  intent: zod_1.z.string().describe(`The intent of the test.
28
36
  Be as detailed as possible.
@@ -64,6 +72,25 @@ const runTest = (0, mcpMablTool_1.defineTool)({
64
72
  if (!params.environmentId) {
65
73
  return (0, common_1.stringToToolResult)('environmentId is required when creating a test. Request the environment explicitly.', true);
66
74
  }
75
+ const allCredentials = await mablApiClient.getCredentials(workspaceId, 500);
76
+ const nonCloudCredentials = allCredentials.filter((credential) => !credential.cloud_only);
77
+ if (params.credentialsId) {
78
+ const selectedCredential = allCredentials.find((cred) => cred.id === params.credentialsId);
79
+ if (!selectedCredential) {
80
+ return (0, common_1.stringToToolResult)(`Credential with id "${params.credentialsId}" not found.`, true);
81
+ }
82
+ if (selectedCredential.cloud_only) {
83
+ return (0, common_1.stringToToolResult)(`Cannot use Cloud Credentials [${params.credentialsId}] for test training. Cloud credentials are only available in cloud runs. Please use a non-cloud credential instead.`, true);
84
+ }
85
+ }
86
+ if (!params.credentialsId &&
87
+ nonCloudCredentials.length > 0 &&
88
+ !params.withoutCredentials) {
89
+ const credentialsList = nonCloudCredentials
90
+ .map((cred) => `- ${cred.name} (ID: ${cred.id}, Type: ${cred.type})`)
91
+ .join('\n');
92
+ return (0, common_1.stringToToolResult)(`Would you like to add credentials to this test? Here are the available non-cloud credentials:\n\n${credentialsList}\n\nIf you want to use one of these credentials, please specify the credentialsId parameter with the desired credential ID. If you don't want to use any credentials, you can proceed without specifying credentialsId and set withoutCredentials to true.`, false);
93
+ }
67
94
  messaging_1.mablEventEmitter.resetOutputEventChannel();
68
95
  let fullIntent = params.intent;
69
96
  if (params.steps) {
@@ -81,6 +108,7 @@ const runTest = (0, mcpMablTool_1.defineTool)({
81
108
  await (0, trainingSessions_1.trainNewTest)({
82
109
  environmentId: params.environmentId,
83
110
  applicationId: params.applicationId,
111
+ credentialsId: params.credentialsId,
84
112
  url: params.url,
85
113
  testName: params.name ?? 'New Test',
86
114
  autoBranch: false,
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const mcpMablTool_1 = require("./mcpMablTool");
4
+ const zod_1 = require("zod");
5
+ const getCredentials = (0, mcpMablTool_1.defineTool)({
6
+ schema: {
7
+ name: 'get-credentials',
8
+ title: 'Get all mabl credentials',
9
+ description: 'Get all mabl credentials',
10
+ inputSchema: zod_1.z.object({}),
11
+ outputSchema: zod_1.z.object({
12
+ credentials: zod_1.z.array(zod_1.z.object({
13
+ id: zod_1.z.string(),
14
+ name: zod_1.z.string(),
15
+ type: zod_1.z.string(),
16
+ cloud_only: zod_1.z.boolean(),
17
+ })),
18
+ }),
19
+ type: 'readOnly',
20
+ },
21
+ handle: async (_, mablApiClient, _server, workspaceId) => {
22
+ const limit = 500;
23
+ const credentials = await mablApiClient.getCredentials(workspaceId, limit);
24
+ const credentialsResponse = credentials.map((credential) => ({
25
+ id: credential.id,
26
+ name: credential.name,
27
+ type: credential.type,
28
+ cloud_only: credential.cloud_only,
29
+ }));
30
+ return {
31
+ content: [
32
+ {
33
+ type: 'text',
34
+ text: JSON.stringify({ credentials: credentialsResponse }, undefined, 2),
35
+ },
36
+ ],
37
+ structuredContent: { credentials: credentialsResponse },
38
+ };
39
+ },
40
+ });
41
+ exports.default = [getCredentials];
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const mcpMablTool_1 = require("./mcpMablTool");
4
+ const zod_1 = require("zod");
5
+ const getWorkspaces = (0, mcpMablTool_1.defineTool)({
6
+ schema: {
7
+ name: 'get-workspaces',
8
+ title: 'Get all available workspaces',
9
+ description: 'Get all workspaces that the user has access to',
10
+ inputSchema: zod_1.z.object({
11
+ limit: zod_1.z
12
+ .number()
13
+ .optional()
14
+ .describe('The maximum number of workspaces to return (default: 50)'),
15
+ }),
16
+ outputSchema: zod_1.z.object({
17
+ workspaces: zod_1.z.array(zod_1.z.object({
18
+ id: zod_1.z.string().describe('The workspace ID'),
19
+ name: zod_1.z.string().describe('The workspace name'),
20
+ })),
21
+ currentWorkspaceId: zod_1.z
22
+ .string()
23
+ .describe('The currently active workspace ID'),
24
+ }),
25
+ type: 'readOnly',
26
+ },
27
+ handle: async (args, mablApiClient, _server, workspaceId) => {
28
+ const limit = args.limit || 50;
29
+ const workspaces = await mablApiClient.getWorkspaces(limit);
30
+ const workspaceList = workspaces.map((workspace) => ({
31
+ id: workspace.id,
32
+ name: workspace.name,
33
+ }));
34
+ return {
35
+ content: [
36
+ {
37
+ type: 'text',
38
+ text: JSON.stringify({
39
+ workspaces: workspaceList,
40
+ currentWorkspaceId: workspaceId,
41
+ }, undefined, 2),
42
+ },
43
+ ],
44
+ structuredContent: {
45
+ workspaces: workspaceList,
46
+ currentWorkspaceId: workspaceId,
47
+ },
48
+ };
49
+ },
50
+ });
51
+ exports.default = [getWorkspaces];
@@ -8,6 +8,7 @@ const getTests_1 = __importDefault(require("./getTests"));
8
8
  const getMablDeployment_1 = __importDefault(require("./getMablDeployment"));
9
9
  const getTestResults_1 = __importDefault(require("./getTestResults"));
10
10
  const getApplications_1 = __importDefault(require("./getApplications"));
11
+ const getCredentials_1 = __importDefault(require("./getCredentials"));
11
12
  const analyzeFailure_1 = __importDefault(require("./analyzeFailure"));
12
13
  const runTest_1 = __importDefault(require("./runTest"));
13
14
  const exportToPlaywright_1 = __importDefault(require("./exportToPlaywright"));
@@ -15,8 +16,11 @@ const createTest_1 = __importDefault(require("./createTest"));
15
16
  const getPlans_1 = __importDefault(require("./getPlans"));
16
17
  const getPlanRunResult_1 = __importDefault(require("./getPlanRunResult"));
17
18
  const getLatestPlanRuns_1 = __importDefault(require("./getLatestPlanRuns"));
19
+ const getWorkspaces_1 = __importDefault(require("./getWorkspaces"));
20
+ const switchWorkspace_1 = __importDefault(require("./switchWorkspace"));
18
21
  exports.default = [
19
22
  ...getApplications_1.default,
23
+ ...getCredentials_1.default,
20
24
  ...getEnvironments_1.default,
21
25
  ...getTests_1.default,
22
26
  ...getPlans_1.default,
@@ -28,4 +32,6 @@ exports.default = [
28
32
  ...createTest_1.default,
29
33
  ...getPlanRunResult_1.default,
30
34
  ...getLatestPlanRuns_1.default,
35
+ ...getWorkspaces_1.default,
36
+ ...switchWorkspace_1.default,
31
37
  ];
@@ -21,6 +21,10 @@ const runTest = (0, mcpMablTool_1.defineTool)({
21
21
  .string()
22
22
  .describe('The id of the environment to run the test in'),
23
23
  testId: zod_1.z.string().describe('The id of the test to run'),
24
+ credentialsId: zod_1.z
25
+ .string()
26
+ .describe('Optional. The id of the credentials to use for running the test. If not provided, the user will be prompted to select from available non-cloud credentials.')
27
+ .optional(),
24
28
  }),
25
29
  type: 'destructive',
26
30
  outputSchema: runTestOutputSchema,
@@ -39,7 +43,8 @@ const runTest = (0, mcpMablTool_1.defineTool)({
39
43
  .on(messaging_1.EventChannelMessageType.outputLogLine, logListener);
40
44
  const result = await (0, run_1.run)({
41
45
  id: params.testId,
42
- 'environment-id': params.environmentId || '',
46
+ 'environment-id': params.environmentId ?? '',
47
+ 'credentials-id': params.credentialsId ?? '',
43
48
  branch: 'master',
44
49
  'branch-changes-only': false,
45
50
  browser: 'chrome',
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const cliConfigProvider_1 = require("../../../../providers/cliConfigProvider");
4
+ const mcpMablTool_1 = require("./mcpMablTool");
5
+ const zod_1 = require("zod");
6
+ const switchWorkspace = (0, mcpMablTool_1.defineTool)({
7
+ schema: {
8
+ name: 'switch-workspace',
9
+ title: 'Switch the current workspace',
10
+ description: 'Switch to a different workspace by providing a workspace ID',
11
+ inputSchema: zod_1.z.object({
12
+ workspaceId: zod_1.z.string().describe('The ID of the workspace to switch to'),
13
+ }),
14
+ type: 'destructive',
15
+ },
16
+ handle: async (args, mablApiClient, _server, _currentWorkspaceId) => {
17
+ const { workspaceId: newWorkspaceId } = args;
18
+ try {
19
+ const workspace = await mablApiClient.getWorkspace(newWorkspaceId);
20
+ await cliConfigProvider_1.CliConfigProvider.setWorkspace(workspace);
21
+ return {
22
+ content: [
23
+ {
24
+ type: 'text',
25
+ text: `Successfully switched workspace to "${workspace.name}" (${newWorkspaceId})`,
26
+ },
27
+ ],
28
+ };
29
+ }
30
+ catch (error) {
31
+ return {
32
+ content: [
33
+ {
34
+ type: 'text',
35
+ text: `Failed to switch workspace: ${error instanceof Error ? error.message : 'Unknown error'}`,
36
+ },
37
+ ],
38
+ };
39
+ }
40
+ },
41
+ });
42
+ exports.default = [switchWorkspace];