@qase/mcp-server 2.0.1 → 2.0.2
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/CHANGELOG.md +10 -0
- package/build/operations-v2/write/case-fields.d.ts +49 -0
- package/build/operations-v2/write/case-fields.d.ts.map +1 -1
- package/build/operations-v2/write/case-fields.js +39 -1
- package/build/operations-v2/write/case-fields.js.map +1 -1
- package/build/operations-v2/write/cases-bulk.js +8 -2
- package/build/operations-v2/write/cases-bulk.js.map +1 -1
- package/build/operations-v2/write/cases.js +4 -1
- package/build/operations-v2/write/cases.js.map +1 -1
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/docs/tools.md +5 -2
- package/package.json +2 -2
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.0.2]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Shared steps can now be referenced from a test case.** `qase_case_upsert` and `qase_case_bulk_create` document a `shared` property on step objects, taking the hash returned by `qase_shared_step_upsert`; `action` is not required for such a step and nesting works at any depth. `shared_step_hash` — the name the API uses when reading a case back — is accepted as an alias and translated to `shared` before the request is sent, so the field seen on read now also works on write. ([#66](https://github.com/qase-tms/qase-mcp-server/issues/66))
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Updated `qase-api-client` to 1.1.13, which adds `shared` to the test step create model.
|
|
17
|
+
|
|
8
18
|
## [2.0.1]
|
|
9
19
|
|
|
10
20
|
### Added
|
|
@@ -13,36 +13,48 @@ export declare const TestStepSchema: z.ZodObject<{
|
|
|
13
13
|
data: z.ZodOptional<z.ZodString>;
|
|
14
14
|
value: z.ZodOptional<z.ZodString>;
|
|
15
15
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
16
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
17
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
16
18
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
17
19
|
action: z.ZodOptional<z.ZodString>;
|
|
18
20
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
19
21
|
data: z.ZodOptional<z.ZodString>;
|
|
20
22
|
value: z.ZodOptional<z.ZodString>;
|
|
21
23
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
24
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
25
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
22
26
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
23
27
|
action: z.ZodOptional<z.ZodString>;
|
|
24
28
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
25
29
|
data: z.ZodOptional<z.ZodString>;
|
|
26
30
|
value: z.ZodOptional<z.ZodString>;
|
|
27
31
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
32
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
33
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
28
34
|
}, z.ZodTypeAny, "passthrough">>, "many">>;
|
|
29
35
|
action: z.ZodOptional<z.ZodString>;
|
|
30
36
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
31
37
|
data: z.ZodOptional<z.ZodString>;
|
|
32
38
|
value: z.ZodOptional<z.ZodString>;
|
|
33
39
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
40
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
41
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
34
42
|
}, "strip", z.ZodTypeAny, {
|
|
35
43
|
value?: string | undefined;
|
|
36
44
|
data?: string | undefined;
|
|
37
45
|
action?: string | undefined;
|
|
38
46
|
expected_result?: string | undefined;
|
|
39
47
|
attachments?: string[] | undefined;
|
|
48
|
+
shared?: string | undefined;
|
|
49
|
+
shared_step_hash?: string | undefined;
|
|
40
50
|
steps?: z.objectOutputType<{
|
|
41
51
|
action: z.ZodOptional<z.ZodString>;
|
|
42
52
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
43
53
|
data: z.ZodOptional<z.ZodString>;
|
|
44
54
|
value: z.ZodOptional<z.ZodString>;
|
|
45
55
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
56
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
57
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
46
58
|
}, z.ZodTypeAny, "passthrough">[] | undefined;
|
|
47
59
|
}, {
|
|
48
60
|
value?: string | undefined;
|
|
@@ -50,12 +62,16 @@ export declare const TestStepSchema: z.ZodObject<{
|
|
|
50
62
|
action?: string | undefined;
|
|
51
63
|
expected_result?: string | undefined;
|
|
52
64
|
attachments?: string[] | undefined;
|
|
65
|
+
shared?: string | undefined;
|
|
66
|
+
shared_step_hash?: string | undefined;
|
|
53
67
|
steps?: z.objectInputType<{
|
|
54
68
|
action: z.ZodOptional<z.ZodString>;
|
|
55
69
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
56
70
|
data: z.ZodOptional<z.ZodString>;
|
|
57
71
|
value: z.ZodOptional<z.ZodString>;
|
|
58
72
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
73
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
74
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
59
75
|
}, z.ZodTypeAny, "passthrough">[] | undefined;
|
|
60
76
|
}>;
|
|
61
77
|
export declare const CaseFieldsSchema: z.ZodObject<{
|
|
@@ -80,36 +96,48 @@ export declare const CaseFieldsSchema: z.ZodObject<{
|
|
|
80
96
|
data: z.ZodOptional<z.ZodString>;
|
|
81
97
|
value: z.ZodOptional<z.ZodString>;
|
|
82
98
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
99
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
100
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
83
101
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
84
102
|
action: z.ZodOptional<z.ZodString>;
|
|
85
103
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
86
104
|
data: z.ZodOptional<z.ZodString>;
|
|
87
105
|
value: z.ZodOptional<z.ZodString>;
|
|
88
106
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
107
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
108
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
89
109
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
90
110
|
action: z.ZodOptional<z.ZodString>;
|
|
91
111
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
92
112
|
data: z.ZodOptional<z.ZodString>;
|
|
93
113
|
value: z.ZodOptional<z.ZodString>;
|
|
94
114
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
115
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
116
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
95
117
|
}, z.ZodTypeAny, "passthrough">>, "many">>;
|
|
96
118
|
action: z.ZodOptional<z.ZodString>;
|
|
97
119
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
98
120
|
data: z.ZodOptional<z.ZodString>;
|
|
99
121
|
value: z.ZodOptional<z.ZodString>;
|
|
100
122
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
123
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
124
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
101
125
|
}, "strip", z.ZodTypeAny, {
|
|
102
126
|
value?: string | undefined;
|
|
103
127
|
data?: string | undefined;
|
|
104
128
|
action?: string | undefined;
|
|
105
129
|
expected_result?: string | undefined;
|
|
106
130
|
attachments?: string[] | undefined;
|
|
131
|
+
shared?: string | undefined;
|
|
132
|
+
shared_step_hash?: string | undefined;
|
|
107
133
|
steps?: z.objectOutputType<{
|
|
108
134
|
action: z.ZodOptional<z.ZodString>;
|
|
109
135
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
110
136
|
data: z.ZodOptional<z.ZodString>;
|
|
111
137
|
value: z.ZodOptional<z.ZodString>;
|
|
112
138
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
139
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
140
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
113
141
|
}, z.ZodTypeAny, "passthrough">[] | undefined;
|
|
114
142
|
}, {
|
|
115
143
|
value?: string | undefined;
|
|
@@ -117,12 +145,16 @@ export declare const CaseFieldsSchema: z.ZodObject<{
|
|
|
117
145
|
action?: string | undefined;
|
|
118
146
|
expected_result?: string | undefined;
|
|
119
147
|
attachments?: string[] | undefined;
|
|
148
|
+
shared?: string | undefined;
|
|
149
|
+
shared_step_hash?: string | undefined;
|
|
120
150
|
steps?: z.objectInputType<{
|
|
121
151
|
action: z.ZodOptional<z.ZodString>;
|
|
122
152
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
123
153
|
data: z.ZodOptional<z.ZodString>;
|
|
124
154
|
value: z.ZodOptional<z.ZodString>;
|
|
125
155
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
156
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
157
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
126
158
|
}, z.ZodTypeAny, "passthrough">[] | undefined;
|
|
127
159
|
}>, "many">>;
|
|
128
160
|
steps_type: z.ZodOptional<z.ZodEnum<["classic", "gherkin"]>>;
|
|
@@ -147,12 +179,16 @@ export declare const CaseFieldsSchema: z.ZodObject<{
|
|
|
147
179
|
action?: string | undefined;
|
|
148
180
|
expected_result?: string | undefined;
|
|
149
181
|
attachments?: string[] | undefined;
|
|
182
|
+
shared?: string | undefined;
|
|
183
|
+
shared_step_hash?: string | undefined;
|
|
150
184
|
steps?: z.objectOutputType<{
|
|
151
185
|
action: z.ZodOptional<z.ZodString>;
|
|
152
186
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
153
187
|
data: z.ZodOptional<z.ZodString>;
|
|
154
188
|
value: z.ZodOptional<z.ZodString>;
|
|
155
189
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
190
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
191
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
156
192
|
}, z.ZodTypeAny, "passthrough">[] | undefined;
|
|
157
193
|
}[] | undefined;
|
|
158
194
|
preconditions?: string | undefined;
|
|
@@ -180,12 +216,16 @@ export declare const CaseFieldsSchema: z.ZodObject<{
|
|
|
180
216
|
action?: string | undefined;
|
|
181
217
|
expected_result?: string | undefined;
|
|
182
218
|
attachments?: string[] | undefined;
|
|
219
|
+
shared?: string | undefined;
|
|
220
|
+
shared_step_hash?: string | undefined;
|
|
183
221
|
steps?: z.objectInputType<{
|
|
184
222
|
action: z.ZodOptional<z.ZodString>;
|
|
185
223
|
expected_result: z.ZodOptional<z.ZodString>;
|
|
186
224
|
data: z.ZodOptional<z.ZodString>;
|
|
187
225
|
value: z.ZodOptional<z.ZodString>;
|
|
188
226
|
attachments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
227
|
+
shared: z.ZodOptional<z.ZodString>;
|
|
228
|
+
shared_step_hash: z.ZodOptional<z.ZodString>;
|
|
189
229
|
}, z.ZodTypeAny, "passthrough">[] | undefined;
|
|
190
230
|
}[] | undefined;
|
|
191
231
|
preconditions?: string | undefined;
|
|
@@ -196,6 +236,15 @@ export declare const CaseFieldsSchema: z.ZodObject<{
|
|
|
196
236
|
steps_type?: "classic" | "gherkin" | undefined;
|
|
197
237
|
tags?: string[] | undefined;
|
|
198
238
|
}>;
|
|
239
|
+
/**
|
|
240
|
+
* Rewrite `shared_step_hash` to `shared` throughout a step tree.
|
|
241
|
+
*
|
|
242
|
+
* The API links a step to a shared step through `shared`, but reports the same
|
|
243
|
+
* link back as `shared_step_hash` — so that is the name callers reach for after
|
|
244
|
+
* reading a case, and sending it produces a confusing "Action field is
|
|
245
|
+
* required". Accept both spellings and send the one the API understands.
|
|
246
|
+
*/
|
|
247
|
+
export declare function resolveSharedStepRefs(steps: unknown): unknown;
|
|
199
248
|
/**
|
|
200
249
|
* Map the user-facing `automation` enum (0=Manual, 1=To be automated,
|
|
201
250
|
* 2=Automated) to the current API contract (`isManual` + `isToBeAutomated`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"case-fields.d.ts","sourceRoot":"","sources":["../../../src/operations-v2/write/case-fields.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"case-fields.d.ts","sourceRoot":"","sources":["../../../src/operations-v2/write/case-fields.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2BxB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMzB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4B3B,CAAC;AAEH;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAmB7D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA0BjG"}
|
|
@@ -7,11 +7,24 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
const stepFields = {
|
|
10
|
-
action: z
|
|
10
|
+
action: z
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe('Step action (classic steps). Not needed when `shared` is set.'),
|
|
11
14
|
expected_result: z.string().optional().describe('Expected result'),
|
|
12
15
|
data: z.string().optional().describe('Test data'),
|
|
13
16
|
value: z.string().optional().describe('Gherkin scenario text (when steps_type is "gherkin")'),
|
|
14
17
|
attachments: z.array(z.string()).optional().describe('Attachment hashes'),
|
|
18
|
+
shared: z
|
|
19
|
+
.string()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe('Hash of an existing shared step to insert at this position, from `qase_shared_step_upsert`. ' +
|
|
22
|
+
'The step then reuses that shared step instead of defining its own content, so `action` ' +
|
|
23
|
+
'can be omitted. Reading the case back reports the link as `shared_step_hash`.'),
|
|
24
|
+
shared_step_hash: z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe('Alias for `shared` — the name used when reading a case. Sent to the API as `shared`.'),
|
|
15
28
|
};
|
|
16
29
|
export const TestStepSchema = z.object({
|
|
17
30
|
...stepFields,
|
|
@@ -47,6 +60,31 @@ export const CaseFieldsSchema = z.object({
|
|
|
47
60
|
attachments: z.array(z.string()).optional(),
|
|
48
61
|
custom_field: z.record(z.any()).optional(),
|
|
49
62
|
});
|
|
63
|
+
/**
|
|
64
|
+
* Rewrite `shared_step_hash` to `shared` throughout a step tree.
|
|
65
|
+
*
|
|
66
|
+
* The API links a step to a shared step through `shared`, but reports the same
|
|
67
|
+
* link back as `shared_step_hash` — so that is the name callers reach for after
|
|
68
|
+
* reading a case, and sending it produces a confusing "Action field is
|
|
69
|
+
* required". Accept both spellings and send the one the API understands.
|
|
70
|
+
*/
|
|
71
|
+
export function resolveSharedStepRefs(steps) {
|
|
72
|
+
if (!Array.isArray(steps))
|
|
73
|
+
return steps;
|
|
74
|
+
return steps.map((step) => {
|
|
75
|
+
if (typeof step !== 'object' || step === null)
|
|
76
|
+
return step;
|
|
77
|
+
const { shared_step_hash: alias, ...rest } = step;
|
|
78
|
+
const resolved = rest;
|
|
79
|
+
if (alias !== undefined && resolved.shared === undefined) {
|
|
80
|
+
resolved.shared = alias;
|
|
81
|
+
}
|
|
82
|
+
if (resolved.steps !== undefined) {
|
|
83
|
+
resolved.steps = resolveSharedStepRefs(resolved.steps);
|
|
84
|
+
}
|
|
85
|
+
return resolved;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
50
88
|
/**
|
|
51
89
|
* Map the user-facing `automation` enum (0=Manual, 1=To be automated,
|
|
52
90
|
* 2=Automated) to the current API contract (`isManual` + `isToBeAutomated`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"case-fields.js","sourceRoot":"","sources":["../../../src/operations-v2/write/case-fields.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,UAAU,GAAG;IACjB,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"case-fields.js","sourceRoot":"","sources":["../../../src/operations-v2/write/case-fields.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { toolRegistry, CreateAnnotation } from '../../utils/registry.js';
|
|
|
4
4
|
import { toResultAsync, createToolError } from '../../utils/errors.js';
|
|
5
5
|
import { ProjectCodeSchema } from '../../utils/validation.js';
|
|
6
6
|
import { normalizeCaseEnums } from '../../utils/case-enums.js';
|
|
7
|
-
import { CaseFieldsSchema, applyAutomationMapping } from './case-fields.js';
|
|
7
|
+
import { CaseFieldsSchema, applyAutomationMapping, resolveSharedStepRefs } from './case-fields.js';
|
|
8
8
|
const CONTEXT = 'bulk case creation';
|
|
9
9
|
/** Qase creates the whole batch in one transaction; 100 keeps the request sane. */
|
|
10
10
|
const MAX_CASES = 100;
|
|
@@ -29,7 +29,13 @@ async function handler(rawArgs) {
|
|
|
29
29
|
const { code, cases } = parsed.data;
|
|
30
30
|
// Same enum handling as qase_case_upsert, so "high" and "blocker" work here
|
|
31
31
|
// too. System fields are cached, so this does not fan out into N API calls.
|
|
32
|
-
const normalized = await Promise.all(cases.map(async (testCase) =>
|
|
32
|
+
const normalized = await Promise.all(cases.map(async (testCase) => {
|
|
33
|
+
const mapped = applyAutomationMapping(await normalizeCaseEnums(testCase));
|
|
34
|
+
if (mapped.steps !== undefined) {
|
|
35
|
+
mapped.steps = resolveSharedStepRefs(mapped.steps);
|
|
36
|
+
}
|
|
37
|
+
return mapped;
|
|
38
|
+
}));
|
|
33
39
|
const client = getApiClient();
|
|
34
40
|
const result = await toResultAsync(client.cases.bulk(code, { cases: normalized }));
|
|
35
41
|
return result.match((r) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cases-bulk.js","sourceRoot":"","sources":["../../../src/operations-v2/write/cases-bulk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"cases-bulk.js","sourceRoot":"","sources":["../../../src/operations-v2/write/cases-bulk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEnG,MAAM,OAAO,GAAG,oBAAoB,CAAC;AAErC,mFAAmF;AACnF,MAAM,SAAS,GAAG,GAAG,CAAC;AAEtB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,IAAI,EAAE,iBAAiB;IACvB,KAAK,EAAE,CAAC;SACL,KAAK,CAAC,gBAAgB,CAAC;SACvB,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,SAAS,EAAE,iCAAiC,SAAS,qCAAqC,CAAC;SAC/F,QAAQ,CAAC,8BAA8B,SAAS,WAAW,CAAC;CAChE,CAAC,CAAC;AAEH,KAAK,UAAU,OAAO,CAAC,OAAgB;IACrC,0EAA0E;IAC1E,2EAA2E;IAC3E,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM;aAChC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,WAAW,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;aAC1E,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,eAAe,CAAC,uBAAuB,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAEpC,4EAA4E;IAC5E,4EAA4E;IAC5E,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1E,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,CAAC,KAAK,GAAG,qBAAqB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,UAAU,EAAS,CAAC,CAAC,CAAC;IAE1F,OAAO,MAAM,CAAC,KAAK,CACjB,CAAC,CAAC,EAAE,EAAE;QACJ,MAAM,GAAG,GAAa,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC;QAC/C,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC;IACtC,CAAC,EACD,CAAC,CAAC,EAAE,EAAE;QACJ,MAAM,eAAe,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC,CACF,CAAC;AACJ,CAAC;AAED,YAAY,CAAC,QAAQ,CAAC;IACpB,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACT,gBAAgB,SAAS,+DAA+D;QACxF,oFAAoF;QACpF,0FAA0F;QAC1F,8FAA8F;QAC9F,wEAAwE;IAC1E,MAAM,EAAE,MAAM;IACd,OAAO;IACP,WAAW,EAAE,gBAAgB;IAC7B,UAAU,EAAE,cAAc;CAC3B,CAAC,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { toolRegistry, CreateAnnotation, DeleteAnnotation } from '../../utils/re
|
|
|
4
4
|
import { toResultAsync, createToolError } from '../../utils/errors.js';
|
|
5
5
|
import { ProjectCodeSchema, IdSchema } from '../../utils/validation.js';
|
|
6
6
|
import { normalizeCaseEnums } from '../../utils/case-enums.js';
|
|
7
|
-
import { CaseFieldsSchema, applyAutomationMapping } from './case-fields.js';
|
|
7
|
+
import { CaseFieldsSchema, applyAutomationMapping, resolveSharedStepRefs } from './case-fields.js';
|
|
8
8
|
const UpsertSchema = z.object({
|
|
9
9
|
code: ProjectCodeSchema,
|
|
10
10
|
id: IdSchema.optional().describe('Case ID — if provided, updates the case; if omitted, creates a new one'),
|
|
@@ -18,6 +18,9 @@ async function upsert(args) {
|
|
|
18
18
|
const client = getApiClient();
|
|
19
19
|
const { code, id, ...data } = args;
|
|
20
20
|
const normalized = applyAutomationMapping(await normalizeCaseEnums(data));
|
|
21
|
+
if (normalized.steps !== undefined) {
|
|
22
|
+
normalized.steps = resolveSharedStepRefs(normalized.steps);
|
|
23
|
+
}
|
|
21
24
|
const result = await toResultAsync(id
|
|
22
25
|
? client.cases.updateCase(code, id, normalized)
|
|
23
26
|
: client.cases.createCase(code, normalized));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cases.js","sourceRoot":"","sources":["../../../src/operations-v2/write/cases.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"cases.js","sourceRoot":"","sources":["../../../src/operations-v2/write/cases.ts"],"names":[],"mappings":"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"}
|
package/build/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "2.0.
|
|
1
|
+
export declare const VERSION = "2.0.2";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/build/version.js
CHANGED
package/docs/tools.md
CHANGED
|
@@ -34,8 +34,8 @@ Every tool's schema uses "label or numeric ID" strings for Qase's configurable e
|
|
|
34
34
|
|
|
35
35
|
| Tool | Description | Key params | Visibility |
|
|
36
36
|
| --- | --- | --- | --- |
|
|
37
|
-
| `qase_case_upsert` | Create or update a test case. If `id` is provided, updates the existing case; if omitted, creates a new one. Enum fields (priority, severity, type, etc.) accept both labels ("high", "blocker") and numeric IDs — the server normalizes automatically. | `code`, `id` (optional), `title` (1-255 chars), `description`, `preconditions`, `postconditions`, `severity`, `priority`, `type`, `layer`, `behavior`, `automation`, `status` (all label-or-ID strings), `is_flaky`, `suite_id`, `milestone_id`, `steps` (array, supports nesting), `steps_type` (enum: classic, gherkin), `tags`, `attachments`, `custom_field` | core |
|
|
38
|
-
| `qase_case_bulk_create` | Create up to 100 test cases in a single request. Use instead of calling `qase_case_upsert` repeatedly when importing or generating several cases at once. Enum fields accept labels or numeric IDs. Creates only — use `qase_case_upsert` with an `id` to update. Returns the IDs of the created cases in submission order. | `code`, `cases` (array, 1-100 — same fields as `qase_case_upsert` without `id`) | discoverable |
|
|
37
|
+
| `qase_case_upsert` | Create or update a test case. If `id` is provided, updates the existing case; if omitted, creates a new one. Enum fields (priority, severity, type, etc.) accept both labels ("high", "blocker") and numeric IDs — the server normalizes automatically. | `code`, `id` (optional), `title` (1-255 chars), `description`, `preconditions`, `postconditions`, `severity`, `priority`, `type`, `layer`, `behavior`, `automation`, `status` (all label-or-ID strings), `is_flaky`, `suite_id`, `milestone_id`, `steps` (array, supports nesting; a step may reference a shared step via `shared` — the shared step hash — instead of `action`), `steps_type` (enum: classic, gherkin), `tags`, `attachments`, `custom_field` | core |
|
|
38
|
+
| `qase_case_bulk_create` | Create up to 100 test cases in a single request. Use instead of calling `qase_case_upsert` repeatedly when importing or generating several cases at once. Enum fields accept labels or numeric IDs. Creates only — use `qase_case_upsert` with an `id` to update. Returns the IDs of the created cases in submission order. | `code`, `cases` (array, 1-100 — same fields as `qase_case_upsert` without `id`, including `shared` step references) | discoverable |
|
|
39
39
|
| `qase_case_delete` | Delete a test case by project code and case ID. | `code`, `id` | discoverable |
|
|
40
40
|
| `qase_defect_upsert` | Create or update a defect. If `id` is provided, updates (including status changes and resolve). If omitted, creates a new defect. Set `status: "resolved"` to resolve an existing defect. | `code`, `id` (optional), `title` (1-255 chars), `actual_result`, `severity` (enum, see [below](#case-enum-values)), `status` (enum: open, in_progress, resolved, invalid), `tags`, `attachments`, `custom_field` | core |
|
|
41
41
|
| `qase_defect_delete` | Delete a defect by project code and defect ID. | `code`, `id` | discoverable |
|
|
@@ -60,6 +60,9 @@ Every tool's schema uses "label or numeric ID" strings for Qase's configurable e
|
|
|
60
60
|
|
|
61
61
|
</details>
|
|
62
62
|
|
|
63
|
+
To insert a shared step into a test case, pass its hash as `shared` on a step object in `qase_case_upsert` or `qase_case_bulk_create`: `{"steps": [{"shared": "<hash>"}]}`. `action` is not required for such a step, and nesting is supported. The read side of the API reports the link as `shared_step_hash`; that spelling is accepted on write too and is translated automatically.
|
|
64
|
+
|
|
65
|
+
|
|
63
66
|
## Composite tools
|
|
64
67
|
|
|
65
68
|
Composite tools chain several underlying operations into one call, so an agent avoids multi-step round-trips for common workflows.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qase/mcp-server",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"mcpName": "io.qase/mcp-server",
|
|
5
5
|
"description": "Official MCP server for Qase Test Management Platform",
|
|
6
6
|
"type": "module",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"lru-cache": "^11.3.5",
|
|
76
76
|
"neverthrow": "^8.2.0",
|
|
77
77
|
"npm": "^12.0.2",
|
|
78
|
-
"qase-api-client": "^1.1.
|
|
78
|
+
"qase-api-client": "^1.1.13",
|
|
79
79
|
"zod": "^3.24.2",
|
|
80
80
|
"zod-to-json-schema": "^3.24.3"
|
|
81
81
|
},
|
package/server.json
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"url": "https://github.com/qase-tms/qase-mcp-server",
|
|
9
9
|
"source": "github"
|
|
10
10
|
},
|
|
11
|
-
"version": "2.0.
|
|
11
|
+
"version": "2.0.2",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"identifier": "@qase/mcp-server",
|
|
16
|
-
"version": "2.0.
|
|
16
|
+
"version": "2.0.2",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
},
|