@smartbear/mcp 0.19.2 → 0.20.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 (39) hide show
  1. package/README.md +15 -2
  2. package/assets/icon.png +0 -0
  3. package/dist/bugsnag/client.js +19 -12
  4. package/dist/collaborator/client.js +10 -10
  5. package/dist/common/client-registry.js +2 -2
  6. package/dist/common/server.js +74 -111
  7. package/dist/common/shutdown.js +165 -0
  8. package/dist/common/transport-http.js +94 -12
  9. package/dist/common/transport-stdio.js +16 -2
  10. package/dist/common/zod-utils.js +62 -7
  11. package/dist/index.js +2 -0
  12. package/dist/package.json.js +1 -1
  13. package/dist/pactflow/client/prompts.js +19 -18
  14. package/dist/pactflow/client/tools.js +8 -13
  15. package/dist/pactflow/client.js +26 -12
  16. package/dist/qmetry/client/tools/testsuite-tools.js +2 -2
  17. package/dist/qmetry/client.js +1 -1
  18. package/dist/reflect/client.js +3 -3
  19. package/dist/reflect/prompt/sap-test.js +5 -5
  20. package/dist/reflect/tool/recording/add-prompt-step.js +6 -14
  21. package/dist/reflect/tool/recording/add-segment.js +4 -14
  22. package/dist/reflect/tool/recording/connect-to-session.js +3 -8
  23. package/dist/reflect/tool/recording/delete-previous-step.js +3 -8
  24. package/dist/reflect/tool/recording/get-screenshot.js +4 -14
  25. package/dist/reflect/tool/suites/cancel-suite-execution.js +4 -14
  26. package/dist/reflect/tool/suites/execute-suite.js +3 -8
  27. package/dist/reflect/tool/suites/get-suite-execution-status.js +4 -14
  28. package/dist/reflect/tool/suites/list-suite-executions.js +3 -8
  29. package/dist/reflect/tool/suites/list-suites.js +2 -1
  30. package/dist/reflect/tool/tests/get-test-status.js +3 -8
  31. package/dist/reflect/tool/tests/list-segments.js +5 -20
  32. package/dist/reflect/tool/tests/list-tests.js +2 -1
  33. package/dist/reflect/tool/tests/run-test.js +3 -8
  34. package/dist/swagger/client/api.js +11 -2
  35. package/dist/swagger/client/portal-types.js +0 -3
  36. package/dist/swagger/client/tools.js +0 -1
  37. package/dist/swagger/client.js +1 -1
  38. package/dist/zephyr/client.js +1 -1
  39. package/package.json +5 -4
@@ -8,14 +8,9 @@ class DeletePreviousStep extends Tool {
8
8
  readOnly: false,
9
9
  idempotent: false,
10
10
  destructive: true,
11
- parameters: [
12
- {
13
- name: "sessionId",
14
- type: z.string(),
15
- description: "The ID of the Reflect recording session",
16
- required: true
17
- }
18
- ]
11
+ inputSchema: z.object({
12
+ sessionId: z.string().describe("The ID of the Reflect recording session")
13
+ })
19
14
  };
