zephyr-scale-mcp-server 0.3.2 → 0.3.3
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 +4 -8
- package/build/tool-handlers.js +464 -303
- package/build/tool-schemas.js +8 -8
- package/build/utils.js +30 -1
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/tool-handlers.ts +551 -364
- package/src/tool-schemas.ts +8 -8
- package/src/types.ts +6 -0
- package/src/utils.ts +43 -1
package/build/tool-schemas.js
CHANGED
|
@@ -176,7 +176,7 @@ export const toolSchemas = [
|
|
|
176
176
|
},
|
|
177
177
|
{
|
|
178
178
|
name: 'create_folder',
|
|
179
|
-
description: 'Create a new folder in Zephyr Scale',
|
|
179
|
+
description: 'Create a new folder in Zephyr Scale. On Cloud: provide a path like "/Parent/Child" — the server resolves parent segments and creates the leaf folder. On Data Center: the full path is sent directly.',
|
|
180
180
|
inputSchema: {
|
|
181
181
|
type: 'object',
|
|
182
182
|
properties: {
|
|
@@ -186,7 +186,7 @@ export const toolSchemas = [
|
|
|
186
186
|
},
|
|
187
187
|
name: {
|
|
188
188
|
type: 'string',
|
|
189
|
-
description: 'Full folder path including parent folders (required). Examples: "/MyFolder" for root folder, "/Parent/Child" for nested folder',
|
|
189
|
+
description: 'Full folder path including parent folders (required). Examples: "/MyFolder" for root folder, "/Parent/Child" for nested folder. On Cloud, individual segment names must not contain "/" or "\\".',
|
|
190
190
|
},
|
|
191
191
|
folder_type: {
|
|
192
192
|
type: 'string',
|
|
@@ -214,7 +214,7 @@ export const toolSchemas = [
|
|
|
214
214
|
},
|
|
215
215
|
{
|
|
216
216
|
name: 'delete_test_case',
|
|
217
|
-
description: 'Delete a specific test case',
|
|
217
|
+
description: 'Delete a specific test case (Data Center only — not supported on Cloud v2)',
|
|
218
218
|
inputSchema: {
|
|
219
219
|
type: 'object',
|
|
220
220
|
properties: {
|
|
@@ -306,22 +306,22 @@ export const toolSchemas = [
|
|
|
306
306
|
},
|
|
307
307
|
{
|
|
308
308
|
name: 'get_test_execution',
|
|
309
|
-
description: 'Get detailed information about a specific test execution by
|
|
309
|
+
description: 'Get detailed information about a specific test execution by ID or key. On Cloud, provide the execution ID or key (e.g., PROJ-E123) directly. On Data Center, also provide test_run_keys to search within.',
|
|
310
310
|
inputSchema: {
|
|
311
311
|
type: 'object',
|
|
312
312
|
properties: {
|
|
313
313
|
execution_id: {
|
|
314
314
|
type: 'string',
|
|
315
|
-
description: 'Test execution ID (e.g., 5805255)',
|
|
315
|
+
description: 'Test execution ID or key (e.g., 5805255 or PROJ-E123)',
|
|
316
316
|
},
|
|
317
317
|
test_run_keys: {
|
|
318
318
|
type: 'array',
|
|
319
|
-
description: 'Array of test run keys to search in (required, e.g., ["PROJ-C152", "PROJ-C161"])',
|
|
319
|
+
description: 'Array of test run keys to search in (required for Data Center, optional for Cloud — e.g., ["PROJ-C152", "PROJ-C161"])',
|
|
320
320
|
items: { type: 'string' },
|
|
321
321
|
minItems: 1
|
|
322
322
|
},
|
|
323
323
|
},
|
|
324
|
-
required: ['execution_id'
|
|
324
|
+
required: ['execution_id'],
|
|
325
325
|
},
|
|
326
326
|
},
|
|
327
327
|
{
|
|
@@ -375,7 +375,7 @@ export const toolSchemas = [
|
|
|
375
375
|
},
|
|
376
376
|
{
|
|
377
377
|
name: 'delete_test_run',
|
|
378
|
-
description: 'Delete a specific test run',
|
|
378
|
+
description: 'Delete a specific test run (Data Center only — not supported on Cloud v2)',
|
|
379
379
|
inputSchema: {
|
|
380
380
|
type: 'object',
|
|
381
381
|
properties: {
|
package/build/utils.js
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
export async function resolveFolderIdByPath(axiosInstance, projectKey, folderPath, folderType) {
|
|
2
|
+
// Normalise: strip leading/trailing slashes, split into segments
|
|
3
|
+
const segments = folderPath.replace(/^\/+|\/+$/g, '').split('/').filter(Boolean);
|
|
4
|
+
if (segments.length === 0)
|
|
5
|
+
return null;
|
|
6
|
+
try {
|
|
7
|
+
// Fetch all folders for the project + type (up to 1000)
|
|
8
|
+
const response = await axiosInstance.get('/folders', {
|
|
9
|
+
params: { projectKey, folderType, maxResults: 1000 },
|
|
10
|
+
});
|
|
11
|
+
const folders = Array.isArray(response.data)
|
|
12
|
+
? response.data
|
|
13
|
+
: response.data?.values ?? [];
|
|
14
|
+
// Walk segments top-down, matching by name under the correct parent
|
|
15
|
+
let parentId = null;
|
|
16
|
+
let matchedId = null;
|
|
17
|
+
for (const segment of segments) {
|
|
18
|
+
const match = folders.find((f) => f.name === segment && (f.parentId ?? null) === parentId);
|
|
19
|
+
if (!match)
|
|
20
|
+
return null;
|
|
21
|
+
matchedId = match.id;
|
|
22
|
+
parentId = match.id;
|
|
23
|
+
}
|
|
24
|
+
return matchedId;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
1
30
|
export function convertToGherkin(bddContent) {
|
|
2
31
|
const bddLines = [];
|
|
3
32
|
const lines = bddContent.split('\n');
|
|
@@ -54,7 +83,7 @@ export function getApiEndpoints(jiraType) {
|
|
|
54
83
|
if (jiraType === 'cloud') {
|
|
55
84
|
return {
|
|
56
85
|
testcase: '/testcases',
|
|
57
|
-
testrun: '/
|
|
86
|
+
testrun: '/testcycles',
|
|
58
87
|
folder: '/folders',
|
|
59
88
|
search: '/testcases/search',
|
|
60
89
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zephyr-scale-mcp-server",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server for Zephyr Scale test case management with comprehensive STEP_BY_STEP, PLAIN_TEXT, and BDD support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./build/index.js",
|
package/src/index.ts
CHANGED
|
@@ -82,7 +82,7 @@ class ZephyrServer {
|
|
|
82
82
|
case 'get_test_run':
|
|
83
83
|
return await this.toolHandlers.getTestRun(args);
|
|
84
84
|
case 'get_test_execution':
|
|
85
|
-
return await this.toolHandlers.getTestExecution(args);
|
|
85
|
+
return await this.toolHandlers.getTestExecution(args as any);
|
|
86
86
|
case 'search_test_cases_by_folder':
|
|
87
87
|
return await this.toolHandlers.searchTestCasesByFolder(args as any);
|
|
88
88
|
case 'search_test_runs':
|