@smartbear/mcp 0.25.1 → 0.26.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.
package/README.md CHANGED
@@ -35,6 +35,7 @@ See individual guides for suggested prompts and supported tools and resources:
35
35
  - [Portal](https://developer.smartbear.com/smartbear-mcp/docs/swagger-portal-integration) - Portal and product management capabilities
36
36
  - [Studio](https://developer.smartbear.com/smartbear-mcp/docs/swagger-studio-integration) - API and Domain management capabilities, including AI-powered API generation from prompts and automatic standardization
37
37
  - [Contract Testing (PactFlow)](https://developer.smartbear.com/pactflow/default/getting-started) - Contract testing capabilities
38
+ - [Functional Testing](https://developer.smartbear.com/smartbear-mcp/docs/functional-testing-integration) - API test discovery capabilities
38
39
  - [QMetry](https://developer.smartbear.com/smartbear-mcp/docs/qmetry-integration) - QMetry Test Management capabilities
39
40
  - [Zephyr](https://developer.smartbear.com/smartbear-mcp/docs/zephyr-integration) - Zephyr Test Management capabilities
40
41
  - [Collaborator](https://developer.smartbear.com/smartbear-mcp/docs/collaborator-integration) - Review and Remote System Configuration management capabilities
@@ -52,7 +53,7 @@ For BugSnag, Swagger, and Zephyr, SmartBear hosts Remote MCP Servers that you ca
52
53
 
53
54
  See the [Remote MCP Servers guide](https://developer.smartbear.com/smartbear-mcp/docs/remote-mcp-servers) for per-client setup instructions. You can connect to multiple remote servers at the same time.
54
55
 
55
- > **Need BearQ, Reflect, QMetry, QTM4J, PactFlow, or Collaborator?** These products are only available via the local npm package below, which bundles all products into a single MCP server.
56
+ > **Need BearQ, Reflect, QMetry, QTM4J, PactFlow, Collaborator, or Functional Testing?** These products are only available via the local npm package below, which bundles all products into a single MCP server.
56
57
 
57
58
  ## Prerequisites
58
59
 
@@ -108,7 +109,8 @@ Alternatively, you can use `npx` (or globally install) the `@smartbear/mcp` pack
108
109
  "COLLABORATOR_LOGIN_TICKET": "${input:collab_login_ticket}",
109
110
  "QTM4J_API_KEY": "${input:qtm4j_api_key}",
110
111
  "QTM4J_BASE_URL": "${input:qtm4j_base_url}",
111
- "QTM4J_AUTOMATION_API_KEY": "${input:qtm4j_automation_api_key}"
112
+ "QTM4J_AUTOMATION_API_KEY": "${input:qtm4j_automation_api_key}",
113
+ "SWAGGER_FUNCTIONAL_TESTING_API_TOKEN": "${input:swagger_functional_testing_api_token}"
112
114
  }
113
115
  }
114
116
  },
@@ -250,6 +252,12 @@ Alternatively, you can use `npx` (or globally install) the `@smartbear/mcp` pack
250
252
  "type": "promptString",
251
253
  "description": "QTM4J Automation API Key - required for automation tools, leave blank to disable them",
252
254
  "password": true
255
+ },
256
+ {
257
+ "id": "swagger_functional_testing_api_token",
258
+ "type": "promptString",
259
+ "description": "Swagger Functional Testing API Token - leave blank to disable Functional Testing tools",
260
+ "password": true
253
261
  }
254
262
  ]
255
263
  }
@@ -291,7 +299,8 @@ Add the following configuration to your `claude_desktop_config.json` to launch t
291
299
  "COLLABORATOR_LOGIN_TICKET": "your collab login ticket",
292
300
  "QTM4J_API_KEY": "your_qtm4j_key",
293
301
  "QTM4J_BASE_URL": "https://qtmcloud.qmetry.com",
294
- "QTM4J_AUTOMATION_API_KEY": "your_qtm4j_automation_api_key"
302
+ "QTM4J_AUTOMATION_API_KEY": "your_qtm4j_automation_api_key",
303
+ "SWAGGER_FUNCTIONAL_TESTING_API_TOKEN": "your_swagger_functional_testing_api_token"
295
304
  }
296
305
  }
