agent-bridge
Agent Bridge is an MCP server that enables local agents like Codex and Claude Code to remotely control a logged-in ChatGPT Pro session in the browser, supporting automated discussions, reviews, and code implementation with secure pairing and multi-session coordination.
README
Agent Bridge
让本地 agent(Codex / Claude Code)通过 MCP 遥控浏览器里已登录的 ChatGPT Pro 会话。
浏览器插件只负责操作页面,输入什么、什么时候发、发完怎么验收,全部由 agent 决定。人不需要往插件里敲任何内容。
架构
Agent (Codex / Claude Code)
│ MCP tool call(stdio)
▼
mcp-server/ Node 进程:MCP server + WebSocket server
│ ws://127.0.0.1:8767
▼
扩展 background WebSocket 客户端,负责重连、保活、动作路由
│ chrome.tabs / content script
▼
ChatGPT 页面 复用你在 Chrome 里已经登录好的 Pro 会话
反过来(server 连插件)行不通:MV3 扩展没法监听端口,所以由扩展主动连 MCP server。
安装
1. 构建并加载扩展
cd <仓库路径>/extension
npm install
npm run build
打开 chrome://extensions → 右上角开启「开发者模式」→「加载已解压的扩展程序」→ 选 extension/dist/ 目录。
2. 启动 MCP server
cd mcp-server && npm install
server 不需要构建,Node 26 直接跑 TypeScript:
node mcp-server/src/index.ts # 或在根目录 npm run mcp
端口默认 8767,用环境变量 AGENT_BRIDGE_PORT 可改(插件那边要在 popup 里同步改)。
3. 注册给 agent
Claude Code:
claude mcp add agent-bridge -- node <仓库路径>/mcp-server/src/index.ts
Codex(~/.codex/config.toml):
[mcp_servers.agent-bridge]
command = "node"
args = ["<仓库路径>/mcp-server/src/index.ts"]
agent 会自己拉起 server 进程,不用另外开终端手动跑。
多会话并行
每个 Claude/Codex 会话会拉起自己的 MCP 进程,但浏览器扩展只有一个连接。agent-bridge 用选主机制解决:先启动的进程监听 8767 成为 hub,后启动的自动作为客户端经 hub 转发;hub 所在会话退出后,客户端会在几秒内自动接管,扩展重连回去。不需要守护进程,也不要去 kill 占用端口的进程——那通常是另一个会话正在用的 hub。
多 agent 共享同一个 ChatGPT 账号。任务的持久身份是会话 URL(/c/<id>):每个任务用 chatgpt_new_conversation 开新会话,首次发送后拿到会话 URL,后续调用用 conversation 参数携带——标签页被关了也会按 URL 自动重开。tabId 仍可用,但它只是会话当前的载体。
4. 配对(v0.3 起必须)
hub 不再接受匿名连接。首次启动 MCP server 时会自动生成配对码:
cat ~/.agent-bridge/pairing-secret # 0600 权限,等同于凭据,别外发
点扩展图标打开 popup → 状态显示「待配对」→ 粘贴配对码 → 配对。只需要做一次,存在扩展本地存储里。
5. 确认链路
popup 状态显示「已连接」即可。没连上就检查 server 是否在跑、地址是否一致、配对码是否正确。
一句话触发协作(内置协议)
不需要手动粘贴 prompt。协议正文内置在 MCP server 的 prompts/*.md 里,与工具同版本演进,通过两个通道暴露:
chatgpt_collab_guide工具:所有客户端都能调,skill 走这条路- MCP prompts(
chatgpt_discuss/chatgpt_review/chatgpt_implement):支持该能力的客户端会列成斜杠命令
配套 skill 在 skill/SKILL.md(已安装到 ~/.claude/skills/chatgpt-pro/)。装好后直接说人话:
和 ChatGPT Pro 探讨一下这个迁移方案
让 ChatGPT Pro review 一下导入模块
让 ChatGPT Pro 按这个计划把代码写了
agent 会自动:判定模式 → 取协议 → 备上下文 → 新会话 → 发送 → 分段等待 → 独立验收 → 按固定格式汇报(含会话链接、SHA 基线、测试结果)。
工具清单
| 工具 | 作用 |
|---|---|
chatgpt_collab_guide |
返回内置协作协议(discuss / review / implement),agent 一句话触发协作时先调它 |
chatgpt_status |
桥接状态、标签页列表、页面处于 idle/generating/login_required |
chatgpt_open |
打开或复用 ChatGPT 标签页,可跳到指定会话恢复上下文 |
chatgpt_new_conversation |
整页导航开新会话,确保无上下文残留 |
chatgpt_attach |
上传本地文件(传路径,server 侧读取),返回大小与 SHA-256 |
chatgpt_send |
写入并发送 prompt,支持超长文本 |
chatgpt_wait_reply |
轮询到本轮回复生成完毕,返回正文与代码块 |
chatgpt_last_reply |
不等待,直接读最后一条回复(含 complete 标志) |
chatgpt_link |
取当前会话 URL 和 id,用于写进交付报告 |
page_text / page_query / page_click |
通用页面操作;page_query 返回可直接回喂给 page_click 的稳定选择器 |
配合双代理协作 prompt
这套工具是按你那份「Codex 当总负责人、ChatGPT Pro 当外部工程师」的 prompt 设计的,几条硬性要求都有对应支撑:
| prompt 里的要求 | 对应能力 |
|---|---|
| 打包 ZIP,记录大小和 SHA-256 | chatgpt_attach 直接返回 bytes 与 sha256,不用另外算 |
| 多个独立任务各开一个对话,避免上下文污染 | chatgpt_new_conversation 走整页导航,草稿和附件都不会残留 |
| ChatGPT Pro 可能很久,不要催促、不要重复发送 | chatgpt_wait_reply 默认等 30 分钟且只读不发;超时只是停止等待,页面上的生成不受影响,再调一次即可续等 |
| 保存每个对话的链接,中断后自主恢复 | chatgpt_link 取链接,chatgpt_open 带 url 跳回去 |
| 登录失效 / 验证码 / 2FA 要暂停并通知人 | 页面一旦判定 login_required,工具直接返回错误并明确要求停下来找人,不会尝试绕过 |
| 交付后独立验收 | chatgpt_wait_reply 单独返回 codeBlocks,补丁可以直接取用,不必二次解析正文 |
典型调用顺序:
chatgpt_status → chatgpt_new_conversation → chatgpt_attach(源码.zip)
→ chatgpt_send(任务说明) → chatgpt_wait_reply → chatgpt_link
安全模型(v0.3)
这条通道能驱动一个已登录的浏览器,所以:
- 配对码鉴权:所有客户端(扩展、agent 进程)握手时必须携带
~/.agent-bridge/pairing-secret(自动生成,0600)。错误配对码、版本不匹配、角色不明都会被拒绝并断开。 - 角色锁定 + Origin 检查:扩展角色必须来自
chrome-extension://Origin(浏览器强制不可伪造,挡网页);网页 Origin 不能当 agent。 - 只绑 127.0.0.1:
AGENT_BRIDGE_HOST配非本机地址会直接拒绝启动。 - hello 5 秒超时:握手不完成的连接会被断开,防止沉默连接阻塞 shutdown。
信任边界声明:配对码文件只能防住"其他 OS 用户"和"无文件权限的进程"。与你同 UID 运行的本机进程(依赖、脚本、其他 agent)属于可信计算基——它们本来就能读你的文件。如果你的威胁模型包含同用户恶意进程,这套机制不够,需要 OS keychain 级别的隔离。
故障排查
| 现象 | 原因与处理 |
|---|---|
| popup 显示未连接 | MCP server 没跑,或端口和 popup 里填的不一致 |
NO_TAB |
还没打开 ChatGPT 页面,先调 chatgpt_open |
TAB_NOT_READY |
页面早于扩展安装就打开了,刷新一下 ChatGPT 标签页 |
LOGIN_REQUIRED |
登录态失效或撞到验证码,必须人工处理,agent 不应尝试绕过 |
ELEMENT_NOT_FOUND |
ChatGPT 改版了,更新 extension/src/content/selectors.ts 里的候选选择器 |
| 回复读到一半 | complete: false 表示还在流式输出,继续等或改用 chatgpt_wait_reply |
长任务建议让标签页保持前台(chatgpt_open 传 focus: true)—— 后台标签页会被 Chrome 节流,轮询会变慢。
开发
agent-bridge/
├── shared/protocol.ts 线协议唯一真值源,extension 与 mcp-server 共享
├── extension/ 浏览器插件(Vite + CRXJS + React,独立 package)
│ └── src/
│ ├── shared/protocol.ts 一行 re-export 到顶层 shared/,保持内部导入路径稳定
│ ├── background/ WebSocket 客户端、重连保活、动作路由
│ ├── content/
│ │ ├── selectors.ts ChatGPT 的 DOM 选择器,改版了只改这里
│ │ ├── chatgpt.ts 页面操作:写入、发送、上传、读状态
│ │ ├── state.ts 页面状态判定(idle/generating/login_required)
│ │ └── serialize.ts 把回复 DOM 还原成 Markdown
│ └── popup/ 连接状态、地址配置、运行日志(kiln 设计语言)
├── mcp-server/ MCP server + WebSocket hub(Node 26 直接跑 TS,无构建)
│ ├── prompts/ 协作协议唯一真值源(protocol + discuss/review/implement)
│ └── src/
│ ├── hub.ts 抢到端口的进程:持有扩展连接,转发 agent 客户端的调用
│ ├── link.ts 没抢到端口的进程:作为客户端接入 hub,hub 挂了触发接管
│ └── prompts.ts 协议装载,经 MCP prompts 和 guide 工具双通道暴露
└── skill/SKILL.md 自然语言触发器(同步到 ~/.claude/skills/chatgpt-pro/)
# 以下都在项目根目录执行
npm run build # 构建扩展到 extension/dist/
npm run typecheck # extension + mcp-server 双侧类型检查
npm run lint
npm test # 全部单测(serialize + state)+ MCP 冒烟(含多会话选主场景)
npm run check:live # 真实浏览器只读自检,需要 Chrome 和扩展在线
npm run preview:popup # 生成 extension/dist/preview.html 核对 popup 视觉
popup 用 kiln 设计语言:暖白衬底 + 无边框白卡片靠暖调阴影分离,陶土红只用于关键动作和状态,控件 36px / 圆角 4px,卡片圆角 6px,字号收在 11–15px。改完 UI 后这样核对三种状态:
npm run build && npm run preview:popup
python3 -m http.server 4173 -d extension/dist
# http://127.0.0.1:4173/preview.html?s=connected | disconnected | granted
字体是个有意的偏离:kiln 主字体为 Noto Sans SC webfont,但 MV3 的 CSP 不放行远程字体,自托管一套完整 CJK 字重要十几 MB,对一个弹窗不成比例,因此走 kiln 定义的系统回退栈(macOS 上解析为 PingFang SC)。
两处容易踩的实现细节,改代码前值得知道:
- 输入框不能直接赋值。 ChatGPT 用的是 ProseMirror,写
innerHTML只改渲染结果,它的内部文档还是空的,一发送就变成空消息。必须走document.execCommand('insertText')—— 那会产生浏览器原生的beforeinput/input事件,ProseMirror 才接得住。 - 长等待不做成单个 RPC。 MV3 的 service worker 空闲 30 秒就被回收,扛不住几十分钟的单次请求。所以所有动作都是瞬时的,「等回复」由 MCP server 轮询
chat.status编排,扩展侧再用 20 秒心跳续命。
判断「新回复出来了」也不只看消息条数:页面可能只渲染了用户那条,此时读到的最后一条仍是上一轮的旧回复。所以 chatgpt_send 会记下发送前的正文快照,chatgpt_wait_reply 拿它做对比,再要求内容连续两轮不变才收尾。
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.