Skip to content
Merged
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
23 changes: 16 additions & 7 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,34 @@ labels: bug
assignees: ""
---

**Describe the bug** A clear and concise description of what the bug is.
## Describe the bug

**To Reproduce** Steps to reproduce the behavior:
A clear and concise description of what the bug is.

## To Reproduce

Steps to reproduce the behavior:

1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior** A clear and concise description of what you expected to
happen.
Expected behavior

A clear and concise description of what you expected to happen.

**Screenshots** If applicable, add screenshots to help explain your problem.
Screenshots

**Environment (please complete the following information):**
If applicable, add screenshots to help explain your problem.

## Environment (please complete the following information):

- OS: [e.g. macOS, Windows, Linux]
- Version [e.g. 1.2.3]
- Client [if applicable]
- Version [e.g. 1.2.3]

**Additional context** Add any other context about the problem here.
## Additional context

Add any other context about the problem here.
19 changes: 12 additions & 7 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ labels: enhancement
assignees: ""
---

**Is your feature request related to a problem? Please describe.** A clear and
concise description of what the problem is. Ex. I'm always frustrated when [...]
## Is your feature request related to a problem? Please describe.

**Describe the solution you'd like** A clear and concise description of what you
want to happen.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe alternatives you've considered** A clear and concise description of
## Describe the solution you'd like

A clear and concise description of what you want to happen.

## Describe alternatives you've considered

A clear and concise description of
any alternative solutions or features you've considered.

**Additional context** Add any other context or screenshots about the feature
request here.
## Additional context

Add any other context or screenshots about the feature request here.
47 changes: 8 additions & 39 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
---
name: CI

on:
push:
branches: [main]
pull_request:
workflow_dispatch:
branches:
- main
release:
types: [published] # Trigger when a release is published

concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{
Expand All @@ -17,40 +19,14 @@ env:
IMAGE_NAME: ${{ github.repository }}

jobs:
determine_changes:
name: "Determine changes"
runs-on: ubuntu-latest
outputs:
# Flag that is raised when any code is changed
code: ${{ steps.changed.outputs.code_any_changed }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: tj-actions/changed-files@v45
id: changed
with:
files_yaml: |
code:
- "**/*"
- "!docs/**/*"
- "!mkdocs.*.yml"
- "!**/*.md"
- "!bin/**"
- "!assets/**"
- "!dist/**"
# Generated markdown and JSON files are checked during test runs
- "docs/reference/cli.md"
- "docs/reference/settings.md"
- "docs/configuration/environment.md"
- "uv.schema.json"
lint:
timeout-minutes: 10
name: "lint"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1

- uses: actions/setup-python@v5
with:
Expand All @@ -59,28 +35,21 @@ jobs:
- name: "Install uv"
uses: astral-sh/setup-uv@v5

- name: "Prettier"
run: |
npx prettier --check "**/*.{json5,yaml,yml}"
npx prettier --prose-wrap always --check "**/*.md"

- name: "Python format"
run: uvx ruff format --diff .

- name: "Python lint"
run: uvx ruff check .

- name: "Validate project metadata"
run: uvx --from 'validate-pyproject[all,store]' validate-pyproject
pyproject.toml
run: uvx --from 'validate-pyproject[all,store]' validate-pyproject pyproject.toml

build-and-publish:
runs-on: ubuntu-latest

permissions:
contents: read
packages: write
# attestations: write
id-token: write

steps:
Expand Down
58 changes: 58 additions & 0 deletions .github/workflows/mega-linter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
# MegaLinter GitHub Action configuration file
# More info at https://megalinter.io
name: MegaLinter

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions: read-all

env: # Comment env block if you don't want to apply fixes
# Apply linter fixes configuration
APPLY_FIXES: all # When active, APPLY_FIXES must also be defined as environment variable (in github/workflows/mega-linter.yml or other CI tool)
APPLY_FIXES_EVENT: none # Decide which event triggers application of fixes in a commit or a PR (pull_request, push, all)
APPLY_FIXES_MODE: commit # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request)

concurrency:
group: ${{ github.ref }}-${{ github.workflow }}
cancel-in-progress: true

jobs:
megalinter:
name: MegaLinter
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
pull-requests: write
steps:
# Git Checkout
- name: Checkout Code
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances
# MegaLinter
- name: MegaLinter
id: ml
# deployed v8.3.0, https://github.com/oxsecurity/megalinter/releases/tag/v8.3.0
uses: oxsecurity/megalinter@1fc052d03c7a43c78fe0fee19c9d648b749e0c01
env:
# All available variables are described in documentation
# https://megalinter.io/configuration/
VALIDATE_ALL_CODEBASE: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} # Validates all source when push on main, else just the git diff with main. Override with true if you always want to lint all sources
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Upload MegaLinter artifacts
- name: Archive production artifacts
if: success() || failure()
uses: actions/upload-artifact@v4
with:
name: MegaLinter reports
path: |
megalinter-reports
mega-linter.log

3 changes: 3 additions & 0 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
name: Upload Python Package

on:
Expand All @@ -19,6 +20,8 @@ jobs:

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Set up uv and Python
uses: astral-sh/setup-uv@v5
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: Tag and Release

on:
push:
branches:
- main

permissions:
contents: write
issues: write
pull-requests: write

jobs:
release:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Use Node.js
uses: actions/setup-node@v4

- name: Run semantic-release
env:
GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE }}
run: npx semantic-release --branches main --plugins "@semantic-release/commit-analyzer,@semantic-release/release-notes-generator,@semantic-release/github"
21 changes: 21 additions & 0 deletions .mega-linter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
# Configuration file for MegaLinter
# See all available variables at https://megalinter.io/configuration/ and in linters documentation

