@mablhq/mabl-cli 2.73.2 → 2.74.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/commands/mcp/mcp_cmds/start.js +16 -23
- package/commands/mcp/mcp_cmds/tools/getEnvironments.js +14 -3
- package/commands/mcp/mcp_cmds/tools/getLatestAuthoredTests.js +18 -23
- package/commands/mcp/mcp_cmds/tools/mcpMablTool.js +16 -2
- package/commands/mcp/mcp_cmds/tools/switchWorkspace.js +10 -22
- package/execution/index.js +1 -1
- package/package.json +1 -1
- package/util/analytics.js +2 -2
|
@@ -23,12 +23,7 @@ exports.builder = (yargs) => {
|
|
|
23
23
|
describe: 'API key (found in the mabl web app)',
|
|
24
24
|
type: 'string',
|
|
25
25
|
demand: false,
|
|
26
|
-
|
|
27
|
-
.option(constants_1.CommandArgWorkspaceId, {
|
|
28
|
-
alias: constants_1.CommandArgAliases.WorkspaceId,
|
|
29
|
-
describe: 'Workspace ID (found in the mabl web app)',
|
|
30
|
-
type: 'string',
|
|
31
|
-
demand: false,
|
|
26
|
+
hidden: true,
|
|
32
27
|
})
|
|
33
28
|
.example('$0 mcp start', 'Start the MCP server');
|
|
34
29
|
};
|
|
@@ -85,21 +80,26 @@ async function startServer(parsed) {
|
|
|
85
80
|
const args = request.params.arguments || {};
|
|
86
81
|
if (!mablApiClient) {
|
|
87
82
|
try {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
? await mablApiClientFactory_1.MablApiClientFactory.createApiClientFromOptionalApiKey(maybeApiKey, false)
|
|
83
|
+
mablApiClient = process.env.CI
|
|
84
|
+
? await mablApiClientFactory_1.MablApiClientFactory.createApiClientFromOptionalApiKey()
|
|
91
85
|
: await mablApiClientFactory_1.MablApiClientFactory.createUserApiClient(false);
|
|
92
86
|
}
|
|
93
87
|
catch (error) {
|
|
88
|
+
const maybeApiKey = parsed[constants_1.CommandArgApiKey];
|
|
89
|
+
const errorMessage = maybeApiKey
|
|
90
|
+
? `The mabl MCP no longer supports authentication via apiKey.
|
|
91
|
+
Please authenticate the CLI by running 'mabl auth login'
|
|
92
|
+
`
|
|
93
|
+
: `
|
|
94
|
+
The CLI is not authenticated.
|
|
95
|
+
Please authenticate the CLI by running 'mabl auth login'
|
|
96
|
+
`;
|
|
94
97
|
return {
|
|
98
|
+
isError: true,
|
|
95
99
|
content: [
|
|
96
100
|
{
|
|
97
101
|
type: 'text',
|
|
98
|
-
text:
|
|
99
|
-
The CLI is not authenticated.
|
|
100
|
-
Please authenticate the CLI by running 'mabl auth login'
|
|
101
|
-
`,
|
|
102
|
-
isError: true,
|
|
102
|
+
text: errorMessage,
|
|
103
103
|
},
|
|
104
104
|
],
|
|
105
105
|
};
|
|
@@ -115,7 +115,7 @@ async function startServer(parsed) {
|
|
|
115
115
|
};
|
|
116
116
|
let workspaceId;
|
|
117
117
|
try {
|
|
118
|
-
workspaceId = await getWorkspaceId(
|
|
118
|
+
workspaceId = await getWorkspaceId(mablApiClient);
|
|
119
119
|
if (!workspaceId) {
|
|
120
120
|
return invalidWorkspaceResponse;
|
|
121
121
|
}
|
|
@@ -138,14 +138,7 @@ async function startServer(parsed) {
|
|
|
138
138
|
await server.connect(transport);
|
|
139
139
|
console.error('Mabl MCP Server running on stdio');
|
|
140
140
|
}
|
|
141
|
-
async function getWorkspaceId(
|
|
142
|
-
if (workspaceId) {
|
|
143
|
-
return workspaceId;
|
|
144
|
-
}
|
|
145
|
-
if (apiKey) {
|
|
146
|
-
const apiKeyDetails = await mablApiClient.getApiKeyDetails();
|
|
147
|
-
return apiKeyDetails.workspace_id;
|
|
148
|
-
}
|
|
141
|
+
async function getWorkspaceId(mablApiClient) {
|
|
149
142
|
const currentWorkspace = await cliConfigProvider_1.CliConfigProvider.getWorkspace();
|
|
150
143
|
if (currentWorkspace?.id) {
|
|
151
144
|
return currentWorkspace.id;
|
|
@@ -1,27 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getEnvironmentsOutputSchema = void 0;
|
|
3
4
|
const mcpMablTool_1 = require("./mcpMablTool");
|
|
4
5
|
const zod_1 = require("zod");
|
|
6
|
+
exports.getEnvironmentsOutputSchema = zod_1.z.object({
|
|
7
|
+
environments: zod_1.z.array(zod_1.z.object({
|
|
8
|
+
id: zod_1.z.string().optional(),
|
|
9
|
+
name: zod_1.z.string().optional(),
|
|
10
|
+
})),
|
|
11
|
+
});
|
|
5
12
|
const getEnvironments = (0, mcpMablTool_1.defineTool)({
|
|
6
13
|
schema: {
|
|
7
14
|
name: 'get_environments',
|
|
8
15
|
title: 'Get all mabl environments',
|
|
9
16
|
description: 'Get all mabl environments. Example: Get my mabl environments',
|
|
10
17
|
inputSchema: zod_1.z.object({}),
|
|
18
|
+
outputSchema: exports.getEnvironmentsOutputSchema,
|
|
11
19
|
type: 'readOnly',
|
|
12
20
|
},
|
|
13
21
|
handle: async (_, mablApiClient, _server, workspaceId) => {
|
|
14
22
|
const limit = 500;
|
|
15
23
|
const environments = await mablApiClient.getEnvironments(workspaceId, limit);
|
|
24
|
+
const environmentsResponse = environments.map((env) => ({
|
|
25
|
+
id: env.id,
|
|
26
|
+
name: env.name,
|
|
27
|
+
}));
|
|
16
28
|
return {
|
|
17
29
|
content: [
|
|
18
30
|
{
|
|
19
31
|
type: 'text',
|
|
20
|
-
text: environments
|
|
21
|
-
.map((env) => `Name: ${env.name} ID: ${env.id}`)
|
|
22
|
-
.join('\n'),
|
|
32
|
+
text: JSON.stringify({ environments: environmentsResponse }, undefined, 2),
|
|
23
33
|
},
|
|
24
34
|
],
|
|
35
|
+
structuredContent: { environments: environmentsResponse },
|
|
25
36
|
};
|
|
26
37
|
},
|
|
27
38
|
});
|
|
@@ -29,30 +29,25 @@ const getLatestAuthoredTests = (0, mcpMablTool_1.defineTool)({
|
|
|
29
29
|
},
|
|
30
30
|
handle: async (args, mablApiClient, _server, workspaceId) => {
|
|
31
31
|
const limit = args.limit || 10;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return (0, common_1.stringToToolResult)('Unable to determine current user information.', true);
|
|
36
|
-
}
|
|
37
|
-
const authoredTestsResponse = await mablApiClient.getJourneys({
|
|
38
|
-
author_id: userInfo.userId,
|
|
39
|
-
organization_id: workspaceId,
|
|
40
|
-
limit,
|
|
41
|
-
});
|
|
42
|
-
const latestAuthoredTests = authoredTestsResponse.map((test) => (0, testUtils_1.normalizeTest)(test));
|
|
43
|
-
return {
|
|
44
|
-
content: [
|
|
45
|
-
{
|
|
46
|
-
type: 'text',
|
|
47
|
-
text: JSON.stringify({ latestAuthoredTests }, undefined, 2),
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
structuredContent: { latestAuthoredTests },
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
return (0, common_1.stringToToolResult)(`Failed to get latest authored tests: ${error instanceof Error ? error.message : String(error)}`, true);
|
|
32
|
+
const userInfo = await cliConfigProvider_1.CliConfigProvider.getCliConfig();
|
|
33
|
+
if (!userInfo.userId) {
|
|
34
|
+
return (0, common_1.stringToToolResult)('Unable to determine current user information.', true);
|
|
55
35
|
}
|
|
36
|
+
const authoredTestsResponse = await mablApiClient.getJourneys({
|
|
37
|
+
author_id: userInfo.userId,
|
|
38
|
+
organization_id: workspaceId,
|
|
39
|
+
limit,
|
|
40
|
+
});
|
|
41
|
+
const latestAuthoredTests = authoredTestsResponse.map((test) => (0, testUtils_1.normalizeTest)(test));
|
|
42
|
+
return {
|
|
43
|
+
content: [
|
|
44
|
+
{
|
|
45
|
+
type: 'text',
|
|
46
|
+
text: JSON.stringify({ latestAuthoredTests }, undefined, 2),
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
structuredContent: { latestAuthoredTests },
|
|
50
|
+
};
|
|
56
51
|
},
|
|
57
52
|
});
|
|
58
53
|
exports.default = [getLatestAuthoredTests];
|
|
@@ -6,9 +6,23 @@ function defineTool(tool) {
|
|
|
6
6
|
const originalHandle = tool.handle;
|
|
7
7
|
return {
|
|
8
8
|
...tool,
|
|
9
|
-
handle: (params, apiClient, server, workspaceId) => {
|
|
9
|
+
handle: async (params, apiClient, server, workspaceId) => {
|
|
10
10
|
(0, interceptor_1.mcpToolInterceptor)(tool.schema.name);
|
|
11
|
-
|
|
11
|
+
try {
|
|
12
|
+
const toolResult = await originalHandle(params, apiClient, server, workspaceId);
|
|
13
|
+
return toolResult;
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
return {
|
|
17
|
+
isError: true,
|
|
18
|
+
content: [
|
|
19
|
+
{
|
|
20
|
+
type: 'text',
|
|
21
|
+
text: `Failed to execute ${tool.schema.name}: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
12
26
|
},
|
|
13
27
|
};
|
|
14
28
|
}
|
|
@@ -15,28 +15,16 @@ const switchWorkspace = (0, mcpMablTool_1.defineTool)({
|
|
|
15
15
|
},
|
|
16
16
|
handle: async (args, mablApiClient, _server, _currentWorkspaceId) => {
|
|
17
17
|
const { workspaceId: newWorkspaceId } = args;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
}
|
|
18
|
+
const workspace = await mablApiClient.getWorkspace(newWorkspaceId);
|
|
19
|
+
await cliConfigProvider_1.CliConfigProvider.setWorkspace(workspace);
|
|
20
|
+
return {
|
|
21
|
+
content: [
|
|
22
|
+
{
|
|
23
|
+
type: 'text',
|
|
24
|
+
text: `Successfully switched workspace to "${workspace.name}" (${newWorkspaceId})`,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
|
40
28
|
},
|
|
41
29
|
});
|
|
42
30
|
exports.default = [switchWorkspace];
|