@qase/mcp-server 1.0.0-beta.1

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 (107) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/README.md +450 -0
  3. package/build/client/index.d.ts +23 -0
  4. package/build/client/index.d.ts.map +1 -0
  5. package/build/client/index.js +55 -0
  6. package/build/client/index.js.map +1 -0
  7. package/build/index.d.ts +32 -0
  8. package/build/index.d.ts.map +1 -0
  9. package/build/index.js +125 -0
  10. package/build/index.js.map +1 -0
  11. package/build/operations/attachments.d.ts +8 -0
  12. package/build/operations/attachments.d.ts.map +1 -0
  13. package/build/operations/attachments.js +123 -0
  14. package/build/operations/attachments.js.map +1 -0
  15. package/build/operations/authors.d.ts +8 -0
  16. package/build/operations/authors.d.ts.map +1 -0
  17. package/build/operations/authors.js +68 -0
  18. package/build/operations/authors.js.map +1 -0
  19. package/build/operations/cases.d.ts +8 -0
  20. package/build/operations/cases.d.ts.map +1 -0
  21. package/build/operations/cases.js +278 -0
  22. package/build/operations/cases.js.map +1 -0
  23. package/build/operations/configurations.d.ts +8 -0
  24. package/build/operations/configurations.d.ts.map +1 -0
  25. package/build/operations/configurations.js +102 -0
  26. package/build/operations/configurations.js.map +1 -0
  27. package/build/operations/custom-fields.d.ts +8 -0
  28. package/build/operations/custom-fields.d.ts.map +1 -0
  29. package/build/operations/custom-fields.js +167 -0
  30. package/build/operations/custom-fields.js.map +1 -0
  31. package/build/operations/defects.d.ts +8 -0
  32. package/build/operations/defects.d.ts.map +1 -0
  33. package/build/operations/defects.js +219 -0
  34. package/build/operations/defects.js.map +1 -0
  35. package/build/operations/environments.d.ts +8 -0
  36. package/build/operations/environments.d.ts.map +1 -0
  37. package/build/operations/environments.js +149 -0
  38. package/build/operations/environments.js.map +1 -0
  39. package/build/operations/milestones.d.ts +8 -0
  40. package/build/operations/milestones.d.ts.map +1 -0
  41. package/build/operations/milestones.js +150 -0
  42. package/build/operations/milestones.js.map +1 -0
  43. package/build/operations/plans.d.ts +8 -0
  44. package/build/operations/plans.d.ts.map +1 -0
  45. package/build/operations/plans.js +153 -0
  46. package/build/operations/plans.js.map +1 -0
  47. package/build/operations/projects.d.ts +8 -0
  48. package/build/operations/projects.d.ts.map +1 -0
  49. package/build/operations/projects.js +186 -0
  50. package/build/operations/projects.js.map +1 -0
  51. package/build/operations/results.d.ts +8 -0
  52. package/build/operations/results.d.ts.map +1 -0
  53. package/build/operations/results.js +208 -0
  54. package/build/operations/results.js.map +1 -0
  55. package/build/operations/runs.d.ts +8 -0
  56. package/build/operations/runs.d.ts.map +1 -0
  57. package/build/operations/runs.js +211 -0
  58. package/build/operations/runs.js.map +1 -0
  59. package/build/operations/search.d.ts +8 -0
  60. package/build/operations/search.d.ts.map +1 -0
  61. package/build/operations/search.js +138 -0
  62. package/build/operations/search.js.map +1 -0
  63. package/build/operations/shared-parameters.d.ts +8 -0
  64. package/build/operations/shared-parameters.d.ts.map +1 -0
  65. package/build/operations/shared-parameters.js +139 -0
  66. package/build/operations/shared-parameters.js.map +1 -0
  67. package/build/operations/shared-steps.d.ts +8 -0
  68. package/build/operations/shared-steps.d.ts.map +1 -0
  69. package/build/operations/shared-steps.js +155 -0
  70. package/build/operations/shared-steps.js.map +1 -0
  71. package/build/operations/suites.d.ts +8 -0
  72. package/build/operations/suites.d.ts.map +1 -0
  73. package/build/operations/suites.js +164 -0
  74. package/build/operations/suites.js.map +1 -0
  75. package/build/operations/system-fields.d.ts +8 -0
  76. package/build/operations/system-fields.d.ts.map +1 -0
  77. package/build/operations/system-fields.js +40 -0
  78. package/build/operations/system-fields.js.map +1 -0
  79. package/build/operations/users.d.ts +8 -0
  80. package/build/operations/users.d.ts.map +1 -0
  81. package/build/operations/users.js +68 -0
  82. package/build/operations/users.js.map +1 -0
  83. package/build/types/index.d.ts +49 -0
  84. package/build/types/index.d.ts.map +1 -0
  85. package/build/types/index.js +13 -0
  86. package/build/types/index.js.map +1 -0
  87. package/build/utils/errors.d.ts +73 -0
  88. package/build/utils/errors.d.ts.map +1 -0
  89. package/build/utils/errors.js +136 -0
  90. package/build/utils/errors.js.map +1 -0
  91. package/build/utils/qql-helpers.d.ts +59 -0
  92. package/build/utils/qql-helpers.d.ts.map +1 -0
  93. package/build/utils/qql-helpers.js +85 -0
  94. package/build/utils/qql-helpers.js.map +1 -0
  95. package/build/utils/registry.d.ts +97 -0
  96. package/build/utils/registry.d.ts.map +1 -0
  97. package/build/utils/registry.js +132 -0
  98. package/build/utils/registry.js.map +1 -0
  99. package/build/utils/test-helpers.d.ts +32 -0
  100. package/build/utils/test-helpers.d.ts.map +1 -0
  101. package/build/utils/test-helpers.js +81 -0
  102. package/build/utils/test-helpers.js.map +1 -0
  103. package/build/utils/validation.d.ts +107 -0
  104. package/build/utils/validation.d.ts.map +1 -0
  105. package/build/utils/validation.js +104 -0
  106. package/build/utils/validation.js.map +1 -0
  107. package/package.json +84 -0
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Error Handling Utilities
3
+ *
4
+ * Provides comprehensive error handling for Qase API interactions:
5
+ * - Custom error classes
6
+ * - Error formatting with user-friendly messages
7
+ * - Type guards for specific error types
8
+ * - Integration with neverthrow Result type
9
+ */
10
+ import { AxiosError } from 'axios';
11
+ import { ResultAsync } from 'neverthrow';
12
+ /**
13
+ * Custom error class for Qase API errors
14
+ */
15
+ export class QaseApiError extends Error {
16
+ statusCode;
17
+ errorCode;
18
+ details;
19
+ constructor(message, statusCode, errorCode, details) {
20
+ super(message);
21
+ this.statusCode = statusCode;
22
+ this.errorCode = errorCode;
23
+ this.details = details;
24
+ this.name = 'QaseApiError';
25
+ Object.setPrototypeOf(this, QaseApiError.prototype);
26
+ }
27
+ }
28
+ /**
29
+ * Format API error into a user-friendly message
30
+ *
31
+ * @param error - The error to format
32
+ * @returns Formatted error message
33
+ */
34
+ export function formatApiError(error) {
35
+ // Handle Axios errors (most common from API calls)
36
+ const axiosError = error;
37
+ if (axiosError.isAxiosError || error instanceof AxiosError) {
38
+ const status = axiosError.response?.status;
39
+ const data = axiosError.response?.data;
40
+ const message = data?.errorMessage || data?.message || axiosError.message;
41
+ // Format based on HTTP status code
42
+ switch (status) {
43
+ case 401:
44
+ return `Authentication failed: ${message}. Please check your QASE_API_TOKEN environment variable.`;
45
+ case 403:
46
+ return `Access forbidden: ${message}. You don't have permission to perform this action.`;
47
+ case 404:
48
+ return `Resource not found: ${message}`;
49
+ case 400:
50
+ return `Invalid request: ${message}`;
51
+ case 422:
52
+ return `Validation error: ${message}`;
53
+ case 429:
54
+ return `Rate limit exceeded: ${message}. Please try again later.`;
55
+ case 500:
56
+ case 502:
57
+ case 503:
58
+ case 504:
59
+ return `Qase API server error: ${message}. Please try again later.`;
60
+ default:
61
+ return message || 'Unknown API error occurred';
62
+ }
63
+ }
64
+ // Handle QaseApiError
65
+ if (error instanceof QaseApiError) {
66
+ return error.message;
67
+ }
68
+ // Handle generic Error
69
+ if (error instanceof Error) {
70
+ return error.message;
71
+ }
72
+ // Handle unknown error types
73
+ return String(error);
74
+ }
75
+ /**
76
+ * Type guard to check if an error is an authentication error (401)
77
+ *
78
+ * @param error - The error to check
79
+ * @returns True if the error is a 401 authentication error
80
+ */
81
+ export function isAuthenticationError(error) {
82
+ const axiosError = error;
83
+ return ((axiosError.isAxiosError || error instanceof AxiosError) && axiosError.response?.status === 401);
84
+ }
85
+ /**
86
+ * Type guard to check if an error is a not found error (404)
87
+ *
88
+ * @param error - The error to check
89
+ * @returns True if the error is a 404 not found error
90
+ */
91
+ export function isNotFoundError(error) {
92
+ const axiosError = error;
93
+ return ((axiosError.isAxiosError || error instanceof AxiosError) && axiosError.response?.status === 404);
94
+ }
95
+ /**
96
+ * Type guard to check if an error is a validation error (400 or 422)
97
+ *
98
+ * @param error - The error to check
99
+ * @returns True if the error is a validation error
100
+ */
101
+ export function isValidationError(error) {
102
+ const axiosError = error;
103
+ return ((axiosError.isAxiosError || error instanceof AxiosError) &&
104
+ (axiosError.response?.status === 400 || axiosError.response?.status === 422));
105
+ }
106
+ /**
107
+ * Type guard to check if an error is a rate limit error (429)
108
+ *
109
+ * @param error - The error to check
110
+ * @returns True if the error is a rate limit error
111
+ */
112
+ export function isRateLimitError(error) {
113
+ const axiosError = error;
114
+ return ((axiosError.isAxiosError || error instanceof AxiosError) && axiosError.response?.status === 429);
115
+ }
116
+ /**
117
+ * Helper to wrap promises in neverthrow Result type
118
+ *
119
+ * Converts Promise<T> to ResultAsync<T, string> with formatted error messages
120
+ *
121
+ * @param promise - The promise to wrap
122
+ * @returns ResultAsync with formatted error on rejection
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * const result = await toResultAsync(apiClient.projects.getProjects());
127
+ * result.match(
128
+ * (projects) => console.log(projects),
129
+ * (error) => console.error(error)
130
+ * );
131
+ * ```
132
+ */
133
+ export function toResultAsync(promise) {
134
+ return ResultAsync.fromPromise(promise, formatApiError);
135
+ }
136
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * QQL Helper Utilities
3
+ *
4
+ * Provides common QQL query patterns and builders for Qase Query Language.
5
+ */
6
+ /**
7
+ * Common QQL entity types
8
+ */
9
+ export declare enum QqlEntity {
10
+ Case = "case",
11
+ Defect = "defect",
12
+ Run = "run",
13
+ Result = "result",
14
+ Plan = "plan",
15
+ Requirement = "requirement"
16
+ }
17
+ /**
18
+ * QQL query builder for common patterns
19
+ */
20
+ export declare class QqlQueryBuilder {
21
+ private parts;
22
+ /**
23
+ * Set entity type
24
+ */
25
+ entity(entityType: QqlEntity): this;
26
+ /**
27
+ * Filter by project
28
+ */
29
+ project(projectCode: string): this;
30
+ /**
31
+ * Filter by multiple projects
32
+ */
33
+ projects(projectCodes: string[]): this;
34
+ /**
35
+ * Add custom condition
36
+ */
37
+ where(condition: string): this;
38
+ /**
39
+ * Order by field
40
+ */
41
+ orderBy(field: string, direction?: 'ASC' | 'DESC'): this;
42
+ /**
43
+ * Build the final query string
44
+ */
45
+ build(): string;
46
+ }
47
+ /**
48
+ * Common QQL query examples
49
+ */
50
+ export declare const QqlExamples: {
51
+ recentFailures: (projectCode: string) => string;
52
+ blockerDefects: (projectCode: string) => string;
53
+ flakyTests: (projectCode: string) => string;
54
+ notAutomated: (projectCode: string) => string;
55
+ byAuthor: (projectCode: string, author: string) => string;
56
+ activeRuns: (projectCode: string) => string;
57
+ byMilestone: (projectCode: string, milestone: string) => string;
58
+ };
59
+ //# sourceMappingURL=qql-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qql-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/qql-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,GAAG,QAAQ;IACX,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,WAAW,gBAAgB;CAC5B;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAgB;IAE7B;;OAEG;IACH,MAAM,CAAC,UAAU,EAAE,SAAS,GAAG,IAAI;IAKnC;;OAEG;IACH,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAKlC;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI;IAMtC;;OAEG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK9B;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,KAAK,GAAG,MAAc,GAAG,IAAI;IAK/D;;OAEG;IACH,KAAK,IAAI,MAAM;CAGhB;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;kCAEQ,MAAM;kCAIN,MAAM;8BAIV,MAAM;gCAIJ,MAAM;4BAIV,MAAM,UAAU,MAAM;8BAIpB,MAAM;+BAIL,MAAM,aAAa,MAAM;CAErD,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * QQL Helper Utilities
3
+ *
4
+ * Provides common QQL query patterns and builders for Qase Query Language.
5
+ */
6
+ /**
7
+ * Common QQL entity types
8
+ */
9
+ export var QqlEntity;
10
+ (function (QqlEntity) {
11
+ QqlEntity["Case"] = "case";
12
+ QqlEntity["Defect"] = "defect";
13
+ QqlEntity["Run"] = "run";
14
+ QqlEntity["Result"] = "result";
15
+ QqlEntity["Plan"] = "plan";
16
+ QqlEntity["Requirement"] = "requirement";
17
+ })(QqlEntity || (QqlEntity = {}));
18
+ /**
19
+ * QQL query builder for common patterns
20
+ */
21
+ export class QqlQueryBuilder {
22
+ parts = [];
23
+ /**
24
+ * Set entity type
25
+ */
26
+ entity(entityType) {
27
+ this.parts.push(`entity = "${entityType}"`);
28
+ return this;
29
+ }
30
+ /**
31
+ * Filter by project
32
+ */
33
+ project(projectCode) {
34
+ this.parts.push(`project = "${projectCode}"`);
35
+ return this;
36
+ }
37
+ /**
38
+ * Filter by multiple projects
39
+ */
40
+ projects(projectCodes) {
41
+ const codes = projectCodes.map((c) => `"${c}"`).join(', ');
42
+ this.parts.push(`project in [${codes}]`);
43
+ return this;
44
+ }
45
+ /**
46
+ * Add custom condition
47
+ */
48
+ where(condition) {
49
+ this.parts.push(`(${condition})`);
50
+ return this;
51
+ }
52
+ /**
53
+ * Order by field
54
+ */
55
+ orderBy(field, direction = 'ASC') {
56
+ this.parts.push(`ORDER BY ${field} ${direction}`);
57
+ return this;
58
+ }
59
+ /**
60
+ * Build the final query string
61
+ */
62
+ build() {
63
+ return this.parts.join(' and ');
64
+ }
65
+ }
66
+ /**
67
+ * Common QQL query examples
68
+ */
69
+ export const QqlExamples = {
70
+ // Find all failed test results in last 7 days
71
+ recentFailures: (projectCode) => `entity = "result" and project = "${projectCode}" and status = "failed" and created >= now("-7d")`,
72
+ // Find all open blocker defects
73
+ blockerDefects: (projectCode) => `entity = "defect" and project = "${projectCode}" and severity = "blocker" and status = "open"`,
74
+ // Find all flaky test cases
75
+ flakyTests: (projectCode) => `entity = "case" and project = "${projectCode}" and isFlaky = true`,
76
+ // Find all active test cases not automated
77
+ notAutomated: (projectCode) => `entity = "case" and project = "${projectCode}" and automation = "Not automated" and status = "Actual"`,
78
+ // Find test cases created by specific author
79
+ byAuthor: (projectCode, author) => `entity = "case" and project = "${projectCode}" and author = "${author}"`,
80
+ // Find test runs in progress
81
+ activeRuns: (projectCode) => `entity = "run" and project = "${projectCode}" and isStarted = true and isEnded = false`,
82
+ // Find cases in specific milestone
83
+ byMilestone: (projectCode, milestone) => `entity = "case" and project = "${projectCode}" and milestone ~ "${milestone}"`,
84
+ };
85
+ //# sourceMappingURL=qql-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qql-helpers.js","sourceRoot":"","sources":["../../src/utils/qql-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,CAAN,IAAY,SAOX;AAPD,WAAY,SAAS;IACnB,0BAAa,CAAA;IACb,8BAAiB,CAAA;IACjB,wBAAW,CAAA;IACX,8BAAiB,CAAA;IACjB,0BAAa,CAAA;IACb,wCAA2B,CAAA;AAC7B,CAAC,EAPW,SAAS,KAAT,SAAS,QAOpB;AAED;;GAEG;AACH,MAAM,OAAO,eAAe;IAClB,KAAK,GAAa,EAAE,CAAC;IAE7B;;OAEG;IACH,MAAM,CAAC,UAAqB;QAC1B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,UAAU,GAAG,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,WAAmB;QACzB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,WAAW,GAAG,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,YAAsB;QAC7B,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,GAAG,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAiB;QACrB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,KAAa,EAAE,YAA4B,KAAK;QACtD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,8CAA8C;IAC9C,cAAc,EAAE,CAAC,WAAmB,EAAE,EAAE,CACtC,oCAAoC,WAAW,mDAAmD;IAEpG,gCAAgC;IAChC,cAAc,EAAE,CAAC,WAAmB,EAAE,EAAE,CACtC,oCAAoC,WAAW,gDAAgD;IAEjG,4BAA4B;IAC5B,UAAU,EAAE,CAAC,WAAmB,EAAE,EAAE,CAClC,kCAAkC,WAAW,sBAAsB;IAErE,2CAA2C;IAC3C,YAAY,EAAE,CAAC,WAAmB,EAAE,EAAE,CACpC,kCAAkC,WAAW,0DAA0D;IAEzG,6CAA6C;IAC7C,QAAQ,EAAE,CAAC,WAAmB,EAAE,MAAc,EAAE,EAAE,CAChD,kCAAkC,WAAW,mBAAmB,MAAM,GAAG;IAE3E,6BAA6B;IAC7B,UAAU,EAAE,CAAC,WAAmB,EAAE,EAAE,CAClC,iCAAiC,WAAW,4CAA4C;IAE1F,mCAAmC;IACnC,WAAW,EAAE,CAAC,WAAmB,EAAE,SAAiB,EAAE,EAAE,CACtD,kCAAkC,WAAW,sBAAsB,SAAS,GAAG;CAClF,CAAC"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Tool Registry System
3
+ *
4
+ * Centralized system for managing MCP tool registration:
5
+ * - Register tools with Zod schemas
6
+ * - Convert Zod schemas to JSON Schema automatically
7
+ * - Store and retrieve tool handlers
8
+ * - Manage tool lifecycle
9
+ */
10
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
11
+ import { z } from 'zod';
12
+ /**
13
+ * Tool handler function type
14
+ * Handlers receive validated arguments and return a promise
15
+ */
16
+ export type ToolHandler<T = any, R = any> = (args: T) => Promise<R>;
17
+ /**
18
+ * Tool definition for registration
19
+ * Contains all information needed to register a tool with the MCP server
20
+ */
21
+ export interface ToolDefinition<T extends z.ZodType = z.ZodType> {
22
+ name: string;
23
+ description: string;
24
+ schema: T;
25
+ handler: ToolHandler;
26
+ }
27
+ /**
28
+ * Tool Registry Class
29
+ * Manages the lifecycle of MCP tools
30
+ */
31
+ export declare class ToolRegistry {
32
+ private tools;
33
+ private handlers;
34
+ /**
35
+ * Register a new tool with the registry
36
+ *
37
+ * @param definition - Tool definition including name, description, schema, and handler
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * toolRegistry.register({
42
+ * name: 'list_projects',
43
+ * description: 'Get all projects',
44
+ * schema: z.object({ limit: z.number().optional() }),
45
+ * handler: async (args) => { ... }
46
+ * });
47
+ * ```
48
+ */
49
+ register<T extends z.ZodType>(definition: ToolDefinition<T>): void;
50
+ /**
51
+ * Get all registered tools
52
+ * Used by the ListToolsRequestSchema handler
53
+ *
54
+ * @returns Array of all registered tools
55
+ */
56
+ getTools(): Tool[];
57
+ /**
58
+ * Get handler function for a specific tool
59
+ *
60
+ * @param name - Tool name
61
+ * @returns Handler function or undefined if not found
62
+ */
63
+ getHandler(name: string): ToolHandler | undefined;
64
+ /**
65
+ * Check if a tool exists in the registry
66
+ *
67
+ * @param name - Tool name
68
+ * @returns True if tool is registered
69
+ */
70
+ hasTool(name: string): boolean;
71
+ /**
72
+ * Get the count of registered tools
73
+ *
74
+ * @returns Number of registered tools
75
+ */
76
+ getToolCount(): number;
77
+ /**
78
+ * Unregister a tool (useful for testing)
79
+ *
80
+ * @param name - Tool name to unregister
81
+ * @returns True if tool was removed, false if not found
82
+ * @internal
83
+ */
84
+ unregister(name: string): boolean;
85
+ /**
86
+ * Clear all registered tools (useful for testing)
87
+ *
88
+ * @internal
89
+ */
90
+ clear(): void;
91
+ }
92
+ /**
93
+ * Global tool registry instance
94
+ * Import and use this instance across all operation modules
95
+ */
96
+ export declare const toolRegistry: ToolRegistry;
97
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/utils/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AAEH,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAEpE;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,CAAC,CAAC;IACV,OAAO,EAAE,WAAW,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,QAAQ,CAAuC;IAEvD;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI;IA0ClE;;;;;OAKG;IACH,QAAQ,IAAI,IAAI,EAAE;IAIlB;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIjD;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9B;;;;OAIG;IACH,YAAY,IAAI,MAAM;IAItB;;;;;;OAMG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAMjC;;;;OAIG;IACH,KAAK,IAAI,IAAI;CAId;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,cAAqB,CAAC"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Tool Registry System
3
+ *
4
+ * Centralized system for managing MCP tool registration:
5
+ * - Register tools with Zod schemas
6
+ * - Convert Zod schemas to JSON Schema automatically
7
+ * - Store and retrieve tool handlers
8
+ * - Manage tool lifecycle
9
+ */
10
+ import { zodToJsonSchema } from 'zod-to-json-schema';
11
+ /**
12
+ * Tool Registry Class
13
+ * Manages the lifecycle of MCP tools
14
+ */
15
+ export class ToolRegistry {
16
+ tools = new Map();
17
+ handlers = new Map();
18
+ /**
19
+ * Register a new tool with the registry
20
+ *
21
+ * @param definition - Tool definition including name, description, schema, and handler
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * toolRegistry.register({
26
+ * name: 'list_projects',
27
+ * description: 'Get all projects',
28
+ * schema: z.object({ limit: z.number().optional() }),
29
+ * handler: async (args) => { ... }
30
+ * });
31
+ * ```
32
+ */
33
+ register(definition) {
34
+ const { name, description, schema, handler } = definition;
35
+ // Convert Zod schema to JSON Schema for MCP protocol
36
+ const jsonSchema = zodToJsonSchema(schema, {
37
+ name: `${name}Input`,
38
+ $refStrategy: 'none', // Inline all definitions
39
+ });
40
+ // Extract the actual schema from definitions if present
41
+ // zodToJsonSchema sometimes wraps the schema in a $ref even with $refStrategy: 'none'
42
+ let inputSchema;
43
+ if (jsonSchema.$ref && jsonSchema.definitions) {
44
+ // Extract from definitions
45
+ const definitionKey = Object.keys(jsonSchema.definitions)[0];
46
+ inputSchema = jsonSchema.definitions[definitionKey];
47
+ }
48
+ else if (jsonSchema.type === 'object') {
49
+ // Use directly
50
+ inputSchema = jsonSchema;
51
+ }
52
+ else {
53
+ // Fallback: create minimal object schema
54
+ inputSchema = {
55
+ type: 'object',
56
+ properties: {},
57
+ };
58
+ }
59
+ // Store tool definition
60
+ this.tools.set(name, {
61
+ name,
62
+ description,
63
+ inputSchema,
64
+ });
65
+ // Store handler function
66
+ this.handlers.set(name, handler);
67
+ // Log registration for debugging (to stderr)
68
+ console.error(`[Registry] Registered tool: ${name}`);
69
+ }
70
+ /**
71
+ * Get all registered tools
72
+ * Used by the ListToolsRequestSchema handler
73
+ *
74
+ * @returns Array of all registered tools
75
+ */
76
+ getTools() {
77
+ return Array.from(this.tools.values());
78
+ }
79
+ /**
80
+ * Get handler function for a specific tool
81
+ *
82
+ * @param name - Tool name
83
+ * @returns Handler function or undefined if not found
84
+ */
85
+ getHandler(name) {
86
+ return this.handlers.get(name);
87
+ }
88
+ /**
89
+ * Check if a tool exists in the registry
90
+ *
91
+ * @param name - Tool name
92
+ * @returns True if tool is registered
93
+ */
94
+ hasTool(name) {
95
+ return this.tools.has(name);
96
+ }
97
+ /**
98
+ * Get the count of registered tools
99
+ *
100
+ * @returns Number of registered tools
101
+ */
102
+ getToolCount() {
103
+ return this.tools.size;
104
+ }
105
+ /**
106
+ * Unregister a tool (useful for testing)
107
+ *
108
+ * @param name - Tool name to unregister
109
+ * @returns True if tool was removed, false if not found
110
+ * @internal
111
+ */
112
+ unregister(name) {
113
+ const hadTool = this.tools.delete(name);
114
+ this.handlers.delete(name);
115
+ return hadTool;
116
+ }
117
+ /**
118
+ * Clear all registered tools (useful for testing)
119
+ *
120
+ * @internal
121
+ */
122
+ clear() {
123
+ this.tools.clear();
124
+ this.handlers.clear();
125
+ }
126
+ }
127
+ /**
128
+ * Global tool registry instance
129
+ * Import and use this instance across all operation modules
130
+ */
131
+ export const toolRegistry = new ToolRegistry();
132
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/utils/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAoBrD;;;GAGG;AACH,MAAM,OAAO,YAAY;IACf,KAAK,GAAsB,IAAI,GAAG,EAAE,CAAC;IACrC,QAAQ,GAA6B,IAAI,GAAG,EAAE,CAAC;IAEvD;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAsB,UAA6B;QACzD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;QAE1D,qDAAqD;QACrD,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,EAAE;YACzC,IAAI,EAAE,GAAG,IAAI,OAAO;YACpB,YAAY,EAAE,MAAM,EAAE,yBAAyB;SAChD,CAAQ,CAAC;QAEV,wDAAwD;QACxD,sFAAsF;QACtF,IAAI,WAAuD,CAAC;QAE5D,IAAI,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;YAC9C,2BAA2B;YAC3B,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC,aAAa,CAA+C,CAAC;QACpG,CAAC;aAAM,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxC,eAAe;YACf,WAAW,GAAG,UAAU,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,yCAAyC;YACzC,WAAW,GAAG;gBACZ,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE;aACf,CAAC;QACJ,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE;YACnB,IAAI;YACJ,WAAW;YACX,WAAW;SACZ,CAAC,CAAC;QAEH,yBAAyB;QACzB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAEjC,6CAA6C;QAC7C,OAAO,CAAC,KAAK,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QACN,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,IAAY;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Test Helper Utilities
3
+ *
4
+ * Provides mock objects and helper functions for testing.
5
+ */
6
+ import { QaseApi } from 'qaseio';
7
+ /**
8
+ * Mock successful API response
9
+ */
10
+ export declare function mockApiSuccess<T>(data: T): Promise<{
11
+ data: {
12
+ status: boolean;
13
+ result: T;
14
+ };
15
+ }>;
16
+ /**
17
+ * Mock API error response
18
+ */
19
+ export declare function mockApiError(statusCode: number, message: string): Promise<never>;
20
+ /**
21
+ * Set environment variables for testing
22
+ */
23
+ export declare function setTestEnv(): void;
24
+ /**
25
+ * Clear environment variables
26
+ */
27
+ export declare function clearTestEnv(): void;
28
+ /**
29
+ * Create mock API client for testing
30
+ */
31
+ export declare function createMockApiClient(): jest.Mocked<Partial<QaseApi>>;
32
+ //# sourceMappingURL=test-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/test-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;;;;;GAOxC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAS/D;AAED;;GAEG;AACH,wBAAgB,UAAU,SAGzB;AAED;;GAEG;AACH,wBAAgB,YAAY,SAG3B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAiCnE"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Test Helper Utilities
3
+ *
4
+ * Provides mock objects and helper functions for testing.
5
+ */
6
+ /**
7
+ * Mock successful API response
8
+ */
9
+ export function mockApiSuccess(data) {
10
+ return Promise.resolve({
11
+ data: {
12
+ status: true,
13
+ result: data,
14
+ },
15
+ });
16
+ }
17
+ /**
18
+ * Mock API error response
19
+ */
20
+ export function mockApiError(statusCode, message) {
21
+ const error = new Error(message);
22
+ error.response = {
23
+ status: statusCode,
24
+ data: {
25
+ errorMessage: message,
26
+ },
27
+ };
28
+ return Promise.reject(error);
29
+ }
30
+ /**
31
+ * Set environment variables for testing
32
+ */
33
+ export function setTestEnv() {
34
+ process.env.QASE_API_TOKEN = 'test-token-123';
35
+ process.env.QASE_API_DOMAIN = 'api.qase.io';
36
+ }
37
+ /**
38
+ * Clear environment variables
39
+ */
40
+ export function clearTestEnv() {
41
+ delete process.env.QASE_API_TOKEN;
42
+ delete process.env.QASE_API_DOMAIN;
43
+ }
44
+ /**
45
+ * Create mock API client for testing
46
+ */
47
+ export function createMockApiClient() {
48
+ return {
49
+ projects: {
50
+ getProjects: jest.fn(),
51
+ getProject: jest.fn(),
52
+ createProject: jest.fn(),
53
+ deleteProject: jest.fn(),
54
+ grantAccess: jest.fn(),
55
+ revokeAccess: jest.fn(),
56
+ },
57
+ cases: {
58
+ getCases: jest.fn(),
59
+ getCase: jest.fn(),
60
+ createCase: jest.fn(),
61
+ updateCase: jest.fn(),
62
+ deleteCase: jest.fn(),
63
+ bulkCreateCases: jest.fn(),
64
+ },
65
+ suites: {
66
+ getSuites: jest.fn(),
67
+ getSuite: jest.fn(),
68
+ createSuite: jest.fn(),
69
+ updateSuite: jest.fn(),
70
+ deleteSuite: jest.fn(),
71
+ },
72
+ runs: {
73
+ getRuns: jest.fn(),
74
+ getRun: jest.fn(),
75
+ createRun: jest.fn(),
76
+ deleteRun: jest.fn(),
77
+ completeRun: jest.fn(),
78
+ },
79
+ };
80
+ }
81
+ //# sourceMappingURL=test-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../src/utils/test-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,UAAU,cAAc,CAAI,IAAO;IACvC,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,IAAI,EAAE;YACJ,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,IAAI;SACb;KACF,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkB,EAAE,OAAe;IAC9D,MAAM,KAAK,GAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IACtC,KAAK,CAAC,QAAQ,GAAG;QACf,MAAM,EAAE,UAAU;QAClB,IAAI,EAAE;YACJ,YAAY,EAAE,OAAO;SACtB;KACF,CAAC;IACF,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,gBAAgB,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,aAAa,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAClC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL,QAAQ,EAAE;YACR,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;YACtB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;YACrB,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE;YACxB,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE;YACxB,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;YACtB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB;QACR,KAAK,EAAE;YACL,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE;YACnB,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;YAClB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;YACrB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;YACrB,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;YACrB,eAAe,EAAE,IAAI,CAAC,EAAE,EAAE;SACpB;QACR,MAAM,EAAE;YACN,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE;YACpB,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE;YACnB,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;YACtB,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;YACtB,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;SAChB;QACR,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;YAClB,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;YACjB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE;YACpB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE;YACpB,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;SAChB;KACF,CAAC;AACX,CAAC"}