chrome-devtools-mcp 贡献指南:开发环境搭建、Evals 测试、发布流程与 JSON Schema 约束
chrome-devtools-mcp(Chrome DevTools for coding agents)是一个让编码智能体通过 MCP 协议控制并检查实时 Chrome 浏览器的开源项目。这篇指南基于仓库的 CONTRIBUTING.md 完整展开,覆盖从签署 CLA、搭建本地开发环境、构建并测试 MCP 服务器,到 Conventional Commits 规范、功能发布清单、Lighthouse 依赖更新、Evals 评测场景编写,直至工具 JSON Schema 的硬性约束——帮助你在动手提交 PR 之前,完整掌握该项目的开发流程与工程约定。
贡献前准备
签署贡献者许可协议(CLA)
向该项目提交代码必须附带一份 Google CLA(Contributor License Agreement)。版权仍归贡献者(或其雇主)所有,CLA 只是授予项目使用和再分发代码的许可。如果本人或现雇主已签署过 Google CLA(哪怕是针对其他项目),通常无需重复签署。
社区准则
项目遵循 Google 开源社区行为准则。所有提交(包括项目成员自己的提交)都需要评审,统一通过 GitHub Pull Request 进行。
本地开发环境搭建
文档明确要求:先确认使用的 Node 版本与 .nvmrc 一致,再执行克隆与构建。当前 .nvmrc 中指定的版本为 v24,而 package.json 的 engines 字段声明的兼容范围是 ^20.19.0 || ^22.12.0 || >=23——开发时以 .nvmrc 声明的 v24 为准。
git clone https://github.com/ChromeDevTools/chrome-devtools-mcp.git
cd chrome-devtools-mcp
npm ci
npm run build
从 package.json 的 scripts 定义可以看到构建的完整构成:
npm run build实际执行tsc && node scripts/post-build.ts,即 TypeScript 编译加后处理;- 项目声明了两个可执行入口(
bin字段):chrome-devtools-mcp(MCP 服务器,指向./build/src/bin/chrome-devtools-mcp.js)和chrome-devtools(CLI,指向./build/src/bin/chrome-devtools.js); - 另有
npm run typecheck(tsc --noEmit)、npm run test(先构建,再经 scripts/test.js 运行并跳过 THIRD_PARTY_NOTICES 相关测试)等配套脚本。
运行与测试构建出的服务器
使用 MCP Inspector
构建完成后,可以直接用官方 Inspector 连接本地服务器:
npx @modelcontextprotocol/inspector node ./build/src/bin/chrome-devtools-mcp.js
这个命令与 package.json bin 字段声明的 chrome-devtools-mcp 入口完全对应。注意 scripts/eval_gemini.ts 中也以 build/src/bin/chrome-devtools-mcp.js 作为被测服务路径,如果该文件不存在会直接报错并提示先执行 npm run build——这说明"先构建、再运行"是所有本地验证流程的前置条件。
配置到真实 MCP 客户端
也可以把本地构建产物直接挂到任意 MCP 客户端的配置里:
{
"mcpServers": {
"chrome-devtools": {
"command": "node",
"args": [
"/<path-to-chrome-devtools-mcp>/build/src/bin/chrome-devtools-mcp.js"
]
}
}
}
将 args 指向自己 checkout 后的 build/src/bin/chrome-devtools-mcp.js 绝对路径即可。这与 README.md 中面向用户发布的 npx -y chrome-devtools-mcp@latest 方式形成对照:前者用于开发验证,后者用于生产使用。
VS Code SSH 远程场景的端口转发
当通过 VS Code SSH 远程开发并运行 @modelcontextprotocol/inspector 时,Inspector 会拉起两个服务,分别监听 6274 和 6277 端口。VS Code 通常能自动检测并转发 6274,但往往检测不到 6277,需要手动添加转发,否则 Inspector 页面无法正常连接。
调试日志
把调试日志写到工作目录下的 log.txt:
npx @modelcontextprotocol/inspector node ./build/src/bin/chrome-devtools-mcp.js --log-file=/your/desired/path/log.txt
日志类别控制沿用惯例的 DEBUG 环境变量;package.json 中的 start-debug 脚本即采用 NODE_DEBUG=mcp:* npm run build && node build/src/bin/chrome-devtools-mcp.js 的方式,聚焦 MCP 相关日志类别。
文档与 CLI 的自动生成
新增工具、或修改工具的名称/描述后,必须运行 npm run gen 重新生成工具参考文档。从 package.json 可以看到该脚本的完整组成:
npm run gen
# 等价于:
# npm run build && npm run cli:generate && npm run docs:generate && npm run update-metrics && npm run format
即:构建 → 生成 CLI(scripts/generate-cli.ts)→ 生成文档(scripts/generate-docs.ts,产物即 docs/tool-reference.md 等参考文档)→ 更新指标(scripts/update_metrics.ts)→ 统一格式化。这意味着工具定义是单一事实来源,文档不是手写的,改完 src/tools/ 下的定义后必须走一遍 gen 流程。
提交与功能发布规范
Conventional Commits
PR 标题和 commit 标题需遵循 Conventional Commits 规范(如 feat:、fix:、chore: 等前缀)。这一规范同时服务于自动化发布流程,见下文。
功能发布清单(Feature release checklist)
尚未对用户开放的不完整功能,提交时统一使用 chore: 前缀;当功能准备发布时,再开一个 feat: 前缀的 PR 将其启用。发布前必须满足以下四条标准(直接引自 CONTRIBUTING.md):
- 功能文档保持最新,例如 README 和 tools reference 已同步更新;
- 功能在 Chrome stable 上可用,否则需在文档中明确版本限制;
- 如需要,对应的 skills 已更新或新增了新的 skill(仓库的 skills/ 目录即为这些技能文件所在位置);
- 功能必须能独立或结合现有功能完成真实用例——项目明确要避免"提供了一组工具却无法真正调试出东西"的半成品功能。
自动化发布流程
chrome-devtools-mcp 的版本发布由 GitHub Actions 自动化(基于 release-please,配置见 release-please-config.json)。发布一个新版本的步骤是:查找标题为 chore(main): release chrome-devtools-mcp 的 PR,对它进行评审、测试并合并即可。当 main 分支上有会出现在 changelog 中的变更时,该 release PR 会被自动创建;当前的发布版本记录在 .release-please-manifest.json,历史变更见 CHANGELOG.md。
更新 Lighthouse 依赖
chrome-devtools-mcp 把 Lighthouse 打包成内部 bundle 供 Lighthouse 相关工具使用(bundle 位于 src/third_party/lighthouse-devtools-mcp-bundle.js),因此升级流程比普通的 npm install 复杂:
- 更新 package.json 中的 Lighthouse 版本并执行
npm install。当前版本为13.4.1,npm 版本目前仅用于获取类型定义; - 将对应的 Lighthouse 仓库版本检出到兄弟目录
../lighthouse; - 运行
npm run update-lighthouse(对应 scripts/update-lighthouse.ts)。注意 Lighthouse 本身要求使用 yarn; - 提交生成的 bundle。若 bundle 引入了新依赖,需同步更新 tests/third_party_notices.test.ts——该测试用于校验第三方许可声明(notices)与依赖清单的一致性,配套脚本还有 scripts/append-lighthouse-notices.ts。
为 Evals 贡献评测场景
项目使用 Gemini 对 MCP 服务器工具做端到端评测,场景文件放在 scripts/eval_scenarios/(如 navigation_test.ts、network_test.ts 等 20 多个场景)。每个场景是一个 TypeScript 文件,导出实现 TestScenario 接口的 scenario 对象。
TestScenario 接口的完整定义位于 scripts/eval_result.ts:
export interface TestScenario {
prompt: string; // 发送给模型的提示词
maxTurns: number; // 最大对话轮次
expectations: (result: Result) => void; // 验证模型发起的工具调用
htmlRoute?: { // (可选)为测试提供自定义 HTML
path: string;
htmlContent: string;
};
serverArgs?: string[]; // (可选)传给 MCP 服务器的额外 CLI 参数
}
其中 htmlRoute 用于在测试中于指定路径提供自定义 HTML 内容;scripts/eval_gemini.ts 在执行时会将 prompt 中的 <TEST_URL> 占位符替换为该路由的真实地址。serverArgs 可以注入如 --no-page-id-routing 之类的额外服务参数。
一个典型场景示例(摘自 CONTRIBUTING.md):
import {TestScenario} from '../eval_gemini.js';
export const scenario: TestScenario = {
prompt: 'Navigate to example.com',
maxTurns: 2,
expectations: calls => {
// 检查至少有一次 'browse_page' 调用
const navigation = calls.find(c => c.name === 'browse_page');
if (!navigation) throw new Error('Model did not browse the page');
// 校验核心参数
if (navigation.args.url !== 'http://example.com') {
throw new Error(`Wrong URL: ${navigation.args.url}`);
}
},
};
评测框架的实际断言能力比示例更丰富。expectations 接收的是 Result 对象(scripts/eval_result.ts),它按顺序消费模型产生的工具调用序列,提供:
assertNextCall(name, expectedArgs?):断言"下一次调用"的名称与关键参数(deepStrictEqual逐字段比较);consumePageNavigation():跳过开头/结尾的list_pages样板调用,断言发生了new_page或navigate_page,并推断出活动页的pageId;hasPageIdRouting:根据服务参数中是否含--no-page-id-routing判断路由模式,让同一断言兼容两种模式。
以 navigation_test.ts 为例:
expectations: result => {
if (result.hasPageIdRouting) {
result.assertNextCall('list_pages');
}
assert.ok(result.remainingCalls.length >= 1);
result.assertNextCall('navigate_page', {
url: 'https://developers.chrome.com',
pageId: result.hasPageIdRouting ? 1 : undefined,
});
},
场景设计原则(引自 CONTRIBUTING.md):验证工具被正确使用,但断言不要过严。对可能变化的参数(如自然语言推理产生的措辞)避免断言精确值,但必须确保 URL、选择器等核心参数正确。
运行评测的入口是 npm run eval(package.json 中定义为 npm run build && node scripts/eval_gemini.ts)。从 scripts/eval_gemini.ts 的实现可以看到运行时细节:以 --isolated 启动服务器(非调试时加 --headless)、强制设置 CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS=true 关闭统计采集、向 prompt 追加随机 queryid 以避免缓存干扰。若启用 skill 前缀模式,还会把 skills/chrome-devtools/SKILL.md 的内容拼接到 prompt 之前。
工具 JSON Schema 的硬性约束
CONTRIBUTING.md 对 src/tools/ 下所有工具定义的 Zod schema 提出了两条硬性限制,并说明由 @local/enforce-zod-schema ESLint 规则强制检查:
- 禁止
.nullable(),禁止.object()类型; - 复杂对象应表示为简短的格式化字符串。
这条规则的实际实现在 scripts/eslint_rules/enforce-zod-schema-rule.js:规则扫描工具 schema 文件中的方法调用,出现 .nullable() 即报 noNullable(建议使用 .optional() 替代);出现 zod.object() 或 z.object() 调用即报 noObject(建议用格式化字符串表达复杂对象)。它有意不区分调用者是否为 ZodObject——即拦截所有 .nullable() 调用。规则在 eslint.config.js 中以 error 级别应用于 src/tools/**/*.ts:
{
name: 'Tools definitions',
files: ['src/tools/**/*.ts'],
rules: {
'@local/enforce-zod-schema': 'error',
},
},
这条约束的工程动机从工具面向 LLM 消费者的定位可以推断:嵌套对象和 nullable 类型对模型的参数生成不友好,扁平化、字符串化的参数设计能降低模型出错概率。此外同目录的 check-license-rule.js 与 no-direct-third-party-imports-rule.js 分别强制许可证头与第三方导入收口(src/ 下只允许经由 src/third_party/index.ts 引入依赖),这些自定义规则与 schema 规则共同构成了项目的 lint 防线。
测试、格式化与代码风格
日常提交前的验证组合,从 package.json 的 scripts 可以整理为:
npm test:构建后通过 scripts/test.js 运行测试(默认跳过 THIRD_PARTY_NOTICES 测试,许可声明测试单独由npm run test:notices执行);npm run test:update-snapshots用于刷新快照,快照文件分布在tests/各目录(如 tests/tools/console.test.js.snapshot);npm run format/npm run check-format:ESLint(含上文自定义规则)加 Prettier 的格式化与检查;npm run typecheck:仅做类型检查;npm run profile/npm run test:memory:基于 scripts/profile/ 的性能剖析与内存泄漏测试,对应.github/workflows中的test-memory-leaks.yml等 CI 流程。
eslint.config.js 中还定义了若干值得注意的全局约束:@local/check-license 为 error 级别、import/no-cycle 禁止循环依赖、第三方导入只能经由 devtools-frontend/mcp/mcp.js 的出口(no-restricted-imports 规则)、@typescript-eslint/consistent-type-imports 等,贡献代码时保持一致的风格能显著减少评审往返。
小结
chrome-devtools-mcp 的贡献流程可以归纳为一条清晰的主线:以 .nvmrc 声明的 Node 版本 npm ci && npm run build 完成本地构建;用 Inspector 或真实 MCP 客户端验证行为,必要时用 --log-file 与 DEBUG 定位问题;未完成的工具用 chore: 提交、成熟后按四条发布清单走 feat: 启用;改动工具定义后必须 npm run gen 同步文档与 CLI;工具 schema 遵守"无 nullable、无 object、复杂参数字符串化"的 ESLint 硬约束;Evals 场景以 TestScenario 四字段描述"提示词 + 轮次上限 + 宽松但核心的断言";版本发布交给 release PR 自动化。遵循这些约定,你的补丁才能顺利通过该项目的评审、CI 与自动化发布链路。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00