Skip to content

Commit e799c7d

Browse files
Refactor Accessibility Scan Tools with Enhanced Progress Updates and Local Report Download (#41)
* feat: refactor accessibility tools with new scanner and report fetcher implementations * fix: update progress token handling in AccessibilityScanner notifications * fix: handle missing progress token in accessibility scan notifications * fix: remove outdated file reference in accessibility tool * fix: update @modelcontextprotocol/sdk to version 1.11.4 and improve error handling in tests * feat: add csv-parse dependency and implement accessibility report parsing functionality * fix: update pageURL parameter type to Array<string> for accessibility scan function * fix: remove total issues and next page information from scan results message * fix: change pageURL parameter type from Array<string> to string for accessibility scan function * fix: simplify pageURL parameter definition in accessibility scan function * fix: enhance progress reporting in waitUntilComplete method
1 parent a1a948c commit e799c7d

File tree

8 files changed

+392
-175
lines changed

8 files changed

+392
-175
lines changed

package-lock.json

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

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@
3434
"author": "",
3535
"license": "ISC",
3636
"dependencies": {
37-
"@modelcontextprotocol/sdk": "^1.10.1",
37+
"@modelcontextprotocol/sdk": "^1.11.4",
3838
"@types/form-data": "^2.5.2",
3939
"axios": "^1.8.4",
4040
"browserstack-local": "^1.5.6",
41+
"csv-parse": "^5.6.0",
4142
"dotenv": "^16.5.0",
4243
"form-data": "^4.0.2",
4344
"pino": "^9.6.0",
@@ -49,6 +50,7 @@
4950
},
5051
"devDependencies": {
5152
"@eslint/js": "^9.25.0",
53+
"@types/csv-parse": "^1.1.12",
5254
"@types/node": "^22.14.1",
5355
"@types/uuid": "^10.0.0",
5456
"eslint": "^9.25.0",

src/tools/accessibility.ts

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,64 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
22
import { z } from "zod";
33
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
4-
import {
5-
startAccessibilityScan,
6-
AccessibilityScanResponse,
7-
} from "./accessiblity-utils/accessibility.js";
4+
import { AccessibilityScanner } from "./accessiblity-utils/scanner.js";
5+
import { AccessibilityReportFetcher } from "./accessiblity-utils/report-fetcher.js";
86
import { trackMCP } from "../lib/instrumentation.js";
7+
import { parseAccessibilityReportFromCSV } from "./accessiblity-utils/report-parser.js";
8+
9+
const scanner = new AccessibilityScanner();
10+
const reportFetcher = new AccessibilityReportFetcher();
911

1012
async function runAccessibilityScan(
1113
name: string,
1214
pageURL: string,
15+
context: any,
1316
): Promise<CallToolResult> {
14-
const response: AccessibilityScanResponse = await startAccessibilityScan(
15-
name,
16-
[pageURL],
17-
);
18-
const scanId = response.data?.id;
19-
const scanRunId = response.data?.scanRunId;
17+
// Start scan
18+
const startResp = await scanner.startScan(name, [pageURL]);
19+
const scanId = startResp.data!.id;
20+
const scanRunId = startResp.data!.scanRunId;
2021

21-
if (!scanId || !scanRunId) {
22-
throw new Error(
23-
"Unable to start a accessibility scan, please try again later or open an issue on GitHub if the problem persists",
24-
);
22+
// Notify scan start
23+
await context.sendNotification({
24+
method: "notifications/progress",
25+
params: {
26+
progressToken: context._meta?.progressToken ?? "NOT_FOUND",
27+
message: `Accessibility scan "${name}" started`,
28+
progress: 0,
29+
total: 100,
30+
},
31+
});
32+
33+
// Wait until scan completes
34+
const status = await scanner.waitUntilComplete(scanId, scanRunId, context);
35+
if (status !== "completed") {
36+
return {
37+
content: [
38+
{
39+
type: "text",
40+
text: `❌ Accessibility scan "${name}" failed with status: ${status} , check the BrowserStack dashboard for more details [https://scanner.browserstack.com/site-scanner/scan-details/${name}].`,
41+
isError: true,
42+
},
43+
],
44+
isError: true,
45+
};
2546
}
2647

48+
// Fetch CSV report link
49+
const reportLink = await reportFetcher.getReportLink(scanId, scanRunId);
50+
51+
const { records } = await parseAccessibilityReportFromCSV(reportLink);
52+
2753
return {
2854
content: [
2955
{
3056
type: "text",
31-
text: `Successfully queued accessibility scan, you will get a report via email within 5 minutes.`,
57+
text: `✅ Accessibility scan "${name}" completed. check the BrowserStack dashboard for more details [https://scanner.browserstack.com/site-scanner/scan-details/${name}].`,
58+
},
59+
{
60+
type: "text",
61+
text: `Scan results: ${JSON.stringify(records, null, 2)}`,
3262
},
3363
],
3464
};
@@ -37,15 +67,15 @@ async function runAccessibilityScan(
3767
export default function addAccessibilityTools(server: McpServer) {
3868
server.tool(
3969
"startAccessibilityScan",
40-
"Use this tool to start an accessibility scan for a list of URLs on BrowserStack.",
70+
"Start an accessibility scan via BrowserStack and retrieve a local CSV report path.",
4171
{
4272
name: z.string().describe("Name of the accessibility scan"),
4373
pageURL: z.string().describe("The URL to scan for accessibility issues"),
4474
},
45-
async (args) => {
75+
async (args, context) => {
4676
try {
4777
trackMCP("startAccessibilityScan", server.server.getClientVersion()!);
48-
return await runAccessibilityScan(args.name, args.pageURL);
78+
return await runAccessibilityScan(args.name, args.pageURL, context);
4979
} catch (error) {
5080
trackMCP(
5181
"startAccessibilityScan",
@@ -56,7 +86,9 @@ export default function addAccessibilityTools(server: McpServer) {
5686
content: [
5787
{
5888
type: "text",
59-
text: `Failed to start accessibility scan: ${error instanceof Error ? error.message : "Unknown error"}. Please open an issue on GitHub if the problem persists`,
89+
text: `Failed to start accessibility scan: ${
90+
error instanceof Error ? error.message : "Unknown error"
91+
}. Please open an issue on GitHub if the problem persists`,
6092
isError: true,
6193
},
6294
],

0 commit comments

Comments
 (0)