@smartbear/mcp 0.7.0 → 0.9.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.
Files changed (52) hide show
  1. package/README.md +19 -2
  2. package/dist/api-hub/client/api.js +198 -23
  3. package/dist/api-hub/client/registry-types.js +22 -0
  4. package/dist/api-hub/client/tools.js +19 -1
  5. package/dist/api-hub/client.js +9 -0
  6. package/dist/bugsnag/client/api/CurrentUser.js +13 -50
  7. package/dist/bugsnag/client/api/Error.js +30 -155
  8. package/dist/bugsnag/client/api/Project.js +56 -124
  9. package/dist/bugsnag/client/api/api.js +3743 -0
  10. package/dist/bugsnag/client/api/base.js +107 -32
  11. package/dist/bugsnag/client/api/configuration.js +26 -0
  12. package/dist/bugsnag/client/api/index.js +2 -0
  13. package/dist/bugsnag/client/filters.js +28 -0
  14. package/dist/bugsnag/client.js +157 -325
  15. package/dist/common/server.js +29 -4
  16. package/dist/common/types.js +6 -1
  17. package/dist/index.js +8 -1
  18. package/dist/pactflow/client/prompt-utils.js +2 -1
  19. package/dist/pactflow/client/tools.js +9 -9
  20. package/dist/pactflow/client/utils.js +5 -4
  21. package/dist/pactflow/client.js +16 -14
  22. package/dist/qmetry/client/api/client-api.js +21 -16
  23. package/dist/qmetry/client/api/error-handler.js +329 -0
  24. package/dist/qmetry/client/auto-resolve.js +74 -0
  25. package/dist/qmetry/client/handlers.js +19 -2
  26. package/dist/qmetry/client/issues.js +26 -0
  27. package/dist/qmetry/client/project.js +56 -0
  28. package/dist/qmetry/client/requirement.js +76 -0
  29. package/dist/qmetry/client/testcase.js +46 -8
  30. package/dist/qmetry/client/testsuite.js +117 -0
  31. package/dist/qmetry/client/tools.js +1455 -4
  32. package/dist/qmetry/client/utils.js +16 -0
  33. package/dist/qmetry/client.js +19 -16
  34. package/dist/qmetry/config/constants.js +14 -0
  35. package/dist/qmetry/config/rest-endpoints.js +20 -0
  36. package/dist/qmetry/types/common.js +313 -8
  37. package/dist/qmetry/types/issues.js +6 -0
  38. package/dist/qmetry/types/project.js +10 -0
  39. package/dist/qmetry/types/requirements.js +19 -0
  40. package/dist/qmetry/types/testcase.js +14 -0
  41. package/dist/qmetry/types/testsuite.js +26 -0
  42. package/dist/reflect/client.js +7 -6
  43. package/dist/zephyr/client.js +16 -0
  44. package/dist/zephyr/common/api-client.js +27 -0
  45. package/dist/zephyr/common/auth-service.js +15 -0
  46. package/dist/zephyr/common/types.js +35 -0
  47. package/dist/zephyr/tool/project/get-projects.js +54 -0
  48. package/dist/zephyr/tool/zephyr-tool.js +1 -0
  49. package/package.json +3 -2
  50. package/dist/bugsnag/client/api/filters.js +0 -167
  51. package/dist/bugsnag/client/configuration.js +0 -10
  52. package/dist/bugsnag/client/index.js +0 -2
@@ -0,0 +1,16 @@
1
+ import { QMETRY_DEFAULTS } from "../config/constants.js";
2
+ /**
3
+ * Shared utility functions for QMetry client modules
4
+ */
5
+ /**
6
+ * Resolves default values for baseUrl and project parameters
7
+ * @param baseUrl - Optional base URL, defaults to QMETRY_DEFAULTS.BASE_URL
8
+ * @param project - Optional project key, defaults to QMETRY_DEFAULTS.PROJECT_KEY
9
+ * @returns Object with resolved baseUrl and project values
10
+ */
11
+ export function resolveDefaults(baseUrl, project) {
12
+ return {
13
+ resolvedBaseUrl: baseUrl || QMETRY_DEFAULTS.BASE_URL,
14
+ resolvedProject: project || QMETRY_DEFAULTS.PROJECT_KEY,
15
+ };
16
+ }
@@ -1,7 +1,8 @@
1
+ import { autoResolveViewIdAndFolderPath, findAutoResolveConfig, } from "./client/auto-resolve.js";
1
2
  import { QMETRY_HANDLER_MAP } from "./client/handlers.js";
2
3
  import { getProjectInfo } from "./client/project.js";
3
4
  import { TOOLS } from "./client/tools.js";
