Link2Chrome 是一个本地优先的浏览器自动化项目,通过 Chrome 扩展、WebSocket 和 MCP Server 将本地 Agent 与真实浏览器连接起来,让 Agent 可以导航页面、执行点击/输入/滚动、读取 DOM、截图、运行 Playwright 风格的自动化脚本,以及管理多任务 Session(标签组)。
- 本地 MCP Server:通过 stdio 向 Claude Code 暴露 26 个统一浏览器工具。
- Chrome 扩展:基于 Manifest V3,通过
chrome.debugger调用 Chrome DevTools Protocol,并用 alarms keepalive 强化连接稳定性。 - WebSocket 桥接:Server 与扩展之间通过本地 WebSocket 通信。
- 页面观察:URL、标题、截图、Markdown 格式 DOM 概览、DOM diff、正文提取、元素查询。
- 浏览器操作:导航、点击、双击、悬停、输入、滚动、拖拽、按键、对话框处理、文件上传。
- browser_code_run:以代码为动作——在长期运行的 Node.js 运行时里执行 JavaScript,控制真实 Chrome 浏览器完成长程、多步骤自动化任务。
- Session 机制:一个任务对应一个 Session,映射到 Chrome 标签组,支持跨标签的多任务并发。
- save_as_pdf:通过 CDP
Page.printToPDF将当前页面保存为 PDF 文件。 - 控制台 & 网络监控:统一的
console_check和network_check工具,支持捕获、查询、重放。
| 类别 | 工具 |
|---|---|
| 导航 & 标签 | browser_navigate, browser_tab, browser_tabs_list, browser_session |
| DOM 观察 | browser_dom_overview, browser_dom_query, browser_dom_search, browser_dom_get_text, browser_dom_wait_for |
| 等待 & 下载 | browser_wait, wait_for_download |
| 截图 & 内容 | browser_screenshot, browser_scrape_with_scroll |
| 动作 | action_click, action_double_click, action_hover, action_scroll, action_drag, action_fill, action_select_option, action_press_key |
| 文件 & 对话框 | upload_file, handle_dialog |
| 脚本 & 自动化 | browser_code_run, script_evaluate, save_as_pdf |
| 监控 & 诊断 | console_check, network_check, browser_diagnose |
.
├── extension/ # Chrome 扩展源码
├── server/ # Python MCP Server
│ ├── main.py # MCP 入口,call_tool 路由
│ ├── tool_descriptions.py # 29 个工具定义
│ ├── session_manager.py # Session → Chrome 标签组映射
│ ├── dom_compressor.py # DOM → Markdown 压缩
│ └── playwright_runtime.py # 旧 Extension 端运行时兼容代码
├── docs/ # 使用说明和设计文档
├── test/ # 测试脚本(含 test_tools.py)
├── claude_config_snippet.json # Claude Code MCP 配置示例
├── setup.sh # 本地安装脚本
└── server/requirements.txt # Python 依赖
- Python 3.10+
- Chrome / Chromium
- Claude Code
当前 MCP Python SDK 要求 Python 3.10 或更高版本。如果本机默认 Python 是 3.9,请先安装 python3.10、python3.11 或 python3.12,再由安装脚本创建隔离虚拟环境,避免污染系统环境。
./setup.sh安装脚本会创建 server/venv,安装服务端依赖,并在缺少 .env 时生成配置模板。
手动安装方式:
python3.10 -m venv server/venv
server/venv/bin/pip install -r server/requirements.txt然后在项目根目录创建 .env:
LOG_LEVEL=INFO
LINK2CHROME_BROWSER=chrome先安装开发者模式 Native Host bootstrap:
node scripts/dev-extension/install.mjs脚本会基于 extension/manifest.json 中的固定 key 推导扩展 ID,并写入 Chrome Native Messaging Host manifest。然后:
- 打开
chrome://extensions/ - 开启「开发者模式」
- 如果之前加载过同一个
extension/但扩展 ID 不是gfmbcnhkhgdlpcdhmolaefigfapbamcg,先移除旧项 - 点击「加载已解压的扩展程序」
- 选择本项目的
extension/目录 - 打开扩展 popup,确认显示
Native Host + :8765或已连接状态
将 claude_config_snippet.json 中的配置合并到 Claude Code 的配置文件中。示例中的 command、args、cwd 均为相对路径,以项目根目录为基准(Claude Code 在项目根启动时可直接使用);若工作目录不同,请调整这三项指向项目根。
This repository includes a local Codex plugin at plugins/chromex.
After restarting Codex, install ChromeX from the ChromeX Local Plugins marketplace. Then run:
codex plugin marketplace add .
codex plugin add chromex@chromex-local
node plugins/chromex/scripts/install.mjs
node plugins/chromex/scripts/diagnose.mjsIf your default Python is 3.9, the installer will look for python3.10, python3.11, or python3.12 and create server/venv with Python 3.10+ before installing dependencies.
对于需要 3 步以上、含条件逻辑、循环、显式等待或长程页面状态轮询的操作,推荐使用 browser_code_run 一次发送代码,而不是逐个调用 MCP 工具:
await browser.nameSession('登录表单');
const tabs = await browser.user.openTabs();
const existing = tabs.find(t => (t.raw?.url || '').includes('example.com/login'));
const tab = existing ? await browser.user.claimTab(existing) : await browser.tabs.new('https://example.com/login');
await tab.playwright.getByPlaceholder('Email').fill('user@example.com');
await tab.playwright.getByPlaceholder('Password').fill('secret');
await tab.playwright.getByRole('button', { name: 'Sign in' }).click();
await tab.playwright.waitForLoadState('networkidle', { timeout: 10000 });
return { title: await tab.title(), url: await tab.url() };// 数据提取示例
const rows = await tab.playwright.evaluate(() => {
return Array.from(document.querySelectorAll('table tr')).map(r => r.innerText);
});
return rows;tab.playwright 支持的常用 API:locator、getByText、getByRole、getByLabel、getByPlaceholder、waitForLoadState、waitForTimeout、evaluate、domSnapshot、screenshot。
每个任务可以绑定一个命名 Session,对应 Chrome 中的一个标签组。Session 同时也是浏览器控制权限边界;页面读取、点击、输入、截图、脚本执行、切换和关闭标签页都必须传同一个 session:
browser_session(
action="new_tab",
session="research",
group_title="调研",
url="https://example.com"
)
browser_dom_overview(session="research")
browser_screenshot(session="research")
browser_session(action="finalize", session="research", keep=[])
browser_session(action="list")
当任务已有明确 URL 时,new_tab 会直接用该 URL 创建首个分组标签页,不需要先创建空白 Session。搜索、筛选和详情查询应优先直接打开可验证的参数化结果 URL,例如 Google 的 ?q= 结果页;只有 URL 规则不确定时才回退到网站 UI。
如需接管用户已有标签页,先通过 runtime 的 browser.user.openTabs() 获取候选,再把返回对象原样传给 browser.user.claimTab(tab);不要猜测裸 tabId。
常见问题的完整处理步骤见 docs/TROUBLESHOOTING.md。
Session 注册表损坏(所有 Session 操作失败) 的快速恢复——无需重启 Claude Code / MCP server,只需重启 Browser Hub 进程,MCP server 会自动拉起新 hub:
pkill -f server.browser_hub然后运行 browser_diagnose 确认 Hub 已重连,browser_session(action="list") 应返回 sessions: [](历史 CLOSED 记录不影响使用)。若刚改过扩展代码,需在 chrome://extensions/ 点击「重新加载」;若仍未恢复,详见 docs/TROUBLESHOOTING.md。
# 运行所有工具定义验证(不需要浏览器连接)
server/venv/bin/python -m pytest test/test_tools.py -v
# 运行完整测试套件
server/venv/bin/python -m pytest test
node --test test/runtime-client.test.mjs- 不要提交
.env、日志、缓存、虚拟环境或运行输出。 - Chrome 扩展使用
debugger权限,请只在可信环境中加载和运行。
MIT License. See LICENSE for details.