browsercontrol 0.1.3__tar.gz → 0.1.4__tar.gz

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.
Files changed (43) hide show
  1. browsercontrol-0.1.4/.claude/settings.local.json +10 -0
  2. browsercontrol-0.1.4/.github/workflows/ci.yml +135 -0
  3. browsercontrol-0.1.4/.github/workflows/dependency-review.yml +39 -0
  4. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/.gitignore +2 -0
  5. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/.pre-commit-config.yaml +0 -8
  6. browsercontrol-0.1.4/CLAUDE.md +114 -0
  7. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/PKG-INFO +162 -14
  8. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/README.md +161 -13
  9. browsercontrol-0.1.4/assets/logo-main.png +0 -0
  10. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/__init__.py +1 -1
  11. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/__main__.py +1 -1
  12. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/browser.py +171 -124
  13. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/config.py +6 -4
  14. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/server.py +2 -1
  15. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/tools/content.py +7 -10
  16. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/tools/devtools.py +32 -54
  17. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/tools/forms.py +23 -6
  18. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/tools/interaction.py +29 -8
  19. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/tools/navigation.py +9 -4
  20. browsercontrol-0.1.4/browsercontrol/tools/recording.py +166 -0
  21. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/pyproject.toml +21 -1
  22. browsercontrol-0.1.4/tests/test_browser.py +367 -0
  23. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/tests/test_content.py +9 -9
  24. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/tests/test_devtools.py +33 -23
  25. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/tests/test_forms.py +22 -11
  26. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/tests/test_interaction.py +27 -14
  27. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/tests/test_navigation.py +9 -9
  28. browsercontrol-0.1.4/tests/test_recording.py +168 -0
  29. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/tests/test_tabs.py +5 -5
  30. browsercontrol-0.1.4/uv.lock +2085 -0
  31. browsercontrol-0.1.3/assets/logo.png +0 -0
  32. browsercontrol-0.1.3/browsercontrol/tools/recording.py +0 -230
  33. browsercontrol-0.1.3/node_modules/.cache/prettier/.prettier-caches/91665f0f9d7600991a6f27263bd495571952d52f.json +0 -1
  34. browsercontrol-0.1.3/tests/test_browser.py +0 -232
  35. browsercontrol-0.1.3/tests/test_recording.py +0 -114
  36. browsercontrol-0.1.3/uv.lock +0 -2001
  37. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/CODE_QUALITY.md +0 -0
  38. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/CONTRIBUTING.md +0 -0
  39. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/LICENSE +0 -0
  40. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/tools/__init__.py +0 -0
  41. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/browsercontrol/tools/tabs.py +0 -0
  42. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/tests/__init__.py +0 -0
  43. {browsercontrol-0.1.3 → browsercontrol-0.1.4}/tests/conftest.py +0 -0
