Skip to content

fix(devpod): launch playwright mcp via headless chromium wrapper (#999)#1000

Merged
takaokouji merged 2 commits into
developfrom
topic/autopilot-999
Jul 12, 2026
Merged

fix(devpod): launch playwright mcp via headless chromium wrapper (#999)#1000
takaokouji merged 2 commits into
developfrom
topic/autopilot-999

Conversation

@smalruby3-editor-bot

Copy link
Copy Markdown

Summary

committed .mcp.jsonplaywright MCP を devpod 内外どちらでも追加設定なしで headless
動作
する単一設定に修正する。実体は薄いラッパー tools/mcp/playwright-mcp.mjs 経由。

根本原因(調査結果)

Issue の当初案 --browser chromium --headlessdevpod では動かないことを実測で確認:

  • @playwright/mcp@latest(現在 0.0.78)がバンドルする playwright-core 1.62 は
    chromium-1232 を要求するが、コンテナには chromium-1217(リポジトリの playwright
    1.59.1 がイメージビルド時 = firewall 適用前に導入した分)しか無い。
  • 不足分は起動時に cdn.playwright.dev から download されるが、devpod の
    egress allowlist が cdn.playwright.dev を遮断しているため失敗する
    curl https://cdn.playwright.dev/ は接続不可を実測)。
  • 結果、素の npx @playwright/mcp@latest [--headless] では
    「Please run npx playwright install」で停止しブラウザが起動しない。

修正

tools/mcp/playwright-mcp.mjsrequire('playwright').chromium.executablePath()
ビルド時に導入済みの chromium を解決し、@playwright/mcp
--executable-path <path> --headless で渡す。

"playwright": {
  "type": "stdio",
  "command": "node",
  "args": ["tools/mcp/playwright-mcp.mjs"],
  "env": {}
}
  • devpod 内: ビルド時導入済み chromium を使う → 追加 download 不要で動く。
  • ホスト: 同じ解決でホストの chromium を使う(未導入でもホストは egress 制限が無いので取得可)。
  • 解決不能時は --executable-path を付けず MCP 既定挙動へフォールバック。

検証(devpod コンテナ内で実施)

  • 単体テスト: node --test tools/mcp/playwright-mcp.test.mjs → 8 pass(TDD: RED→GREEN)。
  • E2E: ラッパーを .mcp.json と同じ node tools/mcp/playwright-mcp.mjs で起動し、
    JSON-RPC で initializebrowser_navigate を実行。chromium-1217 が headless 起動し
    ページタイトルを読み戻せることを確認
    (追加 download なし)。
  • claude mcp list: project scope が node tools/mcp/playwright-mcp.mjs として認識される
    ことを確認(設定が正しくパースされる)。

ドキュメント

headful opt-in 手順と本修正の背景を .devcontainer/README.md に追記した
(既存の tools/host-playwright-mcp.sh の local-scope HTTP override を参照)。

Issue は .claude/rules/scratch-gui/e2e-test.md または .devcontainer/README.md
ドキュメント先として挙げていた。後者を選んだ理由: autopilot worker は root 実行
.claude/ 配下の編集が「自分の設定の編集」確認プロンプトで停止するため
.claude/ 外への配置が正攻法・PR #822 の方針)。

Related Issues

Closes #999

committed .mcp.json の playwright は headful 既定の npx 起動で、display の無い devpod では

ブラウザ起動に失敗していた。--headless を足しても MCP バンドルの playwright-core が要求する

新しい chromium を cdn.playwright.dev から取得しようとし、egress allowlist で遮断され失敗する。

そこで tools/mcp/playwright-mcp.mjs を経由し、リポジトリの playwright がビルド時に導入済みの

chromium を --executable-path で headless 起動する。devpod 内は追加 download 不要・ホストも

同じ解決で動作する単一 committable 設定になる。ホスト headful は既存 local-scope HTTP で opt-in。

Closes #999

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@smalruby3-editor-bot smalruby3-editor-bot Bot added the 🤖 autopilot autopilot が処理対象にした Issue/PR(daemon が付与) label Jul 12, 2026
@smalruby3-editor-bot

smalruby3-editor-bot Bot commented Jul 12, 2026

Copy link
Copy Markdown
Author

🤖 autopilot status

field value
Status Review
AI Status
HITL Yes
Size small

Linked issue #999. Maintained by autopilot (single writer); do not edit.

@github-actions

Copy link
Copy Markdown

🚀 Preview deployed: https://smalruby.jp/smalruby3-editor/topic/autopilot-999/

The README and wrapper JSDoc cited .claude/rules/scratch-gui/e2e-test.md
for the --host/--allowed-hosts gotchas and the "ホストで headful" section,
but those live in tools/host-playwright-mcp.sh's header and .devcontainer/README.md.
Fix the cross-references so readers land on the accurate source.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@smalruby3-editor-bot

Copy link
Copy Markdown
Author

[Question] ドキュメントの相互参照が不正確だったので修正済み(commit 64f3651)。

.devcontainer/README.mdtools/mcp/playwright-mcp.mjs の JSDoc が、headful の
ハマりどころ(--host 0.0.0.0 / --allowed-hosts)と「ホストで headful に見たい場合」
セクションの出典として .claude/rules/scratch-gui/e2e-test.md を挙げていました。しかし実際には:

  • --host / --allowed-hosts のハマりどころ → tools/host-playwright-mcp.sh の先頭コメントに集約されている(e2e-test.md には無い)。
  • 「ホストで headful に見たい場合」セクション → この PR が追加した .devcontainer/README.md 側にある(e2e-test.md には無い。e2e-test.md は host Chrome 操作を memory reference_host_playwright_mcp.md へ委譲しているだけ)。

読者を誤った出典に飛ばすため、参照先を実体のあるファイルに直しました(動作には影響なし・doc のみ)。

@smalruby3-editor-bot

Copy link
Copy Markdown
Author

[FYI] シャットダウン時の子孫プロセス孤立とシグナル終了コードについて(対応不要と判断)。

ラッパーの挙動をコンテナ内で実測した結果、機能面は問題なし(SIGTERM で ~1s 以内に終了・ハングなし、
子の終了コードは正しく透過: exit 37 → 37 / npx 不在 → exit 1)。以下は将来の参考メモ:

  1. spawn('npx', ...) は間に npx を挟むため、Claude Code が MCP を落とすとき
    ラッパー→npx へは SIGTERM が届くが、npx がその孫(実 @playwright/mcp → chromium)へ
    転送しないと chromium が孤立し得る。ただしこれは npx を使う構成に内在する問題で、
    従来の command: "npx" 直起動でも同様であり、本 PR による退行ではない。
  2. child.on('exit')process.kill(process.pid, signal) による再送は、同名の
    signal ハンドラが登録済みのため実際には再終了せず、イベントループ枯渇で exit 0 になる
    (128+signal ではない)。MCP のシャットダウンでは終了コードは問われないので実害なし。

より堅牢にするなら detached: true + プロセスグループ kill での木ごと終了が考えられますが、
効果に対し改修コストが見合わないため今回は据え置きが妥当と判断します。

@smalruby3-editor-bot

Copy link
Copy Markdown
Author

[FYI] @playwright/mcp@latest が未ピン止めである点(対応不要と判断)。

DEFAULT_MCP_SPEC = '@playwright/mcp@latest' のため、起動のたびに npx が最新版を解決します。
.claude/rules/supply-chain-security.md の 3 日ルールは主に package.json の deps を対象とし、
実行時 npx 取得や MCP ランチャは対象外で、かつ従来設定も @playwright/mcp@latest だったため
退行ではありません。buildMcpArgsmcpSpec 引数と単体テストで既にピン止めの余地が
用意されているので、将来 MCP 版の破壊的変更に遭遇したら @playwright/mcp@<version>
固定できます。今回は現状維持で問題ないと判断します。

@smalruby3-editor-bot

Copy link
Copy Markdown
Author

🤖 敵対的レビュー完了。指摘 3 件(Must 0 / Question 1 / FYI 2)。Question はドキュメント参照の不正確さで自分で修正済み(commit 64f3651)。FYI 2 件はコメントのみ(対応不要と判断)。

コアの修正はコンテナ内で E2E 実測済み: ラッパーがビルド時導入済み chromium-1217 を解決し、@playwright/mcp を headless 起動して JSON-RPC browser_navigate でページタイトルを読み戻せることを確認(追加 download なし)。単体テスト 8 pass、終了コード透過・SIGTERM 終了・npx 不在フォールバックも確認。人間レビューへ。

@smalruby3-editor-bot smalruby3-editor-bot Bot added the 🙋 HITL 人間の対応待ち(Project HITL=Yes の投影) label Jul 12, 2026
@smalruby3-editor-bot smalruby3-editor-bot Bot marked this pull request as ready for review July 12, 2026 05:42
@takaokouji takaokouji merged commit 67c7ac9 into develop Jul 12, 2026
9 checks passed
@takaokouji takaokouji deleted the topic/autopilot-999 branch July 12, 2026 06:34
github-actions Bot pushed a commit that referenced this pull request Jul 12, 2026
…lot-999

fix(devpod): launch playwright mcp via headless chromium wrapper (#999)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🤖 autopilot autopilot が処理対象にした Issue/PR(daemon が付与) 🙋 HITL 人間の対応待ち(Project HITL=Yes の投影)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(devpod): Playwright MCP を devpod 内外どちらでも動く headless chromium 構成にして commit

1 participant