Browser Provider Plugins
إضافات مزوّد المتصفح
What this page is, and what it holds.
This page covers Browser Provider Plugins. You will use hermes tools here; about 4 minutes to read. Start on public pages with no sign-in. A browser wired to your accounts acts as you.
How to build a cloud browser backend plugin for Hermes Agent
Outcomes taken from this page, not a template.
- Understand what التحكم في المتصفح is and when you need it.
- Run
hermes toolsand understand what happens next. - Know the common mistake before you hit it.
Exactly as they appear in Hermes.
hermes tools
Jump to the part you need.
Nothing summarised away.
The documentation body below is reproduced from the official source so commands and identifiers stay exact. Each section carries a short note describing what it contains.
Browser provider plugins register a cloud browser backend that services cloud-mode browser_* tool calls (navigate, click, screenshot, …). Built-in providers — Browserbase, Browser Use, and Firecrawl — all ship as plugins under plugins/browser/<name>/. You can add a new one, or override a bundled one, by dropping a directory next to them.
How it fits together
Explains the idea itself. Read it slowly; the later sections build on it.
A browser provider does not implement browsing. It implements session lifecycle: create a remote browser session, hand back a CDP websocket URL, and tear the session down. Hermes' own browser stack (agent-browser + tools/browser_tool.py) connects to whatever CDP URL you return and drives the page from there — every provider gets the full browser_* toolset for free.
The active provider is selected by browser.cloud_provider in config.yaml; the dispatcher in tools/browser_tool.py is a pure registry lookup with no per-provider conditionals.
Discovery
Explains the idea itself. Read it slowly; the later sections build on it.
Hermes scans for browser backends in three places:
- Bundled —
<repo>/plugins/browser/<name>/(auto-loaded withkind: backend) - User —
~/.hermes/plugins/browser/<name>/(opt-in viaplugins.enabledorhermes plugins enable <name>) - Pip — packages declaring a
hermes_agent.pluginsentry point
Each plugin's register(ctx) calls ctx.register_browser_provider(...), which puts the instance into the registry in agent/browser_registry.py.
Directory structure
Settings you configure once. Change one at a time so you can see what each does.
plugins/browser/my-backend/
├── __init__.py # register() entry point
├── provider.py # BrowserProvider subclass
└── plugin.yaml # Manifest with kind: backend and provides_browser_providersplugin.yaml:
name: browser-my-backend
version: 1.0.0
description: "My cloud browser backend. Requires MY_BACKEND_API_KEY."
author: you
kind: backend
provides_browser_providers:
- my-backend__init__.py:
from plugins.browser.my_backend.provider import MyBackendProvider
def register(ctx) -> None:
ctx.register_browser_provider(MyBackendProvider())The BrowserProvider ABC
Commands you type in a terminal. Understand what one does before copying it. Commands here: hermes tools.
Implement agent.browser_provider.BrowserProvider. Three lifecycle methods plus identity:
from agent.browser_provider import BrowserProvider
class MyBackendProvider(BrowserProvider):
@property
def name(self) -> str:
return "my-backend" # the browser.cloud_provider config value
@property
def display_name(self) -> str:
return "My Backend" # shown in `hermes tools`
def is_available(self) -> bool:
"""Cheap check only — env var present, dep importable.
NO network calls: runs at tool-registration time and on every
`hermes tools` paint."""
return bool(os.environ.get("MY_BACKEND_API_KEY"))
def create_session(self, task_id: str) -> dict:
"""Create a remote browser session; return the session-metadata contract."""
session = my_api.create_browser(...)
return {
"session_name": f"my-backend-{task_id}", # unique agent-browser session name
"bb_session_id": session.id, # provider session ID (for cleanup)
"cdp_url": session.cdp_ws_url, # CDP websocket URL
"features": {"stealth": True}, # feature flags you enabled
}
def close_session(self, session_id: str) -> bool:
"""Terminate by provider session ID. Log-and-return-False on error —
never raise, so the dispatcher's cleanup loop keeps moving."""
...
def emergency_cleanup(self, session_id: str) -> None:
"""Best-effort teardown from atexit/signal handlers. Must not raise."""
...The session-metadata contract
create_session() must return at least session_name, bb_session_id, cdp_url, and features. Two quirks worth knowing:
bb_session_idis a legacy key name kept verbatim for backward compatibility withtools/browser_tool.py— it holds your provider's session ID regardless of vendor. Don't rename it.create_session()may raise —ValueErrorfor missing credentials,RuntimeErrorfor network/API failures. The dispatcher surfaces these to the user. This differs fromclose_session/emergency_cleanup, which must never raise.
An optional external_call_id key supports managed-gateway billing.
getsetupschema() — the hermes tools picker row
Override this to appear as a first-class option in the Browser Automation picker with API-key prompts and an install hook:
def get_setup_schema(self) -> dict:
return {
"name": "My Backend",
"badge": "paid",
"tag": "Cloud browser with stealth and proxies",
"env_vars": [
{"key": "MY_BACKEND_API_KEY",
"prompt": "My Backend API key",
"url": "https://mybackend.example"},
],
"post_setup": "agent_browser", # ensures local Chromium is installed (agent-browser itself resolves via npx)
}Per the project standard for tool backends: if a backend can't be selected and configured through hermes tools, it isn't done — "set this env var manually" is not an integration.
Users configure it
Settings you configure once. Change one at a time so you can see what each does.
browser:
cloud_provider: my-backendReference implementations
Explains the idea itself. Read it slowly; the later sections build on it.
The three bundled providers under plugins/browser/ are the canonical examples, in ascending complexity: firecrawl (simplest), browser_use, and browserbase (stealth/proxy/keep-alive feature flags with graceful fallback when paid features are unavailable). Copy the closest one.
Checklist
Commands you type in a terminal. Understand what one does before copying it. Commands here: hermes tools.
- [ ]
nameis lowercase and stable (it's a config value users write) - [ ]
is_available()makes zero network calls - [ ]
create_session()returns the full metadata contract (bb_session_idkey name intact) - [ ]
close_session()/emergency_cleanup()never raise - [ ]
get_setup_schema()exposes your env vars sohermes toolscan configure the backend - [ ]
plugin.yamldeclareskind: backend+provides_browser_providers
2 questions answered by this page alone.
Every option is a real identifier from the Hermes documentation. The wrong ones are real too, just from other pages.