Skip to content

Repository files navigation

Link2Chrome Logo

Link2Chrome

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_checknetwork_check 工具,支持捕获、查询、重放。

工具列表(29 个)

类别 工具
导航 & 标签 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.10python3.11python3.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

加载 Chrome 扩展

先安装开发者模式 Native Host bootstrap:

node scripts/dev-extension/install.mjs

脚本会基于 extension/manifest.json 中的固定 key 推导扩展 ID,并写入 Chrome Native Messaging Host manifest。然后:

  1. 打开 chrome://extensions/
  2. 开启「开发者模式」
  3. 如果之前加载过同一个 extension/ 但扩展 ID 不是 gfmbcnhkhgdlpcdhmolaefigfapbamcg,先移除旧项
  4. 点击「加载已解压的扩展程序」
  5. 选择本项目的 extension/ 目录
  6. 打开扩展 popup,确认显示 Native Host + :8765 或已连接状态

配置 Claude Code

claude_config_snippet.json 中的配置合并到 Claude Code 的配置文件中。示例中的 commandargscwd 均为相对路径,以项目根目录为基准(Claude Code 在项目根启动时可直接使用);若工作目录不同,请调整这三项指向项目根。

Codex Plugin

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.mjs

If 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.

browser_code_run 示例

对于需要 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:locatorgetByTextgetByRolegetByLabelgetByPlaceholderwaitForLoadStatewaitForTimeoutevaluatedomSnapshotscreenshot

Session 机制

每个任务可以绑定一个命名 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 权限,请只在可信环境中加载和运行。

License

MIT License. See LICENSE for details.

About

通过浏览器插件和 MCP,提供给 Agent 最好的 Chrome 操控体验

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages