@roxybrowser/playwright 2.0.2-beta.0 → 2.0.2-beta.2
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 +55 -0
- package/dist/bin/roxybrowser-mcp.js +69 -2
- package/dist/bin/roxybrowser-mcp.js.map +1 -1
- package/dist/mcp/backend/connect.d.ts +1 -0
- package/dist/mcp/backend/connect.d.ts.map +1 -1
- package/dist/mcp/backend/connect.js +4 -2
- package/dist/mcp/backend/connect.js.map +1 -1
- package/dist/mcp/backend/response.d.ts.map +1 -1
- package/dist/mcp/backend/response.js +25 -3
- package/dist/mcp/backend/response.js.map +1 -1
- package/dist/mcp/connectedBrowser.d.ts.map +1 -1
- package/dist/mcp/connectedBrowser.js +75 -5
- package/dist/mcp/connectedBrowser.js.map +1 -1
- package/dist/mcp/runtime.d.ts +1 -0
- package/dist/mcp/runtime.d.ts.map +1 -1
- package/dist/mcp/runtime.js +51 -6
- package/dist/mcp/runtime.js.map +1 -1
- package/dist/mcp/transports/inMemory.d.ts.map +1 -1
- package/dist/mcp/transports/inMemory.js +1 -0
- package/dist/mcp/transports/inMemory.js.map +1 -1
- package/dist/mcp/types.d.ts +2 -0
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/protocol/bidi/backend.d.ts +1 -1
- package/dist/protocol/bidi/backend.d.ts.map +1 -1
- package/dist/protocol/bidi/backend.js +6 -2
- package/dist/protocol/bidi/backend.js.map +1 -1
- package/dist/protocol/bidi/client.d.ts +1 -0
- package/dist/protocol/bidi/client.d.ts.map +1 -1
- package/dist/protocol/bidi/client.js +48 -1
- package/dist/protocol/bidi/client.js.map +1 -1
- package/dist/roxybrowser.bundle.js +583 -425
- package/dist/roxybrowser.bundle.js.map +1 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -113,3 +113,58 @@ await startRoxyBrowserMcpStdio({
|
|
|
113
113
|
outputDir
|
|
114
114
|
});
|
|
115
115
|
```
|
|
116
|
+
|
|
117
|
+
## MCP inspector workflow
|
|
118
|
+
|
|
119
|
+
This repo includes [`@modelcontextprotocol/inspector`](https://github.com/modelcontextprotocol/inspector) as a dev dependency so we can debug the Playwright MCP server locally.
|
|
120
|
+
|
|
121
|
+
### Local stdio inspector
|
|
122
|
+
|
|
123
|
+
Use the inspector to spawn the built MCP server over `stdio`:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
pnpm inspector
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
That command will:
|
|
130
|
+
|
|
131
|
+
- build the TypeScript sources into `dist/`
|
|
132
|
+
- start the MCP Inspector UI on `http://127.0.0.1:6274`
|
|
133
|
+
- launch `node ./dist/bin/roxybrowser-mcp.js` as the inspected MCP server
|
|
134
|
+
|
|
135
|
+
This is the fastest loop when you want to manually exercise tools from the inspector UI.
|
|
136
|
+
|
|
137
|
+
### Local HTTP inspector
|
|
138
|
+
|
|
139
|
+
If you want to keep the MCP server running separately and connect the inspector over Streamable HTTP:
|
|
140
|
+
|
|
141
|
+
Terminal 1:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pnpm mcp:http
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Terminal 2:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pnpm inspector:http
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
By default the HTTP server listens on `http://127.0.0.1:3333/mcp`.
|
|
154
|
+
|
|
155
|
+
### MCP server CLI options
|
|
156
|
+
|
|
157
|
+
The bundled `roxybrowser-mcp` launcher supports both transports:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
node ./dist/bin/roxybrowser-mcp.js --transport stdio
|
|
161
|
+
node ./dist/bin/roxybrowser-mcp.js --transport http --port 3333 --host 127.0.0.1 --path /mcp
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Optional flags:
|
|
165
|
+
|
|
166
|
+
- `--output-dir /absolute/path`
|
|
167
|
+
- `--snapshot-mode full`
|
|
168
|
+
- `--snapshot-mode none`
|
|
169
|
+
|
|
170
|
+
Note: in the currently installed inspector version, the `mcp-inspector` CLI wrapper itself has a local dependency compatibility issue in this workspace, so the reliable path here is the inspector UI flow above via `client/bin/start.js`.
|
|
@@ -1,6 +1,73 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
3
|
+
import { startRoxyBrowserMcpHttp, startRoxyBrowserMcpStdio } from "../mcp/index.js";
|
|
4
|
+
function parseCliOptions(argv) {
|
|
5
|
+
const { values } = parseArgs({
|
|
6
|
+
args: argv,
|
|
7
|
+
options: {
|
|
8
|
+
transport: { type: "string" },
|
|
9
|
+
host: { type: "string" },
|
|
10
|
+
port: { type: "string" },
|
|
11
|
+
path: { type: "string" },
|
|
12
|
+
"output-dir": { type: "string" },
|
|
13
|
+
"snapshot-mode": { type: "string" }
|
|
14
|
+
},
|
|
15
|
+
allowPositionals: false
|
|
16
|
+
});
|
|
17
|
+
const transport = (values.transport ?? "stdio");
|
|
18
|
+
if (transport !== "stdio" && transport !== "http") {
|
|
19
|
+
throw new Error(`Unsupported transport "${transport}". Expected "stdio" or "http".`);
|
|
20
|
+
}
|
|
21
|
+
const snapshotMode = values["snapshot-mode"];
|
|
22
|
+
if (snapshotMode !== undefined
|
|
23
|
+
&& snapshotMode !== "full"
|
|
24
|
+
&& snapshotMode !== "none") {
|
|
25
|
+
throw new Error(`Unsupported snapshot mode "${snapshotMode}". Expected "full" or "none".`);
|
|
26
|
+
}
|
|
27
|
+
const portValue = values.port;
|
|
28
|
+
const port = portValue === undefined ? undefined : Number.parseInt(portValue, 10);
|
|
29
|
+
if (portValue !== undefined && Number.isNaN(port)) {
|
|
30
|
+
throw new Error(`Invalid port "${portValue}". Expected an integer.`);
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
transport,
|
|
34
|
+
...(values.host !== undefined ? { host: values.host } : {}),
|
|
35
|
+
...(port !== undefined ? { port } : {}),
|
|
36
|
+
...(values.path !== undefined ? { path: values.path } : {}),
|
|
37
|
+
...(values["output-dir"] !== undefined ? { outputDir: values["output-dir"] } : {}),
|
|
38
|
+
...(snapshotMode !== undefined ? { snapshotMode: snapshotMode } : {})
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function sharedOptions(options) {
|
|
42
|
+
return {
|
|
43
|
+
...(options.outputDir !== undefined ? { outputDir: options.outputDir } : {}),
|
|
44
|
+
...(options.snapshotMode !== undefined ? { snapshotMode: options.snapshotMode } : {})
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
async function main() {
|
|
48
|
+
const options = parseCliOptions(process.argv.slice(2));
|
|
49
|
+
if (options.transport === "http") {
|
|
50
|
+
const httpOptions = {
|
|
51
|
+
port: options.port ?? 3333,
|
|
52
|
+
...(options.host !== undefined ? { host: options.host } : {}),
|
|
53
|
+
...(options.path !== undefined ? { path: options.path } : {}),
|
|
54
|
+
...sharedOptions(options)
|
|
55
|
+
};
|
|
56
|
+
const bundle = await startRoxyBrowserMcpHttp(httpOptions);
|
|
57
|
+
const host = httpOptions.host ?? "127.0.0.1";
|
|
58
|
+
const path = httpOptions.path ?? "/mcp";
|
|
59
|
+
console.error(`RoxyBrowser MCP HTTP server listening at http://${host}:${httpOptions.port}${path}`);
|
|
60
|
+
const close = async () => {
|
|
61
|
+
await bundle.close();
|
|
62
|
+
process.exitCode = 0;
|
|
63
|
+
};
|
|
64
|
+
process.once("SIGINT", () => void close());
|
|
65
|
+
process.once("SIGTERM", () => void close());
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
await startRoxyBrowserMcpStdio(sharedOptions(options));
|
|
69
|
+
}
|
|
70
|
+
void main().catch((error) => {
|
|
4
71
|
console.error(error instanceof Error ? error.message : String(error));
|
|
5
72
|
process.exitCode = 1;
|
|
6
73
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roxybrowser-mcp.js","sourceRoot":"","sources":["../../src/bin/roxybrowser-mcp.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"roxybrowser-mcp.js","sourceRoot":"","sources":["../../src/bin/roxybrowser-mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/mcp/backend/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/mcp/backend/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;;;;;;;;;AAkCxB,wBAAyB"}
|
|
@@ -9,7 +9,8 @@ const connect = defineTool({
|
|
|
9
9
|
description: "Attach to an existing browser and seed the active tab snapshot.",
|
|
10
10
|
inputSchema: z.object({
|
|
11
11
|
endpoint: z.string().min(1),
|
|
12
|
-
browser: z.enum(["chrome", "firefox"]).default("chrome")
|
|
12
|
+
browser: z.enum(["chrome", "firefox"]).default("chrome"),
|
|
13
|
+
sessionId: z.string().min(1).optional()
|
|
13
14
|
}),
|
|
14
15
|
type: "action"
|
|
15
16
|
},
|
|
@@ -18,7 +19,8 @@ const connect = defineTool({
|
|
|
18
19
|
const result = await context.runtime.connect({
|
|
19
20
|
protocol,
|
|
20
21
|
endpoint: params.endpoint,
|
|
21
|
-
browser: params.browser === "chrome" ? "chromium" : params.browser
|
|
22
|
+
browser: params.browser === "chrome" ? "chromium" : params.browser,
|
|
23
|
+
...(params.sessionId ? { sessionId: params.sessionId } : {})
|
|
22
24
|
});
|
|
23
25
|
response.addTextResult(formatConnectResult({
|
|
24
26
|
...result,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../src/mcp/backend/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,OAAO,GAAG,UAAU,CAAC;IACzB,UAAU,EAAE,QAAQ;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,iEAAiE;QAC9E,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../src/mcp/backend/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,OAAO,GAAG,UAAU,CAAC;IACzB,UAAU,EAAE,QAAQ;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,iEAAiE;QAC9E,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;YACxD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;SACxC,CAAC;QACF,IAAI,EAAE,QAAQ;KACf;IACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;QAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QAC/D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;YAC3C,QAAQ;YACR,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO;YAClE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7D,CAAC,CAAC;QACH,QAAQ,CAAC,aAAa,CACpB,mBAAmB,CAAC;YAClB,GAAG,MAAM;YACT,WAAW,EAAE,MAAM,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW;SAC/E,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAC,CAAC;AAEH,eAAe,CAAC,OAAO,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../src/mcp/backend/response.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../src/mcp/backend/response.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,qBAAa,QAAQ;IAiBjB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAlB5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqE;IAC5F,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,YAAY,CAON;IACd,OAAO,CAAC,OAAO,CAAS;gBAGL,OAAO,EAAE,OAAO,EACxB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAG5C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI3B,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,YAAY,GAAG,IAAI;IAIxE,QAAQ,IAAI,IAAI;IAIhB,kBAAkB,IAAI,IAAI;IAI1B,sBAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IAU3F,SAAS,IAAI,OAAO,CAAC,cAAc,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAwFnE"}
|
|
@@ -61,18 +61,28 @@ export class Response {
|
|
|
61
61
|
sections.push("### Code", "```js", ...this.code, "```");
|
|
62
62
|
}
|
|
63
63
|
if (this.includeSnapshot === "full") {
|
|
64
|
-
const snapshot = await this.context.runtime.snapshot();
|
|
64
|
+
const snapshot = await reconcileSnapshotWithTabs(this.context, await this.context.runtime.snapshot());
|
|
65
65
|
if (sections.length) {
|
|
66
66
|
sections.push("");
|
|
67
67
|
}
|
|
68
68
|
sections.push(formatSnapshot(snapshot));
|
|
69
69
|
}
|
|
70
70
|
if (this.fullSnapshot) {
|
|
71
|
-
|
|
71
|
+
let snapshot = await reconcileSnapshotWithTabs(this.context, await this.context.runtime.snapshot({
|
|
72
72
|
...(this.fullSnapshot.target !== undefined ? { target: this.fullSnapshot.target } : {}),
|
|
73
73
|
...(this.fullSnapshot.depth !== undefined ? { depth: this.fullSnapshot.depth } : {}),
|
|
74
74
|
...(this.fullSnapshot.boxes !== undefined ? { boxes: this.fullSnapshot.boxes } : {})
|
|
75
|
-
});
|
|
75
|
+
}));
|
|
76
|
+
if (!this.fullSnapshot.filename
|
|
77
|
+
&& snapshot.text.trim().length === 0
|
|
78
|
+
&& snapshot.url
|
|
79
|
+
&& snapshot.url !== "about:blank") {
|
|
80
|
+
snapshot = await reconcileSnapshotWithTabs(this.context, await this.context.runtime.snapshot({
|
|
81
|
+
...(this.fullSnapshot.target !== undefined ? { target: this.fullSnapshot.target } : {}),
|
|
82
|
+
...(this.fullSnapshot.depth !== undefined ? { depth: this.fullSnapshot.depth } : {}),
|
|
83
|
+
...(this.fullSnapshot.boxes !== undefined ? { boxes: this.fullSnapshot.boxes } : {})
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
76
86
|
if (this.fullSnapshot.filename) {
|
|
77
87
|
const resolvedFilename = await this.context.resolveOutputFile(this.fullSnapshot.filename);
|
|
78
88
|
await writeFile(resolvedFilename, snapshot.text);
|
|
@@ -106,4 +116,16 @@ export class Response {
|
|
|
106
116
|
};
|
|
107
117
|
}
|
|
108
118
|
}
|
|
119
|
+
async function reconcileSnapshotWithTabs(context, snapshot) {
|
|
120
|
+
const tabs = await context.runtime.listTabs();
|
|
121
|
+
const activeTab = tabs.find((tab) => tab.active);
|
|
122
|
+
if (!activeTab) {
|
|
123
|
+
return snapshot;
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
...snapshot,
|
|
127
|
+
title: activeTab.title || snapshot.title,
|
|
128
|
+
url: activeTab.url || snapshot.url
|
|
129
|
+
};
|
|
130
|
+
}
|
|
109
131
|
//# sourceMappingURL=response.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../../src/mcp/backend/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../../src/mcp/backend/response.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connectedBrowser.d.ts","sourceRoot":"","sources":["../../src/mcp/connectedBrowser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"connectedBrowser.d.ts","sourceRoot":"","sources":["../../src/mcp/connectedBrowser.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAOV,uBAAuB,EACvB,sBAAsB,EAOvB,MAAM,YAAY,CAAC;AA85FpB,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,uBAAuB,CAAC,CAMlC"}
|
|
@@ -4,6 +4,7 @@ import * as cdpModule from "chrome-remote-interface";
|
|
|
4
4
|
import { normalizeAriaSnapshotOptions, retryUntilReady } from "../ariaSnapshot.js";
|
|
5
5
|
import { PLAYWRIGHT_ARIA_SNAPSHOT_EVALUATE_SOURCE as ARIA_SNAPSHOT_EVALUATE_SOURCE } from "../vendor/playwright/ariaSnapshotEvaluate.js";
|
|
6
6
|
import { getBidiClientFactory } from "../protocol/bidi/client.js";
|
|
7
|
+
import { parseSerializedEvaluationResult, wrapWithSerializedEvaluationResult } from "../protocol/evaluationSerializer.js";
|
|
7
8
|
import { McpToolError } from "./errors.js";
|
|
8
9
|
import { ACTION_POINT_EVALUATE_SOURCE, ACTION_POINT_BY_SELECTOR_SOURCE } from "./snapshot.js";
|
|
9
10
|
function delay(ms) {
|
|
@@ -351,7 +352,7 @@ async function evaluateBiDi(client, contextId, functionSource, arg) {
|
|
|
351
352
|
? `(${functionSource})()`
|
|
352
353
|
: `(${functionSource})(${JSON.stringify(arg)})`;
|
|
353
354
|
const response = (await client.scriptEvaluate({
|
|
354
|
-
expression,
|
|
355
|
+
expression: wrapWithSerializedEvaluationResult(expression),
|
|
355
356
|
target: {
|
|
356
357
|
context: contextId
|
|
357
358
|
},
|
|
@@ -361,7 +362,7 @@ async function evaluateBiDi(client, contextId, functionSource, arg) {
|
|
|
361
362
|
if (response.type === "exception") {
|
|
362
363
|
throw new Error(response.exceptionDetails?.text || "BiDi runtime evaluation failed.");
|
|
363
364
|
}
|
|
364
|
-
return response.result
|
|
365
|
+
return parseSerializedEvaluationResult(extractBiDiValue(response.result));
|
|
365
366
|
}
|
|
366
367
|
async function evaluateBiDiRef(client, contextId, functionSource, arg) {
|
|
367
368
|
const expression = arg === undefined
|
|
@@ -389,6 +390,22 @@ async function evaluateBiDiRef(client, contextId, functionSource, arg) {
|
|
|
389
390
|
...(response.result?.value?.handle !== undefined ? { handle: response.result.value.handle } : {})
|
|
390
391
|
};
|
|
391
392
|
}
|
|
393
|
+
function extractBiDiValue(value) {
|
|
394
|
+
if (!value) {
|
|
395
|
+
return undefined;
|
|
396
|
+
}
|
|
397
|
+
if (value.type === "array" && Array.isArray(value.value)) {
|
|
398
|
+
return value.value.map((entry) => extractBiDiValue(entry));
|
|
399
|
+
}
|
|
400
|
+
if (value.type === "object" && Array.isArray(value.value)) {
|
|
401
|
+
const obj = {};
|
|
402
|
+
for (const [key, val] of value.value) {
|
|
403
|
+
obj[key] = extractBiDiValue(val);
|
|
404
|
+
}
|
|
405
|
+
return obj;
|
|
406
|
+
}
|
|
407
|
+
return value.value;
|
|
408
|
+
}
|
|
392
409
|
function toAriaSnapshotPayload(request = {}) {
|
|
393
410
|
return {
|
|
394
411
|
options: normalizeAriaSnapshotOptions({
|
|
@@ -1384,6 +1401,7 @@ class BidiConnectedBrowserSession {
|
|
|
1384
1401
|
bidiListeners = new Map();
|
|
1385
1402
|
responseDataCollector;
|
|
1386
1403
|
activeTabId;
|
|
1404
|
+
ownsSession = false;
|
|
1387
1405
|
constructor(client) {
|
|
1388
1406
|
this.client = client;
|
|
1389
1407
|
}
|
|
@@ -1397,9 +1415,10 @@ class BidiConnectedBrowserSession {
|
|
|
1397
1415
|
}
|
|
1398
1416
|
const client = await getBidiClientFactory()({
|
|
1399
1417
|
browserName: "firefox",
|
|
1400
|
-
webSocketUrl: args.endpoint
|
|
1418
|
+
webSocketUrl: normalizeFirefoxBidiEndpoint(args.endpoint, args.sessionId)
|
|
1401
1419
|
});
|
|
1402
1420
|
const session = new BidiConnectedBrowserSession(client);
|
|
1421
|
+
session.ownsSession = await ensureMcpBiDiSession(client, args.endpoint, args.sessionId);
|
|
1403
1422
|
await session.initialize();
|
|
1404
1423
|
const tabs = await session.refreshTabs();
|
|
1405
1424
|
if (tabs.length === 0) {
|
|
@@ -1462,7 +1481,7 @@ class BidiConnectedBrowserSession {
|
|
|
1462
1481
|
}
|
|
1463
1482
|
async snapshot(request = {}) {
|
|
1464
1483
|
const tabId = await this.getActiveTabId();
|
|
1465
|
-
const result = await evaluateBiDi(this.client, tabId, ARIA_SNAPSHOT_EVALUATE_SOURCE, toAriaSnapshotPayload(request));
|
|
1484
|
+
const result = await retryUntilReady(() => evaluateBiDi(this.client, tabId, ARIA_SNAPSHOT_EVALUATE_SOURCE, toAriaSnapshotPayload(request)));
|
|
1466
1485
|
return toBrowserSnapshot(result, request, {
|
|
1467
1486
|
console: this.consoleSummary(tabId),
|
|
1468
1487
|
consoleLink: await this.takeConsoleLink(tabId)
|
|
@@ -1647,7 +1666,9 @@ class BidiConnectedBrowserSession {
|
|
|
1647
1666
|
await this.client.networkRemoveDataCollector({ collector: this.responseDataCollector }).catch(() => { });
|
|
1648
1667
|
this.responseDataCollector = undefined;
|
|
1649
1668
|
}
|
|
1650
|
-
|
|
1669
|
+
if (this.ownsSession) {
|
|
1670
|
+
await this.client.sessionEnd({}).catch(() => { });
|
|
1671
|
+
}
|
|
1651
1672
|
this.client.close();
|
|
1652
1673
|
}
|
|
1653
1674
|
async navigate(url) {
|
|
@@ -2144,6 +2165,55 @@ class BidiConnectedBrowserSession {
|
|
|
2144
2165
|
return `${relativePath}${lineRange}`;
|
|
2145
2166
|
}
|
|
2146
2167
|
}
|
|
2168
|
+
function normalizeFirefoxBidiEndpoint(endpoint, sessionId) {
|
|
2169
|
+
const url = new URL(endpoint);
|
|
2170
|
+
if (sessionId) {
|
|
2171
|
+
url.pathname = `/session/${sessionId}`;
|
|
2172
|
+
return url.toString();
|
|
2173
|
+
}
|
|
2174
|
+
if (url.pathname === "/" || url.pathname === "") {
|
|
2175
|
+
url.pathname = "/session";
|
|
2176
|
+
}
|
|
2177
|
+
return url.toString();
|
|
2178
|
+
}
|
|
2179
|
+
async function ensureMcpBiDiSession(client, endpoint, sessionId) {
|
|
2180
|
+
await client.sessionStatus({});
|
|
2181
|
+
if (sessionId || isSessionSpecificFirefoxBidiEndpoint(endpoint)) {
|
|
2182
|
+
return false;
|
|
2183
|
+
}
|
|
2184
|
+
try {
|
|
2185
|
+
await client.browsingContextGetTree({});
|
|
2186
|
+
return false;
|
|
2187
|
+
}
|
|
2188
|
+
catch (error) {
|
|
2189
|
+
const message = String(error instanceof Error ? error.message : error);
|
|
2190
|
+
if (!message.includes("session does not exist")
|
|
2191
|
+
&& !message.includes("invalid session id")
|
|
2192
|
+
&& !message.includes("not active")) {
|
|
2193
|
+
throw error;
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
try {
|
|
2197
|
+
await client.sessionNew({
|
|
2198
|
+
capabilities: {
|
|
2199
|
+
alwaysMatch: {
|
|
2200
|
+
acceptInsecureCerts: true
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
});
|
|
2204
|
+
return true;
|
|
2205
|
+
}
|
|
2206
|
+
catch (error) {
|
|
2207
|
+
const message = String(error instanceof Error ? error.message : error);
|
|
2208
|
+
if (message.includes("Maximum number of active sessions")) {
|
|
2209
|
+
throw new Error("Maximum number of active BiDi sessions. Reuse an existing one with sessionId or close the current session first.");
|
|
2210
|
+
}
|
|
2211
|
+
throw error;
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
function isSessionSpecificFirefoxBidiEndpoint(endpoint) {
|
|
2215
|
+
return /^\/session\/[^/]+$/.test(new URL(endpoint).pathname);
|
|
2216
|
+
}
|
|
2147
2217
|
export async function connectBrowserSession(args) {
|
|
2148
2218
|
if (args.protocol === "cdp") {
|
|
2149
2219
|
return CdpConnectedBrowserSession.connect(args);
|