core

Core agent-browser usage guide. Read this before running any agent-browser commands. Covers the snapshot-and-ref workflow, navigating pages, interacting with elements (click, fill, type, select), extracting text and data, taking screenshots, managing tabs, handling forms and auth, waiting for content, running multiple browser sessions in parallel, and troubleshooting common failures. Use when the user asks to interact with a website, fill a form, click something, extract data, take a screenshot, log into a site, test a web app, or automate any browser task.

Install
npx skills add 'https://github.com/vercel-labs/agent-browser/tree/main/skill-data/core'
Download bundle ↓
main · aff6125Scanned 2026-09-17

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗
View on GitHub
← Back to SKILL.md

Authentication Patterns

Login flows, session persistence, OAuth, 2FA, and authenticated browsing.

Related: session-management.md for state persistence details, SKILL.md for quick start.

Contents

Import Auth from Your Browser

The fastest way to authenticate is to reuse cookies from a Chrome session you are already logged into.

Step 1: Start Chrome with remote debugging

# macOS
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --remote-debugging-port=9222

# Linux
google-chrome --remote-debugging-port=9222

# Windows
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222

Log in to your target site(s) in this Chrome window as you normally would.

Security note: --remote-debugging-port exposes full browser control on localhost. Any local process can connect and read cookies, execute JS, etc. Only use on trusted machines and close Chrome when done.

Step 2: Grab the auth state

# Auto-discover the running Chrome and save its cookies + localStorage
agent-browser --auto-connect state save ./my-auth.json

Step 3: Reuse in automation

# Load auth at launch
agent-browser --state ./my-auth.json open https://app.example.com/dashboard

# Or load into an already-launched session
agent-browser open about:blank
agent-browser state load ./my-auth.json
agent-browser open https://app.example.com/dashboard

This works for any site, including those with complex OAuth flows, SSO, or 2FA, as long as Chrome already has valid session cookies.

Security note: State files contain session tokens in plaintext. Add them to .gitignore, delete when no longer needed, and set AGENT_BROWSER_ENCRYPTION_KEY for encryption at rest. See Security Best Practices.

Tip: Combine with --session <id> --restore so the imported auth auto-persists across restarts:

SESSION="$(agent-browser session id --scope worktree --prefix myapp)"
agent-browser --session "$SESSION" --restore --state ./my-auth.json open https://app.example.com/dashboard
# From now on, state is auto-saved/restored for this session

Persistent Profiles

Use --profile to point agent-browser at a Chrome user data directory. This persists everything (cookies, IndexedDB, service workers, cache) across browser restarts without explicit save/load:

# First run: login once
agent-browser --profile ~/.myapp-profile open https://app.example.com/login
# ... complete login flow ...

# All subsequent runs: already authenticated
agent-browser --profile ~/.myapp-profile open https://app.example.com/dashboard

Use different paths for different projects or test users:

agent-browser --profile ~/.profiles/admin open https://app.example.com
agent-browser --profile ~/.profiles/viewer open https://app.example.com

Or set via environment variable:

export AGENT_BROWSER_PROFILE=~/.myapp-profile
agent-browser open https://app.example.com/dashboard

Session Persistence

Use --restore with a stable --session to auto-save and restore cookies + localStorage without managing files:

# Auto-saves state on close, auto-restores on next launch
SESSION="$(agent-browser session id --scope worktree --prefix twitter)"
agent-browser --session "$SESSION" --restore open https://twitter.com
# ... login flow ...
agent-browser --session "$SESSION" --restore close  # state saved to ~/.agent-browser/sessions/

# Next time: state is automatically restored
agent-browser --session "$SESSION" --restore open https://twitter.com

Encrypt state at rest:

export AGENT_BROWSER_ENCRYPTION_KEY=$(openssl rand -hex 32)
agent-browser --session secure --restore open https://app.example.com

Basic Login Flow

