page.close()したのにタブが消えない
Playwright MCPでページを調べてもらうと、便利なのでついタブを増やしてしまいますよね。
そこで最後にpage.close()を呼べば片づくと思うのですが、Chrome拡張経由の接続では「自動操作の接続だけ切れて、実際のタブは残る」という報告があります。
ブラウザのタブが増え続けると、あとからメモリ使用量にも影響します。今回は、どこまでがPlaywrightの仕様で、どこからがMCPや接続方式の問題なのかを整理します。
まずは普通に閉じてみる
Playwright単体なら、ページを作った場所で閉じれば大丈夫です。
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.close();
await browser.close();
この場合、page.close()はページを閉じ、browser.close()はブラウザ全体を閉じます。
順番もわかりやすいですね。では、MCPから同じことをすればよいのでしょうか。
Chrome拡張経由では意味が変わる
Playwright MCPには、専用のChromiumを起動する方式と、すでに開いているChromeへ拡張機能で接続する方式があります。
後者では、Chromeそのものは自分の作業用ブラウザです。MCPが管理している「操作の接続」を閉じても、Chromeのタブを閉じる権限や経路が同じとは限りません。
実際にPlaywright MCPのIssue #1111では、page.close()を実行しても自動操作の表示だけが消え、タブ自体は残るという報告があります。
ここで注意です。これは「Playwrightのpage.close()は必ず壊れている」という話ではありません。専用ブラウザか、既存Chromeへの拡張接続かを分けて考える必要があります。
MCPのタブ操作を使う
MCPの利用者は、ページオブジェクトを直接閉じるのではなく、MCPが用意しているタブ管理を使う方が意図に近いです。
browser_tabs({
action: "list"
})
browser_tabs({
action: "close",
index: 2
})
まず一覧を取得し、不要なタブの番号を確認してから閉じます。現在のタブを閉じる指定と、一覧の番号を指定する方法を混同しないでください。
ただし、拡張接続のIssue #1111のように、タブ操作そのものがChrome側へ届かないケースもあります。閉じる操作が成功したという表示だけで、実際のタブ数が減ったと決めつけない方が安全です。
長時間セッションではメモリも見る
タブが残る問題と別に、長時間のMCPセッションでChromiumのメモリが増え続ける報告もあります。
Playwright MCPのIssue #1636では、長時間稼働するMCPサーバーとChromiumで仮想メモリが増え、ホストのOOM killにつながった事例が報告されています。これはすべての環境で再現するという意味ではありませんが、無人運用では見逃せない症状です。
タブを閉じたつもりでも、ブラウザコンテキストやレンダラーの状態が残っている可能性があります。たまにブラウザ全体を再起動する方が、何でも同じセッションへ詰め込むより安全な場合があります。
# 専用プロファイルでMCPを起動する例
npx @playwright/mcp@latest --headless --isolated
--isolatedではセッション終了時にCookieやストレージも失われます。ログイン状態を使う作業では、便利さと引き換えになる点に注意してください。
無人ループでは終了条件を先に決める
私なら、MCPを無人処理に組み込む時は「タブを閉じる」だけを終了条件にしません。
- 処理開始前にタブ一覧を取得する
- 作成したタブやコンテキストを記録する
- 処理後にタブ一覧を再取得する
- 数が減らなければブラウザ接続の問題として記録する
- 長時間処理はセッションを再作成できる単位に分ける
「閉じるAPIが成功した」ではなく、「実際の一覧から対象が消えた」まで確認するわけです。
それでも接続が壊れたら、同じ操作を何度も繰り返さない方がよいです。Playwright MCPのIssue #1245では、ブラウザを閉じた後も内部の使用中フラグが残り、再接続できなくなる報告があります。クライアントやMCPサーバーを再起動する方が早いこともあります。
まとめ
Playwright MCPでタブが増え続ける時は、まず接続方式を確認しましょう。
専用ブラウザならpage.close()とbrowser.close()の責任範囲を分けます。既存Chromeへの拡張接続なら、MCPのタブ操作と実際のタブ一覧を確認します。
長時間の無人処理では、タブ数とメモリを定期的に見て、セッションを再作成できる設計にしておくのが安心です。閉じたつもりで残っている、という地味な問題が一番あとから効いてきます。
Playwright MCPを使っていて、ほかにも「ここはどう片づけるの」というところがあればコメントに書いていただければと思います。


コメント