weboperator-mcp 1.5.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Artem KK
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # weboperator-mcp
2
+
3
+ MCP server that hands your **live Chrome tab** to any agent client — Claude Desktop, Cursor, Hermes, OpenClaw, OpenHands. Speaks MCP over stdio.
4
+
5
+ It drives the browser you are already signed into, so your sessions, cookies, and extensions come along. Nothing is launched headless and nothing leaves the machine.
6
+
7
+ ## Tools
8
+
9
+ `browser_snapshot` · `browser_navigate` · `browser_click` · `browser_type` · `browser_press` · `browser_scroll` · `browser_screenshot` · `browser_extract` · `browser_solve_captcha` · `weboperator_execute_goal`
10
+
11
+ `browser_snapshot` returns an accessibility tree with numbered interactive elements; the action tools take those numbers, so an agent never guesses at CSS selectors.
12
+
13
+ ## Install
14
+
15
+ The server talks to Chrome through the [WebOperator extension](https://github.com/KazKozDev/WebOperator) and a Native Messaging host, so install the extension first, then register the host:
16
+
17
+ ```bash
18
+ npx -p weboperator-mcp weboperator-bridge-install
19
+ ```
20
+
21
+ Then point your client at the server:
22
+
23
+ ```json
24
+ {
25
+ "mcpServers": {
26
+ "weboperator": {
27
+ "command": "npx",
28
+ "args": ["-y", "weboperator-mcp"]
29
+ }
30
+ }
31
+ }
32
+ ```
33
+
34
+ Reload the extension in `chrome://extensions` after registering the host.
35
+
36
+ ## Configuration
37
+
38
+ | Variable | Default | What it does |
39
+ | --- | --- | --- |
40
+ | `WEBOPERATOR_BRIDGE_PORT` | `8765` | Port of the local bridge HTTP API |
41
+ | `WEBOPERATOR_BRIDGE_HOST` | `127.0.0.1` | Bridge bind address |
42
+ | `WEBOPERATOR_AGENT_SOCKET` | `/tmp/weboperator-bridge.sock` | Unix socket the bridge listens on |
43
+ | `WEBOPERATOR_API_TOKEN` | _(unset)_ | Shared token, required when unauthenticated bridge access is disabled |
44
+
45
+ macOS and Linux. Chrome, Chromium, Brave, Edge, and Arc are all registered by the installer.
46
+
47
+ ## Security
48
+
49
+ Page content is treated as data, never as instructions — the extension's prompt-injection fixtures live in [`evals/fixtures/`](https://github.com/KazKozDev/WebOperator/tree/main/evals/fixtures). `browser_solve_captcha` pauses for you rather than defeating a challenge, and login flows stop for a human instead of typing credentials.
50
+
51
+ MIT © Artem KK · [full documentation](https://github.com/KazKozDev/WebOperator)
package/SKILL.md ADDED
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: weboperator
3
+ description: "Control and automate the live browser (Brave, Chrome) via the WebOperator MCP server. Navigate websites, search, click, type, scroll, take screenshots, extract data, or run autonomous goals directly in the user's active browser."
4
+ version: 1.4.0
5
+ author: WebOperator
6
+ license: MIT
7
+ platforms: [macos, linux, windows]
8
+ metadata:
9
+ hermes:
10
+ tags: [Browser-Automation, WebOperator, MCP, Chrome, Brave, Web-Navigation, Live-Browser]
11
+ ---
12
+
13
+ # WebOperator Browser Automation Skill
14
+
15
+ WebOperator connects Hermes directly to the user's live browser (Brave Browser, Google Chrome) via MCP.
16
+
17
+ > [!IMPORTANT]
18
+ > When the user asks to open a site, search in the browser, scroll, click, or mentions "вебоператор" / "WebOperator", **ALWAYS** use the `mcp__weboperator__*` tools.
19
+ > **DO NOT** use Firecrawl or built-in `web_search`/`web_extract` when the user refers to WebOperator or wants browser automation.
20
+
21
+ ---
22
+
23
+ ## Available MCP Tools
24
+
25
+ All tools are prefixed with `mcp__weboperator__`:
26
+
27
+ ### 1. `mcp__weboperator__browser_navigate`
28
+ Navigate the active tab to a specific URL.
29
+ ```json
30
+ {
31
+ "url": "https://www.google.com"
32
+ }
33
+ ```
34
+
35
+ ### 2. `mcp__weboperator__browser_snapshot`
36
+ Capture the interactive accessibility tree with numbered element IDs (`@1`, `@2`, etc.) from the active tab.
37
+ ```json
38
+ {}
39
+ ```
40
+
41
+ ### 3. `mcp__weboperator__browser_click`
42
+ Click an interactive element by its index from `browser_snapshot` or CSS selector.
43
+ ```json
44
+ {
45
+ "index": 2
46
+ }
47
+ ```
48
+
49
+ ### 4. `mcp__weboperator__browser_type`
50
+ Type text into an input field.
51
+ ```json
52
+ {
53
+ "index": 1,
54
+ "text": "auriculares baratos",
55
+ "clear": true
56
+ }
57
+ ```
58
+
59
+ ### 5. `mcp__weboperator__browser_press`
60
+ Press a keyboard key (e.g. Enter, Tab, Escape).
61
+ ```json
62
+ {
63
+ "key": "Enter"
64
+ }
65
+ ```
66
+
67
+ ### 6. `mcp__weboperator__browser_scroll`
68
+ Scroll the active webpage up or down.
69
+ ```json
70
+ {
71
+ "direction": "down",
72
+ "amount": 500
73
+ }
74
+ ```
75
+
76
+ ### 7. `mcp__weboperator__browser_screenshot`
77
+ Capture a visual PNG screenshot of the active browser viewport.
78
+ ```json
79
+ {}
80
+ ```
81
+
82
+ ### 8. `mcp__weboperator__browser_extract`
83
+ Extract structured text content or answers from the active page.
84
+ ```json
85
+ {
86
+ "instruction": "Extract list of top 5 products with prices"
87
+ }
88
+ ```
89
+
90
+ ### 9. `mcp__weboperator__browser_solve_captcha`
91
+ Attempt to detect and automatically pass or click Cloudflare Turnstile, reCAPTCHA, or hCaptcha verification challenges on the active page.
92
+ ```json
93
+ {
94
+ "type": "auto"
95
+ }
96
+ ```
97
+
98
+ ### 10. `mcp__weboperator__weboperator_execute_goal`
99
+ Run a high-level autonomous goal in the browser end-to-end using WebOperator's planner.
100
+ ```json
101
+ {
102
+ "goal": "Find headphones under 30 euros on amazon.es and summarize top 3 options",
103
+ "timeoutMs": 120000
104
+ }
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Typical Workflow
110
+
111
+ 1. **Open a site**: Call `mcp__weboperator__browser_navigate` with `url`.
112
+ 2. **Inspect page**: Call `mcp__weboperator__browser_snapshot` to see element numbers and text.
113
+ 3. **Interact**: Call `mcp__weboperator__browser_type` or `mcp__weboperator__browser_click` using the element indices.
114
+ 4. **Scroll / Read**: Call `mcp__weboperator__browser_scroll` or `mcp__weboperator__browser_extract`.
115
+ 5. **Or run autonomous goal**: Call `mcp__weboperator__weboperator_execute_goal` with the full prompt.
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ // WebOperator framed JSON client for agents.
3
+ const net = require('net');
4
+ const { randomUUID } = require('crypto');
5
+
6
+ const socketPath = process.env.WEBOPERATOR_AGENT_SOCKET || '/tmp/weboperator-bridge.sock';
7
+ const token = process.env.WEBOPERATOR_API_TOKEN || '';
8
+ const input = process.argv[2] ? JSON.parse(process.argv[2]) : { type: 'bridge.health' };
9
+ const message = {
10
+ id: input.id || randomUUID(),
11
+ type: input.type || 'bridge.health',
12
+ payload: input.payload || {},
13
+ timeoutMs: input.timeoutMs,
14
+ ...(token ? { token } : {}),
15
+ };
16
+
17
+ let buffer = Buffer.alloc(0);
18
+ let nextFrameLength = null;
19
+ const socket = net.createConnection(socketPath, () => sendFrame(socket, message));
20
+
21
+ socket.on('data', (chunk) => {
22
+ buffer = Buffer.concat([buffer, chunk]);
23
+ readFrames();
24
+ });
25
+ socket.on('error', (err) => {
26
+ console.error(err.message);
27
+ process.exitCode = 1;
28
+ });
29
+
30
+ function readFrames() {
31
+ while (true) {
32
+ if (nextFrameLength === null) {
33
+ if (buffer.length < 4) return;
34
+ nextFrameLength = buffer.readUInt32LE(0);
35
+ buffer = buffer.slice(4);
36
+ }
37
+ if (buffer.length < nextFrameLength) return;
38
+ const payload = buffer.slice(0, nextFrameLength).toString('utf8');
39
+ buffer = buffer.slice(nextFrameLength);
40
+ nextFrameLength = null;
41
+ const msg = JSON.parse(payload);
42
+ if (msg.kind === 'event') {
43
+ console.error(JSON.stringify(msg));
44
+ continue;
45
+ }
46
+ console.log(JSON.stringify(msg, null, 2));
47
+ socket.end();
48
+ }
49
+ }
50
+
51
+ function sendFrame(sock, obj) {
52
+ const body = Buffer.from(JSON.stringify(obj), 'utf8');
53
+ const header = Buffer.alloc(4);
54
+ header.writeUInt32LE(body.length, 0);
55
+ sock.write(Buffer.concat([header, body]));
56
+ }