@browserstack/mcp-server 1.0.4 → 1.0.6

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
@@ -4,6 +4,7 @@
4
4
  <img src="assets/browserstack-logo.png" alt="BrowserStack Logo" height="100"> <img src="assets/mcp-logo.png" alt="MCP Server Logo" width="100">
5
5
  </div>
6
6
 
7
+
7
8
  <div align="center">
8
9
  <a href="https://www.npmjs.com/package/@browserstack/mcp-server">
9
10
  <img alt="NPM Version" src="https://img.shields.io/npm/v/%40browserstack%2Fmcp-server">
@@ -11,10 +12,20 @@
11
12
 
12
13
  </div>
13
14
 
15
+ <p align="center">One Platform For All Your Testing Needs</p>
14
16
 
15
- <h3 align="center">One Platform For All Your Testing Needs</h4>
17
+ <div align="center">
18
+ <a href="https://glama.ai/mcp/servers/@browserstack/mcp-server">
19
+ <img width="380" height="200" src="https://glama.ai/mcp/servers/@browserstack/mcp-server/badge" alt="BrowserStack server MCP server" />
20
+ </a>
21
+ </div>
16
22
 
17
- ## 📖 Overview
23
+ <div>
24
+ <a href="https://www.youtube.com/watch?v=sLA7K9v7qZc">
25
+ <img src="assets/thumbnail.webp">
26
+ </a>
27
+ </div>
28
+
18
29
  Enable every developer and tester in your team, whether they are testing manually, starting their automation journey, or scaling test automation.
19
30
  BrowserStack MCP Server allows you to use our cutting-edge [Test Platform](https://www.browserstack.com/test-platform) directly from your favourite AI tools.
20
31
 
@@ -38,20 +49,17 @@ Use the following prompts to use your **mobile apps** on BrowserStack's extensiv
38
49
  "My app crashed on Android 14 device, can you help me debug?"
39
50
  ```
40
51
 
41
- Video Walkthrough:
42
-
43
- [![Watch the video](https://img.youtube.com/vi/vy1sx0J7sTk/0.jpg)](https://www.youtube.com/watch?v=vy1sx0J7sTk)
44
52
 
45
53
  - Unlike emulators, test your app's real-world performance on actual devices. With advanced [App-Profiling features](https://www.browserstack.com/docs/app-live/app-performance-testing), you can debug crashes and performance issues in real-time.
46
54
  - Access all major devices and OS versions from our [device grid](https://www.browserstack.com/list-of-browsers-and-platforms/app_live), We have strict SLAs to provision our global datacenters with newly released devices on [launch day](https://www.browserstack.com/blog/browserstack-launches-iphone-15-on-day-0-behind-the-scenes/).
47
55
 
48
56
  ### 🌐 Manual Web Testing
49
57
 
50
- Similar to the app testing, you can use the following prompts to test your **websites** on BrowserStack's extensive cloud of real browsers and devices. Don't have a Windows machine to test on Internet Explorer? We've got you covered!
58
+ Similar to the app testing, you can use the following prompts to test your **websites** on BrowserStack's extensive cloud of real browsers and devices. Don't have Edge browser installed on your machine ? We've got you covered!
51
59
 
52
60
  ```bash
53
61
  # Test your local websites
54
- "open my website hosted on localhost:3001 on Internet Explorer"
62
+ "open my website hosted on localhost:3001 on Edge"
55
63
  ```
56
64
 
57
65
  - Test websites across different browsers and devices. We support [every major browser](https://www.browserstack.com/list-of-browsers-and-platforms/live) across every major OS.
@@ -81,10 +89,19 @@ Use the following prompts to run/debug/fix your **automated tests** on BrowserSt
81
89
  1. **Create a BrowserStack Account**
82
90
 
83
91
  - Sign up for [BrowserStack](https://www.browserstack.com/signup) if you don't have an account already.
84
- - Note down your `username` and `access_key` from [Account Settings](https://www.browserstack.com/accounts/profile/details)
85
92
 
86
- 2. **Install the MCP Server**
93
+ - â„šī¸ If you have an open-source project, we'll be able to provide you with a [free plan](https://www.browserstack.com/open-source).
94
+ <div align="center">
95
+ <img src="assets/open-source-plan.png" alt="Open Source Plan">
96
+ </div>
97
+
98
+ - Once you have an account (and purchased appropriate plan), note down your `username` and `access_key` from [Account Settings](https://www.browserstack.com/accounts/profile/details).
99
+
100
+ 2. Ensure you are using Node version >= `18.0`. Check your node version using `node --version`. Recommended version: `v22.15.0` (LTS)
101
+ 3. **Install the MCP Server**
102
+
87
103
  - VSCode (Copilot - Agent Mode): `.vscode/mcp.json`:
104
+
88
105
  ```json
89
106
  {
90
107
  "servers": {
@@ -99,10 +116,12 @@ Use the following prompts to run/debug/fix your **automated tests** on BrowserSt
99
116
  }
100
117
  }
101
118
  ```
102
- * In VSCode, make sure to click on `Start` button in the MCP Server to start the server.
103
- ![Start MCP Server](assets/vscode_install.png)
104
119
 
105
- - For Cursor: `.cursor/mcp.json`:
120
+ - In VSCode, make sure to click on `Start` button in the MCP Server to start the server.
121
+ ![Start MCP Server](assets/vscode_install.png)
122
+
123
+ * For Cursor: `.cursor/mcp.json`:
124
+
106
125
  ```json
107
126
  {
108
127
  "mcpServers": {
@@ -117,7 +136,9 @@ Use the following prompts to run/debug/fix your **automated tests** on BrowserSt
117
136
  }
118
137
  }
119
138
  ```
139
+
120
140
  - Claude Desktop: `~/claude_desktop_config.json`:
141
+
121
142
  ```json
122
143
  {
123
144
  "mcpServers": {
@@ -133,7 +154,6 @@ Use the following prompts to run/debug/fix your **automated tests** on BrowserSt
133
154
  }
134
155
  ```
135
156
 
136
-
137
157
  ## 🤝 Recommended MCP Clients
138
158
 
139
159
  - We recommend using **Github Copilot or Cursor** for automated testing + debugging use cases.
@@ -147,6 +167,7 @@ Use the following prompts to run/debug/fix your **automated tests** on BrowserSt
147
167
  ## 📝 Contributing
148
168
 
149
169
  We welcome contributions! Please open an issue to discuss any changes you'd like to make.
170
+ 👉 [**Click here to view our Contributing Guidelines**](https://github.com/browserstack/mcp-server/blob/main/CONTRIBUTING.md)
150
171
 
151
172
  ## 📞 Support
152
173
 
@@ -160,7 +181,6 @@ For support, please:
160
181
 
161
182
  Stay tuned for exciting updates! Have any suggestions? Please open an issue to discuss.
162
183
 
163
-
164
184
  ## 🔗 Resources
165
185
 
166
186
  - [BrowserStack Test Platform](https://www.browserstack.com/test-platform)
package/dist/index.js CHANGED
@@ -14,12 +14,16 @@ const applive_1 = __importDefault(require("./tools/applive"));
14
14
  const observability_1 = __importDefault(require("./tools/observability"));
15
15
  const live_1 = __importDefault(require("./tools/live"));
16
16
  const accessibility_1 = __importDefault(require("./tools/accessibility"));
17
+ const automate_1 = __importDefault(require("./tools/automate"));
18
+ const testmanagement_1 = __importDefault(require("./tools/testmanagement"));
17
19
  function registerTools(server) {
18
20
  (0, bstack_sdk_1.default)(server);
19
21
  (0, applive_1.default)(server);
20
22
  (0, live_1.default)(server);
21
23
  (0, observability_1.default)(server);
22
24
  (0, accessibility_1.default)(server);
25
+ (0, automate_1.default)(server);
26
+ (0, testmanagement_1.default)(server);
23
27
  }
24
28
  // Create an MCP server
25
29
  const server = new mcp_js_1.McpServer({
package/dist/lib/api.js CHANGED
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getLatestO11YBuildInfo = getLatestO11YBuildInfo;
7
+ exports.retrieveNetworkFailures = retrieveNetworkFailures;
7
8
  const config_1 = __importDefault(require("../config"));
8
9
  async function getLatestO11YBuildInfo(buildName, projectName) {
9
10
  const buildsUrl = `https://api-observability.browserstack.com/ext/v1/builds/latest?build_name=${encodeURIComponent(buildName)}&project_name=${encodeURIComponent(projectName)}`;
@@ -20,3 +21,50 @@ async function getLatestO11YBuildInfo(buildName, projectName) {
20
21
  }
21
22
  return buildsResponse.json();
22
23
  }
24
+ // Fetches network logs for a given session ID and returns only failure logs
25
+ async function retrieveNetworkFailures(sessionId) {
26
+ if (!sessionId) {
27
+ throw new Error("Session ID is required");
28
+ }
29
+ const url = `https://api.browserstack.com/automate/sessions/${sessionId}/networklogs`;
30
+ const auth = Buffer.from(`${config_1.default.browserstackUsername}:${config_1.default.browserstackAccessKey}`).toString("base64");
31
+ const response = await fetch(url, {
32
+ method: "GET",
33
+ headers: {
34
+ "Content-Type": "application/json",
35
+ Authorization: `Basic ${auth}`,
36
+ },
37
+ });
38
+ if (!response.ok) {
39
+ if (response.status === 404) {
40
+ throw new Error("Invalid session ID");
41
+ }
42
+ throw new Error(`Failed to fetch network logs: ${response.statusText}`);
43
+ }
44
+ const networklogs = await response.json();
45
+ // Filter for failure logs
46
+ const failureEntries = networklogs.log.entries.filter((entry) => {
47
+ return (entry.response.status === 0 ||
48
+ entry.response.status >= 400 ||
49
+ entry.response._error !== undefined);
50
+ });
51
+ // Return only the failure entries with some context
52
+ return {
53
+ failures: failureEntries.map((entry) => ({
54
+ startedDateTime: entry.startedDateTime,
55
+ request: {
56
+ method: entry.request?.method,
57
+ url: entry.request?.url,
58
+ queryString: entry.request?.queryString,
59
+ },
60
+ response: {
61
+ status: entry.response?.status,
62
+ statusText: entry.response?.statusText,
63
+ _error: entry.response?._error,
64
+ },
65
+ serverIPAddress: entry.serverIPAddress,
66
+ time: entry.time,
67
+ })),
68
+ totalFailures: failureEntries.length,
69
+ };
70
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatAxiosError = formatAxiosError;
4
+ const axios_1 = require("axios");
5
+ /**
6
+ * Formats an AxiosError into a CallToolResult with an appropriate message.
7
+ * @param err - The error object to format
8
+ * @param defaultText - The fallback error message
9
+ */
10
+ function formatAxiosError(err, defaultText) {
11
+ let text = defaultText;
12
+ if (err instanceof axios_1.AxiosError && err.response?.data) {
13
+ const message = err.response.data.message ||
14
+ err.response.data.error ||
15
+ err.message ||
16
+ defaultText;
17
+ text = message;
18
+ }
19
+ else if (err instanceof Error) {
20
+ text = err.message;
21
+ }
22
+ return {
23
+ content: [{ type: "text", text }],
24
+ isError: true,
25
+ };
26
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getNetworkFailures = getNetworkFailures;
7
+ exports.default = addAutomateTools;
8
+ const zod_1 = require("zod");
9
+ const logger_1 = __importDefault(require("../logger"));
10
+ const api_1 = require("../lib/api");
11
+ /**
12
+ * Fetches failed network requests from a BrowserStack Automate session.
13
+ * Returns network requests that resulted in errors or failed to complete.
14
+ */
15
+ async function getNetworkFailures(args) {
16
+ try {
17
+ const failureLogs = await (0, api_1.retrieveNetworkFailures)(args.sessionId);
18
+ logger_1.default.info("Successfully fetched failure network logs for session: %s", args.sessionId);
19
+ // Check if there are any failures
20
+ const hasFailures = failureLogs.totalFailures > 0;
21
+ const text = hasFailures
22
+ ? `${failureLogs.totalFailures} network failure(s) found for session :\n\n${JSON.stringify(failureLogs.failures, null, 2)}`
23
+ : `No network failures found for session`;
24
+ return {
25
+ content: [
26
+ {
27
+ type: "text",
28
+ text,
29
+ },
30
+ ],
31
+ };
32
+ }
33
+ catch (error) {
34
+ const errorMessage = error instanceof Error ? error.message : "An unknown error occurred";
35
+ logger_1.default.error("Failed to fetch network logs: %s", errorMessage);
36
+ return {
37
+ content: [
38
+ {
39
+ type: "text",
40
+ text: `Failed to fetch network logs: ${errorMessage}`,
41
+ isError: true,
42
+ },
43
+ ],
44
+ isError: true,
45
+ };
46
+ }
47
+ }
48
+ function addAutomateTools(server) {
49
+ server.tool("getNetworkFailures", "Use this tool to fetch failed network requests from a BrowserStack Automate session.", {
50
+ sessionId: zod_1.z.string().describe("The Automate session ID."),
51
+ }, getNetworkFailures);
52
+ }
@@ -17,6 +17,7 @@ const nodejsInstructions = `
17
17
  \`\`\`json
18
18
  "browserstack-node-sdk": "latest"
19
19
  \`\`\`
20
+ - Inform user to export BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY as environment variables.
20
21
  `;
21
22
  const pythonInstructions = `
22
23
  Run the following command to install the browserstack-sdk:
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CreateProjFoldSchema = void 0;
7
+ exports.createProjectOrFolder = createProjectOrFolder;
8
+ const axios_1 = __importDefault(require("axios"));
9
+ const config_1 = __importDefault(require("../../config"));
10
+ const zod_1 = require("zod");
11
+ const error_1 = require("../../lib/error"); // or correct path
12
+ // Schema for combined project/folder creation
13
+ exports.CreateProjFoldSchema = zod_1.z.object({
14
+ project_name: zod_1.z
15
+ .string()
16
+ .optional()
17
+ .describe("Name of the project to create."),
18
+ project_description: zod_1.z
19
+ .string()
20
+ .optional()
21
+ .describe("Description for the new project."),
22
+ project_identifier: zod_1.z
23
+ .string()
24
+ .optional()
25
+ .describe("Existing project identifier to use for folder creation."),
26
+ folder_name: zod_1.z.string().optional().describe("Name of the folder to create."),
27
+ folder_description: zod_1.z
28
+ .string()
29
+ .optional()
30
+ .describe("Description for the new folder."),
31
+ parent_id: zod_1.z
32
+ .number()
33
+ .optional()
34
+ .describe("Parent folder ID; if omitted, folder is created at root."),
35
+ });
36
+ /**
37
+ * Creates a project and/or folder in BrowserStack Test Management.
38
+ */
39
+ async function createProjectOrFolder(args) {
40
+ const { project_name, project_description, project_identifier, folder_name, folder_description, parent_id, } = exports.CreateProjFoldSchema.parse(args);
41
+ if (!project_name && !project_identifier && !folder_name) {
42
+ throw new Error("Provide project_name (to create project), or project_identifier and folder_name (to create folder).");
43
+ }
44
+ let projId = project_identifier;
45
+ // Step 1: Create project if project_name provided
46
+ if (project_name) {
47
+ try {
48
+ const res = await axios_1.default.post("https://test-management.browserstack.com/api/v2/projects", { project: { name: project_name, description: project_description } }, {
49
+ auth: {
50
+ username: config_1.default.browserstackUsername,
51
+ password: config_1.default.browserstackAccessKey,
52
+ },
53
+ headers: { "Content-Type": "application/json" },
54
+ });
55
+ if (!res.data.success) {
56
+ throw new Error(`Failed to create project: ${JSON.stringify(res.data)}`);
57
+ }
58
+ // Project created successfully
59
+ projId = res.data.project.identifier;
60
+ }
61
+ catch (err) {
62
+ return (0, error_1.formatAxiosError)(err, "Failed to create project..");
63
+ }
64
+ }
65
+ // Step 2: Create folder if folder_name provided
66
+ if (folder_name) {
67
+ if (!projId)
68
+ throw new Error("Cannot create folder without project_identifier.");
69
+ try {
70
+ const res = await axios_1.default.post(`https://test-management.browserstack.com/api/v2/projects/${encodeURIComponent(projId)}/folders`, {
71
+ folder: {
72
+ name: folder_name,
73
+ description: folder_description,
74
+ parent_id,
75
+ },
76
+ }, {
77
+ auth: {
78
+ username: config_1.default.browserstackUsername,
79
+ password: config_1.default.browserstackAccessKey,
80
+ },
81
+ headers: { "Content-Type": "application/json" },
82
+ });
83
+ if (!res.data.success) {
84
+ throw new Error(`Failed to create folder: ${JSON.stringify(res.data)}`);
85
+ }
86
+ // Folder created successfully
87
+ const folder = res.data.folder;
88
+ return {
89
+ content: [
90
+ {
91
+ type: "text",
92
+ text: `Folder created: ID=${folder.id}, name=${folder.name} in project with identifier ${projId}`,
93
+ },
94
+ ],
95
+ };
96
+ }
97
+ catch (err) {
98
+ return (0, error_1.formatAxiosError)(err, "Failed to create folder.");
99
+ }
100
+ }
101
+ // Only project was created
102
+ return {
103
+ content: [
104
+ { type: "text", text: `Project created with identifier=${projId}` },
105
+ ],
106
+ };
107
+ }
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CreateTestCaseSchema = void 0;
7
+ exports.sanitizeArgs = sanitizeArgs;
8
+ exports.createTestCase = createTestCase;
9
+ const axios_1 = __importDefault(require("axios"));
10
+ const config_1 = __importDefault(require("../../config"));
11
+ const zod_1 = require("zod");
12
+ const error_1 = require("../../lib/error"); // or correct
13
+ exports.CreateTestCaseSchema = zod_1.z.object({
14
+ project_identifier: zod_1.z
15
+ .string()
16
+ .describe("The ID of the BrowserStack project where the test case should be created. If no project identifier is provided, ask the user if they would like to create a new project using the createProjectOrFolder tool."),
17
+ folder_id: zod_1.z
18
+ .string()
19
+ .describe("The ID of the folder within the project where the test case should be created. If not provided, ask the user if they would like to create a new folder using the createProjectOrFolder tool."),
20
+ name: zod_1.z.string().describe("Name of the test case."),
21
+ description: zod_1.z
22
+ .string()
23
+ .optional()
24
+ .describe("Brief description of the test case."),
25
+ owner: zod_1.z
26
+ .string()
27
+ .email()
28
+ .describe("Email of the test case owner.")
29
+ .optional(),
30
+ preconditions: zod_1.z
31
+ .string()
32
+ .optional()
33
+ .describe("Any preconditions (HTML allowed)."),
34
+ test_case_steps: zod_1.z
35
+ .array(zod_1.z.object({
36
+ step: zod_1.z.string().describe("Action to perform in this step."),
37
+ result: zod_1.z.string().describe("Expected result of this step."),
38
+ }))
39
+ .describe("List of steps and expected results."),
40
+ issues: zod_1.z
41
+ .array(zod_1.z.string())
42
+ .optional()
43
+ .describe("List of the linked Jira, Asana or Azure issues ID's. This should be strictly in array format not the string of json."),
44
+ issue_tracker: zod_1.z
45
+ .object({
46
+ name: zod_1.z
47
+ .string()
48
+ .describe("Issue tracker name, For example, use jira for Jira, azure for Azure DevOps, or asana for Asana."),
49
+ host: zod_1.z.string().url().describe("Base URL of the issue tracker."),
50
+ })
51
+ .optional(),
52
+ tags: zod_1.z
53
+ .array(zod_1.z.string())
54
+ .optional()
55
+ .describe("Tags to attach to the test case. This should be strictly in array format not the string of json"),
56
+ custom_fields: zod_1.z
57
+ .record(zod_1.z.string(), zod_1.z.string())
58
+ .optional()
59
+ .describe("Map of custom field names to values."),
60
+ });
61
+ function sanitizeArgs(args) {
62
+ const cleaned = { ...args };
63
+ if (cleaned.description === null)
64
+ delete cleaned.description;
65
+ if (cleaned.owner === null)
66
+ delete cleaned.owner;
67
+ if (cleaned.preconditions === null)
68
+ delete cleaned.preconditions;
69
+ if (cleaned.issue_tracker) {
70
+ if (cleaned.issue_tracker.name === undefined ||
71
+ cleaned.issue_tracker.host === undefined) {
72
+ delete cleaned.issue_tracker;
73
+ }
74
+ }
75
+ return cleaned;
76
+ }
77
+ async function createTestCase(params) {
78
+ const body = { test_case: params };
79
+ try {
80
+ const response = await axios_1.default.post(`https://test-management.browserstack.com/api/v2/projects/${encodeURIComponent(params.project_identifier)}/folders/${encodeURIComponent(params.folder_id)}/test-cases`, body, {
81
+ auth: {
82
+ username: config_1.default.browserstackUsername,
83
+ password: config_1.default.browserstackAccessKey,
84
+ },
85
+ headers: { "Content-Type": "application/json" },
86
+ });
87
+ const { data } = response.data;
88
+ if (!data.success) {
89
+ return {
90
+ content: [
91
+ {
92
+ type: "text",
93
+ text: `Failed to create test case: ${JSON.stringify(response.data)}`,
94
+ isError: true,
95
+ },
96
+ ],
97
+ isError: true,
98
+ };
99
+ }
100
+ const tc = data.test_case;
101
+ return {
102
+ content: [
103
+ {
104
+ type: "text",
105
+ text: `Successfully created test case ${tc.identifier}: ${tc.title}`,
106
+ },
107
+ { type: "text", text: JSON.stringify(tc, null, 2) },
108
+ ],
109
+ };
110
+ }
111
+ catch (err) {
112
+ // Delegate to our centralized Axios error formatter
113
+ return (0, error_1.formatAxiosError)(err, "Failed to create test case");
114
+ }
115
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createProjectOrFolderTool = createProjectOrFolderTool;
4
+ exports.createTestCaseTool = createTestCaseTool;
5
+ exports.default = addTestManagementTools;
6
+ const create_project_folder_1 = require("./testmanagement-utils/create-project-folder");
7
+ const create_testcase_1 = require("./testmanagement-utils/create-testcase");
8
+ /**
9
+ * Wrapper to call createProjectOrFolder util.
10
+ */
11
+ async function createProjectOrFolderTool(args) {
12
+ try {
13
+ return await (0, create_project_folder_1.createProjectOrFolder)(args);
14
+ }
15
+ catch (err) {
16
+ return {
17
+ content: [
18
+ {
19
+ type: "text",
20
+ text: `Failed to create project/folder: ${err instanceof Error ? err.message : "Unknown error"}. Please open an issue on GitHub if the problem persists`,
21
+ isError: true,
22
+ },
23
+ ],
24
+ isError: true,
25
+ };
26
+ }
27
+ }
28
+ /**
29
+ * Creates a test case in BrowserStack Test Management.
30
+ */
31
+ async function createTestCaseTool(args) {
32
+ // Sanitize input arguments
33
+ const cleanedArgs = (0, create_testcase_1.sanitizeArgs)(args);
34
+ try {
35
+ return await (0, create_testcase_1.createTestCase)(cleanedArgs);
36
+ }
37
+ catch (err) {
38
+ return {
39
+ content: [
40
+ {
41
+ type: "text",
42
+ text: `Failed to create test case: ${err instanceof Error ? err.message : "Unknown error"}. Please open an issue on GitHub if the problem persists`,
43
+ isError: true,
44
+ },
45
+ ],
46
+ isError: true,
47
+ };
48
+ }
49
+ }
50
+ /**
51
+ * Registers both project/folder and test-case tools.
52
+ */
53
+ function addTestManagementTools(server) {
54
+ server.tool("createProjectOrFolder", "Create a project and/or folder in BrowserStack Test Management.", create_project_folder_1.CreateProjFoldSchema.shape, createProjectOrFolderTool);
55
+ server.tool("createTestCase", "Use this tool to create a test case in BrowserStack Test Management.", create_testcase_1.CreateTestCaseSchema.shape, createTestCaseTool);
56
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@browserstack/mcp-server",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "BrowserStack's Official MCP Server",
5
5
  "main": "dist/index.js",
6
6
  "repository": {