297
306
  }
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
2
+ import { USER_AGENT } from "../common/info.js";
3
3
  import { getRequestHeader } from "../common/request-context.js";
4
4
  import { ToolError } from "../common/tools.js";
5
5
  import { DEFAULT_API_BASE_URL, AUTHORIZATION_HEADER } from "./config/constants.js";
@@ -53,7 +53,7 @@ class BearQClient {
53
53
  return {
54
54
  Authorization: `Bearer ${token}`,
55
55
  "Content-Type": "application/json",
56
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
56
+ "User-Agent": USER_AGENT
57
57
  };
58
58
  }
59
59
  async registerTools(register, _getInput) {
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
2
+ import { USER_AGENT } from "../common/info.js";
3
3
  import { getRequestHeader } from "../common/request-context.js";
4
4
  import { ToolError } from "../common/tools.js";
5
5
  import { CurrentUserAPI } from "./client/api/CurrentUser.js";
@@ -123,7 +123,7 @@ class BugsnagClient {
123
123
  );
124
124
  },
125
125
  headers: {
126
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`,
126
+ "User-Agent": USER_AGENT,
127
127
  "Content-Type": "application/json",
128
128
  "X-Bugsnag-API": "true",
129
129
  "X-Version": "2"
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { USER_AGENT } from "../common/info.js";
2
3
  import { getRequestHeader } from "../common/request-context.js";
3
4
  const ConfigurationSchema = z.object({
4
5
  base_url: z.url().describe("Collaborator server base URL"),
@@ -47,7 +48,7 @@ class CollaboratorClient {
47
48
  ];
48
49
  const response = await fetch(url, {
49
50
  method: "POST",
50
- headers: { "Content-Type": "application/json" },
51
+ headers: { "Content-Type": "application/json", "User-Agent": USER_AGENT },
51
52
  body: JSON.stringify(body)
52
53
  });
53
54
  if (!response.ok) {
@@ -1,7 +1,11 @@
1
1
  import packageJson from "../package.json.js";
2
2
  const MCP_SERVER_NAME = packageJson.config.mcpServerName;
3
3
  const MCP_SERVER_VERSION = packageJson.version;
4
+ const MCP_TRANSPORT = process.env.MCP_TRANSPORT?.toLowerCase().trim() || "stdio";
5
+ const USER_AGENT = `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION} ${MCP_TRANSPORT}`;
4
6
  export {
5
7
  MCP_SERVER_NAME,
6
- MCP_SERVER_VERSION
8
+ MCP_SERVER_VERSION,
9
+ MCP_TRANSPORT,
10
+ USER_AGENT
7
11
  };
@@ -1,7 +1,7 @@
1
1
  import { enableCompileCache } from "node:module";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
3
  import { clientRegistry } from "./client-registry.js";
4
- import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "./info.js";
4
+ import { USER_AGENT } from "./info.js";
5
5
  import { SmartBearMcpServer } from "./server.js";
6
6
  import { registerShutdownHandler } from "./shutdown.js";
7
7
  import { isOptionalType, getTypeDescription } from "./zod-utils.js";
@@ -21,7 +21,7 @@ function getNoConfigMessage() {
21
21
  }
22
22
  async function runStdioMode() {
23
23
  if (process.argv.includes("--version")) {
24
- console.log(`${MCP_SERVER_NAME}: v${MCP_SERVER_VERSION}`);
24
+ console.log(`User-Agent: ${USER_AGENT}`);
25
25
  process.exit(0);
26
26
  } else if (process.argv.includes("--help")) {
27
27
  console.log(
@@ -1,4 +1,4 @@
1
- const version = "0.25.1";
1
+ const version = "0.26.0";
2
2
  const config = { "mcpServerName": "SmartBear MCP Server" };
3
3
  const packageJson = {
4
4
  version,
@@ -1,5 +1,5 @@
1
1
  import zod__default from "zod";
2
- import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
2
+ import { USER_AGENT } from "../common/info.js";
3
3
  import { isSamplingPolyfillResult } from "../common/pollyfills.js";
4
4
  import { getRequestHeader } from "../common/request-context.js";
5
5
  import { ToolError } from "../common/tools.js";
@@ -178,7 +178,7 @@ class PactflowClient {
178
178
  return {
179
179
  Authorization: authHeader,
180
180
  "Content-Type": "application/json",
181
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
181
+ "User-Agent": USER_AGENT
182
182
  };
183
183
  }
184
184
  if (this.token) {
@@ -189,14 +189,14 @@ class PactflowClient {
189
189
  return {
190
190
  Authorization: authHeader,
191
191
  "Content-Type": "application/json",
192
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
192
+ "User-Agent": USER_AGENT
193
193
  };
194
194
  } else if (this.username && this.password) {
195
195
  const authString = `${this.username}:${this.password}`;
196
196
  return {
197
197
  Authorization: `Basic ${Buffer.from(authString).toString("base64")}`,
198
198
  "Content-Type": "application/json",
199
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
199
+ "User-Agent": USER_AGENT
200
200
  };
201
201
  }
202
202
  return void 0;
@@ -1,4 +1,4 @@
1
- import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../../../common/info.js";
1
+ import { USER_AGENT } from "../../../common/info.js";
2
2
  import { QMETRY_DEFAULTS } from "../../config/constants.js";
3
3
  import { handleQMetryFetchError, handleQMetryApiError } from "./error-handler.js";
4
4
  async function qmetryRequest({
@@ -13,7 +13,7 @@ async function qmetryRequest({
13
13
  const headers = {
14
14
  apikey: token,
15
15
  project: project || QMETRY_DEFAULTS.PROJECT_KEY,
16
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`,
16
+ "User-Agent": USER_AGENT,
17
17
  "qmetry-source": "smartbear-mcp"
