mcpField
U
using-webctl

using-webctl

github.com/oaustegard開発15744 回インストール1 日前に更新
リポジトリ

using-webctl について

Claude.ai コンテナで webctl コマンドラインを使ったブラウザー自動化を支援するスキルです。Chromium の認証プロキシ回避策と、ページの移動・確認・操作コマンドを説明します。

主な機能

  1. 01認証プロキシ転送の設定
  2. 02webctl のセッションと移動コマンド
  3. 03ページスナップショットとスクリーンショット
  4. 04ARIA ベースの検索と操作
  5. 05プロキシのトラブルシューティング

活用シーン

  1. 01Claude.ai コンテナでのブラウザー操作の自動化
  2. 02スナップショットによるページ確認
  3. 03フォームやページ内コントロールの操作
  4. 04Chromium のプロキシトンネル障害の解決

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/oaustegard/claude-skills --skill using-webctl

インストール後、Claude Code で/using-webctlを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

CHANGELOG.md
README.md
scripts/
auth_proxy.py
setup_webctl.py

詳細

Claude.ai コンテナでの webctl の使用

Claude.ai の送信トラフィックが制御された環境で、自動プロキシ認証処理を使って webctl CLI でブラウザーを自動化します。

このスキルを使用する場面

  • ユーザーがブラウザーの自動化、ウェブスクレイピング、またはページ操作を依頼した場合
  • webctl コマンドが ERR_TUNNEL_CONNECTION_FAILED で失敗する場合
  • Playwright/Chromium を認証付き HTTP プロキシ経由で動作させる必要がある場合

主な問題

Claude.ai コンテナは、認証付きの送信プロキシ(JWT 認証情報を含む HTTP_PROXY 環境変数)経由でトラフィックをルーティングします。Chromium は HTTPS CONNECT トンネルのプロキシ認証を適切に処理できないため、curl は動作しても HTTPS ナビゲーションはすべて失敗します。

解決策

ローカルのフォワーディングプロキシ(ポート 18080)が Chromium の接続を中継し、実際の送信プロキシに転送する前に Proxy-Authorization ヘッダーを挿入します。

セットアップ手順

1. webctl をインストールする
pip install webctl --break-system-packages
webctl setup  # Downloads Chromium if needed
2. 認証プロキシモジュールを配置する

еcripts/auth_proxy.py を webctl のデーモンディレクトリにコピーします。

cp /mnt/skills/user/using-webctl/scripts/auth_proxy.py \
   /usr/local/lib/python3.12/dist-packages/webctl/daemon/
3. セッションマネージャーにパッチを適用する

このパッチを /usr/local/lib/python3.12/dist-packages/webctl/daemon/session_manager.py に適用します。

最近の webctl バージョンでは、コンテキストの作成処理が(モバイルエミュレーションとデスクトップの)2 つの分岐に分かれています。どちらにもプロキシ設定を適用する必要があります。cfg = WebctlConfig.load() に続いて if mode == "unattended" and cfg.mobile_emulation: の分岐があるブロックを探します(190 行目付近)。

cfg = WebctlConfig.load()
if mode == "unattended" and cfg.mobile_emulation:
    # Mobile emulation: cleaner pages, fewer ads, simpler layouts
    device = self._playwright.devices["Pixel 7"]
    context = await browser.new_context(
        storage_state=storage_state,
        **device,
    )
else:
    context = await browser.new_context(
        storage_state=storage_state, viewport={"width": 1280, "height": 720}
    )

次の内容に置き換えます。

cfg = WebctlConfig.load()
from .auth_proxy import get_local_proxy_url
proxy_url = get_local_proxy_url()
proxy_config = {"server": proxy_url} if proxy_url else None
if mode == "unattended" and cfg.mobile_emulation:
    # Mobile emulation: cleaner pages, fewer ads, simpler layouts
    device = self._playwright.devices["Pixel 7"]
    context = await browser.new_context(
        storage_state=storage_state,
        proxy=proxy_config,
        **device,
    )
else:
    context = await browser.new_context(
        storage_state=storage_state, viewport={"width": 1280, "height": 720},
        proxy=proxy_config
    )

ファイルに new_context の呼び出しが 1 つしかない場合(古い webctl)、その呼び出しに proxy=proxy_config を挿入し、その直前に 3 行の proxy_url を配置します。

4. 検証する
webctl start --mode unattended
webctl --quiet navigate "https://github.com"
webctl snapshot --interactive-only --limit 10
webctl stop

クイックリファレンス

セッション管理
webctl start --mode unattended    # Headless browser
webctl stop                       # Full shutdown (use --keep-daemon to leave daemon running)
webctl status                     # Current state + console error counts
ナビゲーション
webctl navigate "https://..."
webctl back / webctl forward / webctl reload
観察
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
操作
webctl click 'role=button name~="Submit"'
webctl type 'role=textbox name~="Email"' "[email protected]"
webctl type 'role=textbox name~="Search"' "query" --submit
webctl select 'role=combobox name~="Country"' --label "Germany"
クエリ構文
  • role=button — ARIA ロールで指定
  • name~="partial" — 部分一致(推奨。より堅牢です)
  • name="exact" — 完全一致
  • nth=0 — 複数一致する場合に最初の要素を選択
待機条件
webctl wait network-idle
webctl wait 'exists:role=button name~="Continue"'
webctl wait 'url-contains:"/dashboard"'

トラブルシューティング

ERR_TUNNEL_CONNECTION_FAILED

認証プロキシが読み込まれていません。次を確認してください。

  1. webctl のデーモンディレクトリに auth_proxy.py が存在する
  2. セッションマネージャーにパッチが適用されている
  3. デーモンを再起動する:webctl stop && webctl start --mode unattended
複数一致エラー

条件をより具体的にするか、nth=0 を使用します。

webctl click 'role=link name="Sign in" nth=0'
プロキシが動作していることを確認する
netstat -tlnp | grep 18080

制限事項

  • パッチはセッション内でのみ有効です(コンテナをリセットすると消去されます)
  • ネットワーク設定で許可されたドメインのみアクセスできます
  • Firefox はサポートされていません(送信ポリシーによりダウンロードがブロックされます)

ドメイン制限

システムプロンプトの <network_configuration> で許可されたドメインを確認してください。一般的な許可ドメイン:*.github.com、*.bsky.app、許可された API エンドポイント。

出力フィルタリング

コンテキストの消費を抑えます。

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

コメント