Claude Agent SDK 负责 Agent 循环,可以通过 MCP 调用工具。浏览器由工具处理器启动,成功条件也由项目定义。本例要求状态码实际出现在本地测试页上,点击完成只是其中一步。
选择浏览器接入方式
如果流程固定、输入已知且结果可以验收,适合做成范围明确的工具。探索陌生页面时,通用 Playwright MCP 提供的交互方式更灵活。Anthropic 的 API SDK 还有一套使用独立驱动接口的浏览器工具集。复制示例前,先确认自己接的是哪套 SDK 和接口。
API SDK 浏览器工具集文档 · Playwright 接入文档
浏览器 Agent · 浏览器自动化 · 浏览器自动化 Agent
分开检查注册、执行和任务结果
MCP 客户端能列出三个短名称,说明工具注册成功。下一层是处理函数是否打开了正确的页面。回执同时记录 URL 和可见状态,便于确认结果来自哪张页面。最后一层是任务验收,即使工具调用成功,也要单独看到预期状态才算完成。遇到故障时按这个顺序定位。
实现三个工具
用 tool() 声明参数校验和处理函数,再通过 createSdkMcpServer() 注册。可选 Agent 入口把服务放在 query().options.mcpServers.fixture 下,因此模型看到的工具名是 mcp__fixture__reveal_status。允许名单写完整名称,处理函数仍应约束每次调用能够访问的范围。 SDK 自定义工具文档
示例只允许打开普通或缺少控件的测试页。Playwright 创建没有登录状态的新上下文,参数用枚举,导航限定在测试页自己的来源。按按钮的无障碍名称精确查找,只有恰好一个匹配才点击。点击后读取状态区,并把可见文字与预期状态码核对。
| 工具 | 实际回执 |
|---|---|
open_fixture({variant}) | Status code hidden |
read_status() | 只读页面状态 |
reveal_status() | Status code: SDK-17 |

按执行顺序读源码
先看 fixture.mjs 的两种测试路径,再到 browser-tools.mjs 找精确角色定位、状态回读和调用预算,最后读 smoke.mjs。冒烟客户端通过内存 MCP 枚举工具和调用工具。可选 Agent 循环使用相同的处理函数。先跑冒烟,便于把工具故障与模型授权或提示问题分开。
在本地运行示例
冒烟测试经内存传输连接真实的 SDK MCP 服务,由确定性客户端调用工具,并启动本地 Chromium。它不需要模型凭据。可选 Agent 入口需要你自己的授权 API 密钥。本次运行了冒烟测试,模型入口没有执行。
npm ci
npx playwright install chromium
npm test对照普通路径和故障路径
第一次调用打开普通页,第二次显示状态码,第三次独立读取状态。随后打开缺失按钮的故障页,预期操作失败,再读一次确认状态码仍然隐藏。后续用只读调用触发额度上限,第九次确认预算由宿主执行。冒烟通过说明这些断言在合成页上成立。
查看工具回执
故障页故意移除了按钮。操作工具返回错误、零个匹配,以及仍然隐藏的状态。独立页面读取确认代码没有出现。八次调用用完后,第九次返回预算错误。截图记录页面当时的状态,JSON 记录工具如何报告这次尝试。
{
"isError": true,
"ok": false,
"code": "TARGET_MISSING_OR_AMBIGUOUS",
"expected": "Reveal status code",
"matches": 0,
"observed": "Status code hidden"
}
在执行动作的地方约束工具
本项目只有一个本地来源、两种输入和一个按钮。替换测试页时保留同等的边界。页面内容是待处理数据,里面的指令无权扩大工具权限。不要把网页给出的选择器、脚本或目标地址直接传进处理器。增加写操作之前,先约定允许修改的字段、可执行的环境,以及结果无法确认时如何处理。
确定何时停止
控件缺失或有歧义时,保存页面状态,检查选择器后再改。点击已经执行但状态未更新时,先重新读取页面。调用用完时停止,保留最后一个已确认结果。涉及写入的流程应先准备回读检查,再决定是否重试写操作。
| 失败 | 下一步 |
|---|---|
TARGET_MISSING_OR_AMBIGUOUS | 检查选择器 |
POSTCONDITION_FAILED | 重新读取页面 |
TOOL_BUDGET_EXHAUSTED | 停止并保留最后一次结果 |
一位 Claude Code 用户发现,助手称表单测试已通过,浏览器却没有可见操作。另一条浏览器工具讨论中,有人建议同时验证错误提示出现和后续动作确实停下。两条反馈帮助确定了本例的独立回读与停止检查。 r/ClaudeCode · r/AI_Agents
遇到问题先核对页面
状态读取失败可能因为适配器没打开目标页、页面缺少匹配控件,或点击已经触发但应用拒绝更新。保存失败代码和实际状态。超时或没有匹配时应先查看真实页面,避免把定位条件放宽到可能误点。确定性客户端能复现的问题,优先修工具或测试页,再调整模型提示。
在模型之外验证结果
可选 Agent 入口关闭内置工具,只允许三个工具名,并限制轮数和运行时长。即使模型报告成功,宿主也会独立检查页面。迁移时先写一条你能单独运行的回读检查,例如重新加载后核对保存的字段。
npm run agent先迁移一条小流程
把合成页换成测试来源,把状态码换成一个明确的业务条件,并保留同样窄的输入范围。延续调用预算,记录能区分成功和失败的最少信息,例如动作名、稳定错误码与简短的验证结果。共享日志排除凭据、带用户信息的页面文字和原始表单值。小流程可以重复验证后,再增加其他动作。
常见问题
浏览器由哪个组件启动?
工具宿主里的本地 Playwright 适配器负责启动浏览器。
冒烟测试需要 API 密钥吗?
不需要。客户端直接调用 SDK 注册的 MCP 工具。
可以给示例传任意网址吗?
示例只接受两种测试页模式,导航限定在本地测试来源。
点击后为什么还要验收?
浏览器可以执行点击,但应用仍可能没有产生预期状态。
和通用 Playwright MCP 有什么区别?
通用服务提供可复用的浏览器操作,本例提供三个有明确结果的流程工具。
可以直接接真实表单吗?
先用测试页复现,接真实表单前明确写入策略并实现独立验证。