本文へスキップ

デプロイ — Docker と CDP エンドポイント

Clearcote を常駐の CDP エンドポイントとして動かし、既存のフレームワーク(Playwright、Puppeteer、browser-use、Crawl4AI、Stagehand など)の接続先をそこに向けるだけで使えます。コードの変更は不要です。バイナリを直接起動する(--enable-automation なし)ので、navigator.webdriver は false のままです。仕組みからしてステルスです。

公式 Docker イメージ

イメージを pull すればすぐに使えます。CDP クライアントは公開したポート経由で接続します。

bash
docker run -d --rm -p 127.0.0.1:9222:9222 -e CC_FINGERPRINT=user-7423 teamflatearth/clearcote   # CDP on http://localhost:9222

この方法では、sdk-0.41.0 より前のすべてのイメージと同じく、Chrome はサンドボックスなしで動作します。イメージの seccomp プロファイルを追加すると、Chrome はサンドボックスありで動作します。後述のChrome のサンドボックスを参照してください。

python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp("http://localhost:9222")   # your code, unchanged
    page = browser.contexts[0].new_page()                            # the container's own profile
    page.goto("https://example.com")
    print(page.title())

イメージには、SHA-256 で検証済みの Linux 向けオープンビルド、Windows フォントとメトリック互換のフォント(そのため、ラテン文字のテキストはペルソナのフォントと同じ寸法で計測されます)、そして sdk-0.41.0 以降は、Windows マシンが標準で描画できるそのほかの文字体系のフォント(フォントを参照)が組み込まれています。デフォルトのペルソナは、整合性のあるネイティブ Linux です。ブラウザは仮想ディスプレイ上で headed モードで動作します(純粋なヘッドレスにするには CC_HEADLESS=1)。コンテナに GPU がない場合、WebGL は、ペルソナが名乗る GPU と上限値が一致するバックエンドでソフトウェア描画されます。Linux ペルソナでは headed・ヘッドレスを問わず Mesa、Windows ペルソナでは SwiftShader です。設定はすべて環境変数で行います。

