@smartbear/mcp 0.12.1 → 0.13.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 (89) hide show
  1. package/README.md +30 -6
  2. package/dist/bugsnag/client/api/CurrentUser.js +50 -26
  3. package/dist/bugsnag/client/api/Error.js +156 -93
  4. package/dist/bugsnag/client/api/Project.js +398 -276
  5. package/dist/bugsnag/client/api/api.js +4087 -3837
  6. package/dist/bugsnag/client/api/base.js +155 -173
  7. package/dist/bugsnag/client/api/configuration.js +28 -25
  8. package/dist/bugsnag/client/filters.js +11 -20
  9. package/dist/bugsnag/client.js +1398 -1281
  10. package/dist/bugsnag/input-schemas.js +39 -57
  11. package/dist/collaborator/client.js +335 -371
  12. package/dist/common/bugsnag.js +5 -3
  13. package/dist/common/cache.js +50 -57
  14. package/dist/common/client-registry.js +106 -119
  15. package/dist/common/info.js +7 -3
  16. package/dist/common/register-clients.js +0 -16
  17. package/dist/common/server.js +270 -228
  18. package/dist/common/tools.js +19 -0
  19. package/dist/common/transport-http.js +252 -343
  20. package/dist/common/transport-stdio.js +40 -37
  21. package/dist/common/zod-utils.js +20 -0
  22. package/dist/index.js +18 -23
  23. package/dist/package.json.js +11 -0
  24. package/dist/pactflow/client/ai.js +142 -169
  25. package/dist/pactflow/client/base.js +41 -51
  26. package/dist/pactflow/client/prompt-utils.js +93 -84
  27. package/dist/pactflow/client/prompts.js +95 -92
  28. package/dist/pactflow/client/tools.js +94 -83
  29. package/dist/pactflow/client/utils.js +60 -64
  30. package/dist/pactflow/client.js +399 -320
  31. package/dist/qmetry/client/api/client-api.js +43 -41
  32. package/dist/qmetry/client/api/error-handler.js +264 -310
  33. package/dist/qmetry/client/auto-resolve.js +78 -99
  34. package/dist/qmetry/client/automation.js +139 -162
  35. package/dist/qmetry/client/handlers.js +49 -46
  36. package/dist/qmetry/client/issues.js +133 -115
  37. package/dist/qmetry/client/project.js +153 -174
  38. package/dist/qmetry/client/requirement.js +82 -70
  39. package/dist/qmetry/client/testcase.js +240 -208
  40. package/dist/qmetry/client/testsuite.js +332 -293
  41. package/dist/qmetry/client/tools/automation-tools.js +291 -288
  42. package/dist/qmetry/client/tools/index.js +16 -13
  43. package/dist/qmetry/client/tools/issue-tools.js +534 -543
  44. package/dist/qmetry/client/tools/project-tools.js +635 -656
  45. package/dist/qmetry/client/tools/requirement-tools.js +525 -528
  46. package/dist/qmetry/client/tools/testcase-tools.js +773 -786
  47. package/dist/qmetry/client/tools/testsuite-tools.js +1069 -1083
  48. package/dist/qmetry/client/utils.js +8 -14
  49. package/dist/qmetry/client.js +111 -109
  50. package/dist/qmetry/config/constants.js +48 -44
  51. package/dist/qmetry/config/rest-endpoints.js +51 -48
  52. package/dist/qmetry/types/automation.js +7 -7
  53. package/dist/qmetry/types/common.js +763 -1049
  54. package/dist/qmetry/types/issues.js +26 -19
  55. package/dist/qmetry/types/project.js +32 -25
  56. package/dist/qmetry/types/requirements.js +26 -21
  57. package/dist/qmetry/types/testcase.js +55 -44
  58. package/dist/qmetry/types/testsuite.js +66 -52
  59. package/dist/reflect/client.js +284 -226
  60. package/dist/swagger/client/api.js +645 -662
  61. package/dist/swagger/client/configuration.js +31 -33
  62. package/dist/swagger/client/portal-types.js +204 -244
  63. package/dist/swagger/client/registry-types.js +62 -96
  64. package/dist/swagger/client/tools.js +148 -158
  65. package/dist/swagger/client/user-management-types.js +11 -22
  66. package/dist/swagger/client.js +143 -135
  67. package/dist/swagger/config-utils.js +10 -16
  68. package/dist/zephyr/client.js +43 -42
  69. package/dist/zephyr/common/api-client.js +35 -30
  70. package/dist/zephyr/common/auth-service.js +16 -13
  71. package/dist/zephyr/common/rest-api-schemas.js +3173 -5146
  72. package/dist/zephyr/tool/environment/get-environments.js +66 -66
  73. package/dist/zephyr/tool/priority/get-priorities.js +41 -41
  74. package/dist/zephyr/tool/project/get-project.js +37 -37
  75. package/dist/zephyr/tool/project/get-projects.js +46 -46
  76. package/dist/zephyr/tool/status/get-statuses.js +47 -47
  77. package/dist/zephyr/tool/test-case/get-test-case.js +37 -37
  78. package/dist/zephyr/tool/test-case/get-test-cases.js +62 -62
  79. package/dist/zephyr/tool/test-cycle/get-test-cycle.js +37 -37
  80. package/dist/zephyr/tool/test-cycle/get-test-cycles.js +70 -70
  81. package/dist/zephyr/tool/test-execution/get-test-execution.js +37 -37
  82. package/dist/zephyr/tool/test-execution/get-test-executions.js +43 -43
  83. package/package.json +5 -5
  84. package/dist/bugsnag/client/api/index.js +0 -6
  85. package/dist/common/types.js +0 -6
  86. package/dist/qmetry/client/tools/types.js +0 -1
  87. package/dist/swagger/client/index.js +0 -6
  88. package/dist/tests/unit/bugsnag/utils/factories.js +0 -86
  89. package/dist/zephyr/tool/zephyr-tool.js +0 -1