# Navigate to login page
agent-browser open https://app.example.com/login
agent-browser wait --load domcontentloaded
agent-browser wait --fn "(() => { const usable = (el) => { const style = getComputedStyle(el); return !el.disabled && !el.readOnly && style.display !== 'none' && style.visibility !== 'hidden' && el.getClientRects().length > 0; }; const username = Array.from(document.querySelectorAll('input[type=email], input[type=text], input[autocomplete=username], input[name*=email i], input[name*=user i], input[name*=login i]')).some(usable); const password = Array.from(document.querySelectorAll('input[type=password]')).some(usable); return username && password; })()"

# Get form elements
agent-browser snapshot -i
# Output: @e1 [input type="email"], @e2 [input type="password"], @e3 [button] "Sign In"

# Fill credentials
agent-browser fill @e1 "user@example.com"
agent-browser fill @e2 "password123"

# Submit
agent-browser click @e3
agent-browser wait --url "**/dashboard"

# Verify login succeeded
agent-browser get url  # Should be dashboard, not login

After submitting, wait for the authenticated destination, a success message, or another app-specific condition. Do not use networkidle as a generic login wait because long-lived background connections can keep it from resolving.

For a form reached through an in-page click, challenge clearance, consent dismissal, or another stateful step, use the auth vault without discarding the prepared document:

agent-browser open https://app.example.com/
agent-browser click "a[href='/login']"
agent-browser auth login my-app --no-navigate

--no-navigate suppresses only the initial navigation that auth login normally performs. An existing active top-level HTTP(S) page is required. Before either credential is filled, agent-browser compares the page origin with the effective credential URL using scheme, host, and effective port. Paths, queries, and fragments may differ. Selector waits, credential filling, submit clicking, and submit-triggered navigation remain unchanged.

The command-level --url override takes precedence over stored profile or credential-provider URL metadata. In no-navigation mode it is an expected-origin constraint, not a navigation destination. This supports hosted identity-provider flows:

agent-browser auth login work --no-navigate --url https://identity.example.com/login

Plugins

Use credential provider plugins when credentials live in external vault software. Plugins are configured in agent-browser.json and run as external executables over the agent-browser.plugin.v1 stdio JSON protocol.

Add a plugin with plugin add. A plain name or @scope/name resolves from npm; owner/repo resolves from GitHub:

agent-browser plugin add agent-browser-plugin-vault --name vault
agent-browser plugin add @company/agent-browser-plugin-vault --name vault
agent-browser plugin add org/agent-browser-plugin-cloud-browser
{
  "plugins": [
    {
      "name": "vault",
      "command": "agent-browser-plugin-vault",
      "capabilities": ["credential.read"]
    },
    {
      "name": "cloud-browser",
      "command": "agent-browser-plugin-cloud-browser",
      "capabilities": ["browser.provider"]
    },
    {
      "name": "stealth",
      "command": "agent-browser-plugin-stealth",
      "capabilities": ["launch.mutate"]
    },
    {
      "name": "captcha",
      "command": "agent-browser-plugin-captcha",
      "capabilities": ["command.run", "captcha.solve"]
    }
  ]
}

Inspect configured plugins before use:

agent-browser plugin list
agent-browser plugin show vault

Resolve credentials just-in-time for one login:

agent-browser auth login my-app --credential-provider vault --item "My App"

After stateful setup, combine the provider with no-navigation mode. The provider secret remains in memory and does not enter generated process arguments or normal output:

agent-browser auth login my-app --credential-provider vault --item "My App" --no-navigate --url https://identity.example.com/login

Use a plugin as a browser provider or a generic domain command:

agent-browser --provider cloud-browser open https://example.com
agent-browser plugin run captcha captcha.solve --payload '{"siteKey":"...","url":"https://example.com"}'

plugin run is for command.run and custom capabilities. Core capabilities and protocol request types use their dedicated command paths.

Use --url, --username-selector, --password-selector, and --submit-selector on auth login to override plugin-provided metadata for the current login only.

Gate plugin secret access separately from normal login automation:

