Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Each sandbox is isolated from the others and can be customized with any dependen

## Examples

- [Browser Use in E2B Desktop](./examples/browser-use-python) — give a coding agent a real browser without wiring screenshot, mouse, and keyboard tools by hand.

**SDK Examples**

- Basic Examples:
Expand Down
1 change: 1 addition & 0 deletions examples/browser-use-python/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
E2B_API_KEY=
33 changes: 33 additions & 0 deletions examples/browser-use-python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Browser Use in E2B Desktop

Run Browser Use inside E2B's graphical sandbox. The example installs an isolated Python 3.12 runtime, starts the Chrome already installed in the desktop template with a temporary profile and local CDP endpoint, then connects Browser Use. Your agent gets browser navigation, DOM inspection, screenshots, clicks, and typing without a custom computer-use loop or remote-debugging approval prompt.

## Run it

```bash
cp .env.example .env
# Add your E2B_API_KEY to .env

uv run main.py
```

The example opens `example.com` inside the E2B Desktop Sandbox, reads the page through Browser Use, and checks the title and heading before Chrome and the sandbox are killed.

## Give the browser to a coding agent

Install the Browser Use skill in the same sandbox image or startup command:

```bash
browser-use skill install
```

Claude Code, Codex, OpenClaw, and other coding agents can then call the `browser-use` CLI directly. The browser stays inside the E2B sandbox.

## Why E2B Desktop instead of a plain sandbox?

The desktop template already has Chrome, its system dependencies, and an X display. A plain E2B sandbox needs a browser and those dependencies installed separately.

## Links

- [E2B Desktop](https://github.com/e2b-dev/desktop)
- [Browser Use CLI skill](https://github.com/browser-use/browser-use/blob/main/browser_use/skills/browser-use/SKILL.md)
67 changes: 67 additions & 0 deletions examples/browser-use-python/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from __future__ import annotations

import os
import shlex
import textwrap

from dotenv import load_dotenv
from e2b_desktop import Sandbox


load_dotenv()

if not os.environ.get("E2B_API_KEY"):
raise RuntimeError("Set E2B_API_KEY in .env before running this example")


browser_task = textwrap.dedent(
"""
set -eu
export PATH="$(python3 -m site --user-base)/bin:$PATH"
python3 -m pip install --user --quiet uv
uv python install 3.12
uv tool install --python 3.12 browser-use

chrome_bin="$(command -v google-chrome || command -v chromium || command -v chromium-browser)"
profile_dir="$(mktemp -d)"
"$chrome_bin" \
--no-sandbox \
--disable-dev-shm-usage \
--no-first-run \
--no-default-browser-check \
--user-data-dir="$profile_dir" \
--remote-debugging-address=127.0.0.1 \
--remote-debugging-port=9222 \
about:blank >/tmp/browser-use-chrome.log 2>&1 &
chrome_pid=$!
trap 'kill "$chrome_pid" 2>/dev/null || true; rm -rf "$profile_dir"' EXIT

for _ in $(seq 1 30); do
curl -fsS http://127.0.0.1:9222/json/version >/dev/null && break
sleep 1
done
export BU_CDP_WS="$(python3 -c 'import json, urllib.request; print(json.load(urllib.request.urlopen("http://127.0.0.1:9222/json/version"))["webSocketDebuggerUrl"])')"

browser-use <<'BH'
new_tab("https://example.com")
wait_for_load()
page = js("({title: document.title, heading: document.querySelector('h1')?.textContent})")
print(page)
# Browser Harness may prefix the tab title with a browser-state indicator.
assert page["title"].endswith("Example Domain"), page
assert page["heading"] == "Example Domain", page
BH
"""
).strip()


desktop = Sandbox.create(timeout=300)
try:
result = desktop.commands.run(
f"bash -lc {shlex.quote(browser_task)}",
envs={"DISPLAY": ":0"},
timeout=240,
)
print(result.stdout)
finally:
desktop.kill()
12 changes: 12 additions & 0 deletions examples/browser-use-python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[project]
name = "browser-use-in-e2b-desktop"
version = "0.1.0"
description = "Run Browser Use inside an E2B Desktop Sandbox"
requires-python = ">=3.11"
dependencies = [
"e2b-desktop>=2.4.2,<3",
"python-dotenv>=1.1,<2",
]

[tool.uv]
package = false
Loading