@@ -0,0 +1,10 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(uv run *)",
5
+ "Bash(xargs cat -n)",
6
+ "Bash(git show-ref *)"
7
+ ]
8
+ },
9
+ "prefersReducedMotion": false
10
+ }
@@ -0,0 +1,135 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v4
15
+ with:
16
+ fetch-depth: 0
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v3
20
+ with:
21
+ version: "latest"
22
+
23
+ - name: Install dependencies
24
+ run: uv sync --all-extras
25
+
26
+ - name: Run pre-commit hooks
27
+ run: uv run pre-commit run --all-files
28
+
29
+ - name: Run ruff check
30
+ run: uv run ruff check .
31
+
32
+ - name: Run ruff format check
33
+ run: uv run ruff format --check .
34
+
35
+ test:
36
+ runs-on: ubuntu-latest
37
+ needs: lint
38
+ steps:
39
+ - name: Checkout
40
+ uses: actions/checkout@v4
41
+
42
+ - name: Install uv
43
+ uses: astral-sh/setup-uv@v3
44
+ with:
45
+ version: "latest"
46
+
47
+ - name: Install dependencies
48
+ run: uv sync --all-extras
49
+
50
+ - name: Install Playwright browsers
51
+ run: uv run playwright install chromium --with-deps
52
+
53
+ - name: Run tests
54
+ run: uv run pytest -v
55
+
56
+ # Test on Windows and macOS as well
57
+ test-windows:
58
+ runs-on: windows-latest
59
+ needs: lint
60
+ steps:
61
+ - name: Checkout
62
+ uses: actions/checkout@v4
63
+
64
+ - name: Install uv
65
+ uses: astral-sh/setup-uv@v3
66
+ with:
67
+ version: "latest"
68
+
69
+ - name: Install dependencies
70
+ run: uv sync --all-extras
71
+
72
+ - name: Install Playwright browsers
73
+ run: uv run playwright install chromium
74
+
75
+ - name: Run tests
76
+ run: uv run pytest -v
77
+
78
+ test-macos:
79
+ runs-on: macos-latest
80
+ needs: lint
81
+ steps:
82
+ - name: Checkout
83
+ uses: actions/checkout@v4
84
+
85
+ - name: Install uv
86
+ uses: astral-sh/setup-uv@v3
87
+ with:
88
+ version: "latest"
89
+
90
+ - name: Install dependencies
91
+ run: uv sync --all-extras
92
+
93
+ - name: Install Playwright browsers
94
+ run: uv run playwright install chromium
95
+
96
+ - name: Run tests
97
+ run: uv run pytest -v
98
+
99
+ security:
100
+ runs-on: ubuntu-latest
101
+ needs: lint
102
+ steps:
103
+ - name: Checkout
104
+ uses: actions/checkout@v4
105
+ with:
106
+ fetch-depth: 0
107
+
108
+ - name: Install uv
109
+ uses: astral-sh/setup-uv@v3
110
+ with:
111
+ version: "latest"
112
+
113
+ - name: Install dependencies
114
+ run: uv sync --all-extras
115
+
116
+ - name: Run bandit security checks
117
+ run: uv run bandit -c pyproject.toml -r . --exclude ./tests,./.venv
118
+
119
+ type-check:
120
+ runs-on: ubuntu-latest
121
+ needs: lint
122
+ steps:
123
+ - name: Checkout
124
+ uses: actions/checkout@v4
125
+
126
+ - name: Install uv
127
+ uses: astral-sh/setup-uv@v3
128
+ with:
129
+ version: "latest"
130
+
131
+ - name: Install dependencies
132
+ run: uv sync --all-extras
133
+
134
+ - name: Run mypy (if type hints are used)
135
+ run: uv run mypy browsercontrol/ || echo "No mypy configuration found"
@@ -0,0 +1,39 @@
1
+ # Dependency Review Action
2
+ #
3
+ # This Action will scan dependency manifest files that change as part of a Pull Request,
4
+ # surfacing known-vulnerable versions of the packages declared or updated in the PR.
5
+ # Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable
6
+ # packages will be blocked from merging.
7
+ #
8
+ # Source repository: https://github.com/actions/dependency-review-action
9
+ # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
10
+ name: "Dependency review"
11
+ on:
12
+ pull_request:
13
+ branches: ["main"]
14
+
15
+ # If using a dependency submission action in this workflow this permission will need to be set to:
16
+ #
17
+ # permissions:
18
+ # contents: write
19
+ #
20
+ # https://docs.github.com/en/enterprise-cloud@latest/code-security/supply-chain-security/understanding-your-software-supply-chain/using-the-dependency-submission-api
21
+ permissions:
22
+ contents: read
23
+ # Write permissions for pull-requests are required for using the `comment-summary-in-pr` option, comment out if you aren't using this option
24
+ pull-requests: write
25
+
26
+ jobs:
27
+ dependency-review:
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - name: "Checkout repository"
31
+ uses: actions/checkout@v4
32
+ - name: "Dependency Review"
33
+ uses: actions/dependency-review-action@v4
34
+ # Commonly enabled options, see https://github.com/actions/dependency-review-action#configuration-options for all available options.
35
+ with:
36
+ comment-summary-in-pr: always
37
+ # fail-on-severity: moderate
38
+ # deny-licenses: GPL-1.0-or-later, LGPL-2.0-or-later
39
+ # retry-on-snapshot-warnings: true
@@ -11,3 +11,5 @@ dist/
11
11
 