4
- import { QMETRY_DEFAULTS, QMetryToolsHandlers } from "./config/constants.js";
5
+ import { QMETRY_DEFAULTS } from "./config/constants.js";
5
6
  export class QmetryClient {
6
7
  name = "QMetry";
7
8
  prefix = "qmetry";
@@ -49,31 +50,33 @@ export class QmetryClient {
49
50
  register(tool, (args) => handleAsync(async () => {
50
51
  const a = args;
51
52
  const { baseUrl, projectKey } = resolveContext(a);
52
- // handling for FETCH_TEST_CASES to auto-resolve viewId and folderPath
53
- if (tool.handler === QMetryToolsHandlers.FETCH_TEST_CASES) {
54
- let viewId = a.viewId;
55
- let folderPath = a.folderPath;
56
- if (!viewId || folderPath === undefined) {
53
+ // Dynamic auto-resolve for modules that support viewId, folderPath, and folderID
54
+ const autoResolveConfig = findAutoResolveConfig(tool.handler);
55
+ if (autoResolveConfig) {
56
+ // Check if we need to auto-resolve viewId, folderPath, or folderID
57
+ const needsViewIdResolve = !a.viewId && autoResolveConfig.viewIdPath;
58
+ const needsFolderPathResolve = a.folderPath === undefined;
59
+ const needsFolderIdResolve = autoResolveConfig.folderIdField &&
60
+ !a[autoResolveConfig.folderIdField];
61
+ if (needsViewIdResolve ||
62
+ needsFolderPathResolve ||
63
+ needsFolderIdResolve) {
57
64
  let projectInfo;
58
65
  try {
59
66
  projectInfo = (await getProjectInfo(this.token, baseUrl, projectKey));
60
67
  }
61
68
  catch (err) {
62
- throw new Error(`Failed to auto-resolve viewId/folderPath for project ${projectKey}. ` +
69
+ throw new Error(`Failed to auto-resolve viewId/folderPath/folderID for ${autoResolveConfig.moduleName} in project ${projectKey}. ` +
63
70
  `Please provide them manually or check project access. ` +
64
71
  `Error: ${err instanceof Error ? err.message : String(err)}`);
65
72
  }
66
- if (!viewId && projectInfo?.latestViews?.TC?.viewId) {
67
- viewId = projectInfo.latestViews.TC.viewId;
68
- }
69
- if (folderPath === undefined) {
70
- folderPath = "";
71
- }
73
+ // Apply auto-resolution using the dynamic configuration
74
+ Object.assign(a, autoResolveViewIdAndFolderPath(a, projectInfo, autoResolveConfig));
72
75
  }
73
- a.viewId = viewId;
74
- a.folderPath = folderPath;
75
76
  }
76
- const result = await handlerFn(this.token, baseUrl, projectKey, a);
77
+ // Extract projectKey and baseUrl from arguments to prevent them from being sent in request body
78
+ const { projectKey: _, baseUrl: __, ...cleanArgs } = a;
79
+ const result = await handlerFn(this.token, baseUrl, projectKey, cleanArgs);
77
80
  // Use custom formatter if available, otherwise return JSON
78
81
  const formatted = tool.formatResponse
79
82
  ? tool.formatResponse(result)
@@ -5,8 +5,22 @@ export const QMETRY_DEFAULTS = {
5
5
  export const QMetryToolsHandlers = {
6
6
  SET_PROJECT_INFO: "setProjectInfo",
7
7
  FETCH_PROJECT_INFO: "getProjectInfo",
8
+ FETCH_RELEASES_CYCLES: "getReleasesCycles",
9
+ FETCH_BUILDS: "getBuilds",
10
+ FETCH_PLATFORMS: "getPlatforms",
8
11
  FETCH_TEST_CASES: "getTestCases",
9
12
  FETCH_TEST_CASE_DETAILS: "getTestCaseDetails",
10
13
  FETCH_TEST_CASE_VERSION_DETAILS: "getTestCaseVersionDetails",
11
14
  FETCH_TEST_CASE_STEPS: "getTestCaseSteps",
15
+ FETCH_TEST_CASE_EXECUTIONS: "getTestCaseExecutions",
16
+ FETCH_REQUIREMENTS: "getRequirements",
17
+ FETCH_REQUIREMENT_DETAILS: "getRequirementDetails",
18
+ FETCH_TESTCASES_LINKED_TO_REQUIREMENT: "getTestCasesLinkedToRequirement",
19
+ FETCH_REQUIREMENTS_LINKED_TO_TESTCASE: "getRequirementsLinkedToTestCase",
20
+ FETCH_TESTSUITES_FOR_TESTCASE: "getTestSuitesForTestCase",
21
+ FETCH_TESTCASES_BY_TESTSUITE: "getTestCasesByTestSuite",
22
+ FETCH_EXECUTIONS_BY_TESTSUITE: "getExecutionsByTestSuite",
23
+ FETCH_TESTCASE_RUNS_BY_TESTSUITE_RUN: "getTestCaseRunsByTestSuiteRun",
24
+ FETCH_LINKED_ISSUES_BY_TESTCASE_RUN: "getLinkedIssuesByTestCaseRun",
25
+ FETCH_ISSUES_LINKED_TO_TESTCASE: "getIssuesLinkedToTestCase",
12
26
  };
@@ -1,11 +1,31 @@
1
1
  export const QMETRY_PATHS = {
2
2
  PROJECT: {
3
3
  GET_INFO: "/rest/admin/project/getinfo",
4
+ GET_RELEASES_CYCLES: "/rest/admin/scope/tree",
5
+ GET_BUILD: "/rest/admin/drop/list",
6
+ GET_PLATFORMS: "/rest/admin/platform/list",
4
7
  },
5
8
  TESTCASE: {
6
9
  GET_TC_LIST: "/rest/testcases/list/viewColumns",
7
10
  GET_TC_DETAILS: "/rest/testcases/getVersionDetail",
8
11
  GET_TC_DETAILS_BY_VERSION: "/rest/testcases/list",
9
12
  GET_TC_STEPS: "/rest/testcases/steps/list",
13
+ GET_TC_EXECUTIONS: "/rest/testcases/execution",
14
+ GET_TC_LINKED_TO_RQ: "/rest/testcases/list/forRQ",
15
+ },
16
+ REQUIREMENT: {
17
+ GET_RQ_LIST: "/rest/requirements/list/viewColumns",
18
+ GET_RQ_DETAILS: "/rest/requirements/detail/data",
19
+ GET_RQ_LINKED_TO_TC: "/rest/requirements/list/forTC",
20
+ },
21
+ TESTSUITE: {
22
+ GET_TS_LIST_FOR_TC: "/rest/testsuites/list/forTC",
23
+ GET_TESTCASES_BY_TESTSUITE: "/rest/testcases/list/forTS",
24
+ GET_EXECUTIONS_BY_TESTSUITE: "/rest/execution/list/platformHome",
25
+ GET_TESTCASE_RUNS_BY_TESTSUITE_RUN: "/rest/execution/list/viewColumns",
26
+ GET_LINKED_ISSUES_BY_TESTCASE_RUN: "/rest/execution/issue/list/forTCRun",
27
+ },
28
+ ISSUES: {
29
+ GET_ISSUES_LINKED_TO_TC: "/rest/issues/list/ForTC",
10
30
  },
11
31
  };
@@ -8,6 +8,9 @@ export const DEFAULT_PAGINATION = {
8
8
  export const DEFAULT_FILTER = {
9
9
  filter: "[]",
10
10
  };
11
+ export const DEFAULT_SORT = {
12
+ sort: '[{"property":"name","direction":"ASC"}]',
13
+ };
11
14
  export const DEFAULT_FOLDER_OPTIONS = {
12
15
  scope: "project",
13
16
  showRootOnly: false,
@@ -52,7 +55,7 @@ export const CommonFields = {
52
55
  .default(10),
53
56
  tcID: z
54
57
  .number()
55
- .describe("Test Case numeric ID (required for fetching specific test case details). " +
58
+ .describe("Test Case numeric ID. " +
56
59
  "This is the internal numeric identifier, not the entity key like 'MAC-TC-1684'. " +
57
60
  "You can get this ID from test case search results or by using filters."),
58
61
  id: z
@@ -62,20 +65,42 @@ export const CommonFields = {
62
65
  "You can get this ID from test case search results."),
63
66
  version: z
64
67
  .number()
65
- .describe("Test Case version number (required for fetching specific test case version details). " +
68
+ .describe("Test Case version number. " +
66
69
  "This is the internal numeric identifier for the version."),
67
70
  versionOptional: z
68
71
  .number()
69
72
  .optional()
70
73
  .describe("Test Case version number (optional, defaults to 1). " +
71
74
  "This is the internal numeric identifier for the version."),
72
- viewId: z
75
+ rqID: z
76
+ .number()
77
+ .describe("Requirement numeric ID (required for fetching specific requirement details). " +
78
+ "This is the internal numeric identifier, not the entity key like 'MAC-RQ-730'. " +
79
+ "You can get this ID from requirement search results or by using filters."),
80
+ rqVersion: z
81
+ .number()
82
+ .describe("Requirement version number (required for fetching specific requirement version details). " +
83
+ "This is the internal numeric identifier for the version."),
84
+ tcViewId: z
73
85
  .number()
74
86
  .describe("ViewId for test cases - SYSTEM AUTOMATICALLY RESOLVES THIS. " +
75
87
  "Leave empty unless you have a specific viewId. " +
76
88
  "System will fetch project info using the projectKey and extract latestViews.TC.viewId automatically. " +
77
89
  "Manual viewId only needed if you want to override the automatic resolution."),
78
- folderPath: z
90
+ rqViewId: z
91
+ .number()
92
+ .describe("ViewId for requirements - SYSTEM AUTOMATICALLY RESOLVES THIS. " +
93
+ "Leave empty unless you have a specific viewId. " +
94
+ "System will fetch project info using the projectKey and extract latestViews.RQ.viewId automatically. " +
95
+ "Manual viewId only needed if you want to override the automatic resolution."),
96
+ rqFolderPath: z
97
+ .string()
98
+ .optional()
99
+ .describe("Folder path for requirements - SYSTEM AUTOMATICALLY SETS TO ROOT. " +
100
+ 'Leave empty unless you want specific folder. System will automatically use "" (root directory). ' +
101
+ 'Only specify if user wants specific folder like "Automation/Regression".')
102
+ .default(""),
103
+ tcFolderPath: z
79
104
  .string()
80
105
  .optional()
81
106
  .describe("Folder path for test cases - SYSTEM AUTOMATICALLY SETS TO ROOT. " +
@@ -85,11 +110,74 @@ export const CommonFields = {
85
110
  folderID: z
86
111
  .number()
87
112
  .optional()
88
- .describe("Folder ID for test cases - unique identifier for the folder containing test cases"),
113
+ .describe("Folder ID - unique numeric identifier for the specific folder. " +
114
+ "Use this to target a specific folder within the project hierarchy. " +
115
+ "Applies to any entity type (test cases, requirements, test suites, etc.)."),
116
+ tsFolderID: z
117
+ .number()
118
+ .describe("Test Suite folder ID (required for fetching test suites). " +
119
+ "This is the numeric identifier for the test suite folder. " +
120
+ "IMPORTANT: Get from project info response → rootFolders.TS.id (e.g., 113557 for MAC project). " +
121
+ "Use FETCH_PROJECT_INFO tool first to get this ID if not provided by user. " +
122
+ "For root folder: use rootFolders.TS.id, for sub-folders: use specific folder IDs."),
123
+ tsID: z
124
+ .number()
125
+ .describe("Test Suite numeric ID (required for fetching test cases linked to test suite). " +
126
+ "This is the internal numeric identifier, not the entity key. " +
127
+ "NOTE: To get the tsID - Call API 'Testsuite/Fetch Testsuite' " +
128
+ "From the response, get value of following attribute -> data[<index>].id"),
129
+ gridName: z
130
+ .string()
131
+ .optional()
132
+ .describe("Grid Name to be displayed (default 'TESTEXECUTIONLIST')"),
133
+ teViewId: z
134
+ .number()
135
+ .optional()
136
+ .describe("ViewId for test execution - SYSTEM AUTOMATICALLY RESOLVES THIS. " +
137
+ "Leave empty unless you have a specific viewId. " +
138
+ "System will fetch project info using the projectKey and extract latestViews.TE.viewId automatically. " +
139
+ "Manual viewId only needed if you want to override the automatic resolution."),
140
+ tsfeViewId: z
141
+ .number()
142
+ .describe("ViewId for test suite folders - SYSTEM AUTOMATICALLY RESOLVES THIS. " +
143
+ "Leave empty unless you have a specific viewId. " +
144
+ "System will fetch project info using the projectKey and extract latestViews.TSFS.viewId automatically. " +
145
+ "Manual viewId only needed if you want to override the automatic resolution."),
146
+ tsrunID: z
147
+ .string()
148
+ .describe("Test Suite Run ID (required for fetching test case runs). " +
149
+ "This is the string identifier for the test suite run execution. " +
150
+ "NOTE: To get the tsrunID - Call API 'Execution/Fetch Executions' " +
151
+ "From the response, get value of following attribute -> data[<index>].tsRunID"),
152
+ showTcWithDefects: z
153
+ .boolean()
154
+ .optional()
155
+ .describe("Show test case runs with linked defects")
156
+ .default(false),
157
+ entityId: z
158
+ .number()
159
+ .describe("Id of Test case run (required for fetching linked issues). " +
160
+ "This is the internal numeric identifier for the test case run execution. " +
161
+ "NOTE: To get the entityId - Call API 'Execution/Fetch Testcase Run ID' " +
162
+ "From the response, get value of following attribute -> data[<index>].tcRunID"),
163
+ getLinked: z
164
+ .boolean()
165
+ .optional()
166
+ .describe("True to get only those issues that are linked with this Test case Run, " +
167
+ "False to get those issues which are not linked with this Test case Run. " +
168
+ "Default value true (get linked issues).")
169
+ .default(true),
170
+ istcrFlag: z
171
+ .boolean()
172
+ .optional()
173
+ .describe("Set True for test case run operations")
174
+ .default(true),
89
175
  scope: z
90
176
  .string()
91
177
  .optional()
92
- .describe("Scope of the test cases (default 'project')")
178
+ .describe("Scope of the operation - defines the context for data retrieval. " +
179
+ "Common values: 'project' (default), 'folder', 'release', 'cycle'. " +
180
+ "Applies to any entity type being fetched or operated upon.")
93
181
  .default("project"),
94
182
  filter: z
95
183
  .string()
@@ -109,6 +197,11 @@ export const CommonFields = {
109
197
  .boolean()
110
198
  .optional()
111
199
  .describe("Whether to include sub-entities."),
200
+ getColumns: z
201
+ .boolean()
202
+ .optional()
203
+ .describe("Whether to get column information in response.")
204
+ .default(true),
112
205
  hideEmptyFolders: z
113
206
  .boolean()
114
207
  .optional()
@@ -125,15 +218,47 @@ export const CommonFields = {
125
218
  .string()
126
219
  .optional()
127
220
  .describe("Folder sort order (ASC or DESC)"),
221
+ showArchive: z
222
+ .boolean()
223
+ .optional()
224
+ .describe("Whether to include archived records in the results. " +
225
+ "When true, returns both active and archived items. " +
226
+ "When false, returns only active (non-archived) items. " +
227
+ "Applies to any entity type being fetched (test cases, requirements, releases, cycles, builds, platforms, etc.)."),
128
228
  };
129
229
  export const ProjectArgsSchema = z.object({
130
230
  projectKey: CommonFields.projectKey,
131
231
  });
232
+ export const ReleasesCyclesArgsSchema = z.object({
233
+ projectKey: CommonFields.projectKeyOptional,
234
+ showArchive: CommonFields.showArchive,
235
+ });
236
+ export const BuildArgsSchema = z.object({
237
+ projectKey: CommonFields.projectKeyOptional,
238
+ baseUrl: CommonFields.baseUrl,
239
+ start: CommonFields.start,
240
+ page: CommonFields.page,
241
+ limit: CommonFields.limit,
242
+ filter: CommonFields.filter,
243
+ });
244
+ export const PlatformArgsSchema = z.object({
245
+ projectKey: CommonFields.projectKeyOptional,
246
+ baseUrl: CommonFields.baseUrl,
247
+ start: CommonFields.start,
248
+ page: CommonFields.page,
249
+ limit: CommonFields.limit,
250
+ sort: z
251
+ .string()
252
+ .optional()
253
+ .describe('Sort criteria as JSON string (default \'[{"property":"platformID","direction":"DESC"}]\')')
254
+ .default('[{"property":"platformID","direction":"DESC"}]'),
255
+ filter: CommonFields.filter,
256
+ });
132
257
  export const TestCaseListArgsSchema = z.object({
133
258
  projectKey: CommonFields.projectKeyOptional,
134
259
  baseUrl: CommonFields.baseUrl,
135
- viewId: CommonFields.viewId,
136
- folderPath: CommonFields.folderPath,
260
+ viewId: CommonFields.tcViewId,
261
+ folderPath: CommonFields.tcFolderPath,
137
262
  folderID: CommonFields.folderID,
138
263
  start: CommonFields.start,
139
264
  page: CommonFields.page,
@@ -172,3 +297,183 @@ export const TestCaseStepsArgsSchema = z.object({
172
297
  page: CommonFields.page,
173
298
  limit: CommonFields.limit,
174
299
  });
300
+ export const TestCaseExecutionsArgsSchema = z.object({
301
+ projectKey: CommonFields.projectKeyOptional,
302
+ baseUrl: CommonFields.baseUrl,
303
+ tcid: CommonFields.tcID,
304
+ tcversion: CommonFields.versionOptional,
305
+ start: CommonFields.start,
306
+ page: CommonFields.page,
307
+ limit: CommonFields.limit,
308
+ scope: CommonFields.scope,
309
+ filter: CommonFields.filter,
310
+ });
311
+ export const RequirementListArgsSchema = z.object({
312
+ projectKey: CommonFields.projectKeyOptional,
313
+ baseUrl: CommonFields.baseUrl,
314
+ viewId: CommonFields.rqViewId,
315
+ folderPath: CommonFields.rqFolderPath,
316
+ start: CommonFields.start,
317
+ page: CommonFields.page,
318
+ limit: CommonFields.limit,
319
+ scope: CommonFields.scope,
320
+ getSubEntities: CommonFields.getSubEntities,
321
+ hideEmptyFolders: CommonFields.hideEmptyFolders,
322
+ folderSortColumn: CommonFields.folderSortColumn,
323
+ folderSortOrder: CommonFields.folderSortOrder,
324
+ isJiraFilter: z
325
+ .boolean()
326
+ .optional()
327
+ .describe("'false' if using qmetry filter")
328
+ .default(false),
329
+ filterType: z
330
+ .enum(["QMETRY", "JIRA"])
331
+ .optional()
332
+ .describe("Pass 'QMETRY' or 'JIRA'")
333
+ .default("QMETRY"),
334
+ filter: CommonFields.filter,
335
+ udfFilter: CommonFields.udfFilter,
336
+ sort: z
337
+ .string()
338
+ .optional()
339
+ .describe("Sort Records - refer json schema, Possible property - name, entityKey, associatedVersion, priorityAlias, createdDate, createdByAlias, updatedDate, updatedByAlias, requirementStateAlias, linkedTcCount, linkedDfCount, attachmentCount, createdSystem, owner")
340
+ .default('[{"property":"name","direction":"ASC"}]'),
341
+ });
342
+ export const RequirementDetailsArgsSchema = z.object({
343
+ projectKey: CommonFields.projectKeyOptional,
344
+ baseUrl: CommonFields.baseUrl,
345
+ id: CommonFields.rqID,
346
+ version: CommonFields.rqVersion,
347
+ });
348
+ export const RequirementsLinkedToTestCaseArgsSchema = z.object({
349
+ projectKey: CommonFields.projectKeyOptional,
350
+ baseUrl: CommonFields.baseUrl,
351
+ tcID: CommonFields.tcID,
352
+ getLinked: z
353
+ .boolean()
354
+ .optional()
355
+ .describe("True to get only requirements that are linked with this test case, " +
356
+ "false to get requirements which are not linked with this test case. " +
357
+ "Defaults to true (get linked requirements).")
358
+ .default(true),
359
+ start: CommonFields.start,
360
+ page: CommonFields.page,
361
+ limit: CommonFields.limit,
362
+ rqFolderPath: CommonFields.rqFolderPath,
363
+ filter: CommonFields.filter,
364
+ });
365
+ export const TestCasesLinkedToRequirementArgsSchema = z.object({
366
+ projectKey: CommonFields.projectKeyOptional,
367
+ baseUrl: CommonFields.baseUrl,
368
+ rqID: CommonFields.rqID,
369
+ getLinked: z
370
+ .boolean()
371
+ .optional()
372
+ .describe("True to get only test cases that are linked with this requirement, " +
373
+ "false to get test cases which are not linked with this requirement. " +
374
+ "Defaults to true (get linked test cases).")
375
+ .default(true),
376
+ showEntityWithReleaseCycle: z
377
+ .boolean()
378
+ .optional()
379
+ .describe("True to list only test cases which have given release and cycle, " +
380
+ "false for all test cases regardless of release/cycle association. " +
381
+ "Defaults to false (show all).")
382
+ .default(false),
383
+ start: CommonFields.start,
384
+ page: CommonFields.page,
385
+ limit: CommonFields.limit,
386
+ tcFolderPath: z
387
+ .string()
388
+ .optional()
389
+ .describe("Folder path to get test cases under specific folder. " +
390
+ 'Use empty string "" for root folder or specify path like "/Sample Template".')
391
+ .default(""),
392
+ releaseID: z
393
+ .string()
394
+ .optional()
395
+ .describe("Filter test cases by release ID. " +
396
+ "Use string representation of release ID (e.g., '7138'). " +
397
+ "Get release IDs from FETCH_RELEASES_AND_CYCLES tool."),
398
+ cycleID: z
399
+ .string()
400
+ .optional()
401
+ .describe("Filter test cases by cycle ID. " +
402
+ "Use string representation of cycle ID (e.g., '13382'). " +
403
+ "Get cycle IDs from FETCH_RELEASES_AND_CYCLES tool."),
404
+ filter: CommonFields.filter,
405
+ getSubEntities: z
406
+ .boolean()
407
+ .optional()
408
+ .describe("Allow filter of sub-entities for requirement.")
409
+ .default(true),
410
+ getColumns: z
411
+ .boolean()
412
+ .optional()
413
+ .describe("True to get column information in response.")
414
+ .default(true),
415
+ });
416
+ export const TestSuitesForTestCaseArgsSchema = z.object({
417
+ projectKey: CommonFields.projectKeyOptional,
418
+ baseUrl: CommonFields.baseUrl,
419
+ tsFolderID: CommonFields.tsFolderID,
420
+ viewId: CommonFields.tsfeViewId.optional(),
421
+ start: CommonFields.start,
422
+ page: CommonFields.page,
423
+ limit: CommonFields.limit,
424
+ getColumns: CommonFields.getColumns,
425
+ filter: CommonFields.filter,
426
+ });
427
+ export const IssuesLinkedToTestCaseArgsSchema = z.object({
428
+ projectKey: CommonFields.projectKeyOptional,
429
+ baseUrl: CommonFields.baseUrl,
430
+ tcID: CommonFields.tcID,
431
+ getLinked: CommonFields.getLinked.optional().default(true),
432
+ start: CommonFields.start,
433
+ page: CommonFields.page,
434
+ limit: CommonFields.limit,
435
+ filter: CommonFields.filter,
436
+ });
437
+ export const TestCasesByTestSuiteArgsSchema = z.object({
438
+ projectKey: CommonFields.projectKeyOptional,
439
+ baseUrl: CommonFields.baseUrl,
440
+ tsID: CommonFields.tsID,
441
+ getLinked: CommonFields.getLinked.optional().default(true),
442
+ start: CommonFields.start,
443
+ page: CommonFields.page,
444
+ limit: CommonFields.limit,
445
+ filter: CommonFields.filter,
446
+ });
447
+ export const ExecutionsByTestSuiteArgsSchema = z.object({
448
+ projectKey: CommonFields.projectKeyOptional,
449
+ baseUrl: CommonFields.baseUrl,
450
+ tsID: CommonFields.tsID, // API payload param - sent in request body (REQUIRED)
451
+ tsFolderID: CommonFields.tsFolderID.optional(),
452
+ gridName: CommonFields.gridName,
453
+ viewId: CommonFields.teViewId,
454
+ start: CommonFields.start,
455
+ page: CommonFields.page,
456
+ limit: CommonFields.limit,
457
+ filter: CommonFields.filter,
458
+ });
459
+ export const TestCaseRunsByTestSuiteRunArgsSchema = z.object({
460
+ projectKey: CommonFields.projectKeyOptional,
461
+ baseUrl: CommonFields.baseUrl,
462
+ tsrunID: CommonFields.tsrunID, // API payload param - sent in request body (REQUIRED)
463
+ viewId: CommonFields.teViewId.pipe(z.number()), // API payload param - sent in request body (REQUIRED)
464
+ start: CommonFields.start,
465
+ page: CommonFields.page,
466
+ limit: CommonFields.limit,
467
+ });
468
+ export const LinkedIssuesByTestCaseRunArgsSchema = z.object({
469
+ projectKey: CommonFields.projectKeyOptional,
470
+ baseUrl: CommonFields.baseUrl,
471
+ entityId: CommonFields.entityId, // API payload param - sent in request body (REQUIRED)
472
+ getLinked: CommonFields.getLinked,
473
+ getColumns: CommonFields.getColumns,
474
+ istcrFlag: CommonFields.istcrFlag,
475
+ start: CommonFields.start,
476
+ page: CommonFields.page,
477
+ limit: CommonFields.limit,
478
+ filter: CommonFields.filter,
479
+ });
@@ -0,0 +1,6 @@
1
+ import { DEFAULT_FILTER, DEFAULT_PAGINATION, } from "./common.js";
2
+ export const DEFAULT_FETCH_ISSUES_LINKED_TO_TESTCASE_PAYLOAD = {
3
+ ...DEFAULT_PAGINATION,
4
+ ...DEFAULT_FILTER,
5
+ getLinked: true,
6
+ };
@@ -0,0 +1,10 @@
1
+ import { DEFAULT_FILTER, DEFAULT_PAGINATION, DEFAULT_SORT, } from "./common.js";
2
+ export const DEFAULT_FETCH_BUILD_PAYLOAD = {
3
+ ...DEFAULT_PAGINATION,
4
+ ...DEFAULT_FILTER,
5
+ };
6
+ export const DEFAULT_FETCH_PLATFORMS_PAYLOAD = {
7
+ ...DEFAULT_PAGINATION,
8
+ ...DEFAULT_FILTER,
9
+ ...DEFAULT_SORT,
10
+ };
@@ -0,0 +1,19 @@
1
+ import { DEFAULT_FILTER, DEFAULT_FOLDER_OPTIONS, DEFAULT_PAGINATION, DEFAULT_SORT, } from "./common.js";
2
+ export const DEFAULT_FETCH_REQUIREMENTS_PAYLOAD = {
3
+ ...DEFAULT_PAGINATION,
4
+ ...DEFAULT_FILTER,
5
+ ...DEFAULT_FOLDER_OPTIONS,
6
+ ...DEFAULT_SORT,
7
+ udfFilter: "[]",
8
+ isJiraFilter: false,
9
+ filterType: "QMETRY",
10
+ };
11
+ export const DEFAULT_FETCH_REQUIREMENT_DETAILS_PAYLOAD = {
12
+ // No defaults needed for this simple payload
13
+ };
14
+ export const DEFAULT_FETCH_REQUIREMENTS_LINKED_TO_TESTCASE_PAYLOAD = {
15
+ ...DEFAULT_PAGINATION,
16
+ ...DEFAULT_FILTER,
17
+ getLinked: true,
18
+ rqFolderPath: "",
19
+ };
@@ -17,3 +17,17 @@ export const DEFAULT_FETCH_TESTCASE_STEPS_PAYLOAD = {
17
17
  ...DEFAULT_PAGINATION,
18
18
  version: 1,
19
19
  };
20
+ export const DEFAULT_FETCH_TESTCASES_LINKED_TO_REQUIREMENT_PAYLOAD = {
21
+ ...DEFAULT_PAGINATION,
22
+ ...DEFAULT_FILTER,
23
+ getLinked: true,
24
+ showEntityWithReleaseCycle: false,
25
+ tcFolderPath: "",
26
+ getSubEntities: true,
27
+ getColumns: true,
28
+ };
29
+ export const DEFAULT_FETCH_TESTCASE_EXECUTIONS_PAYLOAD = {
30
+ ...DEFAULT_PAGINATION,
31
+ ...DEFAULT_FILTER,
32
+ scope: DEFAULT_FOLDER_OPTIONS.scope,
33
+ };
@@ -0,0 +1,26 @@
1
+ import { DEFAULT_FILTER, DEFAULT_PAGINATION, } from "./common.js";
2
+ export const DEFAULT_FETCH_TESTSUITES_FOR_TESTCASE_PAYLOAD = {
3
+ ...DEFAULT_PAGINATION,
4
+ ...DEFAULT_FILTER,
5
+ getColumns: true,
6
+ };
7
+ export const DEFAULT_FETCH_TESTCASES_BY_TESTSUITE_PAYLOAD = {
8
+ ...DEFAULT_PAGINATION,
9
+ ...DEFAULT_FILTER,
10
+ getLinked: true,
11
+ };
12
+ export const DEFAULT_FETCH_EXECUTIONS_BY_TESTSUITE_PAYLOAD = {
13
+ ...DEFAULT_PAGINATION,
14
+ ...DEFAULT_FILTER,
15
+ gridName: "TESTEXECUTIONLIST",
16
+ };
17
+ export const DEFAULT_FETCH_TESTCASE_RUNS_BY_TESTSUITE_RUN_PAYLOAD = {
18
+ ...DEFAULT_PAGINATION,
19
+ };
20
+ export const DEFAULT_FETCH_LINKED_ISSUES_BY_TESTCASE_RUN_PAYLOAD = {
21
+ ...DEFAULT_PAGINATION,
22
+ ...DEFAULT_FILTER,
23
+ getLinked: true,
24
+ getColumns: true,
25
+ istcrFlag: true,
26
+ };
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
3
+ import { ToolError, } from "../common/types.js";
3
4
  // ReflectClient class implementing the Client interface
4
5
  export class ReflectClient {
5
6
  headers;
@@ -92,7 +93,7 @@ export class ReflectClient {
92
93
  ],
93
94
  }, async (args, _extra) => {
94
95
  if (!args.suiteId)
95
- throw new Error("suiteId argument is required");
96
+ throw new ToolError("suiteId argument is required");
96
97
  const response = await this.listSuiteExecutions(args.suiteId);
97
98
  return {
98
99
  content: [{ type: "text", text: JSON.stringify(response) }],
@@ -117,7 +118,7 @@ export class ReflectClient {
117
118
  ],
118
119
  }, async (args, _extra) => {
119
120
  if (!args.suiteId || !args.executionId)
120
- throw new Error("Both suiteId and executionId arguments are required");
121
+ throw new ToolError("Both suiteId and executionId arguments are required");
121
122
  const response = await this.getSuiteExecutionStatus(args.suiteId, args.executionId);
122
123
  return {
123
124
  content: [{ type: "text", text: JSON.stringify(response) }],
@@ -136,7 +137,7 @@ export class ReflectClient {
136
137
  ],
137
138
  }, async (args, _extra) => {
138
139
  if (!args.suiteId)
139
- throw new Error("suiteId argument is required");
140
+ throw new ToolError("suiteId argument is required");
140
141
  const response = await this.executeSuite(args.suiteId);
141
142
  return {
142
143
  content: [{ type: "text", text: JSON.stringify(response) }],
@@ -161,7 +162,7 @@ export class ReflectClient {
161
162
  ],
162
163
  }, async (args, _extra) => {
163
164
  if (!args.suiteId || !args.executionId)
164
- throw new Error("Both suiteId and executionId arguments are required");
165
+ throw new ToolError("Both suiteId and executionId arguments are required");
165
166
  const response = await this.cancelSuiteExecution(args.suiteId, args.executionId);
166
167
  return {
167
168
  content: [{ type: "text", text: JSON.stringify(response) }],
@@ -190,7 +191,7 @@ export class ReflectClient {
190
191
  ],
191
192
  }, async (args, _extra) => {
192
193
  if (!args.testId)
193
- throw new Error("testId argument is required");
194
+ throw new ToolError("testId argument is required");
194
195
  const response = await this.runReflectTest(args.testId);
195
196
  return {
196
197
  content: [{ type: "text", text: JSON.stringify(response) }],
@@ -215,7 +216,7 @@ export class ReflectClient {
215
216
  ],
216
217
  }, async (args, _extra) => {
217
218
  if (!args.testId || !args.executionId)
218
- throw new Error("Both testId and executionId arguments are required");
219
+ throw new ToolError("Both testId and executionId arguments are required");
219
220
  const response = await this.getReflectTestStatus(args.testId, args.executionId);
220
221
  return {
221
222
  content: [{ type: "text", text: JSON.stringify(response) }],