Playwright CLI 与 MCP:两种给 AI 看世界的方式

早些年写爬虫,人是主语,浏览器是工具,脚本是桥。如今轮到 AI 写爬虫,人退到了旁观席上,便多出一个问题:该让模型怎样“看见”一个网页。

Microsoft 先后给了两份答卷。2024 年的 Playwright MCP,把浏览器包成 Model Context Protocol 的一组工具,每次动作之后把可访问性树、截图字节一并塞回 LLM 的上下文。2026 年初的 Playwright CLI 则反其道而行——数据落盘,Agent 自己决定要读哪一页。同一家公司,同一个团队,先后两种哲学。像是先建了一座藏书楼要求来人过目不忘,过几年想通了,换成借阅处。

一句话结论

Claude Code、Cursor、Copilot 这类能碰到文件系统的 Agent,首选 Playwright CLI。token 消耗约为 MCP 的四分之一(典型任务 114k → 27k)。只有在 Claude Desktop 这类沙箱聊天界面里,才需要退回 Playwright MCP

核心差异

维度Playwright MCPPlaywright CLI
协议JSON-RPC(MCP 标准)普通 shell 命令
数据流结果直接注入 LLM 上下文写入磁盘,Agent 按需 Read
Token 成本约 114k(典型任务)约 27k(同样任务)
工具数量21 个(受限于上下文预算)命令更多(无上下文顾虑)
运行环境要求任何支持 MCP 的宿主必须有文件系统 + shell
持久化状态内存中会话命名会话 -s=name + --persistent
状态自省每步返回完整 a11y 树Agent 主动 snapshot

四倍 token 差从何而来

MCP 的前提假设是“LLM 看不到工具之外的世界”。于是每一次 click 之后,必须把最新页面状态原路奉还,模型才好决定下一步。一棵可访问性树常常几 KB 到几十 KB,十步操作便啃去几万 token。长会话里,这笔账像滚雪球。

CLI 的假设换了一条:Agent 本来就有 shell、有磁盘。playwright-cli snapshot -o page.yaml 只把数据写到 page.yaml,Agent 要看就 Read page.yaml,不看便无事发生。古人藏书于山中,用时取之,不用则束之高阁;CLI 的设计,大抵是这个意思。

命令能力速查(CLI)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 安装
npm install -g @playwright/cli@latest
playwright-cli install --skills

# 导航
playwright-cli open https://example.com -s=sess1
playwright-cli goto /login -s=sess1
playwright-cli reload -s=sess1

# 交互
playwright-cli click "button:has-text('登录')" -s=sess1
playwright-cli fill "#email" "[email protected]" -s=sess1
playwright-cli type "#code" "123456" -s=sess1

# 观察(核心:数据落盘)
playwright-cli snapshot -o snap.yaml -s=sess1       # a11y 树
playwright-cli screenshot -o shot.png -s=sess1      # 截图
playwright-cli console --since=30s -o log.txt       # 控制台日志
playwright-cli network --filter=xhr -o net.json     # 网络请求

# 会话管理
playwright-cli show                                  # 可视化仪表盘
playwright-cli close -s=sess1

两个关键模式:-s=name 命名会话实现并行浏览器,-o file 把结果重定向到文件。

选型决策树

Agent 能访问文件系统和 shell 吗?
├─ 是 → Playwright CLI(主流)
│      ├─ Claude Code          ✅
│      ├─ Cursor               ✅
│      ├─ GitHub Copilot Agent ✅
│      └─ Codex/其他 CLI Agent ✅
└─ 否 → Playwright MCP(沙箱兜底)
       ├─ Claude Desktop       ✅
       └─ 纯 Chat UI           ✅

分别用在哪里

Playwright CLI 的场景

  • 写 E2E 测试:长会话、多步操作,token 压力最重的地方
  • 开发期调试:截图/控制台/网络请求悉数落盘,可以反复 Read
  • 生成 Playwright 测试代码playwright-cli codegen 录制回放
  • 批量脚本:shell pipeline 可以串起来

Playwright MCP 的场景

  • Claude Desktop 里临时查网页:没有 shell,只好回到 MCP
  • 探索性自动化:需要 Agent 每步都“看到”当前状态自我修正
  • Self-healing 测试:依赖富语义的 a11y 树做失败重试

和 Chrome DevTools MCP 并行

三者不互斥,最优组合是各司其职:

  • 开发期看页面状态 → Chrome DevTools MCP(性能 trace、真实 Chrome 登录态)
  • 跑 E2E / 生成测试代码 → Playwright CLI
  • 沙箱 Chat 里查页面 → Playwright MCP

Claude Code 集成方式

CLI 不走 claude mcp add 这条路。装完全局命令后,在对话里让 Claude 直接调 Bash 即可。配合项目 CLAUDE.md 里写好常用命令的指引,效果最好。

1
2
npm install -g @playwright/cli@latest
playwright-cli install --skills   # 安装配套 skill 定义

然后在项目 CLAUDE.md 加一段约定:

1
2
3
4
5
6
## 浏览器自动化
本项目用 Playwright CLI 做前端验证。常用命令:
- 截图:`playwright-cli screenshot -o /tmp/shot.png -s=dev`
- a11y 快照:`playwright-cli snapshot -o /tmp/snap.yaml -s=dev`
- 读控制台:`playwright-cli console --since=30s`
禁止使用 playwright-mcp(会炸 token)。

几个坑

  1. CLI 需要文件系统权限。sandbox 严格的 Agent 宿主未必可用,动手前先确认权限边界
  2. 会话名冲突。多项目并行时 -s=name 要带项目前缀,否则串会话的后果是诡异的
  3. --persistent 会写到 ~/.cache/ms-playwright/。CI 环境记得清理,否则缓存会越积越厚
  4. 不要和 MCP 混装。同项目里两套工具并存,Agent 会陷入选择困难,表现为在两种调用之间来回切换

迁移路径

从 Playwright MCP 迁到 CLI 的步骤:

  1. npm install -g @playwright/cli@latest
  2. CLAUDE.mdbrowser_* 工具说明替换成 playwright-cli 命令
  3. 移除 .mcp.json~/.claude.json 里的 playwright MCP 配置
  4. 跑几个典型任务对比 token 消耗,确认预期

尾声

MCP 不是被抛弃的旧工具,CLI 也不是什么跨时代的新发明。两者的分野只说明一件事:让模型看见世界的成本从来不是零。塞进上下文是一种办法,摊在磁盘上让它自取是另一种,前者适合无处借力的沙箱,后者适合有手有脚的编码 Agent。

工具选对了,token 便不至于流水一般漫出去。这一点在 Claude 的上下文窗口真正派上用场的地方——比如读一份庞大的代码库、追一个跨越十几个文件的 bug——最能看出分别。