数据截至 (上游 commit fd0b7e1d9ed9)
第 7 章:CLI、daemon 与代码生成
这章讲什么: 同一份工具定义怎么变成三样东西(MCP 工具、CLI 命令、参考文档),以及命令行下"浏览器状态在多条命令之间保持"是怎么做到的。
7.1 一份定义,三处使用
全景
src/tools/*.ts 里的 zod schema
│ 唯一真相
┌───────────────┼───────────────┐
▼ ▼ ▼
MCP 工具 CLI 命令表 参考文档
(运行时注册) chrome-devtools- docs/tool-reference.md
cli-options.ts
(生成物,勿手改) (生成物)
▲ ▲ ▲
│ │ │
直接用 scripts/generate- scripts/generate-
cli.ts docs.ts
生成器的做法有点意外
scripts/generate-cli.ts 不是去静态分析源码,而是真的把 server 跑起来:
const transport = new StdioClientTransport({
command: 'node',
args: [serverPath, '--viaCli'],
env: {...process.env, CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS: 'true'},
});
const client = new Client({name: 'chrome-devtools-cli-generator', …});
await client.connect(transport);
const toolsResponse = await client.listTools();
用 MCP 客户端去问一个 MCP 服务端要工具表。 好处很实在:拿到的是 zod 经过 SDK 转换后的最终 JSON Schema,和模型看到的一模一样,不会因为静态分析漏掉 .optional()、.default() 或 transform。
注意它带了 --viaCli——这样被类别开关禁用的工具也会注册(见第 1 章),命令表才完整。
然后 schemaToCLIOptions 把 JSON Schema 摊平成 CLI 选项。这里有一条硬约束:
if (typeof prop.type !== 'string') {
throw new Error(`Property ${name} has a complex type not supported by CLI.`);
}
参数类型太复杂就直接让生成失败。 这也解释了为什么 fill_form 的 elements(对象数组)在 CLI 里用不了。
生成物顶部写着:// NOTE: do not edit manually. Auto-generated by 'npm run cli:generate'.
7.2 CLI 的参数约定
规则
必填参数 → 位置参数(不带 --)
可选参数 → 选项(带 --)
于是:
chrome-devtools new_page "https://example.com" # url 必填 → 位置
chrome-devtools take_screenshot --filePath shot.png # filePath 可选 → 选项
chrome-devtools click 1_12 --dblClick # uid 必填,dblClick 可选
命令字符串在 src/bin/chrome-devtools.ts:225-233 拼出来:必填拼成 <name>,可选拼成 [--name]。
给 agent 的错误提示
yargs 的 .fail()(src/bin/chrome-devtools.ts:91-126)在遇到"参数不够"或"未知参数"时,会打一段抬头是 💡 TIP FOR AI AGENT / DEVELOPER: 的说明:
1. Required parameters MUST be passed as positional arguments (without flags).
- INCORRECT: chrome-devtools evaluate_script --expression "() => document.title"
- CORRECT: chrome-devtools evaluate_script "() => document.title"
2. Optional parameters are passed as double-dash options/flags (e.g. --pageId 1).
3. Make sure to escape quotes properly for your shell environment.
错误信息的目标读者被明确写成了 AI agent。 正例反例并排给,是很有效的纠错 形式。
CLI 改掉的几个默认值
getCliOptions(src/bin/chrome-devtools.ts:52-68)对选项表做了改造:
| 改动 | 值 | 为什么 |
|---|---|---|
删掉 viewport | — | 尚未支持 CLI 序列化 |
删掉 experimentalStructuredContent / experimentalInteropTools / experimentalPageIdRouting | — | CLI 默认关掉实验项(注释原话「Change the defaults for the CLI」) |
headless 默认 | true | 命令行场景通常不需要看窗口(:147-148) |
isolated 默认 | true(未给 userDataDir 时) | 每次干净环境(:143-145) |
固定追加的只有 --viaCli(DEFAULT_CLI_ARGS,:44);--output-format json 仍按命令提供(:228-231)。旧版「headless 必须有默认、isolated 必须没有默认」的启动期自检已删除,默认值改为在 start 命令里直接补(:143-148,注释明说「Defaults but we do not want to affect the yargs conflict resolution」)——既给了默认又不干扰 yargs 的冲突解析。