Get the FREE Ultimate OpenClaw Setup Guide →

using-webctl

Scanned
npx machina-cli add skill oaustegard/claude-skills/using-webctl --openclaw
Files (1)
SKILL.md
4.5 KB

Using webctl in Claude.ai Containers

Browser automation using webctl CLI with automatic proxy authentication handling for Claude.ai's egress-controlled environment.

When This Skill Applies

  • User requests browser automation, web scraping, or page interaction
  • webctl commands fail with ERR_TUNNEL_CONNECTION_FAILED
  • Playwright/Chromium needs to work through authenticated HTTP proxy

Core Problem

Claude.ai containers route traffic through an authenticated egress proxy (HTTP_PROXY env var with JWT credentials). Chromium doesn't properly handle proxy authentication for HTTPS CONNECT tunnels, causing all HTTPS navigation to fail even though curl works.

Solution

A local forwarding proxy (port 18080) intercepts Chromium connections and injects Proxy-Authorization headers before forwarding to the real egress proxy.

Setup Procedure

1. Install webctl

pip install webctl --break-system-packages
webctl setup  # Downloads Chromium if needed

2. Deploy Auth Proxy Module

Copy scripts/auth_proxy.py to webctl's daemon directory:

cp /mnt/skills/user/using-webctl/scripts/auth_proxy.py \
   /usr/local/lib/python3.12/dist-packages/webctl/daemon/

3. Patch Session Manager

Apply this patch to /usr/local/lib/python3.12/dist-packages/webctl/daemon/session_manager.py:

Find the context creation block (around line 104):

# Create context
context = await browser.new_context(
    storage_state=storage_state, viewport={"width": 1280, "height": 720}
)

Replace with:

# Create context with proxy from env (with auth handling)
from .auth_proxy import get_local_proxy_url
proxy_url = get_local_proxy_url()
proxy_config = {"server": proxy_url} if proxy_url else None

context = await browser.new_context(
    storage_state=storage_state, 
    viewport={"width": 1280, "height": 720},
    proxy=proxy_config
)

4. Verify

webctl start --mode unattended
webctl --quiet navigate "https://github.com"
webctl snapshot --interactive-only --limit 10
webctl stop --daemon

Quick Reference

Session Management

webctl start --mode unattended    # Headless browser
webctl stop --daemon              # Full shutdown
webctl status                     # Current state + console error counts

Navigation

webctl navigate "https://..."
webctl back / webctl forward / webctl reload

Observation

webctl snapshot --interactive-only --limit 30   # Buttons, links, inputs
webctl snapshot --within "role=main"            # Scope to container
webctl query "role=button name~=Submit"         # Debug queries
webctl screenshot --path shot.png

Interaction

webctl click 'role=button name~="Submit"'
webctl type 'role=textbox name~="Email"' "user@example.com"
webctl type 'role=textbox name~="Search"' "query" --submit
webctl select 'role=combobox name~="Country"' --label "Germany"

Query Syntax

  • role=button — By ARIA role
  • name~="partial" — Contains (preferred, more robust)
  • name="exact" — Exact match
  • nth=0 — Select first when multiple matches

Wait Conditions

webctl wait network-idle
webctl wait 'exists:role=button name~="Continue"'
webctl wait 'url-contains:"/dashboard"'

Troubleshooting

ERR_TUNNEL_CONNECTION_FAILED

Auth proxy not loaded. Verify:

  1. auth_proxy.py exists in webctl daemon directory
  2. Session manager is patched
  3. Restart daemon: webctl stop --daemon && webctl start --mode unattended

Multiple matches error

Add specificity or use nth=0:

webctl click 'role=link name="Sign in" nth=0'

Verify proxy is running

netstat -tlnp | grep 18080

Limitations

  • Patch is session-local (container resets clear it)
  • Only allowed domains in network config are accessible
  • No Firefox support (download blocked by egress policy)

Domain Restrictions

Check <network_configuration> in system prompt for allowed domains. Common allowed: *.github.com, *.bsky.app, allowed API endpoints.

Output Filtering

Reduce context consumption:

webctl snapshot --interactive-only --limit 30    # Cap elements
webctl snapshot | grep -i "submit"               # Unix filtering
webctl --quiet navigate "..."                    # Suppress events

Source

git clone https://github.com/oaustegard/claude-skills/blob/main/using-webctl/SKILL.mdView on GitHub

Overview

This skill enables browser automation inside Claude.ai containers using webctl, with a local forwarding proxy that injects Proxy-Authorization headers to pass through the authenticated egress proxy. It supports Playwright/Chromium navigation and web scraping behind the container proxy. The setup intercepts Chromium connections on port 18080 and patches the session manager to route traffic through the proxy.

How This Skill Works

Install webctl and its Chromium runtime, then deploy a local auth proxy (auth_proxy.py) into webctl's daemon. Patch the session manager to obtain a local proxy URL from the auth proxy and pass it to the Chromium context as a proxy configuration. This enables authenticated proxy handling for HTTPS connections in Claude.ai containers, improving reliability when navigating through the egress proxy.

When to Use It

  • User requests browser automation, web scraping, or page interaction inside Claude.ai containers.
  • webctl commands fail with ERR_TUNNEL_CONNECTION_FAILED indicating missing or misloaded proxy auth.
  • Playwright/Chromium must operate through an authenticated HTTP proxy in the container environment.
  • Operating in an egress-controlled setup where direct browser traffic is blocked or filtered.
  • Need reliable, headless browser tasks (navigation, interaction, and screenshots) behind the proxy.

Quick Start

  1. Step 1: Install webctl and set up Chromium: pip install webctl --break-system-packages; webctl setup
  2. Step 2: Deploy the auth proxy: copy scripts/auth_proxy.py to the webctl daemon directory
  3. Step 3: Patch the session manager to use the local proxy from auth_proxy and verify with webctl navigate

Best Practices

  • Install webctl with --break-system-packages to ensure Chromium dependencies are available.
  • Copy scripts/auth_proxy.py to the webctl daemon directory as instructed.
  • Patch session_manager.py to use get_local_proxy_url() and set proxy in browser context.
  • Verify setup by starting the daemon, navigating to a URL, and taking a snapshot.
  • If ERR_TUNNEL_CONNECTION_FAILED persists, confirm the auth proxy is loaded and the daemon is restarted.

Example Use Cases

  • Navigate to a public site (e.g., https://github.com) from within a Claude.ai container and verify via a snapshot.
  • Perform a web scraping task behind the authenticated proxy and extract dynamic content.
  • Use webctl query and click actions to interact with a SPA behind the proxy (e.g., login flow).
  • Capture a visual test (screenshot) of a page to validate layout behind the egress proxy.
  • Diagnose proxy loading issues by checking port 18080 and confirming auth_proxy.py presence in the daemon directory.

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers