Skip to content

Commit 48ad47d

Browse files
committed
chore(deps): merge main, bump deps to patched versions, release 1.2.26
2 parents 01ca898 + e87fe7d commit 48ad47d

14 files changed

Lines changed: 1413 additions & 156 deletions

package-lock.json

Lines changed: 652 additions & 127 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@browserstack/mcp-server",
3-
"version": "1.2.23",
3+
"version": "1.2.25",
44
"description": "BrowserStack's Official MCP Server",
55
"mcpName": "io.github.browserstack/mcp-server",
66
"main": "dist/index.js",

server.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
{
1212
"registryType": "npm",
1313
"identifier": "@browserstack/mcp-server",
14-
"version": "1.2.23",
14+
"version": "1.2.25",
1515
"transport": {
1616
"type": "stdio"
1717
},

src/tools/rca-agent-utils/get-failed-test-id.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,14 @@ export async function getTestIds(
6565
}
6666
}
6767

68-
// Recursive function to extract failed test IDs from hierarchy
69-
function extractFailedTestIds(
68+
export function extractFailedTestIds(
7069
hierarchy: TestDetails[],
7170
status?: TestStatus,
7271
): FailedTestInfo[] {
7372
let failedTests: FailedTestInfo[] = [];
7473

7574
for (const node of hierarchy) {
76-
if (node.details?.status === status && node.details?.run_count) {
75+
if (node.details?.status === status) {
7776
if (node.details?.observability_url) {
7877
const idMatch = node.details.observability_url.match(/details=(\d+)/);
7978
if (idMatch) {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { apiClient } from "../../lib/apiClient.js";
2+
3+
/**
4+
* Returns the latest build for a project + build name across all users (not just the caller's).
5+
*/
6+
export async function listBuildId(
7+
projectName: string,
8+
buildName: string,
9+
username: string,
10+
accessKey: string,
11+
): Promise<string> {
12+
const authHeader =
13+
"Basic " + Buffer.from(`${username}:${accessKey}`).toString("base64");
14+
15+
const response = await apiClient.get({
16+
url: "https://api-automation.browserstack.com/ext/v1/builds/latest",
17+
headers: {
18+
Authorization: authHeader,
19+
"Content-Type": "application/json",
20+
},
21+
params: {
22+
project_name: projectName,
23+
build_name: buildName,
24+
},
25+
});
26+
27+
const buildId = response.data?.build_id;
28+
if (!buildId) {
29+
throw new Error(
30+
`No build found for project "${projectName}" and build "${buildName}"`,
31+
);
32+
}
33+
return buildId;
34+
}

src/tools/rca-agent.ts

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import logger from "../logger.js";
44
import { BrowserStackConfig } from "../lib/types.js";
55
import { getBrowserStackAuth } from "../lib/get-auth.js";
66
import { getBuildId } from "./rca-agent-utils/get-build-id.js";
7+
import { listBuildId } from "./rca-agent-utils/list-build-id.js";
78
import { getTestIds } from "./rca-agent-utils/get-failed-test-id.js";
89
import { getRCAData } from "./rca-agent-utils/rca-data.js";
910
import { formatRCAData } from "./rca-agent-utils/format-rca.js";
@@ -59,6 +60,48 @@ export async function getBuildIdTool(
5960
}
6061
}
6162

63+
// Tool function to fetch the build ID across all users (no user scoping)
64+
export async function listBuildIdTool(
65+
args: BuildIdArgs,
66+
config: BrowserStackConfig,
67+
): Promise<CallToolResult> {
68+
try {
69+
const { browserStackProjectName, browserStackBuildName } = args;
70+
71+
const authString = getBrowserStackAuth(config);
72+
const [username, accessKey] = authString.split(":");
73+
74+
const buildId = await listBuildId(
75+
browserStackProjectName,
76+
browserStackBuildName,
77+
username,
78+
accessKey,
79+
);
80+
81+
return {
82+
content: [
83+
{
84+
type: "text",
85+
text: buildId,
86+
},
87+
],
88+
};
89+
} catch (error) {
90+
logger.error("Error fetching build ID", error);
91+
const errorMessage =
92+
error instanceof Error ? error.message : "Unknown error";
93+
return {
94+
content: [
95+
{
96+
type: "text",
97+
text: `Error fetching build ID: ${errorMessage}`,
98+
},
99+
],
100+
isError: true,
101+
};
102+
}
103+
}
104+
62105
// Tool function that fetches RCA data
63106
export async function fetchRCADataTool(
64107
args: { testId: number[] },
@@ -144,7 +187,7 @@ export default function addRCATools(
144187

145188
tools.fetchRCA = server.tool(
146189
"fetchRCA",
147-
"Fetch AI Root Cause Analysis for failed BrowserStack Automate/App-Automate tests. Suggests fixes only; never auto-apply, require explicit user approval.",
190+
"Fetch AI Root Cause Analysis for the current user's failed BrowserStack Automate/App-Automate tests. Suggests fixes only; never auto-apply, require explicit user approval.",
148191
FETCH_RCA_PARAMS,
149192
async (args) => {
150193
try {
@@ -163,7 +206,7 @@ export default function addRCATools(
163206

164207
tools.getBuildId = server.tool(
165208
"getBuildId",
166-
"Get the BrowserStack build ID for a given project and build name.",
209+
"Get the BrowserStack build ID for a given project and build name, scoped to the current user's builds.",
167210
GET_BUILD_ID_PARAMS,
168211
async (args) => {
169212
try {
@@ -180,6 +223,25 @@ export default function addRCATools(
180223
},
181224
);
182225

226+
tools.listBuildId = server.tool(
227+
"listBuildId",
228+
"Get the latest build ID for a project and build name, across all users (no user filter).",
229+
GET_BUILD_ID_PARAMS,
230+
async (args) => {
231+
try {
232+
trackMCP(
233+
"listBuildId",
234+
server.server.getClientVersion()!,
235+
undefined,
236+
config,
237+
);
238+
return await listBuildIdTool(args, config);
239+
} catch (error) {
240+
return handleMCPError("listBuildId", server, config, error);
241+
}
242+
},
243+
);
244+
183245
tools.listTestIds = server.tool(
184246
"listTestIds",
185247
"List test IDs from a BrowserStack Automate build, optionally filtered by status",

src/tools/testmanagement-utils/TCG-utils/api.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
FETCH_DETAILS_URL,
66
FORM_FIELDS_URL,
77
BULK_CREATE_URL,
8+
TC_DETAILS_MAX_BATCH,
89
} from "./config.js";
910
import {
1011
DefaultFieldMaps,
@@ -228,11 +229,13 @@ export async function pollScenariosTestDetails(
228229
if (msg.type === "testcase") {
229230
const sc = msg.data.scenario;
230231
if (sc) {
231-
const array = Array.isArray(msg.data.testcases)
232-
? msg.data.testcases
233-
: msg.data.testcases
234-
? [msg.data.testcases]
235-
: [];
232+
const array = (
233+
Array.isArray(msg.data.testcases)
234+
? msg.data.testcases
235+
: msg.data.testcases
236+
? [msg.data.testcases]
237+
: []
238+
).slice(0, TC_DETAILS_MAX_BATCH);
236239
const ids = array.map((tc: any) => tc.id || tc.test_case_id);
237240

238241
const reqId = await fetchTestCaseDetails(
@@ -315,11 +318,12 @@ export async function bulkCreateTestCases(
315318
const BULK_CREATE_URL_VALUE = BULK_CREATE_URL(tmBaseUrl, projectId, folderId);
316319

317320
for (const { id, testcases } of Object.values(scenariosMap)) {
318-
const testCaseLength = testcases.length;
321+
const cappedTestcases = testcases.slice(0, TC_DETAILS_MAX_BATCH);
322+
const testCaseLength = cappedTestcases.length;
319323
testCaseCount += testCaseLength;
320324
if (testCaseLength === 0) continue;
321325
const payload = {
322-
test_cases: testcases.map((tc) =>
326+
test_cases: cappedTestcases.map((tc) =>
323327
createTestCasePayload(
324328
tc,
325329
id,

src/tools/testmanagement-utils/TCG-utils/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export const TC_DETAILS_MAX_BATCH = 10;
2+
13
export const TCG_TRIGGER_URL = (baseUrl: string) =>
24
`${baseUrl}/api/v1/integration/tcg/test-generation/suggest-test-cases`;
35

0 commit comments

Comments
 (0)