# Extension points — browser-use/browser-use

> Canonical page: https://codevetter.com/unpack/browser-use/extension-points

# Extension points — browser-use/browser-use

Scanned commit d8110c5ff87ccba887aaa726cdb780f2f84bef8d (2026-09-15). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

New behavior is meant to be added as registered actions, not by editing the step loop. Tools.action and Registry.action are the plugin table; special parameter names are the injection API. Browser behavior is extended by watchdogs that subscribe to bubus events. LLM providers plug in through BaseChatModel and get_llm_by_name. Cloud skills, Gmail, and MCP are additional registries on top of the same action or tool list. System prompts are selected markdown files, overridable with override_system_message or extend_system_message.
- Registry.action(description, param_model, domains/allowed_domains, terminates_sequence) is the registration decorator. It normalizes the function to keyword-only, builds a Pydantic param model from the signature when param_model is omitted, and rejects **kwargs. Tools.action is a pass-through to that decorator. — [browser_use/tools/registry/service.py#L75-L166](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/registry/service.py#L75-L166) [browser_use/tools/registry/service.py#L291-L327](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/registry/service.py#L291-L327) [browser_use/tools/service.py#L2102-L2107](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L2102-L2107)
- Injected parameter names recognized by Registry._get_special_param_types are context, browser_session, page_url, cdp_client, page_extraction_llm, available_file_paths, has_sensitive_data, file_system, and extraction_schema. sensitive_data is added to the context only when the action name is input. The docs warn that the name must be browser_session, not browser. — [browser_use/tools/registry/service.py#L57-L73](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/registry/service.py#L57-L73) [browser_use/tools/registry/service.py#L367-L379](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/registry/service.py#L367-L379)
- Registry.exclude_action and Tools.exclude_action remove a name from the action map and block re-registration. Tools.__getattr__ also exposes registered actions as direct methods for tests. — [browser_use/tools/registry/service.py#L42-L55](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/registry/service.py#L42-L55) [browser_use/tools/service.py#L2109-L2118](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L2109-L2118) [browser_use/tools/service.py#L2268-L2274](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L2268-L2274)
- Per-action domain limits are the domains (alias allowed_domains) argument on Registry.action, separate from BrowserProfile.allowed_domains enforced by SecurityWatchdog. Both can be set. — [browser_use/tools/registry/service.py#L291-L320](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/registry/service.py#L291-L320) [browser_use/browser/profile.py#L628-L635](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/profile.py#L628-L635)
- New browser services are watchdogs: a BaseWatchdog subclass with LISTENS_TO and EMITS class vars, constructed and attach_to_session() inside BrowserSession.attach_all_watchdogs. SecurityWatchdog is the template (LISTENS_TO NavigateToUrlEvent, NavigationCompleteEvent, TabCreatedEvent; EMITS BrowserErrorEvent). — [browser_use/browser/watchdogs/security_watchdog.py#L22-L33](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/watchdogs/security_watchdog.py#L22-L33) [browser_use/browser/session.py#L1688-L1766](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/session.py#L1688-L1766)
- LLM extensions implement BaseChatModel and are either imported lazily from browser_use/__init__.py _LAZY_IMPORTS or constructed by get_llm_by_name. Adding a provider requires both a chat module and a branch in that factory if string names should work. — [browser_use/__init__.py#L76-L115](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/__init__.py#L76-L115) [browser_use/llm/models.py#L89-L226](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/llm/models.py#L89-L226) [browser_use/llm/base.py](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/llm/base.py)
- System prompt extension points are override_system_message (replaces the template) and extend_system_message (appended). Otherwise SystemPrompt._load_prompt_template picks a file under browser_use/agent/system_prompts based on is_browser_use_model, flash_mode, is_anthropic, and Anthropic 4.5 caching. — [browser_use/agent/prompts.py#L28-L80](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/prompts.py#L28-L80) [browser_use/agent/service.py#L174-L175](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L174-L175)
- Cloud skills plug in through Agent(skill_ids=...) and SkillService, which turns each API skill into a registry action in _register_skills_as_actions. Gmail plugs in through register_gmail_actions(tools). MCP tools are a separate list built in the MCP server, not the Registry. — [browser_use/skills/service.py#L19-L50](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/skills/service.py#L19-L50) [browser_use/agent/service.py#L836-L836](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L836-L836) [browser_use/integrations/gmail/actions.py#L29-L51](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/integrations/gmail/actions.py#L29-L51) [browser_use/mcp/server.py#L220-L280](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/mcp/server.py#L220-L280)
- Coordinate clicking is a mode switch: Tools.set_coordinate_clicking re-registers the click action. File types are a dict on FileSystem._file_types (md, txt, json, jsonl, csv, pdf, docx, html, xml, png, gif, jpg, jpeg, webp); a new extension means a new BaseFile subclass in that map. — [browser_use/tools/service.py#L2120-L2173](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L2120-L2173) [browser_use/filesystem/file_system.py#L518-L544](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/filesystem/file_system.py#L518-L544)
- Run hooks are on_step_start and on_step_end passed to Agent.run, plus register_new_step_callback, register_done_callback, register_should_stop_callback, and register_external_agent_status_raise_error_callback on the constructor. output_model_schema swaps the done schema via Tools.use_structured_output_action. — [browser_use/agent/service.py#L154-L167](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L154-L167) [browser_use/agent/service.py#L2503-L2508](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L2503-L2508) [browser_use/tools/service.py#L2092-L2107](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L2092-L2107)
- CLI skill targets are the TARGET_DIR_BUILDERS dict. Adding an assistant is a new entry there, not a new command parser. Legacy CLI verbs are the _LEGACY_HINTS dict; new verbs must not collide with those keys or they will be treated as removed 2.x commands. — [browser_use/skills/install.py#L25-L37](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/skills/install.py#L25-L37) [browser_use/cli.py#L206-L238](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/cli.py#L206-L238)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