20
15
  handle = async (args) => {
21
16
  const { sessionId } = args;
@@ -7,20 +7,10 @@ class GetScreenshot extends Tool {
7
7
  summary: "Capture a screenshot from the current state of an active Reflect recording session",
8
8
  readOnly: true,
9
9
  idempotent: true,
10
- parameters: [
11
- {
12
- name: "sessionId",
13
- type: z.string(),
14
- description: "The ID of the Reflect recording session",
15
- required: true
16
- },
17
- {
18
- name: "format",
19
- type: z.enum(["png", "jpeg"]),
20
- description: "The image format for the screenshot (png or jpeg)",
21
- required: false
22
- }
23
- ]
10
+ inputSchema: z.object({
11
+ sessionId: z.string().describe("The ID of the Reflect recording session"),
12
+ format: z.enum(["png", "jpeg"]).optional().describe("The image format for the screenshot (png or jpeg)")
13
+ })
24
14
  };
25
15
  handle = async (args) => {
26
16
  const { sessionId, format } = args;
@@ -5,20 +5,10 @@ class CancelSuiteExecution extends Tool {
5
5
  specification = {
6
6
  title: "Cancel Suite Execution",
7
7
  summary: "Cancel a reflect suite execution",
8
- parameters: [
9
- {
10
- name: "suiteId",
11
- type: z.string(),
12
- description: "ID of the reflect suite to cancel execution for",
13
- required: true
14
- },
15
- {
16
- name: "executionId",
17
- type: z.string(),
18
- description: "ID of the reflect suite execution to cancel",
19
- required: true
20
- }
21
- ]
8
+ inputSchema: z.object({
9
+ suiteId: z.string().describe("ID of the reflect suite to cancel execution for"),
10
+ executionId: z.string().describe("ID of the reflect suite execution to cancel")
11
+ })
22
12
  };
23
13
  handle = async (args) => {
24
14
  const { suiteId, executionId } = args;
@@ -5,14 +5,9 @@ class ExecuteSuite extends Tool {
5
5
  specification = {
6
6
  title: "Execute Suite",
7
7
  summary: "Execute a reflect suite",
8
- parameters: [
9
- {
10
- name: "suiteId",
11
- type: z.string(),
12
- description: "ID of the reflect suite to execute",
13
- required: true
14
- }
15
- ]
8
+ inputSchema: z.object({
9
+ suiteId: z.string().describe("ID of the reflect suite to execute")
10
+ })
16
11
  };
17
12
  handle = async (args) => {
18
13
  const { suiteId } = args;
@@ -5,20 +5,10 @@ class GetSuiteExecutionStatus extends Tool {
5
5
  specification = {
6
6
  title: "Get Suite Execution Status",
7
7
  summary: "Get the status of a reflect suite execution",
8
- parameters: [
9
- {
10
- name: "suiteId",
11
- type: z.string(),
12
- description: "ID of the reflect suite to get execution status for",
13
- required: true
14
- },
15
- {
16
- name: "executionId",
17
- type: z.string(),
18
- description: "ID of the reflect suite execution to get status for",
19
- required: true
20
- }
21
- ]
8
+ inputSchema: z.object({
9
+ suiteId: z.string().describe("ID of the reflect suite to get execution status for"),
10
+ executionId: z.string().describe("ID of the reflect suite execution to get status for")
11
+ })
22
12
  };
23
13
  handle = async (args) => {
24
14
  const { suiteId, executionId } = args;
@@ -5,14 +5,9 @@ class ListSuiteExecutions extends Tool {
5
5
  specification = {
6
6
  title: "List Suite Executions",
7
7
  summary: "List all executions for a given suite",
8
- parameters: [
9
- {
10
- name: "suiteId",
11
- type: z.string(),
12
- description: "ID of the reflect suite to list executions for",
13
- required: true
14
- }
15
- ]
8
+ inputSchema: z.object({
9
+ suiteId: z.string().describe("ID of the reflect suite to list executions for")
10
+ })
16
11
  };
17
12
  handle = async (args) => {
18
13
  const { suiteId } = args;
@@ -1,10 +1,11 @@
1
+ import { z } from "zod";
1
2
  import { Tool, ToolError } from "../../../common/tools.js";
2
3
  import { API_HOSTNAME } from "../../config/constants.js";
3
4
  class ListSuites extends Tool {
4
5
  specification = {
5
6
  title: "List Suites",
6
7
  summary: "Retrieve a list of all reflect suites available",
7
- parameters: []
8
+ inputSchema: z.object({})
8
9
  };
9
10
  handle = async (_args) => {
10
11
  const response = await fetch(`https://${API_HOSTNAME}/v1/suites`, {
@@ -5,14 +5,9 @@ class GetTestStatus extends Tool {
5
5
  specification = {
6
6
  title: "Get Test Status",
7
7
  summary: "Get the status of a reflect test execution",
8
- parameters: [
9
- {
10
- name: "executionId",
11
- type: z.string(),
12
- description: "ID of the reflect test execution to get status for",
13
- required: true
14
- }
15
- ]
8
+ inputSchema: z.object({
9
+ executionId: z.string().describe("ID of the reflect test execution to get status for")
10
+ })
16
11
  };
17
12
  handle = async (args) => {
18
13
  const { executionId } = args;
@@ -7,26 +7,11 @@ class ListSegments extends Tool {
7
7
  summary: "Retrieve available reusable test segments for the given platform type. Segments are reusable test steps with an optional set of parameters that can used across multiple tests.",
8
8
  readOnly: true,
9
9
  idempotent: true,
10
- parameters: [
11
- {
12
- name: "platform",
13
- type: z.enum(["api", "native-mobile", "web"]),
14
- description: "The platform type to retrieve segments for",
15
- required: true
16
- },
17
- {
18
- name: "offset",
19
- type: z.number(),
20
- description: "Offset for pagination",
21
- required: false
22
- },
23
- {
24
- name: "limit",
25
- type: z.number(),
26
- description: "Maximum number of segments to return",
27
- required: false
28
- }
29
- ]
10
+ inputSchema: z.object({
11
+ platform: z.enum(["api", "native-mobile", "web"]).describe("The platform type to retrieve segments for"),
12
+ offset: z.number().optional().describe("Offset for pagination"),
13
+ limit: z.number().optional().describe("Maximum number of segments to return")
14
+ })
30
15
  };
31
16
  handle = async (args) => {
32
17
  const {
@@ -1,10 +1,11 @@
1
+ import { z } from "zod";
1
2
  import { Tool, ToolError } from "../../../common/tools.js";
2
3
  import { API_HOSTNAME } from "../../config/constants.js";
3
4
  class ListTests extends Tool {
4
5
  specification = {
5
6
  title: "List Tests",
6
7
  summary: "List all reflect tests",
7
- parameters: []
8
+ inputSchema: z.object({})
8
9
  };
9
10
  handle = async (_args) => {
10
11
  const response = await fetch(`https://${API_HOSTNAME}/v1/tests`, {
@@ -5,14 +5,9 @@ class RunTest extends Tool {
5
5
  specification = {
6
6
  title: "Run Test",
7
7
  summary: "Run a reflect test",
8
- parameters: [
9
- {
10
- name: "testId",
11
- type: z.string(),
12
- description: "ID of the reflect test to run",
13
- required: true
14
- }
15
- ]
8
+ inputSchema: z.object({
9
+ testId: z.string().describe("ID of the reflect test to run")
10
+ })
16
11
  };
17
12
  handle = async (args) => {
18
13
  const { testId } = args;
@@ -37,7 +37,7 @@ class SwaggerAPI {
37
37
  return defaultReturn;
38
38
  }
39
39
  const contentType = response.headers.get("content-type");
40
- if (contentType?.includes("application/json")) {
40
+ if (contentType?.includes("application/json") || contentType?.includes("application/problem+json")) {
41
41
  try {
42
42
  return await response.json();
43
43
  } catch (error) {
@@ -69,7 +69,16 @@ class SwaggerAPI {
69
69
  */
70
70
  async handleResponse(response, defaultReturn = {}) {
71
71
  if (!response.ok) {
72
- throw new ToolError(`HTTP ${response.status}: ${response.statusText}`);
72
+ const errorBody = await this.parseResponse(
73
+ response,
74
+ {}
75
+ );
76
+ const detail = typeof errorBody === "object" && errorBody !== null && String(
77
+ errorBody.detail ?? errorBody.message ?? ""
78
+ ) || response.statusText;
79
+ throw new ToolError(
80
+ `HTTP ${response.status}${detail ? `: ${detail}` : ""}`
81
+ );
73
82
  }
74
83
  return this.parseResponse(
75
84
  response,
@@ -157,9 +157,6 @@ const CreateProductArgsSchema = PortalArgsSchema.extend({
157
157
  ),
158
158
  hidden: z.boolean().optional().describe(
159
159
  "Whether the product is hidden from the portal landing page navigation menus - useful for internal or draft products"
160
- ),
161
- role: z.boolean().optional().describe(
162
- "Whether the product has role-based access restrictions - controls if specific user roles are required to access the product"
163
160
  )
164
161
  });
165
162
  const UpdateProductArgsSchema = ProductArgsSchema.extend({
@@ -5,7 +5,6 @@ const TOOLS = [
5
5
  {
6
6
  title: "List Portals",
7
7
  summary: "Search for available portals within Swagger. Only portals where you have at least a designer role, either at the product level or organization level, are returned.",
8
- parameters: [],
9
8
  handler: "getPortals"
10
9
  },
11
10
  {
@@ -18,7 +18,7 @@ class SwaggerClient {
18
18
  api;
19
19
  _apiKey;
20
20
  name = "Swagger";
21
- toolPrefix = "swagger";
21
+ capabilityPrefix = "swagger";
22
22
  configPrefix = "Swagger";
23
23
  config = ConfigurationSchema;
24
24
  async configure(_server, config, _cache) {
@@ -45,7 +45,7 @@ class ZephyrClient {
45
45
  apiClient;
46
46
  _apiToken;
47
47
  name = "Zephyr";
48
- toolPrefix = "zephyr";
48
+ capabilityPrefix = "zephyr";
49
49
  configPrefix = "Zephyr";
50
50
  config = ConfigurationSchema;
51
51
  async configure(_server, config, _cache) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartbear/mcp",
3
- "version": "0.19.2",
3
+ "version": "0.20.0",
4
4
  "description": "MCP server for interacting SmartBear Products",
5
5
  "keywords": [
6
6
  "smartbear",
@@ -31,7 +31,7 @@
31
31
  "mcpServerName": "SmartBear MCP Server"
32
32
  },
33
33
  "scripts": {
34
- "build": "vite build && shx chmod +x dist/*.js",
34
+ "build": "tsc && vite build && shx chmod +x dist/*.js",
35
35
  "lint": "biome lint .",
36
36
  "lint:fix": "biome lint . --fix",
37
37
  "format": "biome format . --write",
@@ -43,8 +43,9 @@
43
43
  "test:coverage": "vitest --coverage",
44
44
  "test:coverage:ci": "vitest --coverage --reporter=verbose",
45
45
  "test:run": "vitest run",
46
- "coverage:check": "vitest --coverage --reporter=verbose --config vitest.config.coverage.ts",
47
- "bump": "node scripts/bump.js"
46
+ "coverage:check": "vitest --coverage --reporter=verbose",
47
+ "bump": "node scripts/bump.js",
48
+ "postpack": "node scripts/pack-mcpb.js"
48
49
  },
49
50
  "dependencies": {
50
51
  "@bugsnag/js": "^8.8.1",