Best practices for using agent-browser with Kernel cloud browsers. Use when automating websites with agent-browser -p kernel, tuning stealth or proxy behavior, persisting profiles, handling iframes, discovering Kernel session IDs or live views, or cleaning up cloud sessions.
Best practices for using agent-browser with Kernel cloud browsers. Use when automating websites with agent-browser -p kernel, tuning stealth or proxy behavior, persisting profiles, handling iframes, discovering Kernel session IDs or live views, or cleaning up cloud sessions.
Agent-Browser with Kernel Cloud Browsers
This skill documents best practices for using agent-browser's built-in Kernel provider (-p kernel) for cloud browser automation.
When to Use This Skill
Use this skill when you need to:
Automate websites using agent-browser -p kernel commands
Handle bot detection on sites with aggressive anti-bot measures
Persist login sessions across automation runs using profiles
Work with iframes including cross-origin payment forms
Get live view URLs for debugging or manual intervention
Find the underlying Kernel session ID for advanced Playwright scripting
Create site-specific automation skills for new websites
Load the kernel-cli skill for Kernel CLI installation and authentication.
Environment Variables
Set these before your first agent-browser -p kernel call. The CLI holds state between invocations.
Variable
Description
Default
KERNEL_API_KEY
Required. Your Kernel API key for authentication
(none)
KERNEL_HEADLESS
Run browser in headless mode (true/false)
true
KERNEL_STEALTH
Launch a stealth browser (true/false)
false
KERNEL_TIMEOUT_SECONDS
Session timeout in seconds
300
KERNEL_PROFILE_NAME
Currently unusable with -p kernel in agent-browser 0.33.0; use the CDP workaround below
(none)
Recommended Configuration
Set options explicitly; agent-browser reads them when it creates the provider session.
export KERNEL_API_KEY="your-api-key"export KERNEL_TIMEOUT_SECONDS=600 # 10-minute timeout for complex workflowsexport KERNEL_HEADLESS=false# Required when you need a live viewexport KERNEL_STEALTH=true# Opt in for bot-sensitive sites# Do not set KERNEL_PROFILE_NAME with -p kernel; use the workaround below.
Profile Persistence
Warning:KERNEL_PROFILE_NAME doesn't work with -p kernel in agent-browser 0.33.0. It sends profile as a string instead of the object required by Kernel, so session creation fails with HTTP 400. It also doesn't set save_changes. Profiles must be pre-created.
Until this is fixed upstream, create the browser with the Kernel CLI and attach agent-browser over CDP. Don't combine -p kernel with --cdp.
PROFILE_NAME=mysite # Create once with: kernel profiles create --name mysite
kernel profiles get "$PROFILE_NAME" >/dev/null
BROWSER=$(kernel browsers create --profile-name "$PROFILE_NAME" --save-changes --timeout 600 -o json)
SESSION_ID=$(jq -er '.session_id' <<<"$BROWSER")
CDP_URL=$(jq -er '.cdp_ws_url' <<<"$BROWSER")
trap'kernel browsers delete "$SESSION_ID" >/dev/null 2>&1 || true' EXIT
agent-browser --session mysite --cdp "$CDP_URL" open https://example.com
agent-browser --session mysite snapshot -i
# Run additional commands with --session mysite, then disconnect and end the Kernel session.
agent-browser --session mysite close
kernel browsers delete "$SESSION_ID"trap - EXIT
Don't print or share CDP_URL; it grants browser access. Deleting the CLI-created session finalizes --save-changes, so later sessions can reuse the authenticated profile.
Basic Usage
agent-browser -p kernel open <url> # Navigate to page
agent-browser -p kernel snapshot -i # Get interactive elements with refs
agent-browser -p kernel click @e1 # Click element by ref
agent-browser -p kernel fill @e2 "text"# Fill input by ref
agent-browser -p kernel close # Close the provider session
For provider-managed sessions, use -p kernel with each command. For the profile/CDP workaround, reuse the same --session name and don't add -p kernel.
Semantic Selectors (Recommended)
Instead of ephemeral @e refs that change on every page load, use semantic selectors via the find command for more stable, readable automation:
# By ARIA role + accessible name (most stable)
agent-browser -p kernel find role button click --name "Log In"
agent-browser -p kernel find role textbox fill "user@email.com" --name "Email"# By visible text content
agent-browser -p kernel find text "View Menus" click
agent-browser -p kernel find text "Submit Order" click
# By form label (great for inputs)
agent-browser -p kernel find label "Username" fill "myuser"
agent-browser -p kernel find label "Password" fill "secret123"# By placeholder text
agent-browser -p kernel find placeholder "Search..."type"query"# By data-testid (if the site uses them)
agent-browser -p kernel find testid "submit-btn" click
# By position (when needed)
agent-browser -p kernel find first "li.item" click
agent-browser -p kernel find nth 2 ".card" hover
When to Use Which Selector
Selector Type
Best For
Stability
find role --name
Buttons, links, navigation
⭐⭐⭐ Most stable
find label
Form inputs with labels
⭐⭐⭐ Most stable
find text
Clickable text elements
⭐⭐ Stable
find testid
Sites with test attributes
⭐⭐⭐ Most stable
find placeholder
Search boxes, inputs
⭐⭐ Stable
@e refs
Unknown sites, quick iteration
⭐ Ephemeral
Recommendation: Use find for production automation. Use @e refs for exploration and quick prototyping, then convert to semantic selectors.
Find the Kernel Session and Live View
Match agent-browser's CDP endpoint to the active Kernel session. Compare the URL without its query string: the CLI and agent-browser can hold different short-lived jwt query values for the same session. The endpoint's scheme, host, and path remain stable. This is more reliable than guessing from creation time when several sessions share a profile. This workflow requires jq.
Do not print or share the CDP URL; it grants browser access. Share a live view URL only with the intended user. A headless session has no live view. If you use --session <name>, include it on every agent-browser command, including get cdp-url.
Handling Bot Detection
Stealth and Proxy Routing
Stealth is opt-in in current agent-browser releases. Set KERNEL_STEALTH=true before the first command for a session; changing it later does not reconfigure the running browser.
A stealth browser can use Kernel's default stealth proxy. If that proxy causes a site-specific network or reputation failure and direct metro egress is acceptable, change the running session without disabling stealth:
kernel browsers update "$SESSION_ID" --disable-default-proxy
# Retry the navigation and compare behavior.# Re-enable the default stealth proxy while continuing the same session.
kernel browsers update "$SESSION_ID" --disable-default-proxy=false
Direct egress changes the public IP and can reduce anti-bot protection. Prefer the default proxy unless testing shows it is the problem. For a configured Kernel proxy, use --proxy-id <proxy-id>; remove it with --clear-proxy.
Manual Login Fallback
If automated login fails:
Resolve SESSION_ID using the CDP-matching workflow above.
Run kernel browsers view "$SESSION_ID" and give the URL only to the intended user.
Ask the user to complete login, then continue in the same agent-browser session.
To persist the login, use the CLI-created profile/CDP workflow above. Close agent-browser, then delete the Kernel session so --save-changes finalizes.
JavaScript Fallback for Tricky Elements
Some elements (especially on bot-protected sites) don't respond to standard commands:
# Click by CSS selector
agent-browser -p kernel eval"document.querySelector('.submit-btn').click()"# Fill by selector (with event dispatch)
agent-browser -p kernel eval"
const el = document.querySelector('#email');
el.value = 'user@example.com';
el.dispatchEvent(new Event('input', {bubbles: true}));
el.dispatchEvent(new Event('change', {bubbles: true}));
"# Click by test ID
agent-browser -p kernel eval"document.querySelector('[data-testid=\"submit\"]').click()"
Anti-Bot Form Fields
Some payment processors (e.g., Point and Pay) use decoy form fields. Only fill fields matching specific patterns:
agent-browser -p kernel eval"
const realInputs = Array.from(document.querySelectorAll('input'))
.filter(el => el.name && el.name.startsWith('xeiinput'));
// Fill only these inputs
"
Handling Iframes
Same-Origin Iframes
Use the frame command to switch context:
agent-browser -p kernel frame "#iframe-id"# Switch to iframe
agent-browser -p kernel snapshot -i # Snapshot within iframe
agent-browser -p kernel click @e1 # Interact within iframe
agent-browser -p kernel frame main # Return to main frame
Cross-Origin Iframes
Try agent-browser frame first; current releases can switch into iframe context, including many cross-origin frames. If an out-of-process or payment iframe still fails, resolve SESSION_ID and use Kernel's Playwright executor:
Return to the main document with agent-browser -p kernel frame main after frame interactions.
Waiting Strategies
Smart waits are critical for fast, reliable automation. Using condition-based waits instead of fixed timeouts can reduce execution time by 50%+ while improving reliability.
Smart Waits (Recommended)
# Wait for page load states
agent-browser -p kernel wait --load domcontentloaded # DOM ready
agent-browser -p kernel wait --load networkidle # Network settled# Wait for specific URL pattern (great for redirects after login)
agent-browser -p kernel wait --url "**/dashboard"
agent-browser -p kernel wait --url "**/order-confirmation"# Wait for text to appear (great for dynamic content)
agent-browser -p kernel wait --text "Password"# Field appeared
agent-browser -p kernel wait --text "Order confirmed"# Success message# Wait for JavaScript condition
agent-browser -p kernel wait --fn "window.appReady === true"
agent-browser -p kernel wait --fn "document.querySelector('.spinner') === null"# Wait for element by CSS selector
agent-browser -p kernel wait"#login-form"
agent-browser -p kernel wait".results-loaded"
Fixed Waits (Last Resort)
# Only when no condition is available
agent-browser -p kernel wait 2000
Element Refs Best Practices
Element refs (@e1, @e2, etc.) are ephemeral and change:
After page navigation
After significant DOM updates
Between browser sessions
Always take a fresh snapshot before interacting:
agent-browser -p kernel snapshot -i
# Now use the refs from this snapshot
agent-browser -p kernel click @e5
Filtering Snapshots
# Filter for specific elements
agent-browser -p kernel snapshot -i | grep -i "button\|submit"# Scope to a specific area
agent-browser -p kernel snapshot -s "#main-content" -i
Login Patterns
Single-Page Form (Optimized)
Username and password on the same page:
agent-browser -p kernel open https://example.com/login
agent-browser -p kernel wait --load domcontentloaded
# Use semantic selectors for stability
agent-browser -p kernel find label "Email" fill "user@example.com"
agent-browser -p kernel find label "Password" fill "secret123"
agent-browser -p kernel find role button click --name "Sign In"# Wait for actual redirect, not arbitrary timeout
agent-browser -p kernel wait --url "**/dashboard"
Two-Step Form (Optimized)
Username first, then password on a second screen:
agent-browser -p kernel open https://example.com/login
agent-browser -p kernel wait --load domcontentloaded
# Step 1: Username
agent-browser -p kernel find label "Username" fill "myuser"
agent-browser -p kernel press Enter
# Wait for password field to appear (not a fixed sleep!)
agent-browser -p kernel wait --text "Password"# Step 2: Password
agent-browser -p kernel find label "Password" fill "secret123"
agent-browser -p kernel press Enter
# Wait for successful redirect
agent-browser -p kernel wait --url "**/home"
Modal Login
Login form appears in a modal overlay:
# Click login link to open modal
agent-browser -p kernel find text "Log In" click
agent-browser -p kernel wait --text "Password"# Wait for modal# Fill modal fields
agent-browser -p kernel find label "Email" fill "user@example.com"
agent-browser -p kernel find label "Password" fill "password123"
agent-browser -p kernel find role button click --name "Sign In"
agent-browser -p kernel wait --url "**/dashboard"
# Click link that opens new tab
agent-browser -p kernel click @e38
agent-browser -p kernel tab 1 # Switch to new tab (0-indexed)
agent-browser -p kernel wait 2000
agent-browser -p kernel snapshot -i # Interact with new tab
Screenshots and Debugging
# Take screenshot
agent-browser -p kernel screenshot ~/Downloads/page.png
# Full page screenshot
agent-browser -p kernel screenshot ~/Downloads/full.png --full
# View console messages
agent-browser -p kernel console
# View page errors
agent-browser -p kernel errors
# Get current URL
agent-browser -p kernel get url
Session Management
Cleanup
Close the same named agent-browser session you opened. This saves profile changes and deletes its Kernel browser:
agent-browser -p kernel close
# Named session: agent-browser -p kernel --session site1 close
If agent-browser is unavailable or close fails, delete the orphan explicitly:
kernel browsers delete "$SESSION_ID"
Do not use close --all when unrelated agent-browser sessions may be running.
Multiple Sessions
Run parallel browser sessions with named sessions:
agent-browser -p kernel --session site1 open https://site1.com
agent-browser -p kernel --session site2 open https://site2.com
agent-browser -p kernel session list
Common Gotchas
Refs change after navigation: Re-snapshot after links, submissions, or major DOM updates.
Wait for outcomes: Use URL, text, load-state, or JavaScript conditions after asynchronous actions.
Provider settings are launch-time settings: Close the current session before changing KERNEL_HEADLESS, KERNEL_STEALTH, or timeout.
Profile persistence needs the CDP workaround: KERNEL_PROFILE_NAME is currently broken. Close agent-browser, then delete the CLI-created Kernel session to finalize --save-changes.
Stealth is not sufficient for every site: Compare proxy routing, use manual login, or fall back to direct Playwright for difficult frames.
Quick Reference
# Start a standard provider session (for persistence, use the CDP workflow above)export KERNEL_TIMEOUT_SECONDS=600
agent-browser -p kernel open https://example.com
# Basic interaction with semantic selectors (recommended)
agent-browser -p kernel wait --load domcontentloaded
agent-browser -p kernel find label "Email" fill "user@example.com"
agent-browser -p kernel find label "Password" fill "secret"
agent-browser -p kernel find role button click --name "Submit"
agent-browser -p kernel wait --url "**/success"# Alternative: snapshot + refs (for exploration)
agent-browser -p kernel snapshot -i
agent-browser -p kernel fill @eN "text"
agent-browser -p kernel click @eM
# Resolve the underlying session before manual intervention
CDP_URL="$(agent-browser -p kernel get cdp-url)"
CDP_ENDPOINT="${CDP_URL%%\?*}"
SESSION_ID="$(kernel browsers list --status active --limit 100 -o json |
jq -r --arg endpoint "$CDP_ENDPOINT" \
'.[] | select((.cdp_ws_url | split("?")[0]) == $endpoint) | .session_id' |
head -n 1)"test -n "$SESSION_ID"
kernel browsers view "$SESSION_ID"# Cleanup (delete by ID only if close fails)
agent-browser -p kernel close