PhantomHand
PhantomHand is a browser control engine for AI agents that uses the Chrome DevTools Protocol and Model Context Protocol (MCP) to give LLMs visual perception and human-like control of a real Chrome browser. Key capabilities include:
Navigation & Tab Management: Navigate to URLs, go back/forward, reload, open/close/switch/list tabs, get page title/URL.
Visual Perception: Scan the viewport for interactable elements (with coordinates), take screenshots, capture full-page PDFs.
Mouse Interaction: Single, double, triple, and right-click; hover, drag (Bezier trajectories), and scroll by delta or to a specific element.
Keyboard & Clipboard: Type text with humanized rhythm, press special keys, send keyboard shortcuts, select all, read/write clipboard.
Form Handling: Set/clear input values, select dropdown options, check/uncheck checkboxes and radio buttons, focus elements, upload files.
DOM & JavaScript: Evaluate arbitrary JS, get HTML content, extract text, get element attributes, extract structured data (JSON).
Network & Observability: Monitor network requests, mock requests, make API calls from the page context, list console messages, run performance traces, manage web storage.
Session Management: Export/import cookies for session persistence.
Timing & Control: Wait for a duration, fast-forward virtual time (skip animations/countdowns), wait for downloads, auto-wait on navigation and interactions.
Anti-Detection & Humanization: Automatically patches browser fingerprints (
navigator.webdriver,window.chrome.runtime, etc.) and simulates human mouse movements and typing patterns.Setup: Retrieve the extension path for initial Chrome setup via
get_extension_info.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@PhantomHand 帮我打开百度网页并搜索今天的天气"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
PhantomHand
PhantomHand 是一个面向 AI 智能体的浏览器控制引擎。它通过 Chrome DevTools Protocol 以 Model Context Protocol (MCP) 标准把浏览器的感知与操控能力暴露给大语言模型,让智能体能像人一样视觉理解网页,并真实地点击、输入、采集信息。
所有命令默认作用于浏览器的当前激活标签页,也可通过显式
tabId参数指定任意标签页。
核心特性
复用已登录的真实浏览器:直接在你的日常 Chrome 上操作,保留登录态、插件、书签——无需另开隔离 profile。
真视觉感知:Set-of-Mark 标注截图,能识别 canvas、视频、复杂 CSS 渲染的内容(纯无障碍树看不到的)。
稳定 ref 引用:每个可交互元素分配稳定的
ref,操控时解析其当前坐标,页面轻微重排也不会失效。拟人与反检测:贝塞尔鼠标轨迹、人类化打字节奏、点击前瞄准停顿;基于
chrome.debugger而非 WebDriver,并自动在页面主世界抹除自动化指纹。信息密度优先:文本快照、批量结构化提取、页面智能摘要、页面身份 API 请求;大体积产物默认存盘或摘要,不回流上下文。
可观测性:console、网络请求、性能指标、Web Storage 全量回流。
Related MCP server: Weavetab MCP
快速使用
在你的 AI Agent(Claude Desktop、Cursor、Windsurf、Antigravity 等)的 MCP 配置中注册 phantom-hand。两种部署方式任选其一。
A. 从 npm 安装(已发布)
{
"mcpServers": {
"phantom-hand": {
"command": "npx",
"args": ["-y", "phantom-hand-mcp"]
}
}
}B. 从本地源码运行(开发 / 未发布)
克隆仓库后先构建,再用产物的绝对路径注册:
npm install && npm run build{
"mcpServers": {
"phantom-hand": {
"command": "node",
"args": ["<项目根目录的绝对路径>/dist/index.cjs"]
}
}
}各 Agent 的配置文件位置
Agent | 配置文件 |
Claude Desktop(Windows) |
|
Claude Desktop(macOS) |
|
Cursor | 工作区 |
Windsurf |
|
Antigravity |
|
保存并重启 Agent,服务会在后台启动并监听 ws://localhost:37210。
安装浏览器扩展(必需)
PhantomHand 通过一个浏览器扩展与 Chrome 通信,需手动加载一次:
让你的 AI 助手调用
get_extension_info工具,获取本机扩展目录的绝对路径(位于~/.npm/_npx/.../extension)。打开
chrome://extensions/,开启右上角「开发者模式」,点击「加载已解压的扩展程序」,选中上一步的目录。点击浏览器工具栏的 PhantomHand 图标,URL 保持默认
ws://localhost:37210,点击「Connect to Agent Server」,指示灯变绿即连接成功。
工具清单
分类 | 工具 |
元信息 |
|
感知 |
|
鼠标 |
|
键盘 / 剪贴板 |
|
滚动 |
|
DOM / JS |
|
表单 |
|
标签页 / 导航 |
|
可观测性 · debug |
|
可观测性 · network |
|
可观测性 · performance |
|
存储 |
|
捕获 / 模拟 |
|
会话 |
|
时序 |
|
核心范式
ref 引用(推荐的元素操控方式)
browser_scan / browser_snapshot 为每个可交互元素分配稳定 ref(如 [ref: 3])。优先用 browser_click_ref / browser_type_ref 按 ref 操控——它会解析元素当前的坐标,即使页面发生轻微重排也能正确命中。若已知目标的选择器,可直接用 browser_query_ref 获取 ref,跳过全页扫描。
穿透同源 iframe
感知会递归进入 shadow DOM 与同源 iframe:iframe 内的元素同样分配 ref,坐标已折算到主页面视口,可直接用 ref 操控,无需关心 iframe 边界与坐标偏移。跨域 iframe(如第三方验证码)的 DOM 不可访问,不会出现在感知结果中。
信息密度
为避免上下文膨胀,大体积产物默认存盘或摘要:
browser_print_to_pdf把 PDF 写入下载目录,仅返回路径;browser_storage_get不传 key 时只返回键名列表;browser_screencast_start/browser_screencast_stop只统计帧数,不回传画面;browser_scan在长页面上提示「视口内 X / 共 Y 个元素」,告知还有多少未展示。
需要采集成片内容时,优先用高密度工具:browser_extract_structured(批量结构化)、browser_read_page(页面摘要)、browser_fetch(直连站点 API)。
自动等待
导航与点击/输入默认启用 auto-wait:导航等待页面 complete,交互等待网络空闲(networkIdle)。对 SPA 中延迟渲染的元素,用 browser_wait_for_element 精确等待其出现、附着或消失。
反检测
PhantomHand 基于 chrome.debugger(CDP)操控浏览器,不携带 WebDriver 指纹。每次连接一个标签页后,会自动向页面的主世界注入轻量补丁(经 Page.addScriptToEvaluateOnNewDocument,在任何站点脚本之前生效),抹除剩余自动化痕迹:
navigator.webdriver→undefined补全
window.chrome.runtime规整
navigator.languages/navigator.plugins修正
permissions.query对notifications的泄漏
注入逐标签页幂等,标签页关闭时自动清理,默认开启、无需配置。鼠标移动采用贝塞尔曲线加随机抖动,打字按字符类型差异化停顿(句末标点长停顿、逗号中停顿),点击前有短暂瞄准停顿。
配置
所有配置通过环境变量驱动(详见 .env.example):
变量 | 默认 | 说明 |
|
| WebSocket 端口 |
| (空) | WebSocket 鉴权 token |
|
| 截图重编码格式( |
|
| 截图质量 1-100 |
|
| 截图最大尺寸,超出则等比缩小 |
|
| auto-wait 等待上限(ms), |
| (空) | 域名白名单(逗号分隔),设置后仅允许这些域名 |
| (空) | 域名黑名单(逗号分隔) |
|
| 设为 |
截图压缩(可选):默认极轻量。安装 npm i sharp 后,截图会按上述参数重编码(webp/jpeg 显著小于 png),降低上下文占用;未安装时返回原图,功能不受影响。
安全
服务默认监听
ws://localhost,仅本机可连。不要将服务暴露到公网或不受信任的远程地址——browser_eval_js等工具等同于本机浏览器的远程代码执行权限。启用鉴权:设置
PHANTOM_HAND_TOKEN=<密钥>,并在扩展弹窗 URL 中追加?token=<密钥>。服务会拒绝未携带正确 token 的连接。除非完全控制远端主机,否则不要在扩展弹窗填写
wss://远程地址。
多 Agent 并发(Proxy Broker)
多个宿主 Agent(如同时运行 Cursor 与 Claude Desktop,各自启动 phantom-hand)可共享同一个浏览器扩展:
第一个进程占用
37210端口,成为 Master,承载 WebSocket 服务并与扩展通信。后续进程发现端口被占用,自动作为 Proxy 连接到 Master,转发命令。
每条请求/响应通过唯一 requestId 路由,并发调用互不串扰。若希望多个 Agent 各自控制独立标签页,可在工具调用中传入显式 tabId(通过 browser_tab_list 获取)。
开发
npm install # 安装依赖
npm run build # esbuild 打包到 dist/index.cjs
npm run dev # 以 tsx 直接运行 src/index.ts
npm start # 运行编译产物
npm test # 单元测试
npm run lint # tsc --noEmit 类型检查端到端功能验证见 test/smoke-test.md。
常见问题
发送指令后浏览器无反应? Chrome 禁止扩展在系统保护页(
chrome://newtab、chrome://settings、chrome://extensions、Web Store 等)执行调试 API。请确保当前聚焦一个常规网页。端口被占用? 若
37210被占用,服务不会结束占用进程,而是自动以 Proxy 模式继续工作(见上节)。如需换端口:设置PORT=xxxx,并在扩展弹窗填入对应端口。浏览器一直显示「正在调试此浏览器」黄条? 这是 CDP 调试的正常表现。扩展会在标签页关闭时自动 detach 调试器;如需立即清除,关闭对应标签页。
剪贴板读取偶尔失败? 现代浏览器要求剪贴板读取有用户手势。无手势上下文中
browser_clipboard_get可能失败——这是浏览器安全策略。按 ref 操作时报「ref not found」? ref 不跨扫描保活。重新
browser_scan/browser_snapshot/browser_query_ref获取新 ref 后再操作。
Available Tools
41 toolsbrowser_checkB
Check or uncheck a checkbox or radio button by CSS selector.
Inputs: checked (required), selector (required).
browser_clear_valueA
Clear the value of an input or textarea element by CSS selector and trigger change events.
Inputs: selector (required).
browser_clickA
Move the mouse to physical coordinates via Bezier curve and simulate a left-click.
Inputs: x (required), y (required).
browser_clipboard_getA
Read text from the system clipboard.
Inputs: no named parameters.
browser_clipboard_setC
Write text to the system clipboard.
Inputs: text (required).
browser_double_clickB
Double-click at physical coordinates. Useful for selecting a word in text.
Inputs: x (required), y (required).
browser_dragA
Drag from one coordinate to another with smooth intermediate steps. Useful for drag-and-drop, slider manipulation, or text selection by dragging.
Inputs: toX (required), toY (required), fromX (required), fromY (required), +1 more.
browser_eval_jsB
Evaluate arbitrary JavaScript in the context of the active page.
Inputs: code (required).
browser_extract_textB
Get the raw text content of the active page or a specific CSS selector.
Inputs: selector.
browser_fast_forwardA
Instantly fast-forward virtual time (e.g., to skip countdowns or animations) without real-world waiting.
Inputs: ms (required).
browser_focusC
Focus on an element identified by CSS selector.
Inputs: selector (required).
browser_get_attributesC
Get all attributes of an element by CSS selector.
Inputs: selector (required).
browser_get_htmlB
Get the HTML content of the active page or a specific CSS selector.
Inputs: selector.
browser_get_page_infoA
Get the current page URL and title.
Inputs: no named parameters.
browser_go_backA
Navigate back in the browser history.
Inputs: no named parameters.
browser_go_forwardA
Navigate forward in the browser history.
Inputs: no named parameters.
browser_hoverB
Hover the mouse over a specific physical coordinate.
Inputs: x (required), y (required).
browser_keyboard_shortcutB
Send a keyboard shortcut with modifier keys. Examples: Ctrl+C for copy, Ctrl+V for paste, Ctrl+A for select all, Ctrl+Z for undo, Ctrl+Shift+I for DevTools.
Inputs: key (required), alt, ctrl, meta, +1 more.
browser_press_keyB
Press a special key (e.g., Enter, Tab, Escape, Backspace).
Inputs: key (required).
browser_reloadA
Reload the current page.
Inputs: no named parameters.
browser_right_clickC
Right-click (context menu) at physical coordinates.
Inputs: x (required), y (required).
browser_scanA
Scan the current page viewport, returning a list of interactable elements and their physical coordinates.
Inputs: no named parameters.
browser_screenshotA
Take a screenshot of the current visible page and return it as an image.
Inputs: no named parameters.
browser_scrollC
Scroll the page using physical mouse wheel events.
Inputs: deltaY (required).
browser_scroll_to_elementB
Scroll the page so the specified element is centered in the viewport.
Inputs: selector (required).
browser_select_allA
Select all text/content in the currently focused element (Ctrl+A). Commonly used before typing to replace existing text in input fields.
Inputs: no named parameters.
browser_select_optionA
Select an option in a dropdown by value attribute or visible text.
Inputs: value (required), selector (required).
browser_session_exportA
Export cookies for the current domain to bypass logins later.
Inputs: no named parameters.
browser_session_importB
Import cookies into the current domain (JSON string).
Inputs: cookies (required).
browser_set_valueA
Directly set the value of an input or textarea element by CSS selector, bypassing the need to click and type. Triggers input and change events. Use this for fast, reliable form filling.
Inputs: value (required), selector (required).
browser_tab_closeA
Close the current active browser tab.
Inputs: no named parameters.
browser_tab_listA
List all open browser tabs with their IDs, titles, and URLs.
Inputs: no named parameters.
browser_tab_newA
Open a new browser tab, optionally navigating to a URL.
Inputs: url.
browser_tab_switchA
Switch to a specific browser tab by its tab ID (obtained from browser_tab_list).
Inputs: tabId (required).
browser_triple_clickA
Triple-click at physical coordinates to select all text in the target element (e.g., select entire text in an input field).
Inputs: x (required), y (required).
browser_typeC
Inject physical keystrokes into the active element (Requires clicking the element first).
Inputs: text (required).
browser_upload_fileC
Upload a local file to a file input element by CSS selector.
Inputs: filePath (required), selector (required).
browser_waitA
Wait/pause for a specified number of milliseconds before the next action. Useful for waiting for animations, AJAX requests, or page transitions. Default: 1000ms, Max: 30000ms.
Inputs: ms.
browser_wait_for_downloadA
Wait for a download to complete and get its path. Default timeout 30s.
Inputs: timeout.
get_extension_infoA
Get the absolute local path to the unpacked browser extension folder. Use this to help the user load the extension if it is not connected.
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 41 tools
Each browser automation tool has a clearly distinct purpose, with different click types, input methods, and navigation actions that are well-described and non-overlapping. Even similar actions like browser_type and browser_set_value are differentiated by how they interact with elements.
Almost all tools follow the consistent pattern of 'browser_' prefix with snake_case verb_noun names (e.g., browser_click, browser_navigate). The only exception is 'get_extension_info' which lacks the prefix, breaking the pattern slightly.
With 41 tools, the server covers a very broad scope of browser interactions. While each tool is justified, the count is on the high end and could potentially be reduced by combining some related actions into more parameterized tools.
The tool set covers nearly all common browser automation scenarios including navigation, clicking, typing, scrolling, tab management, clipboard, sessions, and file operations. A minor gap is the lack of a tool for extracting structured page data beyond raw text/HTML.
Maintenance
Related MCP Connectors
Web scraping, browser automation, screenshots and AI data extraction for AI agents via MCP.
Control a real browser from AI agents: navigate, click, type, screenshot, read the page.
Cloud browser, web extraction, screenshots, and remote CDP tools for AI agents.
Official Browserless MCP server: browser automation, scraping, screenshots and PDFs for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenancesingle-binary MCP server that gives AI agents a browser. 66 tools for navigation, form filling, data extraction, screenshots, and DOM diffing — built on pure Chrome DevTools Protocol.14MIT
- AlicenseNot gradedqualityBmaintenancethe open automation engine for AI agents. Control live browsers and desktop apps locally with instant execution777 npm3AGPL 3.0
- FlicenseBqualityCmaintenanceUltra-fast browser automation server over Chrome DevTools Protocol (CDP), exposed as MCP, enabling AI agents to control a real Chrome browser with low latency and minimal token usage.212-
- AlicenseNot gradedqualityBmaintenanceAn MCP server that lets LLM agents control all Chrome browser tabs via accessibility snapshots, element references, and a virtual cursor, supporting operations like click, type, navigate, screenshot, and video recording.MIT