bash
docker run -d -p 127.0.0.1:9222:9222 -e CC_PLATFORM=linux -e CC_FINGERPRINT=user-7423 -e CC_ACCEPT_LANGUAGE=en-US -e CC_TIMEZONE=America/New_York teamflatearth/clearcote
変数意味
CC_FINGERPRINTシード → 安定したアイデンティティ。指定しないと、コンテナごとにランダムなシードが割り当てられます。シードは起動時に出力され、コンテナのプロファイルに保存されて再起動後も維持されます(sdk-0.39.0 より前のイメージでは、すべてのコンテナが同じシードでした)。アイデンティティを選んだり再利用したりするには、この変数を設定します。
CC_PLATFORMlinux(デフォルト)| windows | macos | android。Windows ペルソナでは Widevine も有効になり、ライセンスビルド(151 r15+)では HLSL シェーダー方言も有効になります(上書きするには CC_WIDEVINE / CC_SHADER_DIALECT)。
CC_BRAND、CC_BRAND_VERSIONChrome(デフォルト)| Edge | Opera | Vivaldi と、名乗るバージョン。
CC_ACCEPT_LANGUAGE、CC_TIMEZONE言語リストと IANA タイムゾーン。
CC_TLS_PROFILE未設定のままにしてください。TLS はペルソナが名乗る Chrome のバージョンに従います。chrome-<major> で固定するのは、対応する CC_BRAND_VERSION と組み合わせる場合だけにしてください。
CC_HARDWARE_CONCURRENCY、CC_GPU_VENDOR、CC_GPU_RENDERER、CC_STORAGE_QUOTAペルソナの個別の値。
CC_HEADLESS、CC_SCREEN1 で純粋なヘッドレス。仮想スクリーンのサイズ(デフォルトは 1920x1080x24)。
CC_EXTRA_ARGS追加のブラウザスイッチ(スペース区切り)。ここに指定した --disable-runtime-suppression は SDK の stock_runtime に相当します(スイッチを持つエンジンでのみ残ります)。--no-sandbox は Chrome のサンドボックスをオフにします。
CLEARCOTE_LICENSE_KEY、CC_VERSIONライセンスビルドを実行します(後述)。
CC_IDLE_EXIT_SECONDSCDP クライアントが接続していない状態がこの秒数続くと停止します。カウントはブラウザが最初に応答した時点から始まります(デフォルトでは停止しません)。--rm と組み合わせると、放置されたコンテナも削除されます。sdk-0.40.0 以降のイメージで使えます。
CC_SECRETS_FILECLEARCOTE_LICENSE_KEY と CC_PROXY(またはそのどちらか)を記述した、コンテナ内の JSON ファイル。起動時に一度だけ読み込まれ、その後削除されます。シークレットを docker inspect に出さない方法を参照してください。sdk-0.40.0 以降のイメージで使えます。
CLEARCOTE_FONT_DIRSコンテナにマウントした独自のフォント(たとえば Windows マシンの Fonts フォルダーのコピー)。フォントを参照してください。sdk-0.41.0 以降のイメージで使えます。
CLEARCOTE_FALLBACK_FONT_DIRSほかのどのフォントにもない文字にだけ使うフォント。イメージは、同梱の各文字体系用フォント(/usr/local/share/clearcote/fonts)をこれに設定しています。それらを置き換えるのでなければ、変更しないでください。
CLEARCOTE_PERSONA_ENV0 にすると、ペルソナをブラウザのコマンドラインに残します。デフォルトでは、対応するエンジン(r32 以降のライセンスビルド)であれば、ペルソナは環境変数経由でコンテナ内のブラウザに渡されるため、ホストのプロセス一覧には現れません。serve-state 行が persona_env を報告します。sdk-0.41.0 以降のイメージで使えます。
コンテナが実際に動いている OS を名乗ってください。ページが読み取れる情報の一部はブラウザの下にあるホスト OS から来ており、ペルソナの設定はそこまで届きません。この Linux イメージでは、CC_PLATFORM の値にかかわらず、テキストのサイズは Linux の FreeType スケーラーで決まり、フォントは fontconfig から供給されます。このイメージで CC_PLATFORM=windows として計測したところ、フォントサイズを 0.01 px ずつ変えたときにテキスト幅が変わったのは 66% のステップでした(実際の Windows 版 Chrome では 99%)。また、Segoe UI と Georgia は計測上はインストール済みに見えるものの、名前を指定して読み込むことはできません。フィンガープリントテストはこの両方を検出します。デフォルトの Linux ペルソナは問題なく通ります。r32 以降のライセンスビルドでは、CLEARCOTE_FONT_DIRS で本物の Windows フォントをマウントすれば名前の問題は解消します(フォント)。ただし、スケーラーはどの設定でも変えられないため、こちらは解消しません。Windows のアイデンティティが必要なら、Windows ビルドを使うか、Windows マシン上で動くホスト型ブラウザを使ってください。Linux サーバー上の serve() や launch() にも同じことが当てはまります。詳細:ユーザーエージェントの下にあるフォントスタック

Docker でライセンスビルドを使う — キーを渡し、キャッシュをマウントする

イメージにはオープンビルドが組み込まれています。CLEARCOTE_LICENSE_KEY を設定すると、コンテナは代わりにライセンスビルドを使います。使われるのは最新のビルドで、Pro プランなら CC_VERSION で特定のビルドを指定できます。無料キーでは常に最新のビルドが動作し、バージョンの固定は拒否されます。

bash
docker run -d -p 127.0.0.1:9222:9222 -v clearcote-cache:/opt/xdg-cache -e CLEARCOTE_LICENSE_KEY=cc_lic_... teamflatearth/clearcote

# Pro only: pin a major, an exact build, or a revision
#   -e CC_VERSION=154        -e CC_VERSION=154.0.8037.57        -e CC_VERSION=r36

キャッシュボリュームは必ずマウントしてください。ライセンスビルドのコンテナは、初回起動時にエンジンをダウンロードします。永続化したボリュームがないと、すべてのコンテナが毎回ダウンロードし直します。ボリュームがあれば、2 回目以降のコンテナはキャッシュ済みのビルドから起動します。

起動ログにどのエンジンが使われたかが表示されるので、キーの設定ミスには、最初のリクエストがブロックされた時点ではなく、起動直後に気づけます。

