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_terminate、branch 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_page 到 raw.githubusercontent.com/...,拿到的是原始 Markdown 全文,零解析损耗、零摘要截断。我的几篇技术梳理笔记都是这么产出的。

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


2. 安装部署

2.1 前置

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

2.2 配置写法

~/.claude.json → projects["<你的项目绝对路径>"].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_snapshot 拿 uid,再把 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 读全文。

相关推荐
ZzT8 分钟前
Claude Duet 安全设计拆解:替你回邮件、付账单的 agent,碰不到你的密码
ai编程·claude
小七-七牛开发者20 分钟前
当 Agent 接手更多工作,我们还能把好关吗?
ai·openai·agent·claude
独隅1 小时前
Claude 高效使用指南深度评测
java·开发语言·claude·claude code
yjm0021 小时前
如何用 Claude Opus 5.5 做一支音乐 MV?代码逐帧渲染完整教程(2026)
ai编程·claude
独隅2 小时前
Claude 新手入门与高效调用指南
claude
独隅2 小时前
Claude 高效应用实战指南
android·java·开发语言·claude·claude code
技术小甜甜4 小时前
【Copilot】能选 Claude 和 GPT-6 了,Excel 分析该交给谁
gpt·excel·copilot·claude·microsoft365·gpt-6
vjmap17 小时前
WebGIS + AI 智能体:唯杰地图智能体平台一句话处理 CAD 图纸,支持 MCP 接入 AI 编辑器
gis·agent·mcp
lugiax19 小时前
开着 Auto Mode 通宵让 AI 敲代码,为什么早上醒来还是卡在半夜?
ai编程·claude