Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
A stable native browser (WKWebView) for OpenClaw agents. Opens a visible window with tab management, URL bar, and login helpers — every website works, includ...
A stable native browser (WKWebView) for OpenClaw agents. Opens a visible window with tab management, URL bar, and login helpers — every website works, includ...
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
A real native browser (WKWebView) for OpenClaw agents. Opens a visible window with tab management, URL bar, and login helpers — every website works, including Perplexity, Grok, Claude, and ChatGPT. Replaces flaky relay-based browser controls with a stable native macOS browser.
Clone the repository and install: git clone https://github.com/yungookim/openclaw-browser.git ~/clawd/openclaw-browser cd ~/clawd/openclaw-browser pip install -e . Verify installation: python -c "import sys; sys.path.insert(0, '/Users/$USER/clawd/openclaw-browser'); from src import OpenClawBrowserSkill, __version__; print(f'openclaw-browser v{__version__} ready')"
import sys sys.path.insert(0, '/Users/<username>/clawd/openclaw-browser') from src import OpenClawBrowserSkill skill = OpenClawBrowserSkill() # Load any website (native WKWebView — all sites work) skill.load('https://perplexity.ai') # Read page content title = skill.get_title() html = skill.get_dom('body') # Execute JavaScript result = skill.execute_js('document.title') # Interact with page skill.click('button.submit') skill.type_text('input[name="query"]', 'Hello world') # Tab management tab_id = skill.browser.new_tab('https://example.com') skill.browser.switch_tab(tab_id) skill.browser.close_tab(tab_id) # Close when done skill.close()
By default, OpenClaw gateway uses the Brave Search API for web search, which: Requires a paid API key Only supports search (no interaction) Cannot log into websites Cannot interact with authenticated web apps openclaw-browser solves this by providing: ✅ No API keys required ✅ Click, type, login, scrape ✅ Persistent cookies & multi-site sessions ✅ JavaScript execution ✅ Screenshot capture ✅ Works with Perplexity, Claude, ChatGPT, Grok
To avoid missing_brave_api_key errors and ensure OpenClaw routes web tasks through openclaw-browser, disable the built-in web tools: Edit ~/.openclaw/openclaw.json: { "tools": { "web": { "search": { "enabled": false }, "fetch": { "enabled": false } } } } Or run: openclaw configure --section tools and disable both web.search and web.fetch.
Native WKWebView — real macOS browser engine, every website works (no headless quirks) Two-window architecture — frameless toolbar (tab bar + URL bar) + native content windows per tab Singleton browser — one instance, reused across calls, with tab management Login helpers — built-in flows for Perplexity, Grok, Claude, ChatGPT Subprocess isolation — browser runs in a child process so it never blocks your agent
OpenClaw Agent │ ▼ OpenClawBrowserSkill (skill_wrapper.py) │ - lazy init, login helpers, convenience methods ▼ NativeBrowser (browser_engine.py, singleton) │ - IPC over stdin/stdout JSON ▼ Child Process (pywebview main thread) ├── Toolbar Window (frameless, always-on-top, chrome_ui.py) │ ├── Tab bar │ ├── URL bar │ └── nav buttons └── Content Windows (one native WKWebView per tab) ├── load_url() ├── execute_js() └── get_dom()
MethodDescriptionskill.load(url, wait=2.0)Load URL in active tabskill.execute_js(code)Run JavaScript, return resultskill.get_dom(selector)Get innerHTML of elementskill.get_title()Get page titleskill.get_url()Get current URLskill.snapshot()Full page HTML + metadata dict
MethodDescriptionskill.click(selector, wait=1.0)Click elementskill.type_text(selector, text)Type into inputskill.wait_for_element(selector, timeout=10)Wait for element to appearskill.scroll_to_bottom()Scroll to page bottomskill.scroll_to_element(selector)Scroll element into view
MethodDescriptionskill.get_cookies()Get all cookiesskill.set_cookie(name, value)Set a cookie
MethodDescriptionskill.login_perplexity(email, pw)Login to Perplexity.aiskill.login_grok(user, pw)Login to Grok (X.com)skill.login_claude(email, pw)Login to Claude.aiskill.login_chatgpt(email, pw)Login to ChatGPT
MethodDescriptionskill.browser.new_tab(url)Open new tabskill.browser.switch_tab(id)Switch to tabskill.browser.close_tab(id)Close tabskill.browser.get_tabs()List all tabs
MethodDescriptionskill.close()Close browser
from src import OpenClawBrowserSkill skill = OpenClawBrowserSkill() skill.load('https://example.com') # Get page content title = skill.get_title() print(f"Page title: {title}") # Execute JavaScript result = skill.execute_js('document.querySelector("h1").textContent') print(f"H1 text: {result}") skill.close()
from src import OpenClawBrowserSkill skill = OpenClawBrowserSkill() skill.load('https://example.com/contact') # Wait for form to load skill.wait_for_element('input[name="email"]') # Fill form skill.type_text('input[name="email"]', 'user@example.com') skill.type_text('textarea[name="message"]', 'Hello from OpenClaw!') skill.click('button[type="submit"]') # Wait for confirmation skill.wait_for_element('.success-message') skill.close()
from src import OpenClawBrowserSkill skill = OpenClawBrowserSkill() # Built-in login helper skill.login_perplexity('your-email@example.com', 'your-password') # Now you can use Perplexity skill.load('https://perplexity.ai') skill.type_text('textarea[placeholder="Ask anything..."]', 'What is quantum computing?') skill.click('button[aria-label="Submit"]') skill.close()
from src import OpenClawBrowserSkill skill = OpenClawBrowserSkill() # Open multiple tabs tab1 = skill.browser.new_tab('https://github.com') tab2 = skill.browser.new_tab('https://stackoverflow.com') # Switch between tabs skill.browser.switch_tab(tab1) title1 = skill.get_title() skill.browser.switch_tab(tab2) title2 = skill.get_title() print(f"Tab 1: {title1}, Tab 2: {title2}") # Close individual tabs skill.browser.close_tab(tab1) skill.browser.close_tab(tab2) skill.close()
macOS 10.14+ (Mojave or later) Python 3.12+ pywebview >= 5.1 (the only dependency)
The browser is a singleton — calling OpenClawBrowserSkill() again reuses the same window. Use new_tab() for additional pages. Subprocess isolation — the browser runs in a child process, so it never blocks your agent. CSS selectors — all interaction methods use CSS selectors (e.g., 'button.submit', 'input[name="email"]') Cookies persist — login sessions are maintained across skill invocations
Run the test suite: # GUI test suite (9 tests, needs display) python test_gui_browser.py # pytest suite pytest tests/ -v
Browser doesn't appear: Make sure you're running on macOS 10.14+ Element not found: Use execute_js() to inspect the page structure Login fails: Check credentials and website changes Performance issues: The browser is a native app, so it should be fast. If slow, check system resources.
Open an issue at: https://github.com/yungookim/openclaw-browser
MIT — see LICENSE
Messaging, meetings, inboxes, CRM, and teammate communication surfaces.
Largest current source with strong distribution and engagement signals.