DISABLE_LINTERS:
- SPELL_CSPELL
- SPELL_LYCHEE

DISABLE_ERRORS_LINTERS:
- COPYPASTE_JSCPD
- DOCKERFILE_HADOLINT
- MARKDOWN_MARKDOWN_LINK_CHECK
- REPOSITORY_CHECKOV
- REPOSITORY_DEVSKIM
- REPOSITORY_KICS
- REPOSITORY_TRIVY

EMAIL_REPORTER: false
FILEIO_REPORTER: false
MARKDOWN_SUMMARY_REPORTER: true
SHOW_ELAPSED_TIME: true
8 changes: 5 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project --no-dev
ADD . /app
COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev

Expand Down Expand Up @@ -52,8 +52,10 @@ RUN apt-get update && \
rm -rf /var/cache/apt/*

# Copy only necessary files from builder
COPY --from=builder --chown=python:python /python /python
COPY --from=builder --chown=app:app /app /app
COPY --from=builder /python /python
COPY --from=builder /app /app
# Set proper permissions
RUN chmod -R 755 /python /app

ENV PATH="/app/.venv/bin:$PATH" \
DISPLAY=:0 \
Expand Down
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ uv tool update-shell

Create a `.env` file:

```
```bash
OPENAI_API_KEY=your-api-key
CHROME_PATH=optional/path/to/chrome
PATIENT=false # Set to true if API calls should wait for task completion
Expand Down Expand Up @@ -65,7 +65,7 @@ browser-use-mcp-server run server --port 8000 --stdio --proxy-port 9000

## Client Configuration

### SSE Mode
### SSE Mode Client Configuration

```json
{
Expand All @@ -77,7 +77,7 @@ browser-use-mcp-server run server --port 8000 --stdio --proxy-port 9000
}
```

### stdio Mode
### stdio Mode Client Configuration

```json
{
Expand Down Expand Up @@ -154,18 +154,29 @@ To develop and test the package locally:

## Docker

Using Docker provides a consistent and isolated environment for running the server.

```bash
# Run with default VNC password
# Build the Docker image
docker build -t browser-use-mcp-server .

# Run the container with the default VNC password ("browser-use")
# --rm ensures the container is automatically removed when it stops
# -p 8000:8000 maps the server port
# -p 5900:5900 maps the VNC port
docker run --rm -p8000:8000 -p5900:5900 browser-use-mcp-server

# Use custom VNC password
echo "your-password" > vnc_password.txt
# Run with a custom VNC password read from a file
# Create a file (e.g., vnc_password.txt) containing only your desired password
echo "your-secure-password" > vnc_password.txt
# Mount the password file as a secret inside the container
docker run --rm -p8000:8000 -p5900:5900 \
-v $(pwd)/vnc_password.txt:/run/secrets/vnc_password \
-v $(pwd)/vnc_password.txt:/run/secrets/vnc_password:ro \
browser-use-mcp-server
```

*Note: The `:ro` flag in the volume mount (`-v`) makes the password file read-only inside the container for added security.*

### VNC Viewer

```bash
Expand All @@ -175,7 +186,7 @@ cd noVNC
./utils/novnc_proxy --vnc localhost:5900
```

Default password: `browser-use`
Default password: `browser-use` (unless overridden using the custom password method)

<div align="center">
<img width="428" alt="VNC Screenshot" src="https://github.com/user-attachments/assets/45bc5bee-418d-4182-94f5-db84b4fc0b3a" />
Expand All @@ -187,7 +198,7 @@ Default password: `browser-use`

Try asking your AI:

```
```text
open https://news.ycombinator.com and return the top ranked article
```

Expand Down