text
[clearcote] engine: /opt/xdg-cache/clearcote/pro-154.0.8037.57-r36/browser/chrome (licensed)
[clearcote] licence lease acquired
SDK 0.26.1 以降でビルドしたイメージが必要です。GitHub で取得した無料キーの場合は 0.30.0 以降が必要です。ライセンスビルドのブラウザは、無料キーのコンテナが実行中もライセンスを最新の状態に保つことを前提としており、それより古いイメージは拒否します。以前に公開された古いイメージはキーを無視し、黙ってオープンビルドを提供します。docker pull teamflatearth/clearcote で更新してください。ライセンスビルドの実行では、起動時に同時実行数のリースも取得するため、コンテナからライセンス API へのアウトバウンド通信が必要です。リースの取得に失敗すると、コンテナは動作できないエンジンを起動するのではなく、理由を表示して終了します。無料キーでは、すべてのコンテナを通じて同時に動かせるブラウザは 1 つです。ライセンスブラウザの数え方を参照してください。

イメージ sdk-0.40.0 以降では、同じキャッシュボリュームを使うライセンスビルドのコンテナを複数同時に起動しても、エンジンのダウンロードは一度だけです。最初のコンテナがダウンロードし、ほかのコンテナはその完了を待ちます。

シークレットを docker inspect に出さない

-e で渡した変数はすべてコンテナの設定の一部になります。そのため、そのコンテナに対して docker inspect を実行できる人(あるいは docker compose config や、たいていのコンテナ管理ダッシュボードを見られる人)には、CLEARCOTE_LICENSE_KEY と、CC_PROXY の URL に含まれるパスワードが平文で見えてしまいます。イメージ sdk-0.40.0 以降では、これらを代わりにファイルで渡せます。CC_SECRETS_FILE で指定したコンテナ内の JSON ファイルで、コンテナは起動時に一度だけそれを読み込み、削除します。このファイルの所有者は、イメージのユーザー(uid 10001)でなければなりません。

bash
printf '{"CLEARCOTE_LICENSE_KEY": "%s"}' "$CLEARCOTE_LICENSE_KEY" > clearcote-secrets.json
tar --owner=10001 --group=10001 --mode=600 -cf clearcote-secrets.tar clearcote-secrets.json
id=$(docker create -p 127.0.0.1:9222:9222 -e CC_SECRETS_FILE=/tmp/clearcote-secrets.json   -v clearcote-cache:/opt/xdg-cache teamflatearth/clearcote)
docker cp - "$id:/tmp" < clearcote-secrets.tar    # copy the file in before the container starts
docker start "$id"
rm clearcote-secrets.json clearcote-secrets.tar

SDK の macOS での起動も、この方法を使っています。ただし Docker デーモンにアクセスできる人は、実行中のコンテナのファイルやメモリを読み取れます。デーモンへのアクセス権は、キーへのアクセス権と同じものとして扱ってください。

sdk-0.40.0 以降のイメージは、init プロセスとして tini を実行します。そのため、コンテナ内で終了したブラウザのヘルパープロセス(たとえば docker exec で実行した、独自にブラウザを起動するスクリプトから生じるもの)は、溜まり続けることなく回収されます。docker stop はこれまでどおりブラウザまで届き、ライセンスの枠を解放します。

フォント

ブラウザから見えるのは、SDK が指定したフォントだけです。まずリリースに同梱された Windows の代替フォント、次に以下のディレクトリです。/usr/share/fonts にあるそれ以外のフォントは届かないため、イメージにフォントをインストールしても、Windows ペルソナが報告する文字幅が変わることはありません。イメージ sdk-0.41.0 以降:

  • 各文字体系用のフォントを内蔵しています。カラー絵文字、中国語・日本語・韓国語(WenQuanYi Zen Hei、IPA Gothic)、そしてアラビア文字、アルメニア文字、ベンガル文字、チェロキー文字、デーヴァナーガリー、エチオピア文字、ジョージア文字、グジャラート文字、グルムキー文字、カンナダ文字、クメール文字、ラーオ文字、マラヤーラム文字、ミャンマー文字、シンハラ文字、タミル文字、テルグ文字、タイ文字、チベット文字などの Noto 書体が /usr/local/share/clearcote/fonts に入っており、CLEARCOTE_FALLBACK_FONT_DIRS がこれをバンドルの後に並べます。これらはバンドルで描画できない文字にだけ使われるため、そうした文字は空の四角形として表示されることなく描画されます。オープンビルドでもライセンスビルドでも同じです。ラテン文字のファミリーは追加されません。
  • 独自のフォント。フォントのディレクトリ(一般的には Windows マシンの C:\Windows\Fonts のコピー)をマウントし、CLEARCOTE_FONT_DIRS で指定します。このディレクトリはバンドルより前に並びます。r32 以降のライセンスビルドでは、ここにあるファミリーはどれもそのフォント自身として、自身の名前で描画され、Helvetica、Times、Courier と CSS の総称ファミリーもそれに従います。古いエンジンは代替フォントを使い続け、このディレクトリはほかのどのフォントにもない文字にだけ使います。使用許諾を受けたフォントだけを使ってください。Docker の外で同じことを行う設定が、SDK の fontDirs です。
