早年间我们聊浏览器自动化,绕不开 Puppeteer;今年再聊 AI Agent,绕不开 MCP。这两个东西碰到一起,就是标题里说的 Puppeteer MCP——一套让 AI 能真正操控浏览器的标准化服务。
如果你还不清楚 MCP 是什么,可以把它理解成 AI 世界的 USB 接口:过去每个 AI 工具都要单独定制对接方式,而 MCP 给出了一套统一连接标准。Puppeteer MCP 就是在这个标准下,把 Puppeteer 强大的浏览器控制能力封装成了 AI 可以直接调用的工具集。简单说,AI 不再只是"读"你喂给它的文字,而是能像人一样打开页面、点击按钮、填表、截图、翻页,真正把浏览器变成它的双手。
这篇文章会比较长,适合三类人:一是做 AI Agent 产品和自动化测试的开发者,二是拿 AI 辅助日常工作的运营、爬虫爱好者,三是对 MCP 协议感兴趣、想快速上手一个真实案例的折腾型玩家。我会把原理、搭建、使用、避坑一次讲完。
1. 项目整体设计与思路拆解
1.1 MCP 到底改变了什么
先说个背景。过去两年,AI 编程助手遍地开花,但大多数时候 AI 只能"看着"你的屏幕,或者靠插件在编辑器里改代码。一旦涉及真实网页——比如登录后台、查数据、下订单——它就抓瞎了,只能把操作步骤用文字写给你,让你自己动手。
MCP(Model Context Protocol,模型上下文协议)要做的事,就是把 AI 和外部工具之间的连接标准化。你可以把它拆成三个角色:
- MCP Host:运行 AI 的上层应用,比如 Claude Desktop、Cursor、自己写的 Agent 程序。
- MCP Client:Host 内部的连接组件,负责跟 MCP Server 通信。
- MCP Server:一个本地或远程服务,把某种具体能力(数据库、文件系统、浏览器……)封装成 AI 能调用的工具列表。
Puppeteer MCP 就是第三个角色里的一个实现,它内部调用 Puppeteer 驱动一个真正的 Chromium 浏览器实例,向外暴露一组浏览器操作工具,比如打开页面、点击元素、输入文字、滚动、截图、抓取文本、等待网络空闲等等。
以前要是让 AI"帮我打开某个网页,把商品标题和价格抓下来",你得写一堆脚本,把爬虫逻辑、翻页逻辑、异常处理全部写好,再让 AI 去生成代码、调代码、跑代码。有了 Puppeteer MCP,AI 可以直接"亲手"操作浏览器,一条路径走通,少了很多中间环节。
1.2 为什么是 Puppeteer
市面上浏览器自动化工具不少,Playwright、Selenium、Cypress 各有拥趸。Puppeteer 能在这个场景里被选中的一个重要原因,是它从一开始就是"以 Chrome/Chromium 为核心"的,API 非常干净,安装即用,不需要额外下载浏览器驱动(Selenium 就得折腾 driver 版本)。Puppeteer 还自带page.screenshot()、page.pdf()这类高频能力,做 AI 可理解的页面反馈非常顺手——AI 是个视觉和文本模型,截图比一堆 HTML 源码直观太多。
另一个原因是官方地位。Puppeteer 的 MCP 服务由 Google 的 Puppeteer 团队亲自维护(仓库地址在puppeteer/puppeteer下的mcp-server目录),版本跟进及时,这比第三方实现靠谱得多。它不是社区里某个临时玩票的项目,而是被纳入官方主线的正规军,出了问题有人管,更新节奏也稳定。
1.3 这套方案适合什么场景
我列几个我能想到的高频场景,你看自己能不能对号入座:
- AI 驱动的前端自动化测试:用自然语言描述测试步骤,AI 执行点击、输入、断言页面内容。
- 数据采集与页面巡检:让 AI 周期性地打开固定站点、抓关键数据,甚至把结果整理成表格或报告。
- 复杂系统的智能操作助手:比如在 OA、ERP、内部运维后台里,让 AI 代替人完成跨页面操作。
- 教学和演示:AI 一步步操作浏览器给用户看,每一步等一两秒,增加安全感和信任感。
如果你的场景只是"定时抓个静态接口",Puppeteer MCP 有点大材小用;但凡是需要"根据页面实际情况做判断、再决定下一步点哪里"的动态流程,这套方案的价值就非常有存在感。
2. 核心细节解析与实操要点
2.1 工具清单与功能边界
聊 MCP 服务,核心看它暴露了哪些工具。Puppeteer MCP 在最新版本中提供的工具包括但不限于:
| 工具名称 | 作用 | 典型场景 |
|---|---|---|
browser_navigate | 跳转到指定 URL | 让 AI 打开新页面 |
browser_click | 按选择器点击页面元素 | 点按钮、点链接 |
browser_fill | 在表单元素中填写内容 | 登录、搜索、填问卷 |
browser_hover | 鼠标悬停到元素上 | 触发下拉菜单、浮层提示 |
browser_select | 在<select>中选择选项 | 选择省份、排序方式 |
browser_screenshot | 对当前视口或整页截图 | 给 AI 提供视觉反馈 |
browser_pdf | 将当前页面导出为 PDF | 存报告、存凭证 |
browser_evaluate | 在页面里执行任意 JavaScript | 跑自定义脚本 |
browser_wait | 等待固定时间或异步条件 | 等待渲染、等待接口返回 |
browser_press_key | 发送键盘按键 | 回车、Esc、Ctrl+A |
browser_close | 关闭当前标签页 | 清理环境 |
这里要特别提一下browser_evaluate,它是一把双刃剑。因为它是执行任意 JS,AI 如果被恶意指令诱导,理论上可以在页面上下文里做任何事。这是 MCP 工具设计里面向"可信 Agent"的假设——你部署给谁用,就要保证这个 AI 的指令源是可信的,不然browser_evaluate就是你环境里的最大后门。
2.2 服务器两种模式的取舍
Puppeteer MCP 支持两种运行模式:
- Stdio 模式:MCP Server 作为 AI 客户端的子进程运行,请求通过标准输入输出流传递。大多数桌面 AI 客户端(Claude Desktop、Cherry Studio)都采用这种模式,部署简单,不需要额外开端口,权限边界也更清晰。
- HTTP / SSE 模式:服务器独立运行,通过 HTTP 或 Server-Sent Events 对外提供服务。适合远程部署、多客户端共享,或者把浏览器能力接入云端 Agent 服务。
实际项目中,建议本地优先用 Stdio,谁在本地跑就让谁起进程,逻辑干净。远程共享或多用户场景再用 HTTP,但一定得加鉴权,别裸奔到公网——Puppeteer MCP 默认没有认证机制,裸 HTTP 等于把一台能点开任意网页的浏览器借给全世界。
2.3 浏览器连接机制
这个 MCP 服务底层会启动一个 Chromium 实例,通过 Puppeteer 连接。比较关键的是它支持"复用已有浏览器"的连接方式:如果你设置了一个保留的 user data directory,AI 操作过的登录状态、Cookie、本地存储都会留存,下次再启动能直接复用会话。
我建议你给 Puppeteer MCP 单独指定一个 user data dir,别跟日常浏览混在一起。这样做的原因,一是登录态隔离,AI 操作后台和你的个人浏览器互不干扰;二是可以随时"格式化"它来对付那些登录态过期、重启后状态错乱的怪问题——删掉那个目录就回到全新状态,花不了一秒钟。
3. 实操过程与核心环节实现
3.1 环境准备与安装
先明确依赖:
- Node.js:建议 v18 以上,Puppeteer 新版要求最低 v18,v20 最稳。
- 一个 MCP 客户端:Claude Desktop、Cursor、Cherry Studio 都行;或者用
mcp-cli这类纯命令行调试工具,适合先验证配置。 - 一个模型:这里无所谓哪家,只要你用的客户端支持 MCP 工具调用即可。
安装 Puppeteer 以及 MCP 服务器依赖,在一个项目目录里:
npm init -y npm install puppeteer @modelcontextprotocol/sdk如果你只想快速用官方打包好的@puppeteer/browsers或者直接用npx跑服务,也可以不管上面这些,直接看下面的客户端配置。但我是建议你在本地先建个独立的测试项目,毕竟后面写自定义脚本、塞browser_evaluate都得有地方放代码。
3.2 服务配置
以 Claude Desktop 为例,配置文件在claude_desktop_config.json里,添加一个 mcpServers 条目:
{ "mcpServers": { "puppeteer": { "command": "npx", "args": [ "-y", "@puppeteer/mcp-server" ] } } }如果你用的是较新的版本,服务还支持传参数,比如指定浏览器路径、headless 模式、user data dir 等:
{ "mcpServers": { "puppeteer": { "command": "npx", "args": [ "-y", "@puppeteer/mcp-server", "--puppeteer.launch.options={\"headless\":false}", "--puppeteer.launch.userDataDir=/tmp/puppeteer-mcp-profile" ] } } }注意--puppeteer.launch.options这里是一整串 JSON,Windows 上转义容易踩坑,建议用--puppeteer.launch.options={"headless":false}时检查一下命令行是否被正确解析。我踩过几次,最后干脆把配置文件里的双引号写成\"转义或者直接不好使就换用户目录,替代方案是写一个启动脚本传参。
3.3 从命令行验证服务
别急着跟客户端绑死,先用mcp-cli这类工具验证你的服务能正常返回工具列表:
npx -y @modelcontextprotocol/inspector npx -y @puppeteer/mcp-server打开 Inspector 界面后,能看到一个工具列表,任意点一个browser_navigate,填写 URL,直接发送,观察返回结果。这一步能帮你把"配置问题"和"服务问题"分开——工具列表能正常加载,说明 MCP 协议层面是通的;具体某个工具报错,才是浏览器操作层面的问题。
3.4 第一次委托 AI 做一次完整操作
我以 Cherry Studio 这类支持 MCP 客户端工具为例。连接成功之后,你随便打开一个新对话,然后给 AI 一个完成任务的自然语言描述,比如:
"打开百度首页,搜索'Puppeteer MCP',然后把搜索结果第一页的标题和链接抓下来,整理成 markdown 列表。"
正常情况下,AI 会自己规划步骤、调用工具、观察页面状态、修正动作,最后完成任务。这是最直观的"让 AI 拥有会点浏览器的手"的体验时刻。
实操时有个细节:AI 每次调用工具,都是拿当前页面截图或 DOM 信息判断下一步的,所以页面加载慢或元素延迟渲染时,AI 可能会傻等或点错地方。你可以在提示词里明确要求"每次操作前先截一张图看看当前页面状态",效果立竿见影。
3.5 用代码直接触发工具调用
如果你不想依赖某个 GUI 客户端,想在自己写的 Agent 程序里接 Puppeteer MCP,也可以直接用 SDK 写一段最小代码:
import { MCPClient } from "@modelcontextprotocol/sdk/client/index.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; const transport = new StdioClientTransport({ command: "npx", args: ["-y", "@puppeteer/mcp-server"] }); const client = new MCPClient({ name: "my-agent", version: "1.0.0" }, transport); await client.connect(); const tools = await client.listTools(); console.log(tools.map(t => t.name)); await client.callTool({ name: "browser_navigate", arguments: { url: "https://example.com" } }); const screenshot = await client.callTool({ name: "browser_screenshot", arguments: { fullPage: true } });这段代码标出了完整链路:创建传输层、建立 MCP 连接、列出可用工具、逐个调用。你在跑之前要确认 SDK 版本跟服务端兼容,2025 年之后的版本基本都用SDK 1.x,接口有所变化,看仓库 README 为准。
4. 核心应用场景与实战演示
4.1 场景一:自然语言驱动的自动化测试
传统写自动化测试用例,是用test框架写 JavaScript 断言。换成 Puppeteer MCP 之后,你可以说:
"打开登录页,输入测试账号和错误密码,点击登录,断言页面出现错误提示。"
AI 会先打开页面、填充表单、点击按钮、等待网络应答,再截一张图作为观测。你甚至可以在背后加一个"再输入正确密码重试,最后截图留档",让 AI 自己把回归流程走完。
这个过程跟写死脚本最大的区别在于容错:页面改版、按钮文案变化,AI 能根据当前截图和 DOM 信息调到新的元素上,不用你手动修选择器。当然,它也不是 100% 靠谱,选择器变化后一次跑不对的情况也有,但配合 AI 对话式的即时反馈,调试效率确实高了不少。
4.2 场景二:页面数据抽取与智能整理
再举个例子。我要从某个后台报表页抓数据,页面有日期筛选、多页表格,还有几个汇总数值。过去要么写爬虫脚本处理分页、要么手动复制粘贴。现在我可以直接说:
"打开报表页,选择最近 30 天,翻遍所有分页,把表格数据全部抓下来,按销售额降序排列,生成 CSV。"
AI 会调用browser_navigate打开页面,browser_select选择时间范围,browser_click点击查询,然后反复browser_evaluate抽取表格行数据,加载更多或翻页,最后它会把结果整理成文本或文件。你要做的只是验收数据完整性。
这里有个经验:抓取数据时让 AI 每次翻页后先等待表格刷新完成。用browser_wait等固定时间,或者调browser_evaluate轮询某个 DOM 节点的文本变化,成功率会大幅提升。纯靠截图判断,经常会出现翻页动画还没结束就开始抓,抓到一半重复或遗漏。
4.3 场景三:跨系统操作联动
有些流程跨越多个系统,比如从 A 系统的订单列表查到订单号,再去 B 系统的物流查询页查询物流状态,最后把结果回填到 A 系统某个字段。这种流程以前靠 RPA 工具或写脚本,现在 AI Agent 可以在 MCP 串联多个工具的前提下,自己做状态记忆和跨页面操作。
需要注意的是跨域下的 Cookie 隔离。Puppeteer MCP 复用的是同一个浏览器上下文,A 系统和 B 系统的会话并存通常没问题。但如果 A、B 两个系统本身有单点登录冲突,AI 操作时会把会话搞乱。这时候建议你在提示词里明确要求 AI"每切换一个系统,先重新确认当前登录态,必要时先访问对应系统的登录页",能省下不少排查时间。
4.4 场景四:无头模式跑批处理
服务器上跑无人值守的采集任务,建议把浏览器设为 headless(无头模式)。默认 Puppeteer MCP 我可以凭经验告诉你有两种方式:要么在服务启动参数里设headless为 true,要么在提示词里要求 AI 调用特定工具后退出。不过 headless 模式下,某些反自动化检测更明显,有的站点能通过 WebDriver 标记、浏览器指纹识别出来,这个下面专门讲。
5. 常见问题与排查技巧实录
5.1 连接失败一列
我自己用下来、群里见人问得最多的问题有这么几类:
| 问题现象 | 可能原因 | 处理方式 |
|---|---|---|
| 客户端显示"未连接" | MCP Server 没启动成功,或命令路径不对 | 先手动跑npx -y @puppeteer/mcp-server看能否输出正常启动日志 |
| 工具列表为空 | SDK 版本与服务端不匹配 | 更新 SDK 到最新版本,或换用官方 README 推荐的版本 |
| 浏览器窗口一闪而过 | 启动参数里的 headless 配置异常 | 检查启动参数 JSON 格式,建议在配置文件中写独立脚本 |
| AI 调用超时 | 页面加载太慢,或 Puppeteer 默认的定位等待超时 | 让 AI 先调用browser_wait等待,再继续操作 |
| 权限或沙箱报错 | Linux 环境缺少依赖库 | 按浏览器沙箱要求安装libnss3、libatk等依赖,或用--no-sandbox(谨慎使用) |
5.2 被目标站点识别为机器人的终极解法
网页总有反爬机制。Puppeteer MCP 启动的 Chromium 和真实用户浏览器之间,存在自动化特征差异,比如navigator.webdriver属性、Chrome DevTools Protocol 连接痕迹等。
应对思路分三层:
- 第一层,降低访问频率,模拟人类操作节奏,让 AI 在两次操作间停顿随机时间;不要连续快速点击。
- 第二层,使用 stealth 插件或引入
puppeteer-extra-plugin-stealth,抹掉部分自动化指纹。注意这不在官方 Puppeteer MCP 默认功能里,需要你额外包一层或自己写脚本。 - 第三层,绕过本地浏览器不确定性,用已登录的真实用户 session 复用——就是前面提到的 user data dir 方案,让 AI 用真实登录态的 Cookie 去访问,识别难度大大降低。
我个人建议优先第三层,因为它最接近真实用户行为,也不违反"减少自动化指纹"的初衷。
5.3 选择器定位不稳定
AI 操作页面时,选择器是由 AI 自己生成的,有时它生成的选择器非常脆弱,比如依赖深层嵌套的 class 名。出现这种情况,我的做法是在提示词里约定一条:"优先使用>