Claude Code + chrome-devtools MCP:安装部署与实战全记录

Claude Code + chrome-devtools MCP:安装部署与实战全记录

实测环境快照chrome-devtools-mcp v1.7.0,Chrome 151.0.7922.172,Node v25.8.2,npm 11.11.1。CLI 参数表按 npx chrome-devtools-mcp@latest --help 实测输出整理,非凭记忆罗列。该包高频迭代,引用前请复核 --help

一句话结论

chrome-devtools MCP 把一个真实的 Chrome 交给 Claude Code:能导航、能在页面里执行任意 JS、能截图、能改视口、能读控制台和网络。它同时解决两类问题------联网取资料 (替代不可靠的搜索工具)和前端调试闭环(本机真机验证,不用人肉点浏览器)。


先把数据摆出来。扫本机全部 Claude Code transcript(~/.claude/projects/**/*.jsonl)统计联网类工具调用:

工具 调用次数 硬失败(is_error 返回体含错误信号
mcp__web-search__web_search 2 2 ---
mcp__web-search__web_page 1 0 ---
内置 WebSearch 49 0 11(403 / timed out / failed 等)
内置 WebFetch 25 0 0

两次 web-search 硬失败的报错完全一样:

erlang 复制代码
Error performing web search after 3 attempts:
No search results parsed for query "ARM64 branch out of range 128MB ___clang_call_terminate libGameAssembly il2cpp 解决".
sql 复制代码
Error performing web search after 3 attempts:
No search results parsed for query ""branch out of range" arm64 "clang_call_terminate" Unity il2cpp order_file fix".

这里有个容易搞错的因果 。直觉上会归因于「代理不稳 / 网络抖动」------全局配置确实给 web-search 挂了 HTTPS_PROXY=http://127.0.0.1:7897。但错误不是 ECONNREFUSED、不是 ETIMEDOUT,是 No search results parsed :HTTP 请求走通了,拿回了页面,解析器在返回的 HTML 里没找到结果节点。重试 3 次全一样。典型成因是搜索引擎返回了反爬页 / 同意页 / 改版后的 DOM,scraper 的选择器失效。

所以真正的痛点不是"经常连不上",而是:

搜索链路会在长尾技术查询上静默返回空 ,且失败点恰好是最需要联网的时刻------__clang_call_terminatebranch out of range 这种带下划线符号名与引号精确匹配的查询,正是 Unity IL2CPP 出包排障(libGameAssembly 超 ARM64 分支寻址上限)的核心线索。

内置 WebSearch 的 49 次调用虽然没有硬失败,但 11 次返回体里带 403 / timed out / failed 字样------它返回的是搜索结果摘要 + 链接列表 ,摘要往往是几十字的截断片段。要读 user_manual.md 全文、要看 GitHub 仓库的 stars 与最后提交时间、要抓 CSDN 正文,摘要给不了。

chrome-devtools 凭什么绕过这些

维度 搜索类 MCP / WebSearch chrome-devtools MCP
取数方式 第三方 scraper 解析搜索结果页 真实 Chrome 渲染真实 URL
反爬 / 同意页 scraper 选择器一失效就返回空 用你的登录态与 profile,人能打开它就能打开
JS 渲染页 拿不到(SPA 内容在 JS 里) 等 JS 跑完再取 DOM
内容粒度 摘要片段 + 链接 document.body.innerText 全文,或 CSS 选择器精确切片
登录墙内资料 无解 复用已登录 profile(内网 wiki / DevOps 平台)
私有地址 无解 http://localhost:5173 也能开
前端调试 不具备 截图 / 视口 / 控制台 / 网络 / 性能全都有

关键认知:它不是"更好的搜索",它是"跳过搜索" 。已知 URL 时直接 navigate_pageraw.githubusercontent.com/...,拿到的是原始 Markdown 全文,零解析损耗、零摘要截断。我的几篇技术梳理笔记都是这么产出的。

补充:不必二选一。实际工作流是 WebSearch 找 URL → chrome-devtools 读全文。搜索负责发现,浏览器负责取证。


2. 安装部署

2.1 前置

要求 实测
Node.js ≥ 22(npx 拉包) v25.8.2 ✅
Chrome 装了就行;--autoConnect144+ 151.0.7922.172 ✅
无需全局装,npx -y 每次拉 v1.7.0(未全局安装,npm ls -g 为空)

2.2 配置写法

~/.claude.jsonprojects["<你的项目绝对路径>"].mcpServers

json 复制代码
"chrome-devtools": {
  "type": "stdio",
  "command": "npx",
  "args": ["-y", "chrome-devtools-mcp@latest", "--autoConnect"],
  "env": {}
}

我在两个前端项目下各放了一份。都是项目级,全局没配------经验是"全局只放所有项目都要用的"。

命令行等价写法(更省事,不用手改 JSON):

bash 复制代码
claude mcp add chrome-devtools --scope project -- npx -y chrome-devtools-mcp@latest --autoConnect

⚠️ 文档漂移提醒 :早期我用的是 --wsEndpoint ws://127.0.0.1:9222/devtools/browser/<id>,后来换成了 --autoConnect。原因很实在:--wsEndpoint 的 browser id 每次重启 Chrome 都会变,写死在配置里必然失效。网上的老教程多半还是 --wsEndpoint 写法,照抄会踩坑。

2.3 三种连接模式怎么选

这是部署时唯一需要想清楚的决策。

① 默认(不加连接参数)------服务器自己起一个干净 Chrome

json 复制代码
"args": ["-y", "chrome-devtools-mcp@latest"]

独立 profile($HOME/.cache/chrome-devtools-mcp/chrome-profile),不碰你日常浏览器。适合 CI、跑自动化。缺点:没有你的登录态。

--autoConnect------接管已在跑的日常 Chrome(推荐)

需 Chrome 144+,且要在 chrome://inspect/#remote-debugging 里把远程调试开关打开一次。好处:

  • 复用日常 profile 的登录态,内网 DevOps / 私有 wiki 直接能读
  • 复用你已经开着的那些标签页,list_pages + select_page 直接切过去
  • 不用管 debugging port 和会变的 browser id

--browserUrl / --wsEndpoint------手动指定调试端点

bash 复制代码
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
  --remote-debugging-port=9222 --user-data-dir=/tmp/cdp-profile
json 复制代码
"args": ["-y", "chrome-devtools-mcp@latest", "--browserUrl", "http://127.0.0.1:9222"]

--browserUrl--wsEndpoint 稳(前者固定端口,后者的 browser id 每次重启都变)。适合远程 / 容器里的 Chrome。

选择建议:日常开发用 --autoConnect ,需要干净环境或 CI 用默认模式,只有跨机器 / 容器才动 --browserUrl

2.4 验证

bash 复制代码
claude mcp list          # 看到 chrome-devtools 且状态 connected
npx -y chrome-devtools-mcp@latest --help   # 单独跑,确认包能拉起

进 Claude Code 后让它 list_pages,能列出标签页即通。

2.5 常用 CLI 参数(v1.7.0 实测)

按重要性排序,不是全表:

参数 作用
--autoConnect 连本机已运行的 Chrome(144+)
--browserUrl / -u 连指定调试端点,如 http://127.0.0.1:9222
--headless 无 UI 模式,CI 用
--isolated 临时 profile,关闭即清理
--channel stable / beta / dev / canary
--viewport 1280x720 初始视口
--proxyServer 给 Chrome 挂代理(等价 --proxy-server
--slim 只暴露 3 个工具(导航 / 执行 JS / 截图),省 context
--screenshotFormat webp --screenshotMaxWidth 截图压缩降尺寸,显著省 context(JPEG/WebP 比 PNG 小 3-5 倍)
--no-category-performance --no-category-network --no-category-emulation 按类关掉不用的工具组,省 context
--blockedUrlPattern / --allowedUrlPattern 限制浏览器能访问的 URL(安全护栏)
--redactNetworkHeaders 脱敏网络请求头里的敏感字段
--no-usage-statistics 关掉 Google 用量统计(默认开)
--logFile /tmp/cdp.log DEBUG=* 出详细日志,报 bug 用

省 context 提示 :29 个工具的 schema 会占掉可观的 context。只用来抓资料的话,--slim + --screenshotFormat webp 是性价比最高的两个开关。

隐私提示--usageStatistics 默认为 true,Google 会收集用量数据(独立于 Chrome 自身的 metrics)。介意就加 --no-usage-statistics,或设 CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS 环境变量。


3. 工具全表(v1.7.0,29 个)

分类 工具
页面/导航 list_pages select_page new_page close_page navigate_page wait_for
观察 take_snapshot(a11y 树,带 uid) take_screenshot evaluate_script
输入交互 click hover drag fill fill_form type_text press_key upload_file handle_dialog
网络 list_network_requests get_network_request
控制台 list_console_messages get_console_message
模拟 emulate(深色模式/地理位置/网络限速/CPU 降频/UA/额外请求头) resize_page
性能/内存 performance_start_trace performance_stop_trace performance_analyze_insight take_heapsnapshot lighthouse_audit

交互两步法

改页面状态要先 take_snapshotuid,再把 uid 传给 click / fill

ini 复制代码
take_snapshot → 得到 uid=1_23 → click(uid: "1_23")

take_snapshot 返回 a11y 树(文本),比截图省 context 且能直接定位元素。优先 snapshot,不要习惯性截图

实际调用分布

transcript 统计(全部项目累计):

工具 次数
evaluate_script 34
navigate_page 15
take_screenshot 13
new_page 6
resize_page 5
list_pages 5
take_snapshot 2
select_page 1

evaluate_script 一家独大,是 navigate_page 的两倍多。说明主力用法不是"模拟用户点点点",而是"把浏览器当带 DOM 和渲染引擎的 REPL" ------进页面里直接取数、算数、调 API。click / fill / fill_form 一次没用过。这个分布值得记住:它决定了 --slim 模式(导航 + 执行 JS + 截图)几乎正好覆盖全部真实需求。


4. 实战场景

以下四个都是真实调用记录,不是构造示例。

4.1 抓官方文档全文

js 复制代码
// 1) 先看仓库结构(这里用了 take_snapshot 读 a11y 树)
navigate_page({ url: "https://github.com/Tencent/InjectFix" })

// 2) 直奔 raw 文件,拿原始 Markdown 全文------不走搜索、不要摘要
navigate_page({ url: "https://raw.githubusercontent.com/Tencent/InjectFix/master/Doc/user_manual.md",
                timeout: 20000 })
evaluate_script({ function: "() => document.body.innerText" })

// 3) 同法取 faq.md / README.md

CSDN 这类正文外包着大量导航和广告的站,用选择器精确切片:

js 复制代码
evaluate_script({ function: `() => {
  const article = document.querySelector('#article_content, .article_content, #content_views, .markdown_views');
  if (article) return article.innerText;
  return document.body.innerText.slice(0, 50000);
}` })

腾讯云文档(cloud.tencent.com/document/product/654/30316)是 JS 渲染的 SPA,WebFetch 抓下来是空壳,浏览器里 innerText 一取就有。

要点--slim 就够;timeout: 20000 给 raw.githubusercontent 留余量;先 slice 限长,避免一次灌爆 context。

4.2 PixiJS游戏 文本截断:在真实渲染引擎里复现测量

一个 PixiJS v8 的 H5 页面(本地 localhost:5173)里,几处中文文案被截断。根因涉及 CanvasTextMetrics 的宽度测量与 padding / stroke 外扩------这是纯运行时数值问题,读代码看不出来

做法是把 PixiJS 本体 import 进页面,直接构造 TextStyle 反复试参:

js 复制代码
evaluate_script({ function: `async () => {
  const m = await import('/node_modules/pixi.js/dist/pixi.mjs');
  const { TextStyle, CanvasTextMetrics } = m;
  await document.fonts.ready;
  const msg = '提交失败,本次记录未计入榜单。';
  const base = { fontFamily: 'MyCustomFont', fontSize: 48, fontWeight: '900',
                 padding: 72, stroke: { color: '#4a4a8a', width: 5 } };
  const metrics = CanvasTextMetrics.measureText(msg, new TextStyle(base));
  return { width: metrics.width, height: metrics.height };
}` })

还顺手用原生 Canvas measureText 交叉验证 PixiJS 的测量值(ctx.font = '900 46px sans-serif'),确认 padding 该给多少。改完 navigate_page({type:"reload"}) + take_screenshot 看结果。

要点

  • await document.fonts.ready 必须等------自定义字体没加载完,测出来的宽度是 fallback 字体的,全错。document.fonts.check('900 46px "MyCustomFont"') 可显式确认。
  • 走 Vite 的 /node_modules/.vite/deps/... 路径可能带 hash 失效,直连 /node_modules/pixi.js/dist/pixi.mjs 更稳。
  • 项目里预留了一个 window.__appDev 调试钩子(暴露 getApp() / showPanel() 之类入口),让 AI 能直接驱动页面状态。为 AI 调试留一个 dev hook,收益极高

4.3 内嵌 WebView 关闭按钮多机型适配

resize_page 扫真机尺寸,逐个量按钮位置:

js 复制代码
resize_page({ width: 390, height: 844 })   // iPhone 12/13 竖屏
resize_page({ width: 430, height: 932 })   // iPhone 14 Pro Max 竖屏
resize_page({ width: 932, height: 430 })   // 横屏

evaluate_script({ function: `() => {
  const btn = document.querySelector('.webview-close-button');
  if (!btn) return { found: false };
  const r = btn.getBoundingClientRect();
  const shell = document.querySelector('.app-shell');
  const cs = getComputedStyle(shell);
  return { rect: r.toJSON(), shellTransform: cs.transform, shellW: cs.width };
}` })

take_screenshot({ filePath: "/tmp/close-btn-portrait.png", format: "png" })

要点 :截图落盘用 filePath 而不是回传 inline,能省大量 context------一张 PNG inline 回来动辄上万 token。

⚠️ 默认情况下,若 MCP client 没协商 roots 能力,写文件的工具被限制在系统临时目录 。所以 /tmp/xxx.png 一定能写,项目内相对路径可能被拒。真要写到项目里得加 --allowUnrestrictedPaths(放宽了沙箱,谨慎)。

4.4 技术选型:抓仓库元数据做横评

做开源库横评时,stars / forks / 语言构成 / 最后提交时间这些动态渲染的数字,搜索摘要给不了,必须真浏览器渲染完再读。过程中还发现某个仓库从旧账号重定向到了新组织------这种重定向只有真实导航才会暴露。


5. 它还能干但我还没用上的

evaluate_script 占了 8 成调用,说明这些能力基本闲置,而前端项目恰好用得上:

  • list_console_messages --- 抓 JS 报错。比让用户手动开 DevTools 复制粘贴快得多,排 WebView 白屏 / WebGL 黑屏这类问题时尤其值。
  • list_network_requests / get_network_request --- 看接口实际请求响应,排"提交失败"这类问题直接得多。
  • emulate --- networkConditions: "Slow 3G" 模拟弱网、cpuThrottlingRate 模拟低端机、extraHttpHeaders 注入测试 header。低端机卡顿类问题可以先在浏览器里复现。
  • performance_start_trace + performance_analyze_insight --- Core Web Vitals 与加载瀑布,首屏优化可用。
  • take_heapsnapshot --- 查 JS 内存泄漏。
  • lighthouse_audit --- 可访问性 / SEO / best practices 打分。

6. 坑与最佳实践

Context 消耗是首要问题。 29 个工具的 schema + 截图 inline 回传能吃掉惊人的 context。对策:--slim--screenshotFormat webp + --screenshotMaxWidth、截图用 filePath 落盘、优先 take_snapshot 而非 take_screenshot--no-category-* 关掉不用的组。

--wsEndpoint 的 browser id 会变。 每次重启 Chrome 都换,写死在配置里必然失效。要手动指定就用 --browserUrl http://127.0.0.1:9222

--autoConnect 要先手动开一次远程调试开关chrome://inspect/#remote-debugging),且 Chrome 需 144+。

JS 里等异步。 await document.fonts.ready、必要时 wait_for({text: [...]})。§4.2 的字体测量踩过这个坑------字体没加载完,测量值全是 fallback 字体的。

evaluate_script 返回值必须 JSON 可序列化。 返 DOM 节点会失败,用 rect.toJSON() / 只挑字段返。

给项目留 dev hook。window 上挂一个 dev 命名空间,暴露几个驱动页面状态的入口,AI 就不用猜内部结构,调试效率差一个量级。

安全边界。 接管日常 profile 意味着把你的全部登录态交给了 agent 。敏感场景用 --isolated 起干净 profile,或用 --allowedUrlPattern / --blockedUrlPattern 限制可访问范围,--redactNetworkHeaders 脱敏请求头(默认关)。别让它带着你的 SSO 会话去访问不该访问的内网系统。

别把它当搜索引擎。 它没有"搜"的能力,只有"打开"的能力。正确工作流:WebSearch 找 URL → chrome-devtools 读全文。

相关推荐
码哥字节4 小时前
Matt Pocock 的 agent skills 好用,但国产 spec-superflow 更狠
agent·ai编程·claude
阿里云云原生5 小时前
从 MCP 协议演进看网关架构变革:Higress v2.2.4 实践与验证报告
mcp
deepseek235 小时前
MCP Gateway 架构实战:企业级 AI Agent 连接层的设计与选型
ai agent·企业架构·mcp
今日无bug6 小时前
从「拿来主义」到「亲手造轮子」:2 种 MCP 文件服务器写法对比
前端·node.js·mcp
SeaDhdhdhdhdh16 小时前
MCP Server 搭建与使用指南
java·ai·agent·mcp
跨境Jacky16 小时前
Shopee AI 选品:Sorftime CLI 实操教程
跨境电商·mcp·sorftime
xrlfreedom21 小时前
大厂 MCP 面试实录:可复用模板工作流与向量检索结合方案设计
mcp·python mcp sdk·向量检索与重排
Lumi--1 天前
MCP(Model Context Protocol):AI 世界的“USB-C“接口
mcp