bash
docker run -d -p 127.0.0.1:9222:9222 -v /srv/windows-fonts:/fonts:ro -e CLEARCOTE_FONT_DIRS=/fonts \
  -e CC_PLATFORM=windows -v clearcote-cache:/opt/xdg-cache -e CLEARCOTE_LICENSE_KEY=cc_lic_... teamflatearth/clearcote
docker exec <container> clearcote info --quick   # which writing systems render, which families are genuine
セキュリティ:CDP エンドポイントはブラウザを完全に制御できます。信頼できるネットワークにだけ公開してください。-p 127.0.0.1:9222:9222 ならホスト内に限定されます。docker/ Dockerfile は監査可能です。自分で再ビルドして検証してください。

Chrome のサンドボックス

Chrome の Linux 用サンドボックスは、各レンダラー(ページを解析・実行するプロセス)を、専用の名前空間の中で seccomp フィルターの下で動かします。そのため、ページがレンダラーを乗っ取っても、その影響はレンダラーの中にとどまります。--no-sandbox を付けると、レンダラーはコンテナのユーザーが持つすべて、つまりそのファイル、ネットワーク、ほかのプロセスにアクセスできます。Docker のデフォルトの seccomp プロファイルは、こうした名前空間を作成する呼び出しを拒否するため、sdk-0.41.0 より前のイメージは常に --no-sandbox で Chrome を実行していました。

イメージ sdk-0.41.0 以降では、コンテナがまず確認を行います。Chrome のサンドボックスと同じ呼び出しを試し、それが成功すれば Chrome をサンドボックスありで実行します。イメージに同梱の seccomp プロファイルを指定してコンテナを起動してください。これは Docker のデフォルトのプロファイルに、Chrome が必要とする名前空間関連の 2 つの呼び出しを追加したものです。

bash
# copy the profile out of the image (--tmpfs keeps docker from first copying the engine into a volume)
docker run --rm --tmpfs /opt/xdg-cache --entrypoint cat teamflatearth/clearcote /etc/clearcote/seccomp.json > clearcote-seccomp.json
docker run -d -p 127.0.0.1:9222:9222 --security-opt seccomp=clearcote-seccomp.json teamflatearth/clearcote
yaml
# docker compose
services:
  clearcote:
    image: teamflatearth/clearcote
    ports: ["127.0.0.1:9222:9222"]
    security_opt: ["seccomp=./clearcote-seccomp.json"]
  • どちらになったかはログに表示されます。[clearcote] sandbox: on (…)、または理由と有効にする方法を添えた [clearcote] sandbox: OFF, Chrome runs with --no-sandbox: … です。serve-state 行には "sandbox": true または false が含まれます。プロファイルを指定しなければ、コンテナはこれまでとまったく同じように動作します。
  • ほかにも、イメージ自身のユーザー(--user 0 ではなく)、CAP_SYS_CHROOT(デフォルトで付与されます。--cap-drop ALL を使う場合は --cap-add SYS_CHROOT で付け直してください)、非特権ユーザー名前空間を許可するホスト、amd64 のマシンが必要です。どれかが欠けている場合、コンテナは --no-sandbox にフォールバックし、その理由を表示します。
  • トレードオフ:このプロファイルを使うと、Chrome に限らずコンテナ内のどのプロセスも、専用のネットワーク名前空間を持つユーザー名前空間を作成できるようになり、Docker のデフォルトのプロファイルでは届かないカーネルのネットワーク関連のコードに到達できます。信頼できないページが動く Chrome のレンダラーは、引き続き Chrome 独自のフィルターの下にあります。サンドボックスがなければ、乗っ取られたレンダラーはコンテナのユーザーが持つすべてにアクセスできるため、それでもプロファイルを使うほうが適切です。代わりに --privileged、--cap-add SYS_ADMIN、seccomp=unconfined を使うのはやめてください。これらはコンテナの保護をはるかに広い範囲でオフにしてしまいます。
  • CC_EXTRA_ARGS=--no-sandbox を指定すると、意図的にオフにできます。--no-zygote、--disable-namespace-sandbox、--renderer-cmd-prefix=、canvas ブリッジ(--canvas-bridge-url=)もサンドボックスをオフにします。この環境では、これらと併用すると Chrome がサンドボックスを動かせないためです。
  • SDK の macOS での起動は、x86_64 CPU 上で動く Docker であれば、このプロファイルを自動で渡します。Apple シリコンではイメージがエミュレーションで動作するため、現時点ではサンドボックスはオフのままです。