12
12
  # Virtual environments
13
13
  .venv/
14
+ .ruff_cache/
15
+ .pytest_cache/
@@ -25,14 +25,6 @@ repos:
25
25
  - id: mixed-line-ending
26
26
  args: [--fix=lf]
27
27
 
28
- # Markdown formatting
29
- - repo: https://github.com/pre-commit/mirrors-prettier
30
- rev: v4.0.0-alpha.8
31
- hooks:
32
- - id: prettier
33
- types_or: [markdown, yaml, json]
34
- exclude: ^(uv\.lock|\.vscode/)
35
-
36
28
  # Python security checks
37
29
  - repo: https://github.com/PyCQA/bandit
38
30
  rev: 1.8.0
@@ -0,0 +1,114 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Overview
6
+
7
+ BrowserControl is an MCP (Model Context Protocol) server that gives AI agents
8
+ vision-first browser automation via Playwright. Its defining idea is **Set of
9
+ Marks (SoM)**: every action returns an annotated screenshot where interactive
10
+ elements are overlaid with numbered red boxes, so the agent acts by referring to
11
+ an element's number (`click(7)`) instead of CSS selectors or XPath.
12
+
13
+ ## Commands
14
+
15
+ This project uses `uv` for all dependency and task management.
16
+
17
+ ```bash
18
+ uv sync # Install deps (use --all-extras in CI to include dev group)
19
+ uv run playwright install chromium # One-time: install the browser engine
20
+
21
+ uv run pytest # Run all tests
22
+ uv run pytest tests/test_navigation.py # Run a single test file
23
+ uv run pytest tests/test_navigation.py::TestScroll::test_scroll_down_medium # Single test
24
+ uv run pytest --cov=browsercontrol # With coverage
25
+
26
+ uv run ruff check . # Lint
27
+ uv run ruff check . --fix # Lint + autofix
28
+ uv run ruff format . # Format (line length 100, double quotes)
29
+ uv run mypy browsercontrol/ # Type-check (strict mode)
30
+ uv run bandit -c pyproject.toml -r . --exclude ./tests,./.venv # Security scan
31
+ uv run pre-commit run --all-files # Run every hook (mirrors the CI lint job)
32
+
33
+ uv run fastmcp dev browsercontrol/server.py # Run the server in dev mode with inspector
34
+ browsercontrol # Run the installed server (also: python -m browsercontrol)
35
+ ```
36
+
37
+ CI (`.github/workflows/ci.yml`) gates on the lint job first, then runs tests on
38
+ Linux/Windows/macOS plus bandit and mypy. Run `ruff check`, `ruff format`, and
39
+ `pytest` locally before pushing.
40
+
41
+ ## Architecture
42
+
43
+ The flow is: agent calls an MCP tool → tool drives the Playwright page → a fresh
44
+ annotated screenshot + element map is captured → both are returned to the agent.
45
+
46
+ **`browser.py` — the heart of the system.** Exposes a single module-global
47
+ `browser = BrowserManager()` instance and a module-global `element_map` dict.
48
+ Key behaviors to understand before touching anything:
49
+
50
+ - `screenshot_with_som()` is called at the end of nearly every tool. It takes a
51
+ screenshot, runs `get_interactive_elements()` (injected JS that collects
52
+ visible, on-screen interactive elements and their bounding boxes), draws the
53
+ numbered boxes, and **overwrites the global `element_map`** with 1-indexed IDs.
54
+ - **Element IDs are ephemeral.** They are only valid against the most recent
55
+ screenshot. Any navigation, click, scroll, or screenshot regenerates the map
56
+ and renumbers everything. Tools look up the target via `get_element_map()` and
57
+ return an error listing valid IDs when the ID is missing.
58
+ - The browser uses `launch_persistent_context` against a profile directory
59
+ (`~/.browsercontrol/user_data` by default), so cookies, localStorage, and login
60
+ state persist across server restarts. Launch args include localhost proxy
61
+ bypass to avoid `ERR_CONNECTION_REFUSED`.
62
+ - DevTools data (console logs, network requests, page errors) is captured by
63
+ event listeners attached in `_setup_page_listeners`, auto-wired to every new
64
+ page/popup, and stored in capped in-memory ring buffers on the manager.
65
+
66
+ **`server.py` — composition root.** Creates the `FastMCP` instance, attaches a
67
+ `lifespan` context manager that starts/stops the browser, and calls each
68
+ `register_*_tools(mcp)`. The server-level `instructions` string is the prompt the
69
+ agent sees describing available tools — keep it in sync when adding tools.
70
+
71
+ **`tools/` — one module per category** (navigation, interaction, forms, content,
72
+ devtools, recording, tabs). Each exports a single `register_<category>_tools(mcp)`
73
+ function that defines inner `async` functions decorated with `@mcp.tool()`.
74
+ Conventions every tool follows:
75
+
76
+ - Signature returns `tuple[str, Image]`: a human-readable status string plus the
77
+ annotated screenshot.
78
+ - Starts with `await browser.ensure_started()` (lazily boots the browser if the
79
+ lifespan hasn't, e.g. in some test paths).
80
+ - Ends by building the result via a local `_get_screenshot_with_summary()`
81
+ helper. **This helper is duplicated verbatim in several tool modules** — if you
82
+ change the summary format, update every copy.
83
+
84
+ **`config.py`** — a `Config` dataclass loaded once at import via
85
+ `Config.from_env()` into a global `config`. All settings come from `BROWSER_*`
86
+ and `LOG_LEVEL` env vars (see README for the full table). Because it is read at
87
+ import time, env changes require a server restart.
88
+
89
+ ## Testing conventions
90
+
91
+ Tests **do not launch a real browser** — everything is mocked. The pattern:
92
+
93
+ - `tests/conftest.py` provides `mock_browser_manager` (a fully stubbed
94
+ `BrowserManager`), `mock_page`, `mock_context`, and `sample_element_map`.
95
+ - A test registers the tools onto a throwaway `FastMCP("test")`, then patches the
96
+ module-level `browser` symbol **in that specific tool module** (e.g.
97
+ `patch("browsercontrol.tools.navigation.browser", mock_browser_manager)`) —
98
+ because each tool module does `from browsercontrol.browser import browser`, it
99
+ holds its own reference that must be patched independently.
100
+ - The tool callable is reached through FastMCP internals:
101
+ `mcp_server._tool_manager._tools["navigate_to"].fn(...)`.
102
+ - `asyncio_mode = "auto"` is set, so `async def test_*` runs without an explicit
103
+ marker (though existing tests also add `@pytest.mark.asyncio`).
104
+
105
+ When adding a tool, add a test covering both the happy path and graceful error
106
+ handling, following the existing per-module test files.
107
+
108
+ ## Conventions
109
+
110
+ - Python 3.11+. Type hints are required and checked by mypy in **strict** mode
111
+ (`disallow_untyped_defs`, etc.) — annotate fully.
112
+ - Commits follow Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`).
113
+ - Pre-commit hooks (ruff, prettier for md/yaml/json, bandit) run on commit;
114
+ `git commit --no-verify` bypasses them but CI will still enforce them.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: browsercontrol
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: MCP server for browser automation with Set of Marks (SoM) - AI agents can see and interact with web pages using numbered element IDs
5
5
  Project-URL: Homepage, https://github.com/adityasasidhar/browsercontrol
6
6
  Project-URL: Repository, https://github.com/adityasasidhar/browsercontrol
@@ -25,7 +25,7 @@ Requires-Dist: playwright>=1.49.0
25
25
  Description-Content-Type: text/markdown
26
26
 
27
27
  <p align="center">
28
- <img src="https://raw.githubusercontent.com/adityasasidhar/browsercontrol/main/assets/logo.png" alt="BrowserControl" width="140">
28
+ <img src="assets/logo-main.png" alt="BrowserControl" width="140">
29
29
  </p>
30
30
 
31
31
  <h1 align="center">BrowserControl</h1>
@@ -145,12 +145,18 @@ python -m browsercontrol
145
145
  fastmcp run browsercontrol.server:mcp
146
146
  ```
147
147
 
148
- ### Connect to Claude Desktop
148
+ ### Connect to Your AI Agent
149
149
 
150
- Add to your Claude configuration file:
150
+ BrowserControl works with any MCP-compatible AI agent or IDE. Choose your platform:
151
151
 
152
152
  <details>
153
- <summary><b>📁 macOS</b> — <code>~/Library/Application Support/Claude/claude_desktop_config.json</code></summary>
153
+ <summary><b>Claude Desktop</b></summary>
154
+
155
+ Add to your Claude configuration file:
156
+
157
+ **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
158
+ **Linux:** `~/.config/Claude/claude_desktop_config.json`
159
+ **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
154
160
 
155
161
  ```json
156
162
  {
@@ -162,17 +168,75 @@ Add to your Claude configuration file:
162
168
  }
163
169
  ```
164
170
 
171
+ Restart Claude Desktop, then ask:
172
+
173
+ > _"Go to GitHub and star the browsercontrol repo"_
174
+
165
175
  </details>
166
176
 
167
177
  <details>
168
- <summary><b>📁 Linux</b> <code>~/.config/Claude/claude_desktop_config.json</code></summary>
178
+ <summary><b>� Gemini CLI / Google AI Studio</b></summary>
179
+
180
+ If using the Gemini CLI or Google AI Studio with MCP support:
181
+
182
+ ```bash
183
+ # Set up MCP configuration
184
+ export MCP_SERVERS='{"browsercontrol": {"command": "browsercontrol"}}'
185
+
186
+ # Or add to your Gemini config file
187
+ ```
188
+
189
+ For Google AI Studio, configure in the MCP settings panel.
190
+
191
+ </details>
192
+
193
+ <details>
194
+ <summary><b>🔧 Cline (VS Code Extension)</b></summary>
195
+
196
+ 1. Install the [Cline extension](https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev)
197
+ 2. Open Cline settings (gear icon)
198
+ 3. Navigate to "MCP Servers"
199
+ 4. Add a new server:
169
200
 
170
201
  ```json
171
202
  {
172
- "mcpServers": {
173
- "browsercontrol": {
203
+ "browsercontrol": {
204
+ "command": "browsercontrol"
205
+ }
206
+ }
207
+ ```
208
+
209
+ </details>
210
+
211
+ <details>
212
+ <summary><b>🤖 Continue.dev (VS Code/JetBrains)</b></summary>
213
+
214
+ Add to your Continue configuration (`~/.continue/config.json`):
215
+
216
+ ```json
217
+ {
218
+ "mcpServers": [
219
+ {
220
+ "name": "browsercontrol",
174
221
  "command": "browsercontrol"
175
222
  }
223
+ ]
224
+ }
225
+ ```
226
+
227
+ </details>
228
+
229
+ <details>
230
+ <summary><b>🎯 Cursor IDE</b></summary>
231
+
232
+ 1. Open Cursor Settings
233
+ 2. Navigate to "Features" → "Model Context Protocol"
234
+ 3. Add server configuration:
235
+
236
+ ```json
237
+ {
238
+ "browsercontrol": {
239
+ "command": "browsercontrol"
176
240
  }
177
241
  }
178
242
  ```
@@ -180,13 +244,79 @@ Add to your Claude configuration file:
180
244
  </details>
181
245
 
182
246
  <details>
183
- <summary><b>📁 Windows</b> — <code>%APPDATA%\Claude\claude_desktop_config.json</code></summary>
247
+ <summary><b>🔌 Zed Editor</b></summary>
248
+
249
+ Add to your Zed settings (`~/.config/zed/settings.json`):
250
+
251
+ ```json
252
+ {
253
+ "context_servers": {
254
+ "browsercontrol": {
255
+ "command": {
256
+ "path": "browsercontrol"
257
+ }
258
+ }
259
+ }
260
+ }
261
+ ```
262
+
263
+ </details>
264
+
265
+ <details>
266
+ <summary><b>🐍 Custom Python Integration</b></summary>
267
+
268
+ Use the MCP Python SDK to integrate BrowserControl into your own agent:
269
+
270
+ ```python
271
+ from mcp import ClientSession, StdioServerParameters
272
+ from mcp.client.stdio import stdio_client
273
+
274
+ # Connect to BrowserControl
275
+ server_params = StdioServerParameters(
276
+ command="browsercontrol",
277
+ args=[],
278
+ )
279
+
280
+ async with stdio_client(server_params) as (read, write):
281
+ async with ClientSession(read, write) as session:
282
+ # Initialize
283
+ await session.initialize()
284
+
285
+ # List available tools
286
+ tools = await session.list_tools()
287
+
288
+ # Call a tool
289
+ result = await session.call_tool("navigate_to", {
290
+ "url": "https://github.com"
291
+ })
292
+ ```
293
+
294
+ </details>
295
+
296
+ <details>
297
+ <summary><b>🚀 Using with uv or pipx</b></summary>
298
+
299
+ If you installed with `uv` or `pipx`, use the full path:
184
300
 
185
301
  ```json
186
302
  {
187
303
  "mcpServers": {
188
304
  "browsercontrol": {
189
- "command": "browsercontrol"
305
+ "command": "uvx",
306
+ "args": ["browsercontrol"]
307
+ }
308
+ }
309
+ }
310
+ ```
311
+
312
+ Or with pipx:
313
+
314
+ ```json
315
+ {
316
+ "mcpServers": {
317
+ "browsercontrol": {
318
+ "command": "pipx",
319
+ "args": ["run", "browsercontrol"]
190
320
  }
191
321
  }
192
322
  }
@@ -194,11 +324,30 @@ Add to your Claude configuration file:
194
324
 
195
325
  </details>
196
326
 
197
- Then ask Claude:
327
+ <details>
328
+ <summary><b>🔧 Advanced Configuration</b></summary>
198
329
 
199
- > _"Go to GitHub and star the browsercontrol repo"_
330
+ You can pass environment variables to customize BrowserControl:
200
331
 
201
- Claude will navigate, find the star button, and click it—showing you screenshots along the way!
332
+ ```json
333
+ {
334
+ "mcpServers": {
335
+ "browsercontrol": {
336
+ "command": "browsercontrol",
337
+ "env": {
338
+ "BROWSER_HEADLESS": "false",
339
+ "BROWSER_VIEWPORT_WIDTH": "1920",
340
+ "BROWSER_VIEWPORT_HEIGHT": "1080",
341
+ "LOG_LEVEL": "DEBUG"
342
+ }
343
+ }
344
+ }
345
+ }
346
+ ```
347
+
348
+ See [Configuration](#-configuration) for all available options.
349
+
350
+ </details>
202
351
 
203
352
  <br>
204
353
 
@@ -307,7 +456,6 @@ Test responsive designs or emulate mobile screens on the fly:
307
456
  | `press_key(key)` | Press keyboard key (Enter, Tab, etc.) |
308
457
  | `hover(element_id)` | Hover over element |
309
458
  | `scroll_to_element(element_id)` | Scroll element into view |
310
- | `upload_file(element_id, path)` | Upload a file to an input |
311
459
  | `wait(seconds)` | Wait for page loading |
312
460
 
313
461
  ### Tab Management