agent-browser --confirm-actions plugin:vault:credential.read auth login my-app --credential-provider vault --item "My App"
agent-browser --confirm-actions plugin:cloud-browser:browser.provider --provider cloud-browser open https://example.com
agent-browser --confirm-actions plugin:stealth:launch.mutate open https://example.com

Do not put vault tokens or passwords in plugin command args. Use the vault vendor's own login/session mechanism or environment outside agent-browser config.

Saving Authentication State

After logging in, save state for reuse:

# Login first (see above)
agent-browser open https://app.example.com/login
agent-browser snapshot -i
agent-browser fill @e1 "user@example.com"
agent-browser fill @e2 "password123"
agent-browser click @e3
agent-browser wait --url "**/dashboard"

# Save authenticated state
agent-browser state save ./auth-state.json

Restoring Authentication

Skip login by loading saved state:

# Load saved auth state
agent-browser state load ./auth-state.json

# Navigate directly to protected page
agent-browser open https://app.example.com/dashboard

# Verify authenticated
agent-browser snapshot -i

OAuth / SSO Flows

For OAuth redirects:

# Start OAuth flow
agent-browser open https://app.example.com/auth/google

# Handle redirects automatically
agent-browser wait --url "**/accounts.google.com**"
agent-browser snapshot -i

# Fill Google credentials
agent-browser fill @e1 "user@gmail.com"
agent-browser click @e2  # Next button
agent-browser wait 2000
agent-browser snapshot -i
agent-browser fill @e3 "password"
agent-browser click @e4  # Sign in

# Wait for redirect back
agent-browser wait --url "**/app.example.com**"
agent-browser state save ./oauth-state.json

Two-Factor Authentication

Handle 2FA with manual intervention:

# Login with credentials
agent-browser open https://app.example.com/login --headed  # Show browser
agent-browser snapshot -i
agent-browser fill @e1 "user@example.com"
agent-browser fill @e2 "password123"
agent-browser click @e3

# Wait for user to complete 2FA manually
echo "Complete 2FA in the browser window..."
agent-browser wait --url "**/dashboard" --timeout 120000

# Save state after 2FA
agent-browser state save ./2fa-state.json

HTTP Basic Auth

For sites using HTTP Basic Authentication:

# Set credentials before navigation
agent-browser set credentials username password

# Navigate to protected resource
agent-browser open https://protected.example.com/api

The credentials also apply to tabs opened later through tab new or click --new-tab, including their first document request.

Manually set authentication cookies:

# Set auth cookie
agent-browser cookies set session_token "abc123xyz"

# Navigate to protected page
agent-browser open https://app.example.com/dashboard

Token Refresh Handling

For sessions with expiring tokens:

#!/bin/bash
# Wrapper that handles token refresh

STATE_FILE="./auth-state.json"

# Try loading existing state
if [[ -f "$STATE_FILE" ]]; then
    agent-browser state load "$STATE_FILE"
    agent-browser open https://app.example.com/dashboard

    # Check if session is still valid
    URL=$(agent-browser get url)
    if [[ "$URL" == *"/login"* ]]; then
        echo "Session expired, re-authenticating..."
        # Perform fresh login
        agent-browser snapshot -i
        agent-browser fill @e1 "$USERNAME"
        agent-browser fill @e2 "$PASSWORD"
        agent-browser click @e3
        agent-browser wait --url "**/dashboard"
        agent-browser state save "$STATE_FILE"
    fi
else
    # First-time login
    agent-browser open https://app.example.com/login
    # ... login flow ...
fi

Security Best Practices

  1. Never commit state files - They contain session tokens

    echo "*.auth-state.json" >> .gitignore
  2. Use environment variables for credentials

    agent-browser fill @e1 "$APP_USERNAME"
    agent-browser fill @e2 "$APP_PASSWORD"
  3. Clean up after automation

    agent-browser cookies clear
    rm -f ./auth-state.json
  4. Use short-lived sessions for CI/CD

    # Don't persist state in CI
    agent-browser open https://app.example.com/login
    # ... login and perform actions ...
    agent-browser close  # Session ends, nothing persisted
Referenced from SKILL.md