SDK から常駐 CDP エンドポイントを立てる — serve()

バイナリを自分で起動し、どのクライアントからでも接続できる cdp_url を取得します。イメージと同じステルスな直接起動を、自分のプロセスから行えます。

python
from clearcote import serve

srv = serve(fingerprint="seed-123", platform="windows")   # -> srv.cdp_url
# attach ANY CDP client:
#   playwright:  p.chromium.connect_over_cdp(srv.cdp_url)
#   puppeteer:   puppeteer.connect({ browserURL: srv.cdp_url, defaultViewport: null })
#   browser-use / Crawl4AI / Stagehand: point them at srv.cdp_url
srv.close()
javascript
import { serve } from "clearcote";
const srv = await serve({ fingerprint: "seed-123", platform: "windows" });
// srv.cdpUrl -> connectOverCDP / puppeteer.connect({ browserURL, defaultViewport: null })
await srv.close();

ヘッドレスの場合、提供されるブラウザには実寸のディスプレイ(ペルソナのもの、または実際のデスクトップから抽出したもの)が割り当てられ、クライアントが接続する前にウィンドウが作業領域に合わせられます。そのため、どのページ、タブ、ポップアップも、画面に収まるウィンドウを報告します(SDK 0.31+)。ウィンドウを小さくしたい場合は windowSize: { width, height }(Python では window_size、.NET では WindowSize)を渡してください。自分で制御したい場合は、args に独自の --window-size を渡します。

1 つのエンドポイントで複数のアイデンティティ — clearcote serve

シェルからは(Python と Node のパッケージ、0.29+)、clearcote serve で常駐エンドポイントを動かせます。このエンドポイントは、接続が要求するアイデンティティごとに別々のブラウザを起動します。シード、プロキシ、タイムゾーン、言語は接続 URL から取得します。同じシードなら、起動中のブラウザを再利用します。

bash
clearcote serve --port 9222 --idle-timeout 300 --max-browsers 16

# then, from any Playwright client:
#   chromium.connect_over_cdp("http://127.0.0.1:9222?fingerprint=acct-1&platform=windows")
#   chromium.connect_over_cdp("http://127.0.0.1:9222?fingerprint=acct-2&proxy=socks5://user:pass@host:1080&geoip=true")
#   (a password-protected proxy needs the licensed build)

デフォルトでは localhost にバインドし、Web ページから発行されうるリクエストは拒否します。アイドル状態のアイデンティティは --idle-timeout 秒後に閉じられ、--max-browsers で同時に動かす数の上限を設定できます(上限を超えたアイデンティティには HTTP 429 が返ります)。--data-dir を使うと再起動をまたいで各アイデンティティのプロファイルが保持され、--allow-host / --allow-origin を使うとリバースプロキシの背後で動かせます。http://127.0.0.1:9222/ を開くと、動作中のものを確認できます。「GitHub で無料」のキーでは、同時に動くブラウザは 1 つだけです。以前の単一アイデンティティ用スクリプト clearcote-serve --port 9222 --fingerprint seed-123 も、引き続き Python パッケージに含まれています。

直接起動 — SDK なしでオープンビルドを使う

Releases ページにあるオープンビルドは素の Chromium バイナリなので、executable_path とスイッチを指定して自分で起動できます。ライセンスビルドには、ライセンストークンを保持する SDK が必要です。以下の追加引数は、Windows 上でこのシードに対して SDK が付与する主なデフォルトです(SDK はさらに feature フラグをマージし、プロキシ経由の場合は QUIC をオフにします)。

python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        executable_path=r"C:\clearcote\chrome.exe",
        ignore_default_args=["--enable-automation", "--enable-unsafe-swiftshader"],
        args=[
            "--fingerprint=seed-123",
            "--fingerprint-platform=windows",
            "--fingerprint-brand=chrome",
            "--accept-lang=en-US,en",
            "--lang=en-US",
            "--timezone=America/New_York",
            "--webrtc-ip-handling-policy=disable_non_proxied_udp",
            "--ignore-gpu-blocklist",
        ],
    )
    browser.new_page().goto("https://example.com")