18
18
  };
19
19
  if (body) {
@@ -1,4 +1,4 @@
1
- import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../../common/info.js";
1
+ import { USER_AGENT } from "../../common/info.js";
2
2
  import { QMETRY_DEFAULTS } from "../config/constants.js";
3
3
  import { QMETRY_PATHS } from "../config/rest-endpoints.js";
4
4
  import { DEFAULT_IMPORT_AUTOMATION_PAYLOAD } from "../types/automation.js";
@@ -91,7 +91,7 @@ async function importAutomationResults(token, baseUrl, project, payload) {
91
91
  const headers = {
92
92
  apikey: token,
93
93
  project: finalPayload.projectID || project || QMETRY_DEFAULTS.PROJECT_KEY,
94
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`,
94
+ "User-Agent": USER_AGENT,
95
95
  "qmetry-source": "smartbear-mcp"
96
96
  // Note: Content-Type will be set automatically by fetch for FormData
97
97
  };
@@ -1,4 +1,4 @@
1
- import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../../common/info.js";
1
+ import { USER_AGENT } from "../../common/info.js";
2
2
  import { CONTENT_TYPES, HTTP_HEADERS } from "../config/constants.js";
3
3
  class AuthService {
4
4
  apiKey;
@@ -13,7 +13,7 @@ class AuthService {
13
13
  return {
14
14
  [HTTP_HEADERS.API_KEY]: this.apiKey,
15
15
  [HTTP_HEADERS.CONTENT_TYPE]: CONTENT_TYPES.JSON,
16
- [HTTP_HEADERS.USER_AGENT]: `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`,
16
+ [HTTP_HEADERS.USER_AGENT]: USER_AGENT,
17
17
  [HTTP_HEADERS.ACCEPT]: CONTENT_TYPES.JSON
18
18
  };
19
19
  }
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
2
+ import { USER_AGENT } from "../common/info.js";
3
3
  import { getRequestHeader } from "../common/request-context.js";
4
4
  import { ToolError } from "../common/tools.js";
5
5
  import { API_KEY_HEADER, REFLECT_API_TOKEN_HEADER, AUTHORIZATION_HEADER } from "./config/constants.js";
@@ -14,6 +14,7 @@ import { ExecuteSuite } from "./tool/suites/execute-suite.js";
14
14
  import { GetSuiteExecutionStatus } from "./tool/suites/get-suite-execution-status.js";
15
15
  import { ListSuiteExecutions } from "./tool/suites/list-suite-executions.js";
16
16
  import { ListSuites } from "./tool/suites/list-suites.js";
17
+ import { GetTestDetail } from "./tool/tests/get-test-detail.js";
17
18
  import { GetTestStatus } from "./tool/tests/get-test-status.js";
18
19
  import { ListSegments } from "./tool/tests/list-segments.js";
19
20
  import { ListTests } from "./tool/tests/list-tests.js";
@@ -72,7 +73,7 @@ class ReflectClient {
72
73
  return {
73
74
  ...this.getAuthHeader(),
74
75
  "Content-Type": "application/json",
75
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
76
+ "User-Agent": USER_AGENT
76
77
  };
77
78
  }
78
79
  getSessionState(sessionId) {
@@ -120,6 +121,7 @@ class ReflectClient {
120
121
  new ExecuteSuite(this),
121
122
  new CancelSuiteExecution(this),
122
123
  new ListTests(this),
124
+ new GetTestDetail(this),
123
125
  new RunTest(this),
124
126
  new GetTestStatus(this)
125
127
  ];
@@ -0,0 +1,37 @@
1
+ import { z } from "zod";
2
+ import { Tool, ToolError } from "../../../common/tools.js";
3
+ import { API_HOSTNAME } from "../../config/constants.js";
4
+ class GetTestDetail extends Tool {
5
+ specification = {
6
+ title: "Get Test Detail",
7
+ toolset: "Tests",
8
+ summary: "Get the full detail of a reflect test, including its name, description, and all recorded steps",
9
+ inputSchema: z.object({
10
+ testId: z.string().describe("ID of the reflect test to retrieve details for")
11
+ })
12
+ };
13
+ handle = async (args) => {
14
+ const { testId } = args;
15
+ if (!testId || !testId.trim())
16
+ throw new ToolError("testId argument is required");
17
+ const response = await fetch(
18
+ `https://${API_HOSTNAME}/v1/tests/${encodeURIComponent(testId)}`,
19
+ {
20
+ method: "GET",
21
+ headers: this.client.getHeaders()
22
+ }
23
+ );
24
+ if (!response.ok) {
25
+ throw new ToolError(
26
+ `Failed to get test detail: ${response.status} ${response.statusText}`
27
+ );
28
+ }
29
+ const data = await response.json();
30
+ return {
31
+ content: [{ type: "text", text: JSON.stringify(data) }]
32
+ };
33
+ };
34
+ }
35
+ export {
36
+ GetTestDetail
37
+ };
@@ -0,0 +1,36 @@
1
+ import { ToolError } from "../../common/tools.js";
2
+ const API_HOSTNAME = "api.reflect.run";
3
+ const FUNCTIONAL_TESTING_API_KEY_HEADER = "X-API-KEY";
4
+ class FunctionalTestingAPI {
5
+ constructor(getToken, userAgent) {
6
+ this.getToken = getToken;
7
+ this.userAgent = userAgent;
8
+ }
9
+ getFtHeaders() {
10
+ const token = this.getToken();
11
+ if (!token) {
12
+ throw new ToolError("Swagger Functional Testing API token not found");
13
+ }
14
+ return {
15
+ [FUNCTIONAL_TESTING_API_KEY_HEADER]: token,
16
+ "Content-Type": "application/json",
17
+ "User-Agent": this.userAgent
18
+ };
19
+ }
20
+ async listTests() {
21
+ const response = await fetch(`https://${API_HOSTNAME}/v1/tests`, {
22
+ method: "GET",
23
+ headers: this.getFtHeaders()
24
+ });
25
+ if (!response.ok) {
26
+ throw new ToolError(
27
+ `Failed to list Functional Testing tests: ${response.status} ${response.statusText}`
28
+ );
29
+ }
30
+ return response.json();
31
+ }
32
+ }
33
+ export {
34
+ FUNCTIONAL_TESTING_API_KEY_HEADER,
35
+ FunctionalTestingAPI
36
+ };
@@ -0,0 +1,11 @@
1
+ const FUNCTIONAL_TESTING_TOOLS = [
2
+ {
3
+ title: "List Tests",
4
+ toolset: "Functional Testing",
5
+ summary: "Lists all API tests available in your Swagger Functional Testing account. Use this tool when you need to discover available tests before running them or checking their status. Do not use this tool to retrieve test execution results or history.",
6
+ handler: "listFunctionalTestingTests"
7
+ }
8
+ ];
9
+ export {
10
+ FUNCTIONAL_TESTING_TOOLS
11
+ };
@@ -1,3 +1,4 @@
1
+ import { FUNCTIONAL_TESTING_TOOLS } from "./functional-testing-tools.js";
1
2
  import { CreatePortalArgsSchema, PortalArgsSchema, UpdatePortalArgsSchema, CreateProductArgsSchema, ProductArgsSchema, UpdateProductArgsSchema, PublishProductArgsSchema, GetProductSectionsArgsSchema, CreateTableOfContentsArgsSchema, GetTableOfContentsArgsSchema, DeleteTableOfContentsArgsSchema, GetDocumentArgsSchema, UpdateDocumentArgsSchema } from "./portal-types.js";
2
3
  import { ApiSearchParamsSchema, ApiDefinitionParamsSchema, CreateApiParamsSchema, ScanStandardizationParamsSchema, CreateApiFromPromptParamsSchema, StandardizeApiParamsSchema } from "./registry-types.js";
3
4
  import { OrganizationsQuerySchema } from "./user-management-types.js";
@@ -165,7 +166,8 @@ const TOOLS = [
165
166
  summary: "Standardize and fix an API definition using AI to ensure compliance with governance policies. Scans the API definition for standardization errors and automatically fixes them using SmartBear AI. Optionally provide 'newVersion' (e.g. patch bump '1.0.0' → '1.0.1') to save the fixed definition as a new version — omitting it will overwrite the current version. Returns the number of errors found and the fixed definition if successful. Use this tool when users ask to standardize, fix, govern, or ensure governance compliance of APIs.",
166
167
  inputSchema: StandardizeApiParamsSchema,
167
168
  handler: "standardizeApi"
168
- }
169
+ },
170
+ ...FUNCTIONAL_TESTING_TOOLS
169
171
  ];
170
172
  export {
171
173
  TOOLS
@@ -1,7 +1,9 @@
1
1
  import { z } from "zod";
2
- import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
2
+ import { USER_AGENT } from "../common/info.js";
3
3
  import { getRequestHeader } from "../common/request-context.js";
4
+ import { ToolError } from "../common/tools.js";
4
5
  import "./config-utils.js";
6
+ import { FunctionalTestingAPI, FUNCTIONAL_TESTING_API_KEY_HEADER } from "./client/functional-testing-api.js";
5
7
  import { SwaggerAPI } from "./client/api.js";
6
8
  import { SwaggerConfiguration } from "./client/configuration.js";
7
9
  import "./client/portal-types.js";
@@ -9,29 +11,43 @@ import "./client/registry-types.js";
9
11
  import { TOOLS } from "./client/tools.js";
10
12
  import "./client/user-management-types.js";
11
13
  const ConfigurationSchema = z.object({
12
- api_key: z.string().describe("Swagger API key for authentication"),
14
+ api_key: z.string().optional().describe("Swagger API key for authentication"),
13
15
  portal_base_path: z.string().optional().describe("Base path for Portal API requests (optional)"),
14
16
  registry_base_path: z.string().optional().describe("Base path for Registry API requests (optional)"),
15
- ui_base_path: z.string().optional().describe("Base URL for the SwaggerHub UI (optional)")
17
+ ui_base_path: z.string().optional().describe("Base URL for the SwaggerHub UI (optional)"),
18
+ functional_testing_api_token: z.string().optional().describe(
19
+ "Swagger Functional Testing API token. Leave empty to disable Functional Testing tools."
20
+ )
16
21
  });
17
22
  class SwaggerClient {
18
23
  api;
19
24
  _apiKey;
25
+ ftApi;
26
+ _ftApiToken;
20
27
  name = "Swagger";
21
28
  capabilityPrefix = "swagger";
22
29
  configPrefix = "Swagger";
23
30
  config = ConfigurationSchema;
24
31
  async configure(_server, config, _cache) {
25
- this._apiKey = config.api_key;
26
- this.api = new SwaggerAPI(
27
- new SwaggerConfiguration({
28
- token: () => this.getAuthToken(),
29
- portalBasePath: config.portal_base_path,
30
- registryBasePath: config.registry_base_path,
31
- uiBasePath: config.ui_base_path
32
- }),
33
- `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
34
- );
32
+ if (config.api_key) {
33
+ this._apiKey = config.api_key;
34
+ this.api = new SwaggerAPI(
35
+ new SwaggerConfiguration({
36
+ token: () => this.getAuthToken(),
37
+ portalBasePath: config.portal_base_path,
38
+ registryBasePath: config.registry_base_path,
39
+ uiBasePath: config.ui_base_path
40
+ }),
41
+ USER_AGENT
42
+ );
43
+ }
44
+ if (config.functional_testing_api_token) {
45
+ this._ftApiToken = config.functional_testing_api_token;
46
+ this.ftApi = new FunctionalTestingAPI(
47
+ () => this.getFtAuthToken(),
48
+ USER_AGENT
49
+ );
50
+ }
35
51
  }
36
52
  getAuthToken() {
37
53
  const contextHeader = getRequestHeader("Swagger-Api-Key") || getRequestHeader("Authorization");
@@ -44,8 +60,16 @@ class SwaggerClient {
44
60
  }
45
61
  return this._apiKey || null;
46
62
  }
63
+ getFtAuthToken() {
64
+ if (!this.ftApi) return null;
65
+ const contextHeader = getRequestHeader(FUNCTIONAL_TESTING_API_KEY_HEADER);
66
+ if (contextHeader) {
67
+ return Array.isArray(contextHeader) ? contextHeader[0] : contextHeader;
68
+ }
69
+ return this._ftApiToken || null;
70
+ }
47
71
  isConfigured() {
48
- return this.api !== void 0;
72
+ return this.api !== void 0 || this.ftApi !== void 0;
49
73
  }
50
74
  getApi() {
51
75
  if (!this.api) throw new Error("Client not configured");
@@ -129,8 +153,20 @@ class SwaggerClient {
129
153
  async standardizeApi(args) {
130
154
  return this.getApi().standardizeApi(args);
131
155
  }
156
+ async listFunctionalTestingTests() {
157
+ if (!this.ftApi) {
158
+ throw new ToolError("Functional Testing API not configured");
159
+ }
160
+ return this.ftApi.listTests();
161
+ }
132
162
  async registerTools(register, _getInput) {
133
163
  TOOLS.forEach((tool) => {
164
+ if (tool.toolset === "Functional Testing" && !this.ftApi) {
165
+ return;
166
+ }
167
+ if (tool.toolset !== "Functional Testing" && !this.api && this.isConfigured()) {
168
+ return;
169
+ }
134
170
  const { handler, formatResponse, ...toolParams } = tool;
135
171
  register(toolParams, async (args, _extra) => {
136
172
  try {
@@ -1,4 +1,4 @@
1
- import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../../common/info.js";
1
+ import { USER_AGENT } from "../../common/info.js";
2
2
  class AuthService {
3
3
  bearerToken;
4
4
  constructor(accessToken) {
@@ -8,7 +8,7 @@ class AuthService {
8
8
  return {
9
9
  Authorization: `Bearer ${this.bearerToken}`,
10
10
  "Content-Type": "application/json",
11
- "User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`,
11
+ "User-Agent": USER_AGENT,
12
12
  "zscale-source": "smartbear-mcp"
13
13
  };
14
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartbear/mcp",
3
- "version": "0.25.1",
3
+ "version": "0.26.0",
4
4
  "description": "MCP server for interacting SmartBear Products",
5
5
  "keywords": [
6
6
  "smartbear",
@@ -51,6 +51,7 @@
51
51
  "dependencies": {
52
52
  "@bugsnag/js": "^8.8.1",
53
53
  "@modelcontextprotocol/sdk": "^1.27.1",
54
+ "js-yaml": "^4.2.0",
54
55
  "node-cache": "^5.1.2",
55
56
  "swagger-client": "^3.37.1",
56
57
  "vite": "^7.3.1",