mcp-browser-bridge 1.1.0 → 1.2.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 +75 -23
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +3 -1
- package/dist/mcp-server.js.map +1 -1
- package/dist/prompts.d.ts +3 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +197 -0
- package/dist/prompts.js.map +1 -0
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -2,43 +2,90 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/mcp-browser-bridge)
|
|
4
4
|
|
|
5
|
-
MCP server that
|
|
5
|
+
MCP server that gives AI coding assistants direct access to the browser — navigate, click, fill forms, run JavaScript, take screenshots, and read page content.
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
-
|
|
8
|
+
MCP Client ←(stdio)→ mcp-browser-bridge ←(WebSocket :7483)→ Browser Extension ←(Chrome APIs)→ Browser
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
Works with any MCP-compatible client: Claude Code, Cursor, Windsurf, Cline, and others.
|
|
12
|
+
|
|
11
13
|
## Quick Start
|
|
12
14
|
|
|
13
15
|
### 1. Install the extension
|
|
14
16
|
|
|
15
|
-
Install from the Chrome Web Store
|
|
17
|
+
Install from the [Chrome Web Store](https://chromewebstore.google.com/detail/browser-bridge-mcp/imdkejagogpjpjfdcncahmnkgfockpcp), or load manually:
|
|
16
18
|
|
|
17
19
|
1. Download or clone this repo.
|
|
18
20
|
2. Open `chrome://extensions`, enable **Developer mode**.
|
|
19
21
|
3. Click **Load unpacked** and select the `extension/` folder.
|
|
20
22
|
|
|
21
|
-
Works in Chrome, Brave, Edge,
|
|
23
|
+
Works in any Chromium browser: Chrome, Brave, Edge, Arc, Vivaldi, Opera.
|
|
24
|
+
|
|
25
|
+
### 2. Add to your MCP client
|
|
26
|
+
|
|
27
|
+
<details>
|
|
28
|
+
<summary><strong>Claude Code</strong></summary>
|
|
22
29
|
|
|
23
|
-
|
|
30
|
+
Run:
|
|
31
|
+
```sh
|
|
32
|
+
claude mcp add browser-bridge -- npx -y mcp-browser-bridge
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or add to `.mcp.json`:
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"browser-bridge": {
|
|
40
|
+
"command": "npx",
|
|
41
|
+
"args": ["-y", "mcp-browser-bridge"]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
</details>
|
|
24
47
|
|
|
25
|
-
|
|
48
|
+
<details>
|
|
49
|
+
<summary><strong>Cursor</strong></summary>
|
|
26
50
|
|
|
51
|
+
Add to `.cursor/mcp.json`:
|
|
27
52
|
```json
|
|
28
53
|
{
|
|
29
54
|
"mcpServers": {
|
|
30
55
|
"browser-bridge": {
|
|
31
56
|
"command": "npx",
|
|
32
|
-
"args": ["-y", "mcp-browser-bridge"]
|
|
33
|
-
"env": { "BRIDGE_WS_PORT": "7483" }
|
|
57
|
+
"args": ["-y", "mcp-browser-bridge"]
|
|
34
58
|
}
|
|
35
59
|
}
|
|
36
60
|
}
|
|
37
61
|
```
|
|
62
|
+
</details>
|
|
63
|
+
|
|
64
|
+
<details>
|
|
65
|
+
<summary><strong>Windsurf</strong></summary>
|
|
66
|
+
|
|
67
|
+
Add to `~/.codeium/windsurf/mcp_config.json`:
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"mcpServers": {
|
|
71
|
+
"browser-bridge": {
|
|
72
|
+
"command": "npx",
|
|
73
|
+
"args": ["-y", "mcp-browser-bridge"]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
</details>
|
|
79
|
+
|
|
80
|
+
<details>
|
|
81
|
+
<summary><strong>Other MCP clients</strong></summary>
|
|
82
|
+
|
|
83
|
+
Use `npx -y mcp-browser-bridge` as the server command in your client's MCP configuration. The server communicates over stdio.
|
|
84
|
+
</details>
|
|
38
85
|
|
|
39
86
|
### 3. Verify
|
|
40
87
|
|
|
41
|
-
Start your MCP client. The extension popup should show a green
|
|
88
|
+
Start your MCP client. The extension popup should show a green **Connected** indicator. Call the `browser_status` tool to confirm.
|
|
42
89
|
|
|
43
90
|
## Available Tools
|
|
44
91
|
|
|
@@ -51,13 +98,24 @@ All tools accept an optional `tabId` parameter. When omitted, they target the ac
|
|
|
51
98
|
| `browser_screenshot` | Capture a screenshot of the visible area of a tab |
|
|
52
99
|
| `browser_evaluate` | Execute JavaScript in a tab and return the result |
|
|
53
100
|
| `browser_click` | Click an element by CSS selector |
|
|
54
|
-
| `browser_fill` | Fill a form field by CSS selector |
|
|
101
|
+
| `browser_fill` | Fill a form field by CSS selector (React-compatible) |
|
|
55
102
|
| `browser_get_content` | Get the text or HTML of a page or element |
|
|
56
103
|
| `browser_get_tabs` | List all open browser tabs |
|
|
57
104
|
| `browser_get_console` | Get captured console log entries from a tab |
|
|
58
105
|
| `browser_wait_for` | Wait for a CSS selector to appear on the page |
|
|
59
106
|
| `browser_send_message` | Send a custom message to the extension |
|
|
60
107
|
|
|
108
|
+
## Included Prompts
|
|
109
|
+
|
|
110
|
+
The server ships two MCP prompts that provide guided workflows to any connected client:
|
|
111
|
+
|
|
112
|
+
| Prompt | Description |
|
|
113
|
+
|--------|-------------|
|
|
114
|
+
| `browse` | General-purpose browser interaction — navigating, clicking, filling forms, screenshotting, running JS. Accepts an optional `task` argument. |
|
|
115
|
+
| `qa-runner` | Structured QA checklist execution — drives the browser through test scenarios defined in markdown and reports pass/fail results. Accepts an optional `checklist` path. |
|
|
116
|
+
|
|
117
|
+
In Claude Code, these appear as slash commands: `/browser-bridge:browse` and `/browser-bridge:qa-runner`.
|
|
118
|
+
|
|
61
119
|
## Configuration
|
|
62
120
|
|
|
63
121
|
The WebSocket port defaults to `7483`. To change it:
|
|
@@ -65,20 +123,16 @@ The WebSocket port defaults to `7483`. To change it:
|
|
|
65
123
|
- **Server side:** Set the `BRIDGE_WS_PORT` environment variable in your MCP config.
|
|
66
124
|
- **Extension side:** Change the port in the extension popup and click Reconnect.
|
|
67
125
|
|
|
68
|
-
## Compatibility
|
|
69
|
-
|
|
70
|
-
Works with any Chromium-based browser: Chrome, Brave, Edge, Arc, Vivaldi, Opera.
|
|
71
|
-
|
|
72
126
|
## Security
|
|
73
127
|
|
|
74
|
-
- WebSocket binds to `127.0.0.1` only
|
|
75
|
-
- Connections restricted to
|
|
128
|
+
- WebSocket binds to `127.0.0.1` only — no network exposure.
|
|
129
|
+
- Connections restricted to browser extension origins.
|
|
76
130
|
- Single extension client at a time.
|
|
77
131
|
|
|
78
132
|
## Troubleshooting
|
|
79
133
|
|
|
80
134
|
**Extension shows "Disconnected"**
|
|
81
|
-
Check that the MCP server is running and the port is free
|
|
135
|
+
Check that the MCP server is running and the port is free:
|
|
82
136
|
```sh
|
|
83
137
|
# macOS/Linux
|
|
84
138
|
lsof -i :7483
|
|
@@ -88,13 +142,13 @@ netstat -aon | findstr :7483
|
|
|
88
142
|
```
|
|
89
143
|
|
|
90
144
|
**Tools return "No extension connected"**
|
|
91
|
-
Open the extension popup and click Reconnect.
|
|
145
|
+
Open the extension popup and click Reconnect.
|
|
92
146
|
|
|
93
147
|
**Screenshots fail**
|
|
94
148
|
The target tab must be visible and focused. Background or minimized tabs cannot be captured.
|
|
95
149
|
|
|
96
150
|
**`browser_evaluate` returns unexpected results**
|
|
97
|
-
|
|
151
|
+
Results must be JSON-serializable. Promises return `{}` — use synchronous expressions or await inside an IIFE and return a plain value.
|
|
98
152
|
|
|
99
153
|
## Development
|
|
100
154
|
|
|
@@ -103,12 +157,10 @@ git clone https://github.com/adbarc92/mcp-browser-bridge.git
|
|
|
103
157
|
cd mcp-browser-bridge
|
|
104
158
|
npm install
|
|
105
159
|
npm run build
|
|
160
|
+
npm test # 53 tests via Vitest
|
|
106
161
|
```
|
|
107
162
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
1. Open `chrome://extensions` and enable Developer mode.
|
|
111
|
-
2. Click "Load unpacked" and select the `extension/` folder.
|
|
163
|
+
Load the extension locally via `chrome://extensions` → **Load unpacked** → select `extension/`.
|
|
112
164
|
|
|
113
165
|
The repo includes a `.mcp.json` configured for local development.
|
|
114
166
|
|
package/dist/mcp-server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAevD,wBAAgB,eAAe,CAAC,EAAE,EAAE,qBAAqB,GAAG,SAAS,CA8NpE"}
|
package/dist/mcp-server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { METHODS, SCREENSHOT_TIMEOUT_MS } from "./protocol.js";
|
|
4
|
+
import { registerPrompts } from "./prompts.js";
|
|
4
5
|
function errorText(err) {
|
|
5
6
|
if (typeof err === "object" && err !== null && "message" in err) {
|
|
6
7
|
return err.message;
|
|
@@ -13,7 +14,7 @@ function textResult(text, isError = false) {
|
|
|
13
14
|
export function createMcpServer(ws) {
|
|
14
15
|
const mcp = new McpServer({
|
|
15
16
|
name: "browser-bridge",
|
|
16
|
-
version: "1.
|
|
17
|
+
version: "1.2.0",
|
|
17
18
|
});
|
|
18
19
|
// 1. browser_status
|
|
19
20
|
mcp.tool("browser_status", "Check if the Chrome extension is connected and get active tab info", {}, async () => {
|
|
@@ -170,6 +171,7 @@ export function createMcpServer(ws) {
|
|
|
170
171
|
return textResult(`Send message failed: ${errorText(err)}`, true);
|
|
171
172
|
}
|
|
172
173
|
});
|
|
174
|
+
registerPrompts(mcp);
|
|
173
175
|
return mcp;
|
|
174
176
|
}
|
|
175
177
|
//# sourceMappingURL=mcp-server.js.map
|
package/dist/mcp-server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAqB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwKpE,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CA0CpD"}
|
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const BROWSE_PROMPT = `# Browse
|
|
3
|
+
|
|
4
|
+
Gives you direct access to a Chromium browser via the Browser Bridge MCP tools.
|
|
5
|
+
|
|
6
|
+
## Available Tools
|
|
7
|
+
|
|
8
|
+
| Tool | Purpose |
|
|
9
|
+
|------|---------|
|
|
10
|
+
| \`browser_status\` | Check connection and get active tab info |
|
|
11
|
+
| \`browser_navigate\` | Go to a URL |
|
|
12
|
+
| \`browser_screenshot\` | Capture visible area of a tab |
|
|
13
|
+
| \`browser_evaluate\` | Run JavaScript in the page context |
|
|
14
|
+
| \`browser_click\` | Click an element by CSS selector |
|
|
15
|
+
| \`browser_fill\` | Fill a form field by CSS selector |
|
|
16
|
+
| \`browser_get_content\` | Get text or HTML of a page or element |
|
|
17
|
+
| \`browser_get_tabs\` | List all open tabs |
|
|
18
|
+
| \`browser_get_console\` | Get console logs from a tab |
|
|
19
|
+
| \`browser_wait_for\` | Wait for a selector to appear |
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
1. Always start with \`browser_status\` to confirm the extension is connected.
|
|
24
|
+
2. Use \`browser_navigate\` to go to the target page.
|
|
25
|
+
3. Use \`browser_screenshot\` to see the current state before interacting.
|
|
26
|
+
4. After any interaction (click, fill), take another screenshot to verify the result.
|
|
27
|
+
|
|
28
|
+
## Selector Tips
|
|
29
|
+
|
|
30
|
+
- Prefer \`[data-testid="foo"]\` selectors when available.
|
|
31
|
+
- \`button:has-text("Submit")\` is NOT supported — use \`browser_evaluate\` to find elements by text content instead.
|
|
32
|
+
- For scrolling, use \`browser_evaluate\` with \`document.querySelector('selector').scrollIntoView()\`. Do NOT use \`window.scrollBy()\` — it doesn't work with many framework scroll containers.
|
|
33
|
+
|
|
34
|
+
## Gotchas
|
|
35
|
+
|
|
36
|
+
- **Screenshots require a visible, focused tab.** Minimized or background tabs will fail.
|
|
37
|
+
- **\`browser_evaluate\` results must be JSON-serializable.** Promises return \`{}\` — use synchronous expressions or await inside an IIFE and return a primitive/plain object.
|
|
38
|
+
- **\`browser_fill\` works with React.** It uses native property setters to trigger React state updates.
|
|
39
|
+
- **All tools accept an optional \`tabId\`.** Omit it to target the active tab.`;
|
|
40
|
+
const QA_RUNNER_PROMPT = `# QA Runner
|
|
41
|
+
|
|
42
|
+
Executes structured QA checklists against a running app using Browser Bridge MCP tools. Reads a checklist markdown file with YAML frontmatter and CSS selectors, drives the browser through each scenario, captures evidence (screenshots, console logs, content checks), and reports pass/fail results.
|
|
43
|
+
|
|
44
|
+
## Prerequisites Check
|
|
45
|
+
|
|
46
|
+
Before running any scenario, verify ALL of these in order:
|
|
47
|
+
|
|
48
|
+
1. **Check browser connection** — Call \`browser_status\`. If \`connected: false\`, stop and tell the user to load the Browser Bridge extension and reconnect.
|
|
49
|
+
2. **Locate the checklist** — Search the project for checklist markdown files (common locations: \`docs/qa/checklists/\`, \`qa/checklists/\`, \`tests/checklists/\`). If the user specifies a file path, use that directly. The file must have YAML frontmatter with \`automation: claude-qa\`. If not, offer guided-manual mode.
|
|
50
|
+
3. **Verify app is running** — Navigate to the \`app_url\` from the checklist frontmatter. If navigation fails, stop and tell the user to start their dev server.
|
|
51
|
+
|
|
52
|
+
## Checklist Format
|
|
53
|
+
|
|
54
|
+
Checklists that support automation have this structure:
|
|
55
|
+
|
|
56
|
+
\`\`\`yaml
|
|
57
|
+
---
|
|
58
|
+
title: Create New Item
|
|
59
|
+
app_url: http://localhost:3000
|
|
60
|
+
preconditions:
|
|
61
|
+
- logged_in: true
|
|
62
|
+
- start_route: /dashboard
|
|
63
|
+
automation: claude-qa
|
|
64
|
+
---
|
|
65
|
+
\`\`\`
|
|
66
|
+
|
|
67
|
+
Steps reference CSS selectors after an arrow:
|
|
68
|
+
|
|
69
|
+
\`\`\`
|
|
70
|
+
1. Click the create button → \`[data-testid="create-button"]\`
|
|
71
|
+
2. Fill in the title → \`[data-testid="title-input"]\` with "My Item"
|
|
72
|
+
3. Click save → \`#save-btn\`
|
|
73
|
+
\`\`\`
|
|
74
|
+
|
|
75
|
+
Verify items specify the check method:
|
|
76
|
+
|
|
77
|
+
\`\`\`
|
|
78
|
+
- [ ] \`screenshot\` Item appears in the list
|
|
79
|
+
- [ ] \`console_check\` No errors in console
|
|
80
|
+
- [ ] \`content_check\` Page contains "My Item"
|
|
81
|
+
- [ ] \`evaluate\` document.querySelector('.item-count').textContent === '1'
|
|
82
|
+
\`\`\`
|
|
83
|
+
|
|
84
|
+
## Selector Conventions
|
|
85
|
+
|
|
86
|
+
Use whatever selectors the project provides. Common patterns by framework:
|
|
87
|
+
|
|
88
|
+
| Framework | Preferred Selector |
|
|
89
|
+
|-----------|-------------------|
|
|
90
|
+
| React / Vue / Svelte | \`[data-testid="foo"]\` |
|
|
91
|
+
| React Native Web / Expo | \`[data-testid="foo"]\` (rendered from \`testID\`) |
|
|
92
|
+
| Angular | \`[data-cy="foo"]\` or \`[data-testid="foo"]\` |
|
|
93
|
+
| Plain HTML | \`#id\`, \`.class\`, or semantic selectors |
|
|
94
|
+
|
|
95
|
+
### Filling inputs in React-based apps
|
|
96
|
+
|
|
97
|
+
Use \`browser_fill\` which handles React state automatically via native property setters. If that doesn't work, fall back to \`browser_evaluate\`:
|
|
98
|
+
|
|
99
|
+
\`\`\`js
|
|
100
|
+
const el = document.querySelector('[data-testid="title-input"]');
|
|
101
|
+
const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
|
|
102
|
+
setter.call(el, 'New Value');
|
|
103
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
104
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
105
|
+
\`\`\`
|
|
106
|
+
|
|
107
|
+
## Execution Flow
|
|
108
|
+
|
|
109
|
+
For each scenario in the checklist:
|
|
110
|
+
|
|
111
|
+
### Execute Steps
|
|
112
|
+
|
|
113
|
+
Map each step to a browser tool call based on its action verb and selector:
|
|
114
|
+
|
|
115
|
+
| Action | Browser Tool |
|
|
116
|
+
|--------|-------------|
|
|
117
|
+
| Navigate to | \`browser_navigate\` |
|
|
118
|
+
| Tap / Click | \`browser_click\` |
|
|
119
|
+
| Enter / Fill / Type | \`browser_fill\` |
|
|
120
|
+
| Verify / Check | \`browser_get_content\` |
|
|
121
|
+
| Wait for | \`browser_wait_for\` |
|
|
122
|
+
| Scroll to | \`browser_evaluate\` with \`element.scrollIntoView()\` |
|
|
123
|
+
|
|
124
|
+
### Execute Verify Items
|
|
125
|
+
|
|
126
|
+
- **\`screenshot\`**: Call \`browser_screenshot\`. Visually inspect the result. Report what you see.
|
|
127
|
+
- **\`console_check\`**: Call \`browser_get_console\`. Check for errors (level: "error"). Warnings are acceptable.
|
|
128
|
+
- **\`content_check\`**: Call \`browser_get_content\` with \`format: "text"\`. Search for expected text.
|
|
129
|
+
- **\`evaluate\`**: Call \`browser_evaluate\` with the JS expression. Check return value.
|
|
130
|
+
|
|
131
|
+
### Record Results
|
|
132
|
+
|
|
133
|
+
After each scenario, record:
|
|
134
|
+
- **Pass**: All verify items confirmed
|
|
135
|
+
- **Fail**: One or more verify items failed (include which ones and why)
|
|
136
|
+
- **Blocked**: Could not execute steps (include the blocking reason)
|
|
137
|
+
|
|
138
|
+
## Reporting
|
|
139
|
+
|
|
140
|
+
After all scenarios complete, output a summary table:
|
|
141
|
+
|
|
142
|
+
\`\`\`
|
|
143
|
+
## QA Results: [Checklist Title]
|
|
144
|
+
|
|
145
|
+
| Scenario | Result | Notes |
|
|
146
|
+
|----------|--------|-------|
|
|
147
|
+
| S1: Create item with all fields | PASS | All verifications confirmed |
|
|
148
|
+
| S2: Minimum fields | PASS | Item created with title only |
|
|
149
|
+
| S3: Validation errors | FAIL | Save button not disabled (see screenshot) |
|
|
150
|
+
| S4: Default state | PASS | Defaults confirmed |
|
|
151
|
+
|
|
152
|
+
**Overall: 3/4 PASS | 1 FAIL**
|
|
153
|
+
\`\`\`
|
|
154
|
+
|
|
155
|
+
Then ask the user if they want to:
|
|
156
|
+
1. Re-run failed scenarios
|
|
157
|
+
2. Update the checklist file with results
|
|
158
|
+
|
|
159
|
+
## Error Recovery
|
|
160
|
+
|
|
161
|
+
- **Element not found**: Wait 3 seconds with \`browser_wait_for\`, retry once. If still missing, mark step as failed and continue.
|
|
162
|
+
- **Navigation timeout**: Retry once. If still failing, mark scenario as blocked.
|
|
163
|
+
- **Console errors during test**: Log them but don't auto-fail unless the verify item specifically checks for console errors.
|
|
164
|
+
- **Screenshot fails**: Note it in results, continue execution. Tab must be visible.`;
|
|
165
|
+
export function registerPrompts(mcp) {
|
|
166
|
+
mcp.prompt("browse", "Interact with the browser — navigate, click, fill forms, take screenshots, run JS, read page content", {
|
|
167
|
+
task: z.string().optional().describe("What to do in the browser"),
|
|
168
|
+
}, async ({ task }) => ({
|
|
169
|
+
messages: [
|
|
170
|
+
{
|
|
171
|
+
role: "user",
|
|
172
|
+
content: {
|
|
173
|
+
type: "text",
|
|
174
|
+
text: task
|
|
175
|
+
? `${BROWSE_PROMPT}\n\n## Task: ${task}`
|
|
176
|
+
: BROWSE_PROMPT,
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
}));
|
|
181
|
+
mcp.prompt("qa-runner", "Run structured QA checklists against a running app via browser automation", {
|
|
182
|
+
checklist: z.string().optional().describe("Path to the QA checklist file, or a requirement ID to search for"),
|
|
183
|
+
}, async ({ checklist }) => ({
|
|
184
|
+
messages: [
|
|
185
|
+
{
|
|
186
|
+
role: "user",
|
|
187
|
+
content: {
|
|
188
|
+
type: "text",
|
|
189
|
+
text: checklist
|
|
190
|
+
? `${QA_RUNNER_PROMPT}\n\n## Run Checklist: ${checklist}`
|
|
191
|
+
: QA_RUNNER_PROMPT,
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gFAqC0D,CAAC;AAEjF,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qFA4H4D,CAAC;AAEtF,MAAM,UAAU,eAAe,CAAC,GAAc;IAC5C,GAAG,CAAC,MAAM,CACR,QAAQ,EACR,sGAAsG,EACtG;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;KAClE,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QACnB,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI;wBACR,CAAC,CAAC,GAAG,aAAa,gBAAgB,IAAI,EAAE;wBACxC,CAAC,CAAC,aAAa;iBAClB;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,GAAG,CAAC,MAAM,CACR,WAAW,EACX,2EAA2E,EAC3E;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kEAAkE,CAAC;KAC9G,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;QACxB,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,SAAS;wBACb,CAAC,CAAC,GAAG,gBAAgB,yBAAyB,SAAS,EAAE;wBACzD,CAAC,CAAC,gBAAgB;iBACrB;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-browser-bridge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "MCP server that bridges AI assistants to the browser via a WebSocket-connected extension",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "tsc",
|
|
14
14
|
"dev": "tsc --watch",
|
|
15
|
+
"test": "vitest run",
|
|
16
|
+
"test:watch": "vitest",
|
|
15
17
|
"prepublishOnly": "npm run build"
|
|
16
18
|
},
|
|
17
19
|
"engines": {
|
|
@@ -43,6 +45,7 @@
|
|
|
43
45
|
"@types/node": "^22.13.4",
|
|
44
46
|
"@types/uuid": "^10.0.0",
|
|
45
47
|
"@types/ws": "^8.18.0",
|
|
46
|
-
"typescript": "^5.7.3"
|
|
48
|
+
"typescript": "^5.7.3",
|
|
49
|
+
"vitest": "^4.1.4"
|
|
47
50
|
}
|
|
48
51
|
}
|