1. 项目概述:连接AI与浏览器的自动化桥梁
如果你正在使用Cursor、Claude Desktop这类AI编程助手,并且希望它们能像真人一样操作浏览器——比如自动填写表单、抓取网页数据、测试Web应用,甚至与那些集成了WebMCP新特性的网站进行智能交互——那么你很可能需要一个可靠的“桥梁”。@tech-sumit/mcp-webmcp正是这样一个工具,它本质上是一个遵循Model Context Protocol(MCP)标准的服务器,其核心使命是将浏览器自动化能力(通过Playwright)和新兴的WebMCP页面工具,无缝地暴露给你常用的AI客户端。
简单来说,它让AI助手获得了“手”和“眼”。通过它,你可以直接在你的AI聊天窗口里输入“帮我在Le Petit Bistro网站上订一个今晚7点、2人、靠窗的位子”,AI就能理解并执行一系列浏览器操作,最终完成预订。这背后的关键,是它将26个精细的浏览器操作指令(如点击、输入、滚动、截图)和2个动态的WebMCP元工具(发现与调用页面内嵌的智能工具)封装成了AI可以理解和调用的标准化“工具”。无论你是开发者想要构建自动化工作流,还是普通用户想提升信息处理效率,这个项目都提供了一个极具潜力的起点。它解决了AI在桌面环境中缺乏直接、可控的Web交互能力的痛点,将浏览器的强大功能变成了AI可编程的接口。
2. 核心架构与设计思路解析
要理解mcp-webmcp的价值,我们需要拆解其架构设计。它并非简单地包装了Playwright API,而是在MCP协议框架下,构建了一个分层清晰、职责分明的代理系统。
2.1 协议层:MCP的核心作用
Model Context Protocol(MCP)是由Anthropic提出的一种开放协议,旨在为AI应用(客户端)和各种数据源、工具(服务器)之间建立标准化的通信方式。你可以把它想象成AI世界的“USB协议”或“插件标准”。一个MCP服务器负责声明它能提供哪些“工具”(Tools)和“资源”(Resources),而像Cursor、Claude Desktop这样的MCP客户端则负责发现这些能力并调用它们。
mcp-webmcp严格遵循这一协议。它作为服务器启动后,会向连接的客户端宣告:“我这里有browser_click、browser_navigate、webmcp_list_tools等28个工具可用。” 客户端接收到这个列表后,就能在对话中智能地建议或直接使用这些工具。这种设计带来了巨大的灵活性:服务器只需专注于实现工具逻辑,而客户端负责复杂的对话管理、上下文理解和工具调用决策,实现了关注点分离。
2.2 连接层:双模式适应不同场景
项目提供了两种核心的连接/传输模式,以适应不同的使用环境和需求,这是其设计上的一大亮点。
stdio(标准输入输出)模式:这是最常用、最集成化的方式。当你在mcp.json配置文件中使用npx或node命令时,MCP客户端(如Cursor)会作为一个父进程,直接启动mcp-webmcp子进程。两者通过进程间的标准输入(stdin)和标准输出(stdout)管道进行JSON-RPC消息通信。这种模式的优势是零网络配置、启动快速,并且生命周期由客户端管理(关闭客户端时,服务器进程通常也会终止)。它非常适合个人本地开发环境。
HTTP模式:通过运行mcp-webmcp start命令,服务器会启动一个HTTP服务(默认端口3100),并在/mcp端点提供SSE(Server-Sent Events)流式通信。任何兼容MCP协议的客户端都可以通过HTTP连接到这个地址。这种模式的优势在于:
- 跨机器访问:你可以在一台性能更强的机器上运行服务器,让本地的客户端连接过去。
- 独立进程:服务器进程独立于客户端运行,更加稳定。
- 调试与监控:你可以直接使用
curl或Postman等工具观察/mcp端点的通信流量,便于调试。 - 服务化部署:为团队提供共享的浏览器自动化服务成为可能。
选择哪种模式取决于你的使用场景。对于绝大多数个人用户与Cursor/Claude Desktop的集成,stdio模式是首选,简单直接。而HTTP模式则为高级用法和共享服务打开了大门。
2.3 浏览器管理层:启动策略的智慧
如何管理浏览器实例是另一个关键设计点。mcp-webmcp提供了两种策略,体现了对资源消耗和响应速度的权衡。
--launch模式(启动即用):在服务器启动时,立即通过Playwright的chromium.launch()方法启动一个Chrome/Edge浏览器实例。这种方式确保了所有工具在AI第一次调用时就立即可用,延迟最低。但它也意味着只要MCP服务器在运行,就会有一个浏览器进程常驻内存,消耗资源。这适合那些需要频繁、快速进行浏览器交互的场景,或者你不介意这点资源开销。
工具触发模式(按需启动):这是默认模式。服务器启动时,并不立即打开浏览器。它只是注册了所有工具。当AI客户端首次需要操作浏览器时(例如,它决定要导航到一个网页),它会先调用browser_launch工具。此时,服务器才会执行启动浏览器的操作。这种方式将控制权完全交给了AI代理,更加节能。只有当真正需要时才会消耗资源,适合间歇性使用的场景。这种“惰性初始化”策略在云服务或资源受限的环境中尤为重要。
实操心得:启动模式的选择我个人在实际使用中,如果是在个人开发机上长期开着Cursor,我会选择
--launch模式,因为即开即用的体验更好,省去了AI每次都要先“启动浏览器”这个思考步骤。但如果是在一台内存紧张的笔记本上,或者我只是偶尔需要AI帮忙处理网页,那么默认的按需启动模式更友好。你可以根据mcp.json中args数组是否包含"--launch"来轻松切换。
3. 环境准备与详细配置指南
在体验AI驱动浏览器之前,扎实的环境准备是成功的第一步。这里不仅列出步骤,更解释每个环节的必要性。
3.1 硬性前提:Node.js与特定版本Chrome
Node.js v18+:这是运行JavaScript服务器的基础。v18是一个重要的分水岭,它包含了更新的V8引擎、稳定的Fetch API等现代特性,mcp-webmcp依赖的这些特性在更早版本中可能不稳定或不存在。使用node -v检查版本,如果版本过低,建议通过 nvm (Mac/Linux)或 nvm-windows 进行版本管理,这是管理多个Node版本的最佳实践。
Chrome/Edge 146+(必须Beta或Canary):这是整个项目最核心、也最容易出错的依赖。为什么必须是146+且是Beta/Canary?因为WebMCP这个关键特性目前还是一个实验性功能,尚未进入Chrome稳定版。Chrome 146是第一个在Beta频道中默认启用该实验性标志的版本之一。
- 版本检查:务必执行项目提供的命令来确认。在Mac上,如果你只安装了稳定版Chrome,那么
--version命令输出的版本号很可能在120-130之间,这绝对无法工作。你需要专门安装 Chrome Beta 或 Chrome Canary 。 - 路径问题:Playwright在启动浏览器时会尝试查找系统默认路径。
mcp-webmcp通过--channel参数(如chrome-beta)来指定使用哪个渠道的浏览器。确保你安装的Beta/Canary浏览器位于操作系统的标准应用程序目录(如/Applications或C:\Program Files\),否则可能需要额外配置Playwright的浏览器路径,这会更复杂。
3.2 客户端配置详解:以Cursor为例
配置MCP客户端是连接的关键。我们以功能强大的Cursor IDE为例,展示最详细的配置过程。
定位配置文件:Cursor的MCP配置文件通常位于~/.cursor/mcp.json(Mac/Linux)或C:\Users\<你的用户名>\.cursor\mcp.json(Windows)。如果文件不存在,直接创建它即可。
配置文件结构剖析:下面是一个功能完整的配置示例,我们逐行解析:
{ "mcpServers": { "mcp-webmcp": { "command": "npx", "args": [ "-y", "@tech-sumit/mcp-webmcp", "--launch", "--channel", "chrome-canary", "--headless" ], "env": { "DEBUG": "playwright:*" } } } }mcpServers:这是一个对象,键值对定义了多个MCP服务器。键名(如"mcp-webmcp")是自定义的,会显示在客户端的工具列表中。command:"npx"。这告诉Cursor去调用npx命令。npx是Node.js自带的工具,能自动下载并运行npm包,无需全局安装@tech-sumit/mcp-webmcp,非常方便。args: 传递给npx和后续包的参数数组。"-y": 告诉npx在需要下载包时自动回答“yes”,避免交互式提问导致进程挂起。"@tech-sumit/mcp-webmcp": 要运行的npm包名。"--launch": 采用启动即用模式。"--channel","chrome-canary": 指定使用Chrome Canary渠道。如果你安装了Beta,就改为"chrome-beta"。"--headless": 在无头模式下运行浏览器。这意味着浏览器会在后台运行,没有图形用户界面。这能极大节省系统资源,特别适合执行自动化任务、截图或数据抓取。如果你需要观察AI的操作过程进行调试,则不要加这个参数。
env(可选): 设置环境变量。这里设置DEBUG: "playwright:*"会让Playwright输出非常详细的调试日志,对于排查浏览器启动、页面加载、元素查找失败等问题至关重要。在一切正常后,可以移除它以保持日志清洁。
保存与生效:保存mcp.json后,你需要重启Cursor。重启后,Cursor会读取新的配置并尝试启动MCP服务器。你可以在Cursor的聊天界面中,通过输入/并查看工具列表,或者查看Cursor底部的状态栏/日志,来确认mcp-webmcp服务器是否成功连接。
注意事项:配置的常见陷阱
- 路径错误:如果你全局安装了
mcp-webmcp,也可以将command设为"mcp-webmcp",args设为["--launch"]。但使用npx是更推荐的方式,它能保证总是使用最新版本。- 参数格式:
args是一个数组,每个参数都是独立的字符串。错误的格式如args: ["-y @tech-sumit/mcp-webmcp --launch"]会导致启动失败。- 端口冲突:如果你之前手动启动过Chrome并指定了
--remote-debugging-port=9222,或者同时运行了多个mcp-webmcp实例,可能会遇到端口冲突。确保关闭多余的进程。
3.3 Claude Desktop及其他客户端的配置
对于Claude Desktop,原理完全相同,只是配置文件路径不同:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
配置内容与Cursor完全一致。同样,修改配置后需要重启Claude Desktop应用。
项目还提供了快速配置命令mcp-webmcp config cursor和mcp-webmcp config claude。这些命令会尝试自动检测并写入上述配置文件。但在使用前,最好手动备份原有配置,并理解它写入的内容。
4. 工具集深度解析与实战应用
成功连接后,AI助手就获得了28件“武器”。理解每类工具的用途、参数和最佳实践,是高效利用它们的关键。
4.1 浏览器自动化工具:模拟真实用户操作
这24个工具覆盖了用户在浏览器中可能进行的大部分操作,它们基于Playwright,稳定且强大。
导航与状态获取:
browser_navigate: 核心工具。除了简单的URL跳转,在实践中,处理页面加载状态是关键。Playwright默认会等待到load事件,但对于单页应用(SPA),可能需要等待特定元素出现。这时可以结合browser_wait工具。browser_snapshot: 这是最重要的工具之一。它返回页面的可访问性树(Accessibility Tree),并给每个可交互元素附加了一个唯一的[ref=N]引用。AI代理通过这个快照来“看到”页面结构,并决定操作哪个元素。快照比纯HTML更简洁,包含了角色(role)、名称(name)等语义化信息。browser_screenshot: 获取视觉快照。对于需要验证页面样式、识别验证码(结合OCR)或存档的场景非常有用。注意,它返回的是PNG格式的base64字符串。
元素交互:
browser_click: 通过ref点击元素。其内部实现非常健壮:它会先尝试将元素滚动到视图中,然后检查是否可点击。如果因为元素被遮挡(如模态框)而导致常规点击失败,工具会自动尝试使用force: true参数,直接在该元素的坐标上触发点击事件。这在处理一些前端框架生成的复杂UI时很有效。browser_type与browser_fill: 两者都用于输入文本,但有重要区别。browser_type模拟真实的键盘输入,逐个字符触发keydown,keypress,keyup事件,这对于那些依赖键盘事件监听器的输入框(例如某些富文本编辑器或自定义输入组件)是必须的。而browser_fill则是直接设置输入框的value属性,速度更快,但可能不会触发某些JavaScript事件。经验法则:对于普通输入框,用fill;对于需要触发复杂交互的输入框,用type。browser_select_option: 用于下拉选择框。参数需要提供value或label。对于现代前端框架生成的非原生<select>元素(如自定义下拉框),这个工具可能失效,此时可能需要结合browser_click来模拟展开和选择操作。
标签页与JavaScript:
browser_tab_*系列:管理多标签页。AI可以打开新标签页抓取对比信息,或关闭不再需要的页面以释放资源。browser_evaluate: 在页面上下文中执行任意JavaScript代码,并返回结果。这是实现复杂操作的“逃生舱”。例如,可以直接用JS获取页面上的所有链接、操作复杂的数据对象、调用页面内定义的函数等。使用时需注意,代码是在浏览器环境中执行,无法直接使用Node.js模块。
4.2 WebMCP元工具:与智能网页直接对话
这是mcp-webmcp区别于普通浏览器自动化工具的核心价值所在。WebMCP是一个正在发展的浏览器API提案,它允许网页主动向AI助手声明自己提供哪些工具。
工作原理:
- 一个支持WebMCP的网站(例如一个演示用的餐厅预订页面)会在其JavaScript中调用
navigator.modelContextTesting.registerTool(...)(目前是实验性API)来注册工具,例如book_table。 - 该工具会定义其输入参数(如姓名、时间、人数)和输出格式。
- 当AI助手通过
mcp-webmcp导航到这个页面时,它可以调用webmcp_list_tools来获取当前页面注册的所有工具列表及其完整的JSON Schema描述。 - 然后,AI助手可以根据Schema,构造正确的参数,调用
webmcp_call_tool来直接执行页面提供的功能。
动态性与上下文:WebMCP工具是页面级的,这意味着当你导航到另一个页面时,可用的工具列表会改变。因此,最佳实践是:在需要与页面进行智能交互前,先调用一次webmcp_list_tools来发现当前可用的功能。
实战意义:这代表了未来人机交互的一种范式。网站不再仅仅提供被动的内容和表单,而是可以主动提供结构化的、语义丰富的“服务接口”给AI。AI可以像调用本地API一样调用网页功能,实现更深度的、语义化的自动化,而无需依赖脆弱的DOM元素选择器。
4.3 元素定位策略:ref系统的奥秘
AI如何知道要点击页面上哪个按钮?答案就在browser_snapshot生成的[ref=N]系统中。
- 生成快照:当调用
browser_snapshot时,服务器会通过Playwright获取页面的可访问性树。这个树比DOM更精简,专注于可交互元素(按钮、链接、输入框等)。 - 分配引用:服务器遍历这个树,为每个具有可操作性的节点按顺序分配一个唯一的数字
ref,例如[ref=1],[ref=2]。 - AI决策:AI接收到这个带注释的快照。快照中会包含元素的角色(如
button)、名称(如Submit)、状态等信息。AI基于任务(如“点击提交按钮”)和这些语义信息,判断出ref=5对应的元素很可能是目标按钮。 - 解析与操作:AI调用
browser_click({ref: 5})。服务器内部维护着一个从ref到Playwright定位器(Locator)的映射。它使用类似page.getByRole('button').nth(index)的方法来精确地找到对应的元素并执行点击。
这种方式的优势在于稳定性。相比于依赖可能变化的CSS选择器或XPath,ref是基于当前页面状态的实时映射,只要页面结构在两次快照间没有剧烈变动(如完全重新渲染),ref就能稳定地指向同一个元素。它本质上是将元素定位的复杂性从AI的提示词中转移到了服务器的实时计算中。
5. 完整实战流程:从零开始让AI预订餐厅
让我们通过一个完整的、可复现的示例,将上述所有概念串联起来。假设我们要让AI助手通过一个支持WebMCP的演示页面来预订餐厅。
5.1 准备工作:启动演示服务器
首先,你需要一个支持WebMCP的网页来测试。项目作者通常提供一个演示页面。你可以寻找相关的示例代码库,或者自己创建一个简单的HTML文件,其中包含注册了WebMCP工具的JavaScript。为了模拟,假设我们有一个本地运行在http://localhost:5173的演示应用,它提供了一个book_table工具。
确保你的mcp.json配置正确,并且已经重启了Cursor。在Cursor的聊天框中,你应该能感觉到AI助手“知道”了新的工具(有时需要手动触发工具列表刷新)。
5.2 交互对话与工具调用链
现在,你可以像与一个懂技术的助手对话一样,开始你的任务。以下是一个模拟的对话和AI背后可能执行的工具调用序列:
你(用户):“嘿,帮我用浏览器打开本地餐厅演示页面,并查看它能做什么。”
AI助手(思考后):
- 它发现当前没有浏览器实例,于是首先调用
browser_launch工具,参数为{“channel”: “chrome-beta”}。服务器启动Chrome Beta。 - 接着,它调用
browser_navigate,参数为{“url”: “http://localhost:5173”}。浏览器加载页面。 - 为了“查看能做什么”,它调用
webmcp_list_tools。服务器从页面获取到注册的工具列表,例如返回[{“name”: “book_table”, “description”: “Book a table at the restaurant”, “inputSchema”: {…}}]。AI将这个信息解读并回复给你:“这个页面提供了一个‘book_table’工具,可以用来预订餐厅位子,需要提供姓名、时间、人数等信息。”
你:“太好了,那就用我的名字‘Alex’,预订今晚7点,2个人的位子,备注要安静点的座位。”
AI助手(思考后):
- 它已经知道有
book_table工具,并且从之前的schema中知道了所需的参数结构。 - 它构造一个符合schema的JSON对象,例如:
(注意:AI需要根据当前日期推断出“今晚”的具体日期,这体现了其上下文理解能力。){ “name”: “Alex”, “date”: “2023-10-27”, “time”: “19:00”, “guests”: 2, “specialRequest”: “Quiet seat, please.” } - 它调用
webmcp_call_tool,参数为{“name”: “book_table”, “arguments”: {…上面那个JSON…}}。 - 服务器将调用转发给页面内的JavaScript函数。页面逻辑处理预订:可能会填充表单、提交、并返回一个确认消息,如
“Reservation confirmed for Alex at 2023-10-27 19:00 for 2 guests.”。 - AI将成功结果反馈给你:“已成功为Alex预订今晚7点2人位,备注了需要安静座位。”
你:“很好,截个图给我看看确认页面吧。”
AI助手:
- 它调用
browser_screenshot工具。 - 服务器返回一个PNG图片的base64编码数据。
- AI(或客户端)可能会将base64数据解码并显示为图片,或者直接告诉你截图已保存。
在整个过程中,你无需编写任何代码,也无需手动操作浏览器。你通过自然语言描述目标,AI负责规划步骤、选择合适的工具、处理参数并执行。mcp-webmcp在此充当了无缝的翻译官和执行者。
5.3 进阶:结合自动化工具与WebMCP工具
有时,页面可能只提供了部分功能的WebMCP工具。例如,一个电商页面可能提供了search_product工具,但结账流程还是传统的表单。这时,AI可以混合使用两类工具:
- 调用
webmcp_call_tool执行search_product(“wireless headphones”)。 - 使用
browser_snapshot查看搜索结果列表。 - 通过分析快照,识别出第一个产品的“加入购物车”按钮的
ref。 - 调用
browser_click点击该ref。 - 调用
browser_navigate进入购物车页面。 - 使用
browser_fill和browser_click来完成后续的表单填写和提交。
这种混合模式展现了最大的灵活性:WebMCP工具用于结构良好、语义清晰的交互;传统的浏览器自动化工具则用于处理尚未被WebMCP覆盖的、或需要更精细控制的交互环节。
6. 故障排查与性能优化实战记录
即使配置正确,在实际使用中也可能遇到各种问题。这里记录了一些常见问题的根因和解决方案,以及提升稳定性和效率的技巧。
6.1 连接与启动类问题
问题:启动时报错 “Chrome version X is not supported” 或 “WebMCP is NOT available”。
- 根因:这是最常见的问题,几乎总是因为浏览器版本不符合要求或实验性标志未开启。
- 排查步骤:
- 确认版本:在终端中运行
/Applications/Google\ Chrome\ Beta.app/Contents/MacOS/Google\ Chrome\ Beta --version(路径根据你的系统和安装渠道调整),确保输出版本 >= 146。 - 确认渠道:确保你安装的是Beta或Canary,而不是 Stable。
- 检查标志(仅限CDP模式):如果你不使用
--launch,而是手动启动Chrome并连接,必须确保启动命令包含--enable-features=WebMCPTesting。--launch模式会自动添加此标志。 - 关闭所有Chrome实例:有时旧的稳定版Chrome进程会干扰。彻底关闭所有Chrome窗口,再重试。
- 确认版本:在终端中运行
问题:错误信息 “No browser contexts found” 或 “无法连接到浏览器”。
- 根因:服务器试图通过Chrome DevTools Protocol (CDP) 连接到一个未启用远程调试的浏览器实例,或者连接地址/端口不对。
- 解决方案:
- 首选:在配置中启用
--launch模式,让服务器自己管理浏览器生命周期,一劳永逸。 - 手动连接:如果你想复用已有的浏览器窗口,需要手动启动Chrome并指定调试端口:
然后在配置中不要使用/Applications/Google\ Chrome\ Beta.app/Contents/MacOS/Google\ Chrome\ Beta --remote-debugging-port=9222 --enable-features=WebMCPTesting--launch标志。服务器会尝试连接到localhost:9222。
- 首选:在配置中启用
6.2 操作执行类问题
问题:browser_click或browser_type失败,提示元素未找到或不可交互。
- 根因:页面状态在AI决策和工具执行之间发生了变化(动态内容加载),或者元素被遮挡。
- 排查与解决:
- 引入等待:在关键操作(如点击、输入)前,让AI主动调用
browser_wait工具,等待某个特定CSS选择器出现或等待一段时间。例如,提交表单后等待“成功提示”元素出现。 - 重试机制:在复杂的AI工作流中,可以设计简单的重试逻辑。如果一次点击失败,可以重新获取快照 (
browser_snapshot),重新寻找元素并尝试。 - 利用
force参数:browser_click内部已包含对遮挡元素的force重试。如果常规操作频繁失败,可以检查页面是否有固定的页头、弹窗等,可能需要先关闭或滚动避开。 - 检查快照:让AI输出它看到的快照片段,确认它试图操作的元素
ref是否确实对应你期望的按钮或输入框。有时AI可能会误判。
- 引入等待:在关键操作(如点击、输入)前,让AI主动调用
问题:browser_screenshot超时。
- 根因:Playwright的截图默认会等待网络空闲和字体加载,如果页面有持续的网络活动(如WebSocket)或加载了大型网络字体,可能会超时。服务器设置了10秒超时。
- 解决方案:
- 对于已知的“慢”页面,可以考虑在截图前先等待一个代表页面已完全加载的特定元素 (
browser_wait)。 - 如果不需要完美截图(不关心字体),可以尝试让AI先执行
browser_evaluate注入一段JavaScript来停止动画或异步加载,然后再截图。但这属于高级技巧。
- 对于已知的“慢”页面,可以考虑在截图前先等待一个代表页面已完全加载的特定元素 (
6.3 性能与稳定性优化技巧
- 善用无头模式 (
--headless):对于后台自动化任务(数据抓取、定时检查等),务必启用无头模式。这将节省大量系统资源(GPU内存、CPU),并且运行速度更快。 - 按需启动浏览器:如果不是持续需要浏览器交互,使用默认的“工具触发启动”模式。让AI在需要时才调用
browser_launch,用完后可以(通过脚本或指示AI)导航到一个空白页或直接不操作,但浏览器进程仍会运行。目前没有直接的browser_close工具,如果需要彻底释放资源,可能需要重启MCP服务器。 - 管理标签页:鼓励AI在完成任务后,使用
browser_tab_close关闭不再需要的标签页。浏览器标签页过多会消耗内存。 - 快照的粒度:
browser_snapshot返回整个页面的可访问性树,对于复杂页面可能很大。虽然AI能处理,但传输和解析需要时间。在设计自动化流程时,可以引导AI先导航到目标子页面再进行操作,而不是在一个庞大首页的快照中寻找元素。 - HTTP模式用于调试:当遇到难以复现的问题时,可以切换到HTTP模式 (
mcp-webmcp start),然后用一个简单的脚本或curl手动发送MCP请求,观察原始响应,这能帮你确定问题是出在服务器端、浏览器端还是AI客户端的理解上。
7. 开发与扩展:深入项目内部
如果你对mcp-webmcp的工作原理感兴趣,或者想为其添加新的浏览器工具,可以参与到项目的开发中。
7.1 项目结构与核心模块
克隆项目后,你会看到典型的TypeScript项目结构。核心逻辑主要集中在src/目录下:
server.ts: MCP服务器的入口,负责初始化MCP协议服务器,注册工具。tools/: 这个目录很可能包含了所有工具的实现。每个工具都是一个独立的模块,导出其名称、描述、输入Schema和实现函数。browser/: 浏览器自动化工具的实现,它们会调用一个共享的PlaywrightBrowserSource类来执行实际操作。webmcp/: WebMCP元工具的实现。
browser-source.ts: 可能定义了PlaywrightBrowserSource类,它封装了与Playwright浏览器实例的连接、页面管理以及所有底层操作(点击、截图、执行JS等)。这是与Playwright API直接交互的地方。cli.ts: 命令行接口的定义,处理mcp-webmcp、mcp-webmcp start等命令。
理解数据流:AI客户端的请求 → MCP服务器 (server.ts) → 路由到对应的工具函数 (tools/) → 调用PlaywrightBrowserSource执行操作 → 将结果通过MCP协议返回给客户端。
7.2 如何添加一个新的浏览器工具
假设你想添加一个browser_get_text工具,用于获取某个元素的文本内容。
- 在
tools/browser/目录下创建新文件,例如get-text.ts。 - 定义工具Schema:使用
zod库(项目很可能用它进行输入验证)定义输入参数,例如需要一个ref数字。import { z } from “zod”; const InputSchema = z.object({ ref: z.number().describe(“The ref of the element to get text from”), }); - 实现工具函数:函数接收验证后的输入和上下文(包含浏览器源实例)。
export async function handleBrowserGetText( input: z.infer<typeof InputSchema>, context: { browserSource: PlaywrightBrowserSource } ) { const { ref } = input; // 通过 browserSource 获取页面和元素定位器 const page = await context.browserSource.getPage(); const locator = context.browserSource.getLocatorByRef(ref); // 使用 Playwright 获取文本 const text = await locator.textContent(); return { content: [{ type: “text”, text: text || “” }], }; } - 导出工具描述:导出一个符合MCP工具格式的对象。
export const browserGetTextTool = { name: “browser_get_text”, description: “Gets the text content of an element identified by ref.”, inputSchema: InputSchema, handler: handleBrowserGetText, }; - 注册工具:在
tools/browser/index.ts或类似的聚合文件中,导入并导出你的新工具。 - 重建与测试:运行
pnpm build重新编译,然后使用本地开发配置在Cursor中测试你的新工具。
7.3 调试与贡献
- 使用DEBUG环境变量:在运行服务器时设置
DEBUG=playwright:*可以打印Playwright的详细日志,对于理解浏览器交互过程非常有帮助。 - 查看MCP通信:在HTTP模式下,你可以直接观察
/mcp端点的SSE流,看到原始的JSON-RPC请求和响应。 - 编写测试:项目使用Vitest。为新工具添加单元测试和集成测试是保证代码质量的最佳方式。
- 遵循代码风格:提交代码前,运行
pnpm lint和pnpm format来确保代码风格一致。
mcp-webmcp项目打开了一扇门,让AI助手能够安全、可控地与真实的Web世界交互。从基础的浏览器自动化到超前的WebMCP页面工具调用,它提供了一个不断演进的基础设施。无论是用于个人效率提升,还是作为构建更复杂AI智能体(Agent)的底层能力,它都值得你深入探索和实践。记住,从满足版本要求的Chrome Beta/Canary开始,仔细配置你的客户端,然后从一个简单的导航和截图任务入手,逐步尝试更复杂的交互流程,你很快就会掌握让AI成为你得力网页助手的技巧。