Playwright MCP をPythonから使ってみる
概要
「Playwright MCP」は、Playwright(マイクロソフトが提供するクロスブラウザ自動化フレームワーク)を拡張し、LLM(大規模言語モデル)やエージェントとブラウザ操作をリアルタイムに連携させるための「MCP(Model Context Protocol)サーバー」を実装したものです。
具体的には、AIエージェントや他のツールがブラウザ上で「何をどう操作すべきか」を理解・指示し、Playwrightを通じてその操作を実行する仕組みを提供します。たとえば、Webページを開いて、自動で動的な操作を行い、結果を取得する…という流れを、AIが絡んで担えるように設計されています。
主な特徴
以下が、Playwright MCPが持つ特徴です。
ブラウザの「アクセシビリティツリー」(ページ構造)や状態をAIエージェントが取得/参照できる仕組みがある。
多様なブラウザ(Chromium, Firefox, WebKit)に対してPlaywrightが対応しているため、Playwright MCPもそれを活用可能
エージェントやLLMが「このボタンをクリック」「このフォームに入力」など、ブラウザ操作を命令できるインターフェースをもつ。
単なるスクリプト実行ではなく、「AIがアプリを探索する」「テスト用コードを生成する」「動的に操作を決定する」といった応用が可能となっている。
なぜ注目されているのか
従来のブラウザ自動化は、テストスクリプトや手動定義のフローに依存し、「アクセスや画面幅やデバイスによって動的に変わるUI/UX」や「AIが判断して操作を選ぶ」という要件には限界がありました。
Playwright MCPは、AI(LLM)を「操作を判断する主体」として活用できるように設計されており、従来のスクリプト型自動化から一歩進んだ“エージェント型”自動化の実現を支えます。
結果として、例えば「ユーザーがマウスやキーボードで操作するような複雑なアプリケーションのテスト」や「UI上の探索と検証をAIに任せる運用」が可能になります。
ユースケース例
Webアプリケーションのエンド・ツー・エンドテスト。AIが探索動作を行い、ユーザーシナリオを自動生成して実行。
AIを用いたデバッグ時のブラウザ操作支援。例えば、LLMが問題となる操作を見つけ、Playwright MCPを通じてその場で再現・検証することが可能です
ブラウザ上でのデータ抽出・操作の自動化。AIが「このデータを取得し、この操作を実行」と理解・指示し、実際に操作を実行。
セットアップ&基本的な使い方
インストール・起動の流れ
Node.jsの環境を用意。(なければ公式サイトからDL&インストール
Playwright本体をインストール
Playwright MCPサーバーを起動。
クライアント(テストスクリプト、AIエージェント)からMCPサーバーに接続し、ブラウザを操作できるようにする
# Node 18+ が必要
$node -v
# Playwright のブラウザバイナリをインストール
#npx playwright install
# Playwright MCP サーバは npx で起動できる(起動確認)
$ npx @playwright/mcp@latest --help
#Pythonのライブラリのインストール
pip install playwright>=1.46.0
pip install asyncio
pip install argparse
Pythonは執筆時点だと3.13がベストです。それ以外のバージョンだとインストール時に関連モジュールの依存性などコケる可能性があります
サンプルコード
# -*- coding: utf-8 -*-
import asyncio
from mcp import ClientSession, StdioServerParameters, types
from mcp.client.stdio import stdio_client
async def main():
# Playwright MCP サーバを npx で起動
server = StdioServerParameters(
command="npx",
args=[
"@playwright/mcp@latest",
"--browser=chrome", # 任意: ブラウザ指定
"--user-data-dir", r"C:\chrome_profiles\mcp-chrome", # 任意: 永続プロファイル
"--output-dir", r"C:\mcp_outputs", # 任意: PDF/トレース保存先
# "--headless", # ヘッドレス化したい場合に有効化
# "--isolated", # 使い捨てプロファイルで動かす場合
# "--save-trace", "--save-session", # 記録系
],
env=None
)
async with stdio_client(server) as (read, write):
async with ClientSession(read, write) as session:
# 初期化 & ツール一覧
await session.initialize()
tools = await session.list_tools()
print("Tools:", [t.name for t in tools.tools])
# 1) URLへ遷移(browser_navigate)
await session.call_tool("browser_navigate", arguments={"url": "https://example.com"})
# 2) 画面上のテキスト入力例(browser_type)
# ref は本来スナップショットで得るが、まずは element 説明を付けて簡易送信
await session.call_tool("browser_type", arguments={
"element": "the search input",
"ref": "css:input[name='q']", # 代表例:CSSやdata-testidに基づく参照
"text": "playwright mcp",
"submit": True
})
# 3) クリック例(browser_click)
await session.call_tool("browser_click", arguments={
"element": "the search button",
"ref": "css:button[type='submit']"
})
# 4) JS評価(browser_evaluate)
result = await session.call_tool("browser_evaluate", arguments={
"function": "() => document.title"
})
title = ""
if result.content and isinstance(result.content[0], types.TextContent):
title = result.content[0].text
print("Page title:", title)
if __name__ == "__main__":
asyncio.run(main())
コード解説
このコードでやっていることはあなたが上司で、AI秘書にブラウザ操作を頼むイメージです。
あなた(=Python側)は「命令を出す人」
秘書(=Playwright MCPサーバ)が「実際にブラウザを触る人」
秘書との通信ルール(=MCPプロトコル)で会話する
という関係です。
コード構成
# -*- coding: utf-8 -*-
import asyncio
from mcp import ClientSession, StdioServerParameters, types
from mcp.client.stdio import stdio_client
ここではmcpライブラリをインポートしています。当たり前なので割愛。
① MCPサーバ(秘書)を呼び出す
server = StdioServerParameters(
command="npx",
args=[
"@playwright/mcp@latest",
"--browser=chrome",
"--user-data-dir", r"C:\chrome_profiles\mcp-chrome",
"--output-dir", r"C:\mcp_outputs",
],
)
→ 「npx コマンドで秘書を起動して、Chromeブラウザを開いて」と頼んでいます。
--user-data-dir は「自分の机の引き出し」。ここにブラウザの状態(ログイン情報など)を保存しておく設定です。
--output-dir は「報告書を置くフォルダ」。スクショ・トレースなどがここに保存されます。
② Pythonから会話を開始
async with stdio_client(server) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
→ 「電話をかけて、秘書と会話を始める」場面です。
initialize() でまず自己紹介をして「今日のタスクを始めます」と宣言します。
③ 利用できる“業務メニュー”を聞く
tools = await session.list_tools()
print("Tools:", [t.name for t in tools.tools])
→ 秘書に「あなたは何ができますか?」と尋ねている部分です。
返ってくるリストには "browser_navigate", "browser_click", "browser_type" などが並びます。
つまり「URLを開く」「クリックする」「文字を打つ」など、秘書ができる業務一覧が表示されるようなイメージです。
④ ブラウザでページを開く
await session.call_tool("browser_navigate", arguments={"url": "https://example.com"})
→ 「まずこのサイトを開いて」と指示しています。
まさに「ナビゲート(案内)」ですね。
⑤ 入力ボックスに文字を打つ
await session.call_tool("browser_type", arguments={
"element": "the search input",
"ref": "css:input[name='q']",
"text": "playwright mcp",
"submit": True
})
→ 「検索欄に“playwright mcp”って入力して、Enter押してね」という指示。
ここで "ref" は “場所の説明メモ” です。
「画面上のどこにあるか」を CSSセレクタで伝えます。
日本語で言うと:「ページ右上の検索欄に」みたいな住所を伝えるイメージ。このCSSセレクタはAIエージェントと連携させるときはAI側がHTMLから勝手に判断してくれるイメージです
⑥ ボタンをクリック
await session.call_tool("browser_click", arguments={
"element": "the search button",
"ref": "css:button[type='submit']"
})
→ 「そのボタンを押してね」という指示。
クリック操作も、要素を CSSやテキスト説明で指定できます。
秘書はそれを理解してクリックしてくれます。
⑦ ページの情報を取得
result = await session.call_tool("browser_evaluate", arguments={
"function": "() => document.title"
})
→ 「今開いてるページのタイトルを教えて」と質問。
ブラウザのJSを直接実行して、結果を返してもらいます。
browser_evaluate は「ブラウザにメモを渡して、それを実行させる」命令です。
⑧ 結果を整形して出力
if result.content and isinstance(result.content[0], types.TextContent):
title = result.content[0].text
print("Page title:", title)
→ 秘書が返してきた報告書(JSON)を読んで、「ページタイトルは〇〇です」と出力。
このPythonコードは、「AIがあなたの代わりにブラウザで検索・入力・操作を行う秘書」を使っているイメージです。
テスト自動化にも、SNS投稿やDM送信の自動化やニュース収集にも応用できます。
活用シーン・メリット/デメリット
メリット
テスト自動化の効率化:AIが探索・操作を担うことで、従来手動で書いていたテストスクリプトの量を削減できる可能性があります。
柔軟性の向上:UI変更や動的なフローにも、AI+MCPの組み合わせで適応しやすくなります。
コラボレーション:複数の“クライアント”(エージェント・スクリプト・人間)が1つのブラウザセッションを共有・操作できる設計が可能。
デメリット/留意点
セキュリティリスク:上述の通り、ブラウザ操作をAIに委ねるという構造上、悪用リスクや情報漏洩リスクが存在します。
運用監視の必要性:多数クライアントの接続や並列操作では、負荷分散・モニタリングが不可欠です。