独自のイメージをビルドする(SDK ベース)

Clearcote は Linux x64 のバイナリを提供しているので、コンテナ内でヘッドレスで動かせます。イメージには、ブラウザのランタイムライブラリ、fontconfig、SDK が必要です。ブラウザはシステムフォントではなく、リリースに同梱のフォントバンドルを使います。そのため、apt でインストールしたフォントは、指定するまでブラウザからは見えません。公式イメージと同じように、各文字体系用のフォントを 1 つのディレクトリにリンクして CLEARCOTE_FALLBACK_FONT_DIRS で指定するか(SDK 0.41.0+)、独自のフォントを CLEARCOTE_FONT_DIRS で指定してください(フォントを参照)。/usr/share/fonts 全体を指定してはいけません。そこにあるラテン文字のファミリーによって、Windows ペルソナの文字幅が変わってしまいます。Linux では、ペルソナはデフォルトで整合性のあるネイティブ Linux のアイデンティティになります。WebRTC の漏洩対策はデフォルトで有効で、Privacy Sandbox の API は Google Chrome と同じく有効のままです。libegl1 と libgl1-mesa-dri をインストールしておくと、SDK は Linux ペルソナの WebGL を EGL 経由の Mesa で描画し、上限値とレンダラーの形式が実際の Linux マシンが報告するものと同じになります。ヘッドレスでは SDK 0.39.0 から、headed でも 0.42.0 からこの動作になるため、どちらのモードでも WebGL のサーフェスは 1 つです。これらがない場合は SwiftShader にフォールバックします。ウィンドウマネージャーのない Xvfb 上で headed 起動すると、最初のページの前にウィンドウが画面に合わせられます(SDK 0.42.0)。

dockerfile
FROM node:22-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
      xz-utils libnss3 libnspr4 libgbm1 libasound2 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
      libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libxfixes3 libxext6 libxrender1 \
      libpango-1.0-0 libcairo2 libx11-6 libxcb1 libexpat1 libdbus-1-3 ca-certificates libegl1 libgl1-mesa-dri \
      fontconfig fonts-noto-color-emoji fonts-ipafont-gothic fonts-wqy-zenhei \
 && F=/usr/local/share/clearcote/fonts && mkdir -p $F && cd /usr/share/fonts \
 && cp -l truetype/noto/NotoColorEmoji.ttf truetype/wqy/wqy-zenhei.ttc opentype/ipafont-gothic/ipag.ttf $F/ \
 && rm -rf /var/lib/apt/lists/*
# emoji + CJK, used only where the bundle has no glyph
ENV CLEARCOTE_FALLBACK_FONT_DIRS=/usr/local/share/clearcote/fonts
WORKDIR /app
RUN npm i clearcote
RUN node --input-type=module -e "import { download } from 'clearcote'; await download();"   # bake the binary in
COPY run.mjs .
CMD ["node", "run.mjs"]
run.mjs
import { launchPersistentContext } from "clearcote";
const ctx = await launchPersistentContext("/tmp/prof", {
  headless: true,
  fingerprint: "user-1",
  proxy: { server: "http://gateway:8080", username: "u", password: "p" },
  geoip: true,      // timezone + languages + WebRTC IP matched to the proxy exit
  humanize: true,   // trusted bezier input; navigator.webdriver stays false
  args: ["--no-sandbox"],
});
const page = ctx.pages()[0] ?? (await ctx.newPage());
await page.goto("https://example.com");
await ctx.close();
重いページで /dev/shm が原因のクラッシュが起きないよう、コンテナは --shm-size=1g を付けて実行してください。Python でもまったく同じです(from clearcote import launch_persistent_context、オプションは snake_case)。

CDP で接続できるもの

クライアント方法
Playwrightchromium.connect_over_cdp(url) / connectOverCDP(url)
Puppeteerpuppeteer.connect({ browserURL: url, defaultViewport: null })
browser-use · Crawl4AI · StagehandCDP / エンドポイントの設定をその URL に向ける
CDP に対応したあらゆるクライアントそのポートで生の DevTools Protocol を使う

代わりに AI エージェントに操作させたい場合は、MCP サーバーを参照してください。直接起動のほうがステルス性が高い理由は、検知の仕組みで解説しています。