@smartbear/mcp 0.9.0 → 0.11.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 (64) hide show
  1. package/README.md +38 -11
  2. package/dist/bugsnag/client/api/index.js +2 -0
  3. package/dist/bugsnag/client/filters.js +0 -6
  4. package/dist/bugsnag/client.js +238 -380
  5. package/dist/bugsnag/input-schemas.js +51 -0
  6. package/dist/collaborator/client.js +377 -0
  7. package/dist/common/cache.js +63 -0
  8. package/dist/common/client-registry.js +128 -0
  9. package/dist/common/register-clients.js +31 -0
  10. package/dist/common/server.js +77 -28
  11. package/dist/common/transport-http.js +377 -0
  12. package/dist/common/transport-stdio.js +43 -0
  13. package/dist/index.js +18 -60
  14. package/dist/pactflow/client/tools.js +4 -4
  15. package/dist/pactflow/client.js +39 -19
  16. package/dist/qmetry/client/auto-resolve.js +22 -0
  17. package/dist/qmetry/client/handlers.js +18 -4
  18. package/dist/qmetry/client/issues.js +98 -1
  19. package/dist/qmetry/client/project.js +18 -1
  20. package/dist/qmetry/client/testcase.js +79 -1
  21. package/dist/qmetry/client/testsuite.js +156 -1
  22. package/dist/qmetry/client/tools/index.js +17 -0
  23. package/dist/qmetry/client/tools/issue-tools.js +545 -0
  24. package/dist/qmetry/client/tools/project-tools.js +348 -0
  25. package/dist/qmetry/client/tools/requirement-tools.js +530 -0
  26. package/dist/qmetry/client/tools/testcase-tools.js +526 -0
  27. package/dist/qmetry/client/tools/testsuite-tools.js +772 -0
  28. package/dist/qmetry/client/tools/types.js +1 -0
  29. package/dist/qmetry/client.js +33 -11
  30. package/dist/qmetry/config/constants.js +14 -0
  31. package/dist/qmetry/config/rest-endpoints.js +10 -0
  32. package/dist/qmetry/types/common.js +287 -2
  33. package/dist/qmetry/types/issues.js +11 -1
  34. package/dist/qmetry/types/project.js +7 -0
  35. package/dist/qmetry/types/testcase.js +6 -0
  36. package/dist/qmetry/types/testsuite.js +19 -1
  37. package/dist/reflect/client.js +10 -4
  38. package/dist/{api-hub → swagger}/client/api.js +190 -2
  39. package/dist/{api-hub → swagger}/client/configuration.js +6 -1
  40. package/dist/swagger/client/index.js +6 -0
  41. package/dist/{api-hub → swagger}/client/portal-types.js +126 -0
  42. package/dist/swagger/client/tools.js +161 -0
  43. package/dist/swagger/client/user-management-types.js +24 -0
  44. package/dist/swagger/client.js +141 -0
  45. package/dist/swagger/config-utils.js +18 -0
  46. package/dist/zephyr/client.js +44 -6
  47. package/dist/zephyr/common/api-client.js +8 -0
  48. package/dist/zephyr/common/rest-api-schemas.js +5174 -0
  49. package/dist/zephyr/tool/priority/get-priorities.js +43 -0
  50. package/dist/zephyr/tool/project/get-project.js +39 -0
  51. package/dist/zephyr/tool/project/get-projects.js +7 -13
  52. package/dist/zephyr/tool/status/get-statuses.js +49 -0
  53. package/dist/zephyr/tool/test-case/get-test-case.js +39 -0
  54. package/dist/zephyr/tool/test-case/get-test-cases.js +64 -0
  55. package/dist/zephyr/tool/test-cycle/get-test-cycle.js +39 -0
  56. package/dist/zephyr/tool/test-cycle/get-test-cycles.js +72 -0
  57. package/dist/zephyr/tool/test-execution/get-test-execution.js +39 -0
  58. package/package.json +2 -2
  59. package/dist/api-hub/client/index.js +0 -5
  60. package/dist/api-hub/client/tools.js +0 -104
  61. package/dist/api-hub/client.js +0 -98
  62. package/dist/qmetry/client/tools.js +0 -1673
  63. package/dist/zephyr/common/types.js +0 -35
  64. /package/dist/{api-hub → swagger}/client/registry-types.js +0 -0
@@ -0,0 +1,141 @@
1
+ import { z } from "zod";
2
+ import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
3
+ // Apply backward compatibility for API_HUB_API_KEY
4
+ import "./config-utils.js";
5
+ import { SwaggerAPI, SwaggerConfiguration, TOOLS, } from "./client/index.js";
6
+ const ConfigurationSchema = z.object({
7
+ api_key: z.string().describe("Swagger API key for authentication"),
8
+ });
9
+ // Tool definitions for API Hub API client
10
+ export class SwaggerClient {
11
+ api;
12
+ name = "Swagger";
13
+ toolPrefix = "swagger";
14
+ configPrefix = "Swagger";
15
+ config = ConfigurationSchema;
16
+ async configure(_server, config, _cache) {
17
+ this.api = new SwaggerAPI(new SwaggerConfiguration({ token: config.api_key }), `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`);
18
+ return true;
19
+ }
20
+ getApi() {
21
+ if (!this.api)
22
+ throw new Error("Client not configured");
23
+ return this.api;
24
+ }
25
+ // Delegate API methods to the SwaggerAPI instance
26
+ async getPortals() {
27
+ return this.getApi().getPortals();
28
+ }
29
+ async createPortal(body) {
30
+ return this.getApi().createPortal(body);
31
+ }
32
+ async getPortal(args) {
33
+ return this.getApi().getPortal(args.portalId);
34
+ }
35
+ async deletePortal(args) {
36
+ return this.getApi().deletePortal(args.portalId);
37
+ }
38
+ async updatePortal(args) {
39
+ const { portalId, ...body } = args;
40
+ return this.getApi().updatePortal(portalId, body);
41
+ }
42
+ async getPortalProducts(args) {
43
+ return this.getApi().getPortalProducts(args.portalId);
44
+ }
45
+ async createPortalProduct(args) {
46
+ const { portalId, ...body } = args;
47
+ return this.getApi().createPortalProduct(portalId, body);
48
+ }
49
+ async getPortalProduct(args) {
50
+ return this.getApi().getPortalProduct(args.productId);
51
+ }
52
+ async deletePortalProduct(args) {
53
+ return this.getApi().deletePortalProduct(args.productId);
54
+ }
55
+ async updatePortalProduct(args) {
56
+ const { productId, ...body } = args;
57
+ return this.getApi().updatePortalProduct(productId, body);
58
+ }
59
+ async publishPortalProduct(args) {
60
+ const { productId, preview } = args;
61
+ return this.getApi().publishPortalProduct(productId, preview);
62
+ }
63
+ async getPortalProductSections(args) {
64
+ const { productId, ...params } = args;
65
+ return this.getApi().getPortalProductSections(productId, params);
66
+ }
67
+ async createTableOfContents(args) {
68
+ const { sectionId, ...body } = args;
69
+ return this.getApi().createTableOfContents(sectionId, body);
70
+ }
71
+ async getTableOfContents(args) {
72
+ return this.getApi().getTableOfContents(args);
73
+ }
74
+ async getDocument(args) {
75
+ return this.getApi().getDocument(args);
76
+ }
77
+ async updateDocument(args) {
78
+ return this.getApi().updateDocument(args);
79
+ }
80
+ async deleteDocument(args) {
81
+ return this.getApi().deleteDocument(args);
82
+ }
83
+ async deleteTableOfContents(args) {
84
+ return this.getApi().deleteTableOfContents(args);
85
+ }
86
+ // Registry API methods for SwaggerHub Design functionality
87
+ async searchApis(args = {}) {
88
+ return this.getApi().searchApis(args);
89
+ }
90
+ async getApiDefinition(args) {
91
+ return this.getApi().getApiDefinition(args);
92
+ }
93
+ async createOrUpdateApi(args) {
94
+ return this.getApi().createOrUpdateApi(args);
95
+ }
96
+ async createApiFromTemplate(args) {
97
+ return this.getApi().createApiFromTemplate(args);
98
+ }
99
+ // User Management API methods
100
+ async getOrganizations(args) {
101
+ return this.getApi().getOrganizations(args);
102
+ }
103
+ async scanStandardization(args) {
104
+ return this.getApi().scanStandardization(args);
105
+ }
106
+ registerTools(register, _getInput) {
107
+ TOOLS.forEach((tool) => {
108
+ const { handler, formatResponse, ...toolParams } = tool;
109
+ register(toolParams, async (args, _extra) => {
110
+ try {
111
+ // Dynamic method invocation
112
+ const handlerFn = this[handler];
113
+ if (typeof handlerFn !== "function") {
114
+ throw new Error(`Handler '${handler}' not found on SwaggerClient`);
115
+ }
116
+ const result = await handlerFn.call(this, args);
117
+ // Use custom formatter if available, otherwise return JSON
118
+ const formattedResult = formatResponse
119
+ ? formatResponse(result)
120
+ : result;
121
+ const responseText = typeof formattedResult === "string"
122
+ ? formattedResult
123
+ : JSON.stringify(formattedResult);
124
+ return {
125
+ content: [{ type: "text", text: responseText }],
126
+ };
127
+ }
128
+ catch (error) {
129
+ return {
130
+ content: [
131
+ {
132
+ type: "text",
133
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`,
134
+ },
135
+ ],
136
+ };
137
+ }
138
+ });
139
+ });
140
+ }
141
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Configuration utilities for Swagger client
3
+ * Handles backward compatibility with legacy environment variables
4
+ */
5
+ /**
6
+ * Apply API_HUB_API_KEY fallback to SWAGGER_API_KEY if needed
7
+ * This modifies process.env to enable backward compatibility
8
+ * @deprecated API_HUB_API_KEY support - TODO: Remove after migration period (May 2026)
9
+ */
10
+ export function applySwaggerApiKeyFallback() {
11
+ // If SWAGGER_API_KEY is not set but API_HUB_API_KEY is, use the legacy variable
12
+ if (!process.env.SWAGGER_API_KEY && process.env.API_HUB_API_KEY) {
13
+ console.warn("[Swagger] API_HUB_API_KEY is deprecated. Please use SWAGGER_API_KEY instead.");
14
+ process.env.SWAGGER_API_KEY = process.env.API_HUB_API_KEY;
15
+ }
16
+ }
17
+ // Apply the fallback immediately when this module is imported
18
+ applySwaggerApiKeyFallback();
@@ -1,16 +1,54 @@
1
+ import z from "zod";
1
2
  import { ApiClient } from "./common/api-client.js";
3
+ import { GetPriorities } from "./tool/priority/get-priorities.js";
4
+ import { GetProject } from "./tool/project/get-project.js";
2
5
  import { GetProjects } from "./tool/project/get-projects.js";
6
+ import { GetStatuses } from "./tool/status/get-statuses.js";
7
+ import { GetTestCase } from "./tool/test-case/get-test-case.js";
8
+ import { GetTestCases } from "./tool/test-case/get-test-cases.js";
9
+ import { GetTestCycle } from "./tool/test-cycle/get-test-cycle.js";
10
+ import { GetTestCycles } from "./tool/test-cycle/get-test-cycles.js";
11
+ import { GetTestExecution } from "./tool/test-execution/get-test-execution.js";
12
+ const BASE_URL_DEFAULT = "https://api.zephyrscale.smartbear.com/v2";
13
+ const ConfigurationSchema = z.object({
14
+ api_token: z.string().describe("Zephyr Scale API token for authentication"),
15
+ base_url: z
16
+ .string()
17
+ .url()
18
+ .optional()
19
+ .describe("Zephyr Scale API base URL")
20
+ .default(BASE_URL_DEFAULT),
21
+ });
3
22
  export class ZephyrClient {
4
23
  apiClient;
5
24
  name = "Zephyr";
6
- prefix = "zephyr";
7
- constructor(bearerToken, baseUrl = "https://api.zephyrscale.smartbear.com/v2") {
8
- this.apiClient = new ApiClient(bearerToken, baseUrl);
25
+ toolPrefix = "zephyr";
26
+ configPrefix = "Zephyr";
27
+ config = ConfigurationSchema;
28
+ async configure(_server, config, _cache) {
29
+ this.apiClient = new ApiClient(config.api_token, config.base_url || BASE_URL_DEFAULT);
30
+ return true;
31
+ }
32
+ getApiClient() {
33
+ if (!this.apiClient)
34
+ throw new Error("Client not configured");
35
+ return this.apiClient;
9
36
  }
10
37
  registerTools(register, _getInput) {
11
- const tools = [new GetProjects(this.apiClient)];
12
- tools.forEach((tool) => {
38
+ const apiClient = this.getApiClient();
39
+ const tools = [
40
+ new GetProjects(apiClient),
41
+ new GetProject(apiClient),
42
+ new GetTestCycles(apiClient),
43
+ new GetTestCycle(apiClient),
44
+ new GetPriorities(apiClient),
45
+ new GetStatuses(apiClient),
46
+ new GetTestCases(apiClient),
47
+ new GetTestCase(apiClient),
48
+ new GetTestExecution(apiClient),
49
+ ];
50
+ for (const tool of tools) {
13
51
  register(tool.specification, tool.handle);
14
- });
52
+ }
15
53
  }
16
54
  }
@@ -1,3 +1,4 @@
1
+ import { ToolError } from "../../common/types.js";
1
2
  import { AuthService } from "./auth-service.js";
2
3
  export class ApiClient {
3
4
  baseUrl;
@@ -22,6 +23,13 @@ export class ApiClient {
22
23
  method: "GET",
23
24
  headers: this.defaultHeaders,
24
25
  });
26
+ return await this.validateAndGetResponseBody(response);
27
+ }
28
+ async validateAndGetResponseBody(response) {
29
+ if (!response.ok) {
30
+ const errorText = await response.text();
31
+ throw new ToolError(`Request failed with status ${response.status}: ${errorText}`);
32
+ }
25
33
  return response.json();
26
34
  }
27
35
  }