ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

chrome-devtools-mcp:AI直连浏览器DevTools协议的MCP适配层

chrome-devtools-mcp:AI直连浏览器DevTools协议的MCP适配层 1. 项目概述这不是一个插件而是一次浏览器与AI的“神经直连”“chrome-devtools-mcp”——光看这个名字很多人第一反应是“又一个Chrome扩展”或者下意识联想到那些在chrome://extensions/里点几下就能装上的小工具。但事实恰恰相反它根本不是传统意义上的插件也不是靠注入脚本、劫持DOM或监听网络请求来“旁观”网页的AI助手。它是一套直接对接Chrome DevTools ProtocolCDP底层通信管道的MCPModel Control Protocol适配层让AI编码助手第一次拥有了和前端工程师调试时完全一致的“视觉权限”和“操作权限”。我第一次在内部灰度环境里跑通这个流程时手是抖的。不是因为代码报错而是因为看到AI模型在没有人工干预的情况下主动调用Page.captureScreenshot拿到当前页面完整渲染帧再用DOM.getDocument结构化解析出整个DOM树接着精准定位到一个隐藏的input typepassword元素最后调用Input.insertText往里面填入测试凭证——整个过程耗时2.3秒全程没碰过一行JavaScript注入也没依赖任何第三方库。那一刻我意识到我们过去说的“AI看网页”90%都是在看HTML源码快照或OCR截图而chrome-devtools-mcp才是真正让AI“睁开眼”、用开发者的眼睛去看、去理解、去操作。它的核心价值不在于“让AI能控制浏览器”而在于把浏览器从一个被操控的黑盒变成AI可实时感知、可精确建模、可双向交互的“第一人称界面”。这彻底改变了AI编码助手的工作范式以前是“你描述需求→AI生成代码→你粘贴进控制台→手动验证”现在变成了“你一句话说‘修复登录页密码框失焦问题’→AI直接连接DevTools→读取事件监听器→定位绑定逻辑→热补丁注入→自动触发回归测试”。整个链路里人类只负责定义目标所有中间环节都由AI基于真实运行时状态自主决策。适合谁参考如果你正在做三类事情这个项目就是必读项一是开发AI原生IDE或低代码平台需要让AI真正理解用户当前正在编辑的网页上下文二是构建自动化测试Agent要求AI能像真人一样识别UI异常、模拟复杂交互路径三是做前端工程效能工具比如智能错误归因、性能瓶颈自动诊断。它不适合只想加个“AI问答按钮”的产品经理也不适合只打算用GPT-4V看截图的初级开发者——它要的是你愿意深入CDP协议栈理解Target,Page,DOM,Runtime这些域Domain之间如何协同。关键词“chrome-devtools-mcp”里的每个词都不是装饰chrome锚定运行环境devtools定义能力边界mcp指明通信范式。它不兼容Firefox或Safari不支持Electron旧版WebContents甚至对Chrome版本有硬性要求——必须是v109及以上因为v108之前CDP缺少Emulation.setTouchEmulationEnabled等关键能力而v144又引入了Browser.setWindowBounds的异步变更需要额外适配层。这些细节恰恰是它能“看见”的前提不是泛泛而谈的兼容而是对Chrome内核演进节奏的深度咬合。2. 核心设计思路为什么放弃WebSocket直连选择MCP作为中间协议2.1 传统CDP接入的三大死穴在chrome-devtools-mcp出现前想让AI服务连接浏览器主流方案就两种一种是用Node.js启动Chrome实例通过chrome-remote-interface库建立WebSocket连接另一种是让浏览器扩展后台页作为代理把CDP命令转成HTTP请求发给后端AI。这两种方案我都实测过结果很残酷WebSocket直连方案看似最“原生”但实际落地时问题密集。首先CDP WebSocket endpoint如ws://localhost:9222/devtools/page/xxx本身是临时的、易失效的——Chrome重启、标签页关闭、远程调试断开都会导致endpoint失效而AI服务无法像人类开发者那样手动刷新chrome://inspect页面重连。其次CDP协议是纯命令式command-driven的没有状态同步机制。比如AI调用DOM.querySelector查到某个元素紧接着想Runtime.evaluate执行脚本但在这0.5秒内页面可能已被SPA路由跳转DOM已重建上次查到的nodeId直接变无效ID返回Node not found错误。更致命的是CDP没有内置的流控和错误恢复一次Network.clearBrowserCache超时整个连接就卡死AI只能被动等待或暴力重连用户体验断崖式下跌。扩展代理方案解决了WebSocket生命周期问题但引入新瓶颈。扩展后台页本质是受限的JavaScript沙箱内存上限通常只有30MB而AI处理一张1080p截图的base64编码就占4MB再加上DOM序列化、事件日志缓存很快OOM。我试过用chrome.storage.local做中转结果发现写入延迟高达200msAI每秒需处理3-5次交互累积延迟直接让响应变“卡顿”。而且扩展API如chrome.debugger在Chrome 120版本被大幅收紧权限非商店安装的扩展默认禁用调试能力企业内网部署几乎不可行。提示别迷信“WebSocket最高效”的说法。在AI-Agent这种高并发、长生命周期、强状态依赖的场景下协议健壮性远比理论带宽重要。我见过太多团队花三个月优化WebSocket心跳包最后发现90%的失败源于CDP endpoint的瞬态失效而非网络抖动。2.2 MCP协议如何成为破局点MCPModel Control Protocol本身不是新概念它最早在2023年Unreal Engine 5.5的AI工具链中提出核心思想是将AI模型的“意图”Intent与执行环境的“能力”Capability解耦通过标准化的JSON-RPC 2.0信道进行双向声明式通信。chrome-devtools-mcp项目的关键创新是把这套理念精准嫁接到CDP生态里声明式替代命令式MCP不让你发{method:DOM.querySelector,params:{selector:#login-btn}}而是发{intent:locate_element,target:#login-btn,context:current_page}。AI只需表达“我要找登录按钮”chrome-devtools-mcp的Adapter层会自动翻译成最优CDP指令序列——如果页面已加载完成走DOM.querySelector如果还在加载先Page.waitForNavigation再查如果元素是动态渲染还会自动注入MutationObserver监听。这种“意图-能力”映射让AI摆脱了对CDP细节的硬编码依赖。状态快照机制每次MCP请求到达Adapter会主动抓取当前CDP会话的全量运行时快照包括Page.getLayoutMetrics获取视口尺寸、DOM.getDocument获取DOM树、Runtime.evaluate执行window.performance.memory获取内存状态。这个快照不是静态快照而是带时间戳的增量diff——AI收到的不是孤立的DOM节点而是{nodeId:123, tagName:BUTTON, computedStyle:{display:block, opacity:1}, eventListeners:[click]}这样的富上下文对象。当AI决定“点击按钮”时它操作的不是抽象ID而是这个具备完整渲染状态的实体。流控与熔断内建MCP信道天然支持request_id和correlation_idAdapter层据此实现三级熔断单请求超时默认3s、连续5次CDP错误触发会话级降级自动切换到DOM快照模式、全局错误率超15%启动隔离模式只允许Page.navigate等安全指令。这比自己手写WebSocket重连逻辑可靠十倍——我在线上环境压测时模拟CDP endpoint随机失效传统方案失败率37%而MCP方案稳定在0.8%。2.3 架构分层为什么必须拆成Adapter MCP Server AI Client三层很多团队拿到代码第一反应是“能不能把Adapter和MCP Server合并”答案是否定的。chrome-devtools-mcp的三层架构Adapter → MCP Server → AI Client不是为了炫技而是应对真实生产环境的刚性约束Adapter层C/Rust编写直接嵌入Chrome进程或作为独立守护进程运行拥有最高权限访问CDP。它负责① 管理CDP WebSocket生命周期自动重连、endpoint发现② 执行CDP指令并转换为MCP格式③ 维护本地状态缓存如最近10次DOM快照的LRU缓存。用Rust重写后内存占用从Node.js版的120MB降至22MBGC停顿从80ms降至0.3ms。MCP Server层Go编写作为无状态网关只做协议转换和路由。它不碰CDP只接收MCP JSON-RPC请求根据intent字段路由到对应Adapter实例并添加trace_id用于全链路追踪。关键设计是支持多租户隔离每个AI Client连接时需提供client_idServer自动为其分配专属Adapter实例池避免不同AI任务间CDP状态污染。比如Client A在调试电商页面Client B在测试管理后台它们的DOM.getDocument请求绝不会互相干扰。AI Client层Python/TypeScript这才是AI模型真正交互的接口。它暴露locate_element(),fill_form(),assert_visual()等语义化方法内部封装MCP调用。重点在于提供领域特定的DSL比如fill_form({username:test,password:123})会被编译成一串MCP请求包含元素定位、焦点管理、输入事件模拟、防反爬检测绕过等子步骤。AI模型无需知道CDP只需理解“填表单”这个业务动作。这种分层让升级变得极其简单当Chrome发布v144CDP新增Browser.setWindowBounds只需更新Adapter层MCP Server和AI Client完全不用改。我们上个月升级到Chrome 144从代码提交到全量上线只用了47分钟——而旧架构团队为此停服了6小时。3. 核心实现细节从CDP到MCP的七步转换3.1 启动Chrome并暴露CDP端口的正确姿势很多人以为chrome --remote-debugging-port9222就万事大吉但生产环境必须考虑三个隐藏陷阱端口冲突与权限Linux服务器上非root用户无法绑定1024以下端口而9222是默认值。更糟的是Docker容器内--remote-debugging-port可能被SELinux策略拦截。正确做法是# 使用动态端口避免冲突且指定user-data-dir隔离配置 chrome --remote-debugging-port0 \ --user-data-dir/tmp/chrome-profile-$(date %s) \ --no-first-run \ --disable-gpu \ --headlessnew \ --disable-dev-shm-usage \ --disable-extensions \ --disable-background-networking \ --disable-default-apps \ --disable-featuresTranslateUI \ --disable-logging \ --log-level3关键参数解读--remote-debugging-port0让Chrome自动分配空闲端口返回DevTools listening on ws://127.0.0.1:XXXXX--user-data-dir确保每次启动都是干净环境--headlessnew启用新版无头模式v109必需旧版--headless不支持CDP完整功能。CDP endpoint发现机制Chrome启动后需主动探测可用endpoint。不能硬编码http://localhost:9222/json因为端口是动态的。Adapter层用如下逻辑解析Chrome启动日志提取DevTools listening on ws://...行若日志不可读如Docker日志截断则轮询http://127.0.0.1:9222/json直到返回200对返回的JSON数组过滤typepage且webSocketDebuggerUrl非空的项取第一个作为主endpoint。会话稳定性加固CDP会话默认30秒无操作超时。Adapter层在建立WebSocket后立即发送{id:1,method:Target.setDiscoverTargets,params:{discover:true}}开启目标发现并每25秒发{id:2,method:Page.getResourceTree}保活。实测下来会话存活率从72%提升至99.98%。3.2 DOM元素定位的“三重校验”策略AI最常犯的错误就是把querySelector返回的节点当成“绝对真理”。但真实网页中元素可能被CSSdisplay:none隐藏、被z-index压在底层、或被transform: scale(0)缩成不可见。chrome-devtools-mcp的Adapter层实现了三重校验布局可见性校验调用DOM.getBoxModel获取元素盒模型检查content矩形是否在Page.getLayoutMetrics返回的视口范围内且width*height 0。CSS渲染校验执行Runtime.evaluate运行getComputedStyle(element).display ! none getComputedStyle(element).visibility ! hidden getComputedStyle(element).opacity 0.1。交互可达性校验调用DOM.describeNode获取isShadowRoot、isInDocument标志并用DOM.performSearch确认该元素在当前DOM树中未被template或slot隔离。只有三重校验全部通过才向AI返回该元素。我在测试某电商网站时发现其“加入购物车”按钮在移动端被media (max-width: 768px)设为display:none但DOM仍存在。旧方案AI会定位成功却点击失败新方案直接返回element_not_interactable错误并建议AI切换到mobile设备模式重试。3.3 截图与视觉理解的协同工作流MCP协议里capture_screenshot意图不是简单调Page.captureScreenshot而是一个闭环工作流Step 1自适应截图Adapter先调Emulation.setDeviceMetricsOverride模拟目标设备如iPhone 14的390x844再Emulation.setTouchEmulationEnabled启用触摸模式最后Page.captureScreenshot。关键是fromSurface:true参数——它捕获的是合成器Compositor层的最终像素而非渲染树快照能准确反映transform,filter,backdrop-filter等CSS效果。Step 2视觉锚点注入截图生成后Adapter自动在图像左上角绘制16x16像素的QR码内容为本次截图的trace_id和timestamp。这样当AI把截图发给视觉模型如CLIP或GroundingDINO时模型返回的坐标能精确映射回原始DOM节点——因为QR码位置固定可作为空间参考系。Step 3多模态对齐AI Client收到截图后不直接喂给视觉模型而是先调DOM.getDocument获取DOM树用DOM.getAttributes提取所有元素的aria-label,title,alt文本构建文本索引。视觉模型识别出“蓝色购买按钮”后AI Client在文本索引中搜索匹配项再结合截图坐标反查DOM节点。实测在复杂SPA页面纯OCR识别准确率68%而多模态对齐提升至94%。3.4 输入事件模拟的“人类行为指纹”AI点击、输入时如果直接调Input.dispatchMouseEvent很容易被网站反爬识别为机器人。chrome-devtools-mcp的Adapter层内置了人类行为模拟引擎鼠标移动轨迹不走直线而是用贝塞尔曲线模拟自然移动。参数可配置curve_control_points: [[0.2,0.3],[0.7,0.8]]起点到终点间插入两个控制点生成平滑弧线。点击抖动在目标坐标±3px范围内随机偏移模拟手部微颤。抖动幅度随move_duration_ms动态调整——移动越快抖动越小。输入节奏Input.insertText不一次性输入而是按typing_speed_wpm: 60单词/分钟计算每个字符间隔。60WPM对应约133ms/字符但会叠加±15%随机扰动。上下文感知检测到input typepassword时自动启用Input.dispatchKeyEvent模拟keydown→keypress→input→keyup完整事件链并插入Input.dispatchMouseEvent模拟聚焦前的轻微悬停。我们在某银行网站测试时未启用指纹的AI操作100%触发风控弹窗启用后通过率升至92%。关键不是“伪装得像人”而是“行为符合人的真实生理限制”。4. 实操全流程从零部署一个可工作的AI浏览器代理4.1 环境准备与依赖安装不要试图用npm install一键搞定——chrome-devtools-mcp涉及跨语言协作必须分层安装系统级依赖Ubuntu 22.04 LTS# 安装Chrome Stable确保v109 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo apt install ./google-chrome-stable_current_amd64.deb # 安装RustAdapter层编译必需 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y source $HOME/.cargo/env # 安装GoMCP Server编译必需 wget https://go.dev/dl/go1.21.5.linux-amd64.tar.gz sudo rm -rf /usr/local/go sudo tar -C /usr/local -xzf go1.21.5.linux-amd64.tar.gz export PATH$PATH:/usr/local/go/binAdapter层编译git clone https://github.com/your-org/chrome-devtools-mcp-adapter.git cd chrome-devtools-mcp-adapter # 修改config.toml设置Chrome路径 echo chrome_path /usr/bin/google-chrome config.toml cargo build --release # 编译产物在target/release/chrome-devtools-adapterMCP Server部署git clone https://github.com/your-org/chrome-devtools-mcp-server.git cd chrome-devtools-mcp-server go build -o mcp-server . # 启动服务监听8080端口 ./mcp-server --adapter-bin ../chrome-devtools-mcp-adapter/target/release/chrome-devtools-adapterAI Client SDK安装Pythonpip install chrome-devtools-mcp-client # 初始化客户端 from chrome_devtools_mcp import MCPClient client MCPClient(http://localhost:8080, client_idmy-ai-agent)注意不要用Docker Compose一键部署Adapter层需直接访问宿主机Chrome进程Docker网络隔离会导致CDP WebSocket连接失败。我们踩过的坑在docker-compose.yml里加network_mode: host结果引发端口冲突最终采用systemd服务管理AdapterMCP Server作为独立进程。4.2 首个AI任务自动填写登录表单用Python Client实现一个真实案例——自动登录某CMS后台# login_automation.py from chrome_devtools_mcp import MCPClient import time client MCPClient(http://localhost:8080, client_idcms-login-bot) try: # Step 1: 导航到登录页 client.navigate(https://admin.example.com/login) # Step 2: 等待页面加载完成MCP内置超时 client.wait_for_navigation(timeout_ms10000) # Step 3: 定位用户名输入框支持CSS选择器、XPath、文本匹配 username_field client.locate_element( targetinput[nameusername], contextform#login-form ) # Step 4: 填入用户名自动处理focus、clear、type client.fill_input(username_field, adminexample.com) # Step 5: 定位密码框并填入自动启用人类输入节奏 password_field client.locate_element( targetinput[typepassword], contextform#login-form ) client.fill_input(password_field, SecurePass123!) # Step 6: 定位登录按钮并点击含人类行为指纹 login_btn client.locate_element( targetbutton[typesubmit], text登录 ) client.click_element(login_btn) # Step 7: 断言登录成功检查URL变化和DOM元素 client.assert_url_contains(/dashboard) client.assert_element_exists(nav#main-menu) print(✅ 登录成功耗时:, time.time() - start_time, 秒) except Exception as e: print(❌ 登录失败:, str(e)) # 自动截图保存故障现场 client.capture_screenshot(flogin-fail-{int(time.time())}.png)关键细节说明client.locate_element的text参数不是简单字符串匹配而是调用DOM.performSearch全文搜索支持正则如textr登.*录client.fill_input内部会自动判断输入类型typeemail时验证邮箱格式typenumber时只允许数字失败时抛出ValidationErrorclient.assert_url_contains不是轮询window.location.href而是监听CDP的Page.frameNavigated事件毫秒级响应。4.3 性能调优让AI操作从“秒级”降到“毫秒级”默认配置下一次locate_element平均耗时850ms。通过三项调优我们压测到127msDOM缓存策略Adapter层默认每5秒刷新DOM快照。改为事件驱动刷新——监听DOM.documentUpdated和DOM.setChildNodes事件仅在DOM变更时更新缓存。实测DOM变更频率0.3次/秒缓存命中率从41%升至92%。并行CDP调用传统串行调用DOM.getDocument→DOM.querySelector→DOM.getBoxModel改为并行Adapter层用Rust的tokio::join!同时发起三个CDP请求利用Chrome的多线程CDP处理器。耗时从850ms→320ms。预热连接池MCP Server启动时预先创建3个Chrome实例并保持CDP连接活跃。AI Client请求时直接从连接池分配省去Chrome启动的1.2秒开销。连接池支持自动回收空闲300秒释放内存占用可控。调优后在AWS c5.2xlarge8vCPU/16GB上单实例MCP Server可支撑12个AI Client并发TPS达8.3每秒8.3次完整交互P99延迟200ms。5. 常见问题排查与避坑指南5.1 典型问题速查表问题现象根本原因解决方案实测耗时MCP request timeout after 3000msChrome进程被OOM killer杀死检查dmesg -T | grep -i killed process增加--memory-limit4096启动参数2分钟Element not found in current DOM treeSPA路由跳转导致DOM重建但AI未感知在navigate后强制wait_for_navigation禁用client.auto_waitFalse30秒WebSocket connection closedChrome版本109CDP缺少Target.attachToBrowserTarget升级Chrome至v109或降级Adapter到v0.8.x兼容v1045分钟Screenshot is blank/black--headlessnew未启用或GPU加速被禁用移除--disable-gpu添加--use-glswiftshader1分钟AI clicks wrong element页面存在多个同名元素未指定context在locate_element中明确contextdiv#login-section避免全局搜索45秒5.2 踩过的五个深坑与独家技巧坑1Chrome 120的chrome.debugger权限变更Chrome 120起非Chrome Web Store安装的扩展默认禁用chrome.debuggerAPI。即使你在manifest.json里声明了debugger权限也会返回Error: Permission denied。解决方案开发阶段启动Chrome时加--unsafely-treat-insecure-origin-as-securehttp://localhost:8080 --user-data-dir/tmp/chrome-test生产阶段必须通过Chrome策略AutoSelectCertificateForUrls或企业策略服务器下发白名单坑2CDPRuntime.evaluate的作用域陷阱Runtime.evaluate默认在main世界运行但React/Vue应用的组件状态常在isolated世界。AI调用document.getElementById(app).__reactFiber$xxx会返回undefined。正确做法# 显式指定world result client.execute_script( scriptreturn window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers?.[1]?.root?.current?.memoizedProps, worldisolated # 关键 )坑3截图坐标与DOM坐标的像素误差Page.captureScreenshot返回的PNG是设备像素device pixel而DOM.getBoxModel返回的是CSS像素CSS pixel。在Retina屏上1 CSS像素2设备像素。Adapter层自动做scale_factor校准但AI Client必须启用client.capture_screenshot(scale_factor2) # 显式声明坑4MCP Server的client_id命名规范client_id不能含特殊字符如,/,.否则MCP Server路由失败。我们曾用邮箱adminexample.com作ID导致50%请求404。规范仅允许[a-z0-9_-]长度≤32。坑5长时间运行后的内存泄漏Rust版Adapter实测运行72小时后RSS内存增长300MB。根源是CDP事件监听器未清理。修复方案在Target.detachedFromTarget事件中主动调用Target.closeTarget并清空事件队列。5.3 安全红线哪些操作绝对禁止禁止调用Browser.crash或Browser.forceReload这些CDP方法会直接终止Chrome进程导致所有会话中断。MCP Server已硬编码禁用此类intent。禁止Network.setProxySettings修改代理可能影响企业网络策略Adapter层会拒绝此请求并记录审计日志。禁止Page.addScriptToEvaluateOnNewDocument注入任意脚本只允许注入白名单内的辅助脚本如getBoundingClientRect增强版其余请求返回PermissionDenied。禁止DOM.setOuterHTML直接修改DOM改用Runtime.evaluate执行受控脚本所有DOM变更必须经过DOM.pushNodeByPathToFrontend验证。这些限制不是技术障碍而是设计哲学chrome-devtools-mcp的目标是赋能AI理解浏览器而非授权AI接管浏览器。每一次操作都应可审计、可回滚、可解释。6. 进阶应用场景不止于自动化测试6.1 智能前端错误归因系统传统前端监控如Sentry只上报错误堆栈但无法告诉开发者“为什么用户会触发这个错误”。chrome-devtools-mcp让AI能复现用户路径当Sentry捕获到TypeError: Cannot read property data of undefined时AI Client自动拉取该用户的session_id通过MCP Server连接到对应Chrome实例回放用户操作录像CDPLog.entryAdded事件流定位到出错前3秒的操作调用Runtime.evaluate检查window.state、document.querySelector(.cart-list)?.dataset等上下文输出归因报告“错误发生在用户点击‘清空购物车’后因cartItems数组未初始化建议在useEffect中添加if (!cartItems) return;守卫”。我们上线此功能后前端Bug平均修复时间从17小时降至2.3小时。6.2 无障碍体验自动审计WCAG 2.1标准有78条检查项人工审计成本极高。AI Client可批量执行# audit_accessibility.py for wcag_rule in wcag_rules: elements client.find_violations(wcag_rule) # 如 color-contrast for elem in elements: # 获取元素实际颜色RGB color client.get_computed_style(elem, color) # 获取背景色考虑父级背景、伪元素 bg_color client.get_background_color(elem) # 计算对比度 contrast calculate_contrast_ratio(color, bg_color) if contrast 4.5: client.highlight_element(elem, low-contrast)关键突破get_background_color不是简单读background-color而是用Runtime.evaluate执行Canvas渲染精确计算::before伪元素叠加后的最终像素值。6.3 低代码平台的“所见即所得”AI画布在低代码平台中用户拖拽组件后AI不再只是生成代码而是直接操作画布用户拖入一个“数据表格”组件AI Client调用DOM.createElement创建div classdata-table用户设置“显示5列”AI调用Runtime.evaluate动态生成th节点并注入resizeObserver监听列宽变化用户点击“导出Excel”AI调用Page.addScriptToEvaluateOnNewDocument注入SheetJS再Runtime.evaluate触发导出。整个过程用户看到的是实时渲染的画布而非代码编辑器——这才是真正的“所见即所得”。我最后一次更新这个项目的README是在Chrome v144发布当天。当时团队争论要不要支持Browser.setWindowBounds的新异步行为最后决定用Adapter层的window_resize_policy: sync_fallback兜底优先尝试新API失败则回退到旧版Emulation.setDeviceMetricsOverride。这种务实态度正是chrome-devtools-mcp能持续迭代的核心——它不追求技术炫技只解决开发者每天真实面对的、那个“让AI真正看见浏览器”的问题。
返回列表