Implementing User Login for Hermes Agent's Browser Tool

An analysis of how Hermes Agent's browser tool handles websites requiring login, including automated form filling, Camofox persistent profiles, VNC human-in-the-loop collaboration, and JS injection approaches.

Hermes Agent’s browser tool folds authentication into the normal page-interaction flow, relying on the state-persistence capabilities of different backends to keep you logged in. Based on a direct analysis of the NousResearch/hermes-agent source code, this article walks through the five concrete approaches it uses when dealing with “websites that require a login to access.”

1. Interactive Automated Login (General Approach)

This is the most basic approach and works on every backend. The Agent simulates a human logging in through a standard chain of browser operations:

  1. browser_navigate(url) — opens the login page
  2. browser_type(ref, text) — fills in the username/password fields
  3. browser_click(ref) or browser_press("Enter") — clicks the sign-in button or submits the form
  4. browser_snapshot() — confirms whether the login succeeded (page redirects, personal dashboard appears, etc.)

In the implementation in tools/browser_tool.py, browser_type invokes the fill command under the hood, which clears the input field before typing so stale content doesn’t remain. This approach requires zero configuration and is highly universal, but it tends to fail against CAPTCHA, 2FA, QR codes, and strong anti-bot detection.

For login-walled sites you need to visit repeatedly, Hermes can keep your session across tasks, and the core carrier for that is the Camofox backend.

Camofox Managed Persistence

When the CAMOFOX_URL environment variable points to a local Camofox server and persistence is enabled in config.yaml:

tools/browser_camofox_state.py derives a deterministic userId from the current Hermes profile and maps it to a fixed local directory (~/.hermes/browser_auth/camofox/). When the Camofox server receives the same userId, it reuses the same browser profile, so cookies, localStorage, IndexedDB, and other login state can be preserved across tasks.

In the cleanup logic of tools/browser_tool.py, when managed persistence is enabled the Agent performs soft cleanup — it only releases local in-memory tracking rather than destroying the server-side browser context, so session cookies are preserved.

3. JavaScript Injection (Programmatic Authentication)

Hermes’s browser_console tool accepts an expression parameter to run arbitrary JavaScript in the page context (equivalent to the DevTools Console). This lets the Agent directly:

  • Read/set cookies: document.cookie = "session_id=xxx"
  • Manipulate localStorage: localStorage.setItem('token', 'xxx')
  • Inject a JWT or API token

This capability is implemented in _browser_eval in tools/browser_tool.py, and the Camofox backend also exposes a corresponding /tabs/{tabId}/eval REST endpoint. It’s suited to scenarios where the developer already has a session token and needs to skip the login form.

4. Human-in-the-loop Login

When you encounter heavy anti-bot protection, CAPTCHA, QR-code login, or SSO, Hermes offers two human-in-the-loop paths, though their interaction shapes differ significantly.

4.1 Camofox + VNC: A Live, Interactable Browser Window

This is the only approach in the code that provides a browser UI a human can directly click, type into, and scan from.

In tools/browser_camofox.py, initialization probes the Camofox server’s /health endpoint. If the server returns a vncPort, Hermes caches it as _vnc_url and writes that address into the result after every camofox_navigate() call:

The interface a human sees: open vnc_url in your own browser, typically a noVNC web client, which shows a remote-desktop-level browser window. You can click buttons, fill in forms, scan QR codes, and drag sliders through CAPTCHAs, or watch the Agent’s automation and take over at any time.

The collaboration flow: when the Agent detects that login or verification is blocked, it sends the vnc_url to you, pauses sending browser-operation commands, and waits for your “login/verification done” feedback before continuing automation. If managed_persistence is enabled at the same time, once you log in once through VNC, later tasks can reuse that session directly.

4.2 browser_vision: One-Way Static Screenshot Assistance

This is a universal approach available on every backend, but it’s one-way. After calling browser_vision, the Agent saves a screenshot of the current page locally and sends it into the chat as an image attachment via MEDIA:<path>.

The user can only look, not click. A typical workflow is:

  1. The Agent reaches a verification page and finds itself blocked
  2. The Agent screenshots and sends it back; the user sees, for example, an SMS verification-code field
  3. The Agent asks the user for the verification code through the conversation
  4. The user replies with the digits, and the Agent continues filling them in with browser_type

This approach is essentially ineffective for scenarios that require direct human manipulation of page elements (clicking an “I’m not a robot” checkbox, dragging puzzle pieces, scanning a QR code to log in).

5. Connecting to an Already-Logged-In Browser (CDP Override)

Hermes supports connecting to an existing Chrome DevTools Protocol (CDP) endpoint via the BROWSER_CDP_URL environment variable. You can:

  1. Launch an ordinary Chrome locally (with --remote-debugging-port)
  2. Manually log in to the target website
  3. Hand Hermes the CDP websocket address of that Chrome
  4. The Agent then performs operations directly in that already-authenticated browser instance

In tools/browser_tool.py, _get_cdp_override() reads that environment variable, and _get_session_info() creates the corresponding CDP session, completely bypassing local launch and cloud providers.

6. Security & Protection

In the browser_navigate implementation there’s a credential-leak safety check. The Agent decodes the URL and scans it for API-key or token prefixes, blocking navigation as soon as it finds any:

This prevents prompt-injection attacks from leaking a user’s sensitive credentials through navigation links.

Summary

Approach Implementation Best Used For
Automated form login navigate → type → click/press Ordinary username/password login with no heavy anti-bot protection
Persistent Profile/Cookie Camofox managed_persistence Long-term, repeated access to the same site
Inject Token/Cookie via JS browser_console(expression=...) Already have a session token and need to skip login fast
Human-in-the-loop (live VNC) Camofox backend + vnc_url Complex verification such as CAPTCHA, QR codes, SSO
Human-in-the-loop (screenshot aid) browser_vision + conversation relay Light collaboration such as passing back verification codes
Connect an already-logged-in browser BROWSER_CDP_URL User already has a login environment; Agent only does follow-up operations

Overall, Hermes’s login strategy = interactive form filling + backend state retention + human-in-the-loop fallback. In the default local agent-browser CLI backend and the cloud Browserbase / Browser Use backends, the code does not reserve a browser UI that a human can directly operate; for genuine real-time human-in-the-loop collaboration, Camofox + VNC is currently the most complete path implemented in the code.