@@ -1,3 +1,5 @@
1
- // workaround for a known issue with Bugsnag types in node16 modules: https://github.com/bugsnag/bugsnag-js/issues/2052
2
- import * as Bugsnag from "@bugsnag/js";
3
- export default Bugsnag.default;
1
+ import * as Bugsnag$1 from "@bugsnag/js";
2
+ const Bugsnag = Bugsnag$1.default;
3
+ export {
4
+ Bugsnag as default
5
+ };
@@ -1,63 +1,56 @@
1
1
  import NodeCache from "node-cache";
2
- /**
3
- * Common cache service that can be shared across all clients.
4
- * Wraps NodeCache and provides a way to disable caching entirely.
5
- * Reads CACHE_ENABLED and CACHE_TTL environment variables for configuration.
6
- */
7
- export class CacheService {
8
- cache;
9
- enabled;
10
- constructor() {
11
- // Read configuration from environment variables
12
- this.enabled = process.env.CACHE_ENABLED !== "false";
13
- const ttl = process.env.CACHE_TTL
14
- ? Number.parseInt(process.env.CACHE_TTL, 10)
15
- : 86400; // Default 24 hours
16
- this.cache = this.enabled
17
- ? new NodeCache({
18
- stdTTL: ttl,
19
- })
20
- : null;
2
+ class CacheService {
3
+ cache;
4
+ enabled;
5
+ constructor() {
6
+ this.enabled = process.env.CACHE_ENABLED !== "false";
7
+ const ttl = process.env.CACHE_TTL ? Number.parseInt(process.env.CACHE_TTL, 10) : 86400;
8
+ this.cache = this.enabled ? new NodeCache({
9
+ stdTTL: ttl
10
+ }) : null;
11
+ }
12
+ /**
13
+ * Get a value from the cache
14
+ */
15
+ get(key) {
16
+ if (!this.enabled || !this.cache) {
17
+ return void 0;
21
18
  }
22
- /**
23
- * Get a value from the cache
24
- */
25
- get(key) {
26
- if (!this.enabled || !this.cache) {
27
- return undefined;
28
- }
29
- return this.cache.get(key);
19
+ return this.cache.get(key);
20
+ }
21
+ /**
22
+ * Set a value in the cache
23
+ */
24
+ set(key, value) {
25
+ if (!this.enabled || !this.cache) {
26
+ return false;
30
27
  }
31
- /**
32
- * Set a value in the cache
33
- */
34
- set(key, value) {
35
- if (!this.enabled || !this.cache) {
36
- return false;
37
- }
38
- return this.cache.set(key, value);
28
+ return this.cache.set(key, value);
29
+ }
30
+ /**
31
+ * Delete a value from the cache
32
+ */
33
+ del(key) {
34
+ if (!this.enabled || !this.cache) {
35
+ return 0;
39
36
  }
40
- /**
41
- * Delete a value from the cache
42
- */
43
- del(key) {
44
- if (!this.enabled || !this.cache) {
45
- return 0;
46
- }
47
- return this.cache.del(key);
48
- }
49
- /**
50
- * Check if caching is enabled
51
- */
52
- isEnabled() {
53
- return this.enabled;
54
- }
55
- /**
56
- * Clear all cache entries
57
- */
58
- flushAll() {
59
- if (this.enabled && this.cache) {
60
- this.cache.flushAll();
61
- }
37
+ return this.cache.del(key);
38
+ }
39
+ /**
40
+ * Check if caching is enabled
41
+ */
42
+ isEnabled() {
43
+ return this.enabled;
44
+ }
45
+ /**
46
+ * Clear all cache entries
47
+ */
48
+ flushAll() {
49
+ if (this.enabled && this.cache) {
50
+ this.cache.flushAll();
62
51
  }
52
+ }
63
53
  }
54
+ export {
55
+ CacheService
56
+ };
@@ -1,128 +1,115 @@
1
- import { ZodOptional, ZodString } from "zod";
2
- /**
3
- * Central registry for all MCP clients
4
- * Add new clients here to make them automatically available
5
- */
1
+ import { ZodURL } from "zod";
2
+ import { unwrapZodType, isOptionalType } from "./zod-utils.js";
6
3
  class ClientRegistry {
7
- entries = [];
8
- enabledClients = null;
9
- /**
10
- * Configure which clients should be enabled based on MCP_CLIENTS env var
11
- * If not set or empty, all clients are enabled
12
- * If set, should be comma-separated list of client names (case-insensitive)
13
- */
14
- constructor() {
15
- const enabledClientsEnv = process.env.MCP_CLIENTS?.trim();
16
- if (!enabledClientsEnv) {
17
- // Empty or not set = all clients enabled
18
- this.enabledClients = null;
19
- return;
20
- }
21
- // Parse comma-separated list and normalize to lowercase for comparison
22
- this.enabledClients = new Set(enabledClientsEnv
23
- .split(",")
24
- .map((name) => name.trim().toLowerCase())
25
- .filter((name) => name.length > 0));
4
+ entries = [];
5
+ enabledClients = null;
6
+ /**
7
+ * Configure which clients should be enabled based on MCP_CLIENTS env var
8
+ * If not set or empty, all clients are enabled
9
+ * If set, should be comma-separated list of client names (case-insensitive)
10
+ */
11
+ constructor() {
12
+ const enabledClientsEnv = process.env.MCP_CLIENTS?.trim();
13
+ if (!enabledClientsEnv) {
14
+ this.enabledClients = null;
15
+ return;
26
16
  }
27
- /**
28
- * Check if a client is enabled based on MCP_CLIENTS configuration
29
- */
30
- isClientEnabled(name) {
31
- if (this.enabledClients === null) {
32
- return true; // All clients enabled
33
- }
34
- return this.enabledClients.has(name.toLowerCase());
17
+ this.enabledClients = new Set(
18
+ enabledClientsEnv.split(",").map((name) => name.trim().toLowerCase()).filter((name) => name.length > 0)
19
+ );
20
+ }
21
+ /**
22
+ * Check if a client is enabled based on MCP_CLIENTS configuration
23
+ */
24
+ isClientEnabled(name) {
25
+ if (this.enabledClients === null) {
26
+ return true;
35
27
  }
36
- /**
37
- * Validate if a config option is an Allowed Endpoint URL
38
- * Supports both exact matches and regex patterns
39
- * Patterns starting with / and ending with / are treated as regex
40
- * @param zodType The Zod type definition for the config option
41
- * @param value The actual config value to validate
42
- */
43
- validateAllowedEndpoint(zodType, value) {
44
- if (zodType instanceof ZodOptional) {
45
- zodType = zodType._def.innerType;
46
- }
47
- if (zodType instanceof ZodString) {
48
- if (zodType.isURL) {
49
- const allowedEndpoints = process.env.MCP_ALLOWED_ENDPOINTS?.split(",");
50
- if (allowedEndpoints) {
51
- for (const endpoint of allowedEndpoints) {
52
- const trimmedEndpoint = endpoint.trim();
53
- // Check if this is a regex pattern (wrapped in /)
54
- if (trimmedEndpoint.startsWith("/") &&
55
- trimmedEndpoint.endsWith("/")) {
56
- try {
57
- const pattern = trimmedEndpoint.slice(1, -1); // Remove leading/trailing /
58
- const regex = new RegExp(pattern);
59
- if (regex.test(value)) {
60
- return;
61
- }
62
- }
63
- catch (error) {
64
- console.warn(`Invalid regex pattern in MCP_ALLOWED_ENDPOINTS: ${trimmedEndpoint}, error: ${error}`);
65
- }
66
- }
67
- else {
68
- // Exact match
69
- if (value === trimmedEndpoint) {
70
- return;
71
- }
72
- }
73
- }
74
- throw new Error(`URL ${value} is not allowed`);
75
- }
28
+ return this.enabledClients.has(name.toLowerCase());
29
+ }
30
+ /**
31
+ * Validate if a config option is an Allowed Endpoint URL
32
+ * Supports both exact matches and regex patterns
33
+ * Patterns starting with / and ending with / are treated as regex
34
+ * @param zodType The Zod type definition for the config option
35
+ * @param value The actual config value to validate
36
+ */
37
+ validateAllowedEndpoint(zodType, value) {
38
+ if (unwrapZodType(zodType) instanceof ZodURL) {
39
+ const allowedEndpoints = process.env.MCP_ALLOWED_ENDPOINTS?.split(",");
40
+ if (allowedEndpoints) {
41
+ for (const endpoint of allowedEndpoints) {
42
+ const trimmedEndpoint = endpoint.trim();
43
+ if (trimmedEndpoint.startsWith("/") && trimmedEndpoint.endsWith("/")) {
44
+ try {
45
+ const pattern = trimmedEndpoint.slice(1, -1);
46
+ const regex = new RegExp(pattern);
47
+ if (regex.test(value)) {
48
+ return;
49
+ }
50
+ } catch (error) {
51
+ console.warn(
52
+ `Invalid regex pattern in MCP_ALLOWED_ENDPOINTS: ${trimmedEndpoint}, error: ${error}`
53
+ );
76
54
  }
77
- }
78
- }
79
- /**
80
- * Register a client class
81
- * @param name Display name for the client (for logging)
82
- */
83
- register(client) {
84
- this.entries.push(client);
85
- }
86
- /**
87
- * Get all registered clients (filtered by MCP_CLIENTS if configured)
88
- */
89
- getAll() {
90
- return this.entries.filter((entry) => this.isClientEnabled(entry.name));
91
- }
92
- /**
93
- * Configures all enabled clients on the given MCP server
94
- * @param server The MCP server on which the client is registered
95
- * @param getConfigValue A function that obtains a configuration value for the given client and requirement name
96
- * @returns The number of clients successfully configured
97
- */
98
- async configure(server, getConfigValue) {
99
- let configuredCount = 0;
100
- entryLoop: for (const entry of this.getAll()) {
101
- const config = {};
102
- for (const configKey of Object.keys(entry.config.shape)) {
103
- const value = getConfigValue(entry, configKey);
104
- if (value !== null) {
105
- // validate if a config option is an Allowed Endpoint URL
106
- this.validateAllowedEndpoint(entry.config.shape[configKey], value);
107
- config[configKey] = value;
108
- }
109
- else if (!entry.config.shape[configKey].isOptional()) {
110
- continue entryLoop; // Skip configuring this client - missing required config
111
- }
112
- }
113
- if (await entry.configure(server, config)) {
114
- server.addClient(entry);
115
- configuredCount++;
55
+ } else {
56
+ if (value === trimmedEndpoint) {
57
+ return;
116
58
  }
59
+ }
117
60
  }
118
- return configuredCount;
61
+ throw new Error(`URL ${value} is not allowed`);
62
+ }
119
63
  }
120
- /**
121
- * Clear all registrations (useful for testing)
122
- */
123
- clear() {
124
- this.entries = [];
64
+ }
65
+ /**
66
+ * Register a client class
67
+ * @param name Display name for the client (for logging)
68
+ */
69
+ register(client) {
70
+ this.entries.push(client);
71
+ }
72
+ /**
73
+ * Get all registered clients (filtered by MCP_CLIENTS if configured)
74
+ */
75
+ getAll() {
76
+ return this.entries.filter((entry) => this.isClientEnabled(entry.name));
77
+ }
78
+ /**
79
+ * Configures all enabled clients on the given MCP server
80
+ * @param server The MCP server on which the client is registered
81
+ * @param getConfigValue A function that obtains a configuration value for the given client and requirement name
82
+ * @returns The number of clients successfully configured
83
+ */
84
+ async configure(server, getConfigValue) {
85
+ let configuredCount = 0;
86
+ entryLoop: for (const entry of this.getAll()) {
87
+ const config = {};
88
+ for (const configKey of Object.keys(entry.config.shape)) {
89
+ const value = getConfigValue(entry, configKey);
90
+ if (value !== null) {
91
+ this.validateAllowedEndpoint(entry.config.shape[configKey], value);
92
+ config[configKey] = value;
93
+ } else if (!isOptionalType(entry.config.shape[configKey])) {
94
+ continue entryLoop;
95
+ }
96
+ }
97
+ await entry.configure(server, config);
98
+ if (entry.isConfigured()) {
99
+ await server.addClient(entry);
100
+ configuredCount++;
101
+ }
125
102
  }
103
+ return configuredCount;
104
+ }
105
+ /**
106
+ * Clear all registrations (useful for testing)
107
+ */
108
+ clear() {
109
+ this.entries = [];
110
+ }
126
111
  }
127
- // Create and export the singleton registry
128
- export const clientRegistry = new ClientRegistry();
112
+ const clientRegistry = new ClientRegistry();
113
+ export {
114
+ clientRegistry
115
+ };
@@ -1,3 +1,7 @@
1
- import packageJson from "../../package.json" with { type: "json" };
2
- export const MCP_SERVER_NAME = packageJson.config.mcpServerName;
3
- export const MCP_SERVER_VERSION = packageJson.version;
1
+ import packageJson from "../package.json.js";
2
+ const MCP_SERVER_NAME = packageJson.config.mcpServerName;
3
+ const MCP_SERVER_VERSION = packageJson.version;
4
+ export {
5
+ MCP_SERVER_NAME,
6
+ MCP_SERVER_VERSION
7
+ };
@@ -1,12 +1,3 @@
1
- /**
2
- * Client registration module
3
- *
4
- * This file registers all available MCP clients with the client registry.
5
- * To add a new client:
6
- * 1. Import the client class
7
- * 2. Call clientRegistry.register() with the client details
8
- * 3. Specify if the client needs the MCP server instance or async initialization
9
- */
10
1
  import { BugsnagClient } from "../bugsnag/client.js";
11
2
  import { CollaboratorClient } from "../collaborator/client.js";
12
3
  import { PactflowClient } from "../pactflow/client.js";
@@ -15,17 +6,10 @@ import { ReflectClient } from "../reflect/client.js";
15
6
  import { SwaggerClient } from "../swagger/client.js";
16
7
  import { ZephyrClient } from "../zephyr/client.js";
17
8
  import { clientRegistry } from "./client-registry.js";
18
- // Register Reflect client
19
9
  clientRegistry.register(new ReflectClient());
20
- // Register Bugsnag client
21
10
  clientRegistry.register(new BugsnagClient());
22
- // Register Swagger client
23
11
  clientRegistry.register(new SwaggerClient());
24
- // Register PactFlow/Pact Broker client
25
12
  clientRegistry.register(new PactflowClient());
26
- // Register QMetry client
27
13
  clientRegistry.register(new QmetryClient());
28
- // Register Zephyr client
29
14
  clientRegistry.register(new ZephyrClient());
30
- // Register Collaborator client
31
15
  clientRegistry.register(new CollaboratorClient());