Playwright MCP×Claude Codeでログイン操作を自動化する設計|run_code_unsafeで同一ページ実行
Claude Code と Playwright MCP を組み合わせてブラウザ操作を自動化していると、テスト対象環境への「毎回同じログイン手順」を、いかに少ないツール往復で・後続操作に引き継げる形で実行するかが課題になります。この記事では、browser_run_code_unsafe で本物の Playwright スクリプトを同一ページ上で一気通貫実行する設計に至るまでの検討過程を、メリット・リスク・却下した代替案とあわせて整理します。特定のサービスに依存しない、汎用的な自動化パターンとして読めるようまとめました。
何を自動化したかったのか?
「毎回同じログイン手順」を定型化したい
自動化したかったのは、テスト対象のステージング環境への定型ログインです。中身は毎回ほぼ同じで、次のような一連の操作を繰り返します。
- WAF などの前段を通すためのユーザーエージェント(UA)/ヘッダの上書き
- アクセス拒否(403)になっていないかのチェック
- 既存セッションのログアウト
- ログインフォームへのメール・パスワード入力と送信
- ログイン後ページへの遷移確認
これを Claude Code から Playwright MCP 経由で毎回手作業的に実行すると、ツール呼び出しが何往復も発生してしまいます。往復が増えるほど時間もセッション消費もかさむため、「引き継ぎやすさ」を保ったまま往復を最小化する設計を探しました。
認証情報はディスクに残さない前提
前提として、認証情報(メール・パスワード・バイパス用トークンなど)を平文でファイルに保存しない方針を置いています。毎回、安全な保管先から取得してメモリ上だけで扱う、という制約のもとで設計しています。
採用した設計:run_code_unsafe に一本化する
実行時の流れ
結論として採用したのは、テンプレート化した Playwright スクリプトを1回のツール呼び出しで同一ページ上に流し込む方式です。実行時の流れは次の4ステップです。
- 認証情報を安全な保管先から取得(メール・パスワード・バイパス用トークンを抽出)
- 静的なテンプレート JS ファイル(
pageを受け取って動く本物の Playwright コード)を読み込み、プレースホルダー(__EMAIL__など)を取得値で安全に置換する(JSON.stringifyでエスケープ)。これで完成した JS コード文字列ができる browser_run_code_unsafeを1回だけ呼び、完成コードをcodeパラメータで渡して実行。同じブラウザ/ページの中で「UA 上書き → 403 チェック → ログアウト → フォーム入力 → 送信 → 遷移確認」まで一気通貫で完了する- 戻り値(成功/失敗、遷移先 URL など)を見て、後続の手順固有ステップ(通常の
browser_snapshot/click等)に進む
ポイントは、ツール呼び出し回数が実質「認証情報の取得1回 + run_code_unsafe 1回」の2回に収まることです。
テンプレートは「指示書」ではなく「動くコード」
この設計の肝は、テンプレートが散文の手順書ではなく、実際に page を受け取って動く Playwright スクリプトである点です。プレースホルダーを実値で置換するだけで、そのまま実行可能なコードになります。
この方式のメリットは?
往復が激減し、引き継ぎ問題も起きない
最大の利点は、往復の削減とブラウザの引き継ぎやすさを両立できることです。
- 本物の Playwright スクリプト:テンプレートは実際に動くコードで、指示書ではない。解釈のブレが入らない
- 往復回数が激減:逐次ツール呼び出しの従来案(6〜7回)が2回になり、時間・セッション消費の両方が実質的に減る
- ブラウザの引き継ぎ問題がない:
browser_run_code_unsafeは、後続操作で使うのと同じページ上で動く。別プロセスの Node スクリプト案で懸念した「ログインだけ別ブラウザになり後続に引き継げない」問題が起きない - 追加インストール不要:スクリプトは Playwright MCP サーバー自身のプロセス内で実行されるため、実行 PC に Node.js/Playwright を別途入れる必要がない(MCP 自体が前提なので、追加の環境依存が発生しない)
- 秘密情報をディスクに残さない:認証情報は
codeパラメータとしてメモリ上で受け渡すだけで、ファイルに書き出さない
デメリット・リスクは何か?
強い権限のツールである点に注意
一方で、無視できないリスクもあります。とくに browser_run_code_unsafe が任意コード実行相当の強い権限を持つツールである点は、運用前に理解しておく必要があります。
- RCE 相当の強権限:
browser_run_code_unsafeは「RCE に相当する」と公式に説明されるツール。実行環境の権限モード次第では、初回に承認プロンプトが出る可能性が高い(通常のクリック・入力より警戒されやすい) - セレクタが未検証:ログインフォームのメール欄・パスワード欄・送信ボタンのセレクタは手順の記述から推測したもので、実際の DOM で動作確認できていない場合がある。初回実行で失敗しうるため、実物を見て調整が必要
- 置換ロジックは都度の作業として残る:プレースホルダー → 実値の置換はコード生成なので、置換ミスがあれば実行時エラーになる。値が毎回変わる以上、どこかで代入する工程は必ず残り、完全にゼロにはできない
- 認証情報取得のコストは残る:平文でファイル保存しない方針を守る以上、毎回1回の取得は残る(ただし1回のみで、反復的な手探りではない)
- 人的承認が必須の管理画面は対象外:SAML+多要素認証で人手による承認が必須の管理コンソールは、このスクリプトでは自動化できない。到達したら人に承認を仰ぐ運用は変わらない
却下した代替案との比較
今回の案にたどり着くまでに、いくつかの案を比較検討しました。往復回数・引き継ぎやすさ・PC 依存性の3軸で並べると違いが明確になります。
| 案 | 実体 | 往復回数 | 引き継ぎ | PC 依存 |
|---|---|---|---|---|
| 当初案(指示書) | Markdown 手順書。逐次ツール呼び出し | 多い(6〜7回) | 問題なし | なし |
| A案(evaluate 一本化) | 1回の browser_evaluate にまとめる |
少ない(2〜3回) | 問題なし | なし |
| B案(別 Node スクリプト) | 完全に独立したスクリプトを Bash で実行 | 最小(1回) | 別ブラウザになり引き継げない | Node/Playwright の導入が必要 |
| 採用案 | run_code_unsafe で同一ページ上に実行 |
少ない(2回) | 問題なし | なし(MCP プロセス内実行) |
採用案は、実質「B案の速さ」を「A案の引き継ぎやすさ・PC 非依存性」を保ったまま実現する形になっています。
まとめ:速さと引き継ぎやすさを両立させる勘所
Claude Code × Playwright MCP で定型ログインを自動化するなら、テンプレート化した本物の Playwright スクリプトを browser_run_code_unsafe で同一ページ上に一気に流すのが、往復の少なさとブラウザ引き継ぎやすさを両立する現実解でした。
一方で、このツールは任意コード実行相当の強い権限を持つため、承認フローやセレクタの実地検証は避けて通れません。秘密情報をディスクに残さない・毎回メモリ上で受け渡すという原則を守りつつ、強権限ツールの扱いに注意する——この2点が、安全に自動化を回すための勘所だと感じました。
※本記事は設計時点での検討内容をまとめたものです。ツールの権限モデルや API は将来変わる可能性があります。認証情報の取り扱いは、各自の環境のセキュリティポリシーに従ってください。