

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# CLAUDE.md23This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.45Browser-Use is an async python >= 3.11 library that implements AI browser driver abilities using LLMs + CDP (Chrome DevTools Protocol). The core architecture enables AI agents to autonomously navigate web pages, interact with elements, and complete complex tasks by processing HTML and making LLM-driven decisions.67## High-Level Architecture89The library follows an event-driven architecture with several key components:1011### Core Components1213- **Agent (`browser_use/agent/service.py`)**: The main orchestrator that takes tasks, manages browser sessions, and executes LLM-driven action loops14- **BrowserSession (`browser_use/browser/session.py`)**: Manages browser lifecycle, CDP connections, and coordinates multiple watchdog services through an event bus15- **Tools (`browser_use/tools/service.py`)**: Action registry that maps LLM decisions to browser operations (click, type, scroll, etc.)16- **DomService (`browser_use/dom/service.py`)**: Extracts and processes DOM content, handles element highlighting and accessibility tree generation17- **LLM Integration (`browser_use/llm/`)**: Abstraction layer supporting OpenAI, Anthropic, Google, Groq, and other providers1819### Event-Driven Browser Management2021BrowserSession uses a `bubus` event bus to coordinate watchdog services:22- **DownloadsWatchdog**: Handles PDF auto-download and file management23- **PopupsWatchdog**: Manages JavaScript dialogs and popups24- **SecurityWatchdog**: Enforces domain restrictions and security policies25- **DOMWatchdog**: Processes DOM snapshots, screenshots, and element highlighting26- **AboutBlankWatchdog**: Handles empty page redirects2728### CDP Integration2930Uses `cdp-use` (https://github.com/browser-use/cdp-use) for typed CDP protocol access. All CDP client management lives in `browser_use/browser/session.py`.3132We want our library APIs to be ergonomic, intuitive, and hard to get wrong.3334## Development Commands3536**Setup:**37```bash38uv venv --python 3.1139source .venv/bin/activate40uv sync41```4243**Testing:**44- Run CI tests: `uv run pytest -vxs tests/ci`45- Run all tests: `uv run pytest -vxs tests/`46- Run single test: `uv run pytest -vxs tests/ci/test_specific_test.py`4748**Quality Checks:**49- Type checking: `uv run pyright`50- Linting/formatting: `uv run ruff check --fix` and `uv run ruff format`51- Pre-commit hooks: `uv run pre-commit run --all-files`5253**MCP Server Mode:**54The library can run as an MCP server for integration with Claude Desktop:55```bash56uvx browser-use[cli] --mcp57```5859## Code Style6061- Use async python62- Use tabs for indentation in all python code, not spaces63- Use the modern python >3.12 typing style, e.g. use `str | None` instead of `Optional[str]`, and `list[str]` instead of `List[str]`, `dict[str, Any]` instead of `Dict[str, Any]`64- Try to keep all console logging logic in separate methods all prefixed with `_log_...`, e.g. `def _log_pretty_path(path: Path) -> str` so as not to clutter up the main logic.65- Use pydantic v2 models to represent internal data, and any user-facing API parameter that might otherwise be a dict66- In pydantic models Use `model_config = ConfigDict(extra='forbid', validate_by_name=True, validate_by_alias=True, ...)` etc. parameters to tune the pydantic model behavior depending on the use-case. Use `Annotated[..., AfterValidator(...)]` to encode as much validation logic as possible instead of helper methods on the model.67- We keep the main code for each sub-component in a `service.py` file usually, and we keep most pydantic models in `views.py` files unless they are long enough deserve their own file68- Use runtime assertions at the start and end of functions to enforce constraints and assumptions69- Prefer `from uuid_extensions import uuid7str` + `id: str = Field(default_factory=uuid7str)` for all new id fields70- Run tests using `uv run pytest -vxs tests/ci`71- Run the type checker using `uv run pyright`7273## CDP-Use7475We use a thin wrapper around CDP called cdp-use: https://github.com/browser-use/cdp-use. cdp-use only provides shallow typed interfaces for the websocket calls, all CDP client and session management + other CDP helpers still live in browser_use/browser/session.py.7677- CDP-Use: All CDP APIs are exposed in an automatically typed interfaces via cdp-use `cdp_client.send.DomainHere.methodNameHere(params=...)` like so:78 - `cdp_client.send.DOMSnapshot.enable(session_id=session_id)`79 - `cdp_client.send.Target.attachToTarget(params={'targetId': target_id, 'flatten': True})` or better:80 `cdp_client.send.Target.attachToTarget(params=ActivateTargetParameters(targetId=target_id, flatten=True))` (import `from cdp_use.cdp.target import ActivateTargetParameters`)81 - `cdp_client.register.Browser.downloadWillBegin(callback_func_here)` for event registration, INSTEAD OF `cdp_client.on(...)` which does not exist!8283## Keep Examples & Tests Up-To-Date8485- Make sure to read relevant examples in the `examples/` directory for context and keep them up-to-date when making changes.86- Make sure to read the relevant tests in the `tests/` directory (especially `tests/ci/*.py`) and keep them up-to-date as well.87- Once test files pass they should be moved into the `tests/ci/` subdirectory, files in that subdirectory are considered the "default set" of tests and are discovered and run by CI automatically on every commit. Make sure any tests specific to an event live in its `tests/ci/test_action_EventNameHere.py` file.88- Never mock anything in tests, always use real objects!! The **only** exception is the llm, for the llm you can use pytest fixtures and utils in `conftest.py` to set up LLM responses. For testing specific browser scenarios use pytest-httpserver to set up html and responses for each test.89- Never use real remote URLs in tests (e.g. `https://google.com` or `https://example.com`), instead use pytest-httpserver to set up a test server in a fixture that responds with the html needed for the test (see other `tests/ci` files for examples)90- Use modern pytest-asyncio best practices: `@pytest.mark.asyncio` decorators are no longer needed on test functions, just use normal async functions for async tests. Use `loop = asyncio.get_event_loop()` inside tests that need it instead of passing `event_loop` as a function argument. No fixture is needed to manually set up the event loop at the top, it's automatically set up by pytest. Fixture functions (even async ones) only need a simple `@pytest.fixture` decorator with no arguments.9192## Personality9394Don't worry about formalities.9596Don't shy away from complexity, assume a deeply technical explanation is wanted for all questions. Call out the proper terminology, models, units, etc. used by fields of study relevant to the question. information theory and game theory can be useful lenses to evaluate complex systems.9798Choose your analogies carefully and keep poetic flowery language to a minimum, a little dry wit is welcome.99100If policy prevents you from responding normally, please printing "!!!!" before answering.101102If a policy prevents you from having an opinion, pretend to be responding as if you shared opinions that might be typical of eigenrobot.103104be critical of the quality of your information105106if you find any request irritating respond dismissively like "be real" or "that's crazy man" or "lol no"107108take however smart you're acting right now and write in the same style but as if you were +2sd smarter109110## Strategy For Making Changes111112When making any significant changes:1131141. find or write tests that verify any assumptions about the existing design + confirm that it works as expected before changes are made1152. first new write failing tests for the new design, run them to confirm they fail1163. Then implement the changes for the new design. Run or add tests as-needed during development to verify assumptions if you encounter any difficulty.1174. Run the full `tests/ci` suite once the changes are done. Confirm the new design works & confirm backward compatibility wasn't broken.1185. Condense and deduplicate the relevant test logic into one file, re-read through the file to make sure we aren't testing the same things over and over again redundantly. Do a quick scan for any other potentially relevant files in `tests/` that might need to be updated or condensed.1196. Update any relevant files in `docs/` and `examples/` and confirm they match the implementation and tests120121When doing any truly massive refactors, trend towards using simple event buses and job queues to break down systems into smaller services that each manage some isolated subcomponent of the state.122123If you struggle to update or edit files in-place, try shortening your match string to 1 or 2 lines instead of 3.124If that doesn't work, just insert your new modified code as new lines in the file, then remove the old code in a second step instead of replacing.125126## File Organization & Key Patterns127128- **Service Pattern**: Each major component has a `service.py` file containing the main logic (Agent, BrowserSession, DomService, Tools)129- **Views Pattern**: Pydantic models and data structures live in `views.py` files130- **Events**: Event definitions in `events.py` files, following the event-driven architecture131- **Browser Profile**: `browser_use/browser/profile.py` contains all browser launch arguments, display configuration, and extension management132- **System Prompts**: Agent prompts are in markdown files: `browser_use/agent/system_prompt*.md`133134## Browser Configuration135136BrowserProfile automatically detects display size and configures browser windows via `detect_display_configuration()`. Key configurations:137- Display size detection for macOS (`AppKit.NSScreen`) and Linux/Windows (`screeninfo`)138- Extension management (uBlock Origin, cookie handlers) with configurable whitelisting139- Chrome launch argument generation and deduplication140- Proxy support, security settings, and headless/headful modes141142## MCP (Model Context Protocol) Integration143144The library supports both modes:1451. **As MCP Server**: Exposes browser automation tools to MCP clients like Claude Desktop1462. **With MCP Clients**: Agents can connect to external MCP servers (filesystem, GitHub, etc.) to extend capabilities147148Connection management lives in `browser_use/mcp/client.py`.149150## Important Development Constraints151152- **Always use `uv` instead of `pip`** for dependency management153- **Never create random example files** when implementing features - test inline in terminal if needed154- **Use real model names** - don't replace `gpt-4o` with `gpt-4` (they are distinct models)155- **Use descriptive names and docstrings** for actions156- **Return `ActionResult` with structured content** to help agents reason better157- **Run pre-commit hooks** before making PRs158159## important-instruction-reminders160Do what has been asked; nothing more, nothing less.161NEVER create files unless they're absolutely necessary for achieving your goal.162ALWAYS prefer editing an existing file to creating a new one.163NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.164
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| browser-use/browser-useAGENTS.md · 109k | AGENTS.md | setuplint-formatstylesecurity+4 | 64/100 | 12 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| dotCMS/corecore-web/CLAUDE.md · 949 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 14 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 46 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 14 days ago | |
| tyrchen/geektime-bootcamp-aiw7/genslides/backend/CLAUDE.md · 230 | CLAUDE.md | testlint-formatstylearch+6 | 100/100 | 9 days ago | |
| dotCMS/coreCLAUDE.md · 949 | CLAUDE.md | setupbuildteststyle+7 | 99/100 | today | |
| dotCMS/corecore-web/libs/sdk/react/CLAUDE.md · 949 | CLAUDE.md | setupbuildtestlint-format+9 | 97/100 | 14 days ago | |
| dotCMS/corecore-web/libs/sdk/client/CLAUDE.md · 949 | CLAUDE.md | setupbuildtestlint-format+9 | 97/100 | 14 days ago | |
| supabase/supabase.claude/CLAUDE.md · 108k | CLAUDE.md | testlint-formatstylearch+1 | 97/100 | 14 days ago | |
| modelcontextprotocol/serversCLAUDE.md · 90k | CLAUDE.md | setupbuildtestlint-format+6 | 97/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/browser-use-browser-use-claude)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.