1. 项目概述:为AI编程助手装上“暂停与询问”按钮

如果你和我一样,深度使用Cursor、Claude Code这类集成了AI编程助手的IDE,一定经历过这样的场景:你给AI下达一个复杂的重构指令,它开始噼里啪啦地生成代码,一口气改了十几个文件。你心里有点打鼓,想让它先停一下,看看它到底打算怎么改,但发现根本没有一个合适的“暂停”机制。你只能等它全部执行完,再花时间去Review那一大堆改动,一旦发现方向错了,又得花好几个回合去纠正,宝贵的AI请求配额就这么白白浪费了。

这正是Relay项目要解决的核心痛点。它不是一个独立的AI工具,而是一个**“人机协同检查点”**。简单来说,它给现有的AI编程助手(只要是支持MCP协议的)增加了一个强制性的“暂停并询问”环节。当AI助手准备执行一系列操作前,它会先调用Relay提供的工具,将它的计划( retell )展示给你,并等待你的确认、修改或补充。只有在你给出“Answer”后,它才会继续执行。整个过程在一个JSON-RPC调用内完成,数据完全在本地流转。

想象一下,这就像给你的AI助手配了一个副驾驶。以前是它自己闷头开,你只能事后看导航记录;现在它每到一个关键路口都会主动问你:“左转还是右转?” 你掌握了主动权,避免了它开进死胡同,也省下了掉头重来的油钱(也就是你的AI配额)。

2. 核心设计思路:为什么是MCP + 本地HTTP?

2.1 为什么选择MCP协议作为切入点?

MCP(Model Context Protocol)正在成为AI开发工具间通信的事实标准。Cursor、Claude Code、Windsurf等主流AI IDE都已原生支持。通过实现一个MCP Server,Relay可以无缝“插入”到这些IDE的生态中,成为AI助手可调用的一个“工具”。这种方式侵入性最小,无需修改IDE本身,也无需AI模型侧做任何适配,兼容性最好。

从技术实现角度看,MCP基于JSON-RPC over stdio(标准输入输出)。这意味着Relay的MCP服务端( relay mcp-cursor 等)启动后,会通过管道与IDE通信。当AI模型决定调用 relay_interactive_feedback 工具时,IDE会将这个调用通过管道发送给Relay的服务端。这种设计决定了Relay的核心通信模型是 同步阻塞 的:服务端必须给出响应,IDE和AI才会继续执行。这正好契合了“检查点”需要等待人工输入的特性。

2.2 本地HTTP层:GUI与MCP服务解耦的关键决策

如果仅仅实现MCP服务,那么每次调用工具时,都需要弹出一个新的用户界面(UI)来收集反馈。这会导致几个问题:窗口管理混乱、状态难以保持、资源消耗大。这也是早期类似项目(如 interactive-feedback-mcp )的体验痛点。

Relay的架构创新在于引入了 本地HTTP层 作为GUI与MCP服务之间的桥梁。它的工作流程是这样的:

  1. 独立GUI进程 :你首先运行 relay gui-cursor ,启动一个独立的、常驻的桌面应用窗口。这个窗口基于Tauri(Rust + Web前端)构建,启动后会随机绑定一个本地端口(如127.0.0.1:54321),并将端口号和认证令牌写入一个配置文件( gui_endpoint_cursor.json )。
  2. MCP服务发现GUI :当MCP服务端( relay mcp-cursor )收到工具调用时,它会去读取上述配置文件,获取HTTP服务的地址和令牌。
  3. HTTP API交互 :MCP服务端通过HTTP POST /v1/feedback 将AI的 retell 内容发送给GUI,GUI在对应标签页中展示。然后MCP服务端通过 GET /v1/feedback/wait/:id 长轮询这个请求, 阻塞 等待用户操作。
  4. 用户反馈与返回 :你在GUI中输入文本、粘贴图片或附加文件后点击提交,HTTP服务会将结果返回。MCP服务端收到结果后,再通过原先的stdio管道将结果返回给IDE,完成整个JSON-RPC调用。

这种设计的优势非常明显:

  • 单一窗口,多标签管理 :所有AI的暂停请求都在同一个应用的不同标签页中处理,界面整洁,会话( relay_mcp_session_id )可以跨多次调用保持连续性。
  • 资源高效 :只需启动一个GUI进程,无论AI调用多少次工具。
  • 稳定性高 :即使GUI崩溃重启,只要MCP服务端还在,它可以重新读取新的端点文件或自动重启GUI,恢复工作流程。
  • 扩展性强 :HTTP API可以很容易地与其他本地脚本或工具集成,比如实现自动化回复。

注意 :这里有一个关键细节,MCP服务端在找不到GUI端点文件时,会尝试自动启动GUI进程( relay gui-<ide> )。这个设计确保了即使用户忘记先打开GUI,整个流程也能自举成功,对新手非常友好。

3. 从零开始部署与配置Relay

3.1 安装与首次启动

Relay提供了预编译的二进制文件,支持macOS、Windows和Linux。对于大多数用户,直接从GitHub Releases页面下载对应系统的最新版本是最快的方式。

macOS用户的特别注意事项 : 由于项目没有购买苹果昂贵的开发者证书进行公证(Notarize),从浏览器下载的 .app 文件会被系统标记为“已隔离”(quarantined)。首次打开时,你会看到“无法打开,因为无法验证开发者”的警告。 不要慌张,这并不意味着软件有问题。 你有两个选择:

  1. 推荐方法 :在Finder中找到 Relay.app ,按住 Control 键点击(或右键点击),选择“打开”,然后在弹出的对话框中再次点击“打开”。这相当于你手动确认了一次信任,之后就可以正常双击打开了。
  2. 命令行方法 :如果你习惯命令行,可以将应用移到 应用程序 文件夹后,执行以下命令移除隔离属性:
    xattr -dr com.apple.quarantine "/Applications/Relay.app"
    

安装后,首次运行 Relay (或从命令行执行 relay 命令),你会看到一个IDE选择页面。这里有四个选项:Cursor、Claude Code、Windsurf和Other。 这个选择至关重要 ,因为它决定了后续的配置模板、规则提示词以及一些IDE特有的功能(如Cursor的用量监控)是否可用。

3.2 配置IDE以连接Relay MCP服务

选择对应的IDE模式(例如Cursor)并进入主界面后,最关键的一步是告诉你的IDE:“嘿,我这里有一个新的MCP服务器可以用”。

对于Cursor用户(最常用的场景)

  1. 在Relay的GUI中,点击左下角的设置图标(⚙️),进入“Environment & MCP”设置页。

  2. 这里Relay会尝试自动检测你的Cursor配置目录和PATH环境变量。最方便的功能是“ Inject into Cursor MCP config ”按钮。点击它,Relay会自动在你的用户级MCP配置文件( ~/.cursor/mcp.json )中添加 relay-mcp 服务器的配置。

  3. 配置内容大致如下,Relay会自动填充正确的二进制路径:

    {
      "mcpServers": {
        "relay-mcp": {
          "command": "/path/to/relay",
          "args": ["mcp-cursor"],
          "autoApprove": ["relay_interactive_feedback"]
        }
      }
    }
    
    • command :指向你Relay可执行文件的绝对路径。
    • args : ["mcp-cursor"] 表示运行Cursor模式的MCP服务器。
    • autoApprove : ["relay_interactive_feedback"] 这个设置非常建议保留。它让Cursor自动批准对此工具的调用,无需你每次在IDE里手动点击“允许”。如果没有这个,每次AI调用Relay时你都需要在Cursor里点一下确认,体验会大打折扣。
  4. 点击“Copy JSON”可以复制配置片段。如果你有项目特定的MCP配置(在项目根目录的 .cursor/mcp.json ),你需要手动将这段JSON合并进去。

  5. 重要 :修改MCP配置后,必须 完全重启Cursor (关闭所有窗口再重新打开),新的MCP服务器才会被加载。

对于使用WSL(Windows Subsystem for Linux)但Relay安装在Windows的情况 : 这是一个常见且棘手的跨系统场景。你的AI Agent运行在WSL的Linux环境中,但 relay.exe 在Windows。直接配置 command 为Windows路径是行不通的。Relay提供了专门的参数 --exe_in_wsl 来解决路径转换问题。你的配置需要像这样:

{
  "mcpServers": {
    "relay-mcp": {
      "command": "relay.exe",
      "args": ["mcp-cursor", "--exe_in_wsl"],
      "autoApprove": ["relay_interactive_feedback"]
    }
  }
}

当使用 --exe_in_wsl 参数时,Relay的MCP服务端会识别到自己是在WSL环境下被调用,但需要去启动Windows宿主上的GUI进程。它会进行一系列路径转换和 wsl.exe 命令的封装,确保进程间通信能正确建立。虽然过程复杂,但Relay帮你封装好了,你只需要加这个参数即可。

3.3 安装规则提示词(Rule Prompts)

配置好MCP只是打通了“道路”,要让AI“知道”什么时候该走这条路,就需要规则提示词。你可以把它理解为给AI助手的一份“工作手册”,告诉它:“当你准备执行一系列操作之前,先调用Relay工具问问用户”。

在Relay的“Settings -> Rule prompts”页面,点击“Install to Cursor rules”按钮。这个操作会在你的用户规则目录( ~/.cursor/rules/ )下创建一个名为 relay-interactive-feedback.mdc 的文件。这个文件包含了引导AI模型在适当时机调用 relay_interactive_feedback 的指令。

规则文件的工作原理与局限性 : 这个 .mdc 文件会被Cursor在会话开始时加载,并作为系统提示词的一部分提供给AI模型。它 强烈建议 模型在每次“回合”结束时调用Relay工具,并维护 relay_mcp_session_id 。但必须明白, 规则文件是指导性的,而非强制性的 。AI模型,尤其是具有较强自主性的Agent,有时可能会忽略这个建议。如果发现AI不调用Relay,请按以下步骤排查:

  1. 确认 relay-mcp 服务器在Cursor的MCP设置中已启用(绿色状态)。
  2. 确认规则文件已正确安装。你可以手动打开 ~/.cursor/rules/relay-interactive-feedback.mdc 检查内容。
  3. 重启Cursor,确保新规则被加载。
  4. 在Agent设置中,检查是否设置了限制工具调用的参数,或者Agent本身就有“尽量自主完成”的倾向性设置。

4. 核心工作流程与实操详解

4.1 一次完整的人机交互循环拆解

假设你已经完成了安装、配置和规则安装。现在,你在Cursor中让AI助手“重构项目中的用户认证模块”。让我们一步步拆解Relay介入后的完整流程:

  1. AI规划与工具调用 :AI模型分析你的需求后,制定了一个初步计划:“我将先修改 auth.js ,然后更新 userMiddleware.js ,最后调整路由配置。” 根据规则提示词的引导,它在输出最终代码前,决定调用 relay_interactive_feedback 工具。它构造了一个类似下面的JSON-RPC请求:

    {
      "retell": "我将开始重构用户认证模块。第一步,我将重写`auth.js`中的密码哈希函数,使用bcrypt替代当前的MD5,并增加盐值。第二步,更新`userMiddleware.js`中的会话检查逻辑。第三步,在`routes.js`中为新的认证流程添加端点。请确认是否继续,或有任何修改意见。",
      "commands": ["/cursor.edit", "/cursor.terminal", "/cursor.search"],
      "skills": ["javascript", "node.js", "refactoring"],
      // 首次调用,不提供session_id
    }
    
  2. MCP服务端处理 :Cursor IDE将这个调用通过stdio发送给 relay mcp-cursor 进程。MCP服务端解析请求,发现 retell 非空,且没有 relay_mcp_session_id ,因此判定这是一个新会话。

  3. 寻找GUI端点 :MCP服务端读取配置文件目录下的 gui_endpoint_cursor.json ,获取GUI的HTTP地址(如 http://127.0.0.1:54321 )和Bearer Token。

  4. 发起HTTP请求并等待 :MCP服务端向GUI的 /v1/feedback 端点发送POST请求,提交上述内容。然后立即向 /v1/feedback/wait/:request_id 发起一个GET请求,这个请求会 挂起 (长轮询),直到GUI端有结果。

  5. GUI展示与用户交互 :Relay的GUI应用收到请求后,会在主窗口创建一个新的标签页(或激活对应会话的标签页)。标签页的标题通常是时间戳(如 05-10 14:30:15 )。你会在页面中央看到AI发送过来的 retell 内容。下方是一个富文本编辑器,你可以:

    • 直接批准 :输入“好的,继续”或直接点击提交(快捷键 Cmd/Ctrl+Enter )。
    • 提供修正 :“第二步的中间件逻辑需要先检查JWT令牌是否过期,再检查权限。”
    • 附加文件 :将设计草图、API文档截图拖入或粘贴到编辑器,这些会成为 attachments
    • 使用斜杠命令 :输入 / 会弹出菜单,里面包含了AI传来的 commands skills 列表,方便你快速插入指令。
  6. 结果返回与循环继续 :你点击提交后,GUI的HTTP服务会将你的回答、可能的附件列表以及一个 新生成的 relay_mcp_session_id 返回给正在等待的MCP服务端。MCP服务端再将这个结果封装成JSON-RPC响应,通过stdio发回给Cursor。AI模型收到响应后,解析其中的 human 字段得到你的反馈,并保存 relay_mcp_session_id 。然后它开始执行第一步,执行完后,在开始第二步前,它 必须 再次调用 relay_interactive_feedback ,并且这次要带上之前收到的 session_id ,这样Relay就会在同一个GUI标签页中更新内容,实现会话的连续性。

4.2 会话管理: relay_mcp_session_id 的妙用

relay_mcp_session_id 是这个流程中实现连贯对话的关键。它是一个由Relay生成的唯一字符串标识符。它的工作逻辑是:

  • 发起新会话 :AI第一次调用工具时,不提供或提供空的 relay_mcp_session_id 。Relay会生成一个新的ID,并在响应中返回。
  • 延续会话 :AI在后续调用中,必须将这个ID放在请求的 relay_mcp_session_id 字段里。Relay GUI会根据这个ID找到对应的已有标签页,用新的 retell 内容 替换 旧内容,而不是开新标签页。这样,整个重构任务的所有中间确认点都集中在同一个视图里,上下文清晰。
  • 标签页命名 :GUI标签页的标题通常是该会话 第一次创建时的时间 (格式 MM-DD HH:mm:ss )。这能帮你快速定位到某个时间点开始的长时间任务。

实操心得 :在编写自定义的AI Agent或工作流时,务必在代码中妥善保存和传递 relay_mcp_session_id 。丢失这个ID会导致Relay开启一个新的标签页,打断会话的连续性,使得审查历史上下文变得困难。一个简单的做法是,在Agent的内存状态或工作流变量中,专门用一个字段来存储这个ID。

4.3 高级功能:自动回复与用量监控

自动回复(Auto-Reply) : 有时候,你可能希望在某些非关键步骤让AI自动通过,而不需要手动点击。例如,在CI/CD流水线中运行一个自动化的代码审查Agent。Relay提供了两种自动回复机制:

  1. 一次性回复 :在Relay的配置目录下创建 auto_reply_oneshot.txt 文件,里面直接写上你想回复的内容(例如“LGTM”)。下一次工具调用时,Relay会直接使用这个内容作为 human 回复,并且 立即删除该文件 。这适用于单次临时批准。
  2. 循环回复 :创建 auto_reply_loop.txt 文件。Relay会使用其中的内容回复 每一次 工具调用,直到你删除或修改这个文件。这在自动化测试场景下非常有用。

Cursor用量监控 : 这是Cursor模式下的一个独家实用功能。Relay能够读取Cursor本地存储的令牌信息(通过跨平台的解密方式),从而获取你当前账户的API使用情况。在Relay GUI的右下角,你会看到一个类似信号图标的按钮。点击它会弹出一个面板,显示:

  • 当前计划 :例如, Pro Plan
  • 用量统计 :今天/本周/本月使用了多少提示词(Prompt)和补全(Completion)的token数。
  • 配额与预测 :显示你的月度配额剩余多少,并根据近期使用速率预测配额耗尽的时间。 这个功能让你在频繁使用AI辅助时,能随时掌握“油量”,避免在关键时刻配额耗尽。

5. 常见问题排查与实战技巧

5.1 问题排查清单

即使按照指南操作,你也可能会遇到一些问题。下面是一个快速排查清单:

问题现象 可能原因 解决方案
AI助手从不调用Relay 1. MCP服务器未启用。
2. 规则提示词未安装或未生效。
3. Agent自身设置限制。
1. 检查Cursor设置 -> MCP Servers,确保 relay-mcp 是绿色启用状态。
2. 检查 ~/.cursor/rules/ 下是否有 relay-interactive-feedback.mdc 文件,重启Cursor。
3. 检查Agent的配置,是否有“禁用外部工具”或“自主模式”的选项。
调用Relay时Cursor提示“未批准工具” MCP配置中缺少 autoApprove 字段。 mcp.json 中为 relay-mcp 服务器配置添加 "autoApprove": ["relay_interactive_feedback"] ,然后重启Cursor。
Relay GUI窗口没有弹出,或提示连接失败 1. GUI进程未启动。
2. 防火墙/安全软件阻止了本地回环通信。
3. 配置文件损坏。
1. 手动运行 relay gui-cursor 启动GUI。
2. 检查系统防火墙设置,确保允许127.0.0.1的通信。
3. 删除配置目录下的 gui_endpoint_cursor.json relay_gui_cursor_alive.marker 文件,然后重启GUI和IDE。
WSL环境下无法启动Windows的Relay GUI 路径或参数配置错误。 确保MCP配置的 args 中包含了 --exe_in_wsl 。检查 command 是否能在WSL的PATH中找到 relay.exe (可能需要将Windows的 %USERPROFILE%\.relay\ 目录添加到WSL的PATH中)。
会话不连续,每次都开新标签页 AI没有正确传递 relay_mcp_session_id 检查你的AI Agent逻辑,确保它将上一次工具调用的响应中的 relay_mcp_session_id 字段保存下来,并在下一次调用时原样传回。
附件功能不起作用 可能是一次性粘贴了过多或过大的文件。 Relay的HTTP传输有大小限制(默认约16MB)。确保单个附件大小合理。检查配置目录的 attachments 文件夹是否有写入权限。

5.2 实战技巧与最佳实践

  1. 明确指令边界 :在给AI下指令时,可以主动暗示检查点。例如:“请分析这个函数的性能瓶颈, 在修改前 先告诉我你的方案。” 这样AI更容易在正确的时机触发Relay。
  2. 利用附件传递上下文 :Relay的附件功能非常强大。你可以将错误日志截图、UML图、产品需求文档直接粘贴到反馈框。AI在下一个回合就能“看到”这些视觉信息,这对于调试复杂问题或理解业务逻辑至关重要。
  3. 管理长期运行的会话 :对于一个需要多次确认的长期任务(比如重构整个项目),保持一个 relay_mcp_session_id 贯穿始终。你可以在Relay的标签页里看到完整的、按时间顺序的决策历史,这比在IDE的聊天记录里翻找要直观得多。
  4. 清理磁盘空间 :Relay会存储所有的交互日志( feedback_log.txt )和附件(在 qa_archive/ attachments/ 目录)。默认附件保留30天。你可以定期通过“Settings -> Cache”页面查看存储使用情况,并一键清理旧文件。
  5. CLI工具用于调试与自动化 :除了GUI模式, relay feedback 命令非常有用。例如,你可以在终端测试Relay是否能正常工作: relay feedback --retell "测试消息" 。这在写脚本自动化某些流程时(比如结合 cron 定时任务和AI进行日报生成)能派上大用场。 --timeout 参数可以控制等待时间,避免脚本永远挂起。

5.3 理解“暂停MCP”功能

在Relay的“Environment & MCP”设置里,有一个“Pause MCP”的开关。打开它,Relay会向配置目录写入一个特殊的标记文件( mcp_pause.json )。当这个标记存在时,MCP服务端在收到任何 relay_interactive_feedback 调用时,会直接返回一个特殊的 retell 内容: <<<RELAY_MCP_PAUSED>>>

这个功能有什么用? 假设你正在专注地进行一段不需要AI干预的纯手工编码,或者你的AI配额即将用尽,你想暂时禁用所有需要人工确认的环节。打开这个开关,AI助手在调用Relay时会立刻收到这个“已暂停”的信号。一个设计良好的、遵循了Relay规则提示词的AI,在收到这个信号后,应该理解当前处于“自动通过”模式,从而不等待反馈直接继续执行。这相当于一个全局的“自动模式”开关。

6. 开发与构建:深入Relay技术栈

如果你对Relay的内部实现感兴趣,或者想要自己从源码构建,它的技术选型也体现了现代桌面应用开发的趋势。

前端(GUI) :基于 Vue 3 TypeScript ,使用Vite进行构建。这带来了优秀的开发体验和类型安全。UI层负责渲染对话、管理标签页、处理富文本输入和文件上传。

后端/本地服务 :这是Relay的精华所在,分为两部分:

  1. Tauri核心 :使用 Rust 编写,通过Tauri框架创建桌面窗口、管理系统托盘图标、并暴露出一系列安全的HTTP API接口( /v1/feedback 等)供前端调用。Tauri的优势是打包体积小、性能高、安全性好(前端与系统隔离)。
  2. MCP服务端 :同样用 Rust 编写,使用 clap 库处理命令行参数。它独立于GUI进程,负责实现MCP协议,与IDE通过stdio通信,并与Tauri HTTP服务交互。

构建与开发命令

# 克隆项目
git clone https://github.com/andeya/ide-relay-mcp.git
cd ide-relay-mcp

# 安装前端依赖并构建
npm install
npm run build

# 构建Rust后端 (MCP服务端和Tauri)
cargo build --manifest-path src-tauri/Cargo.toml --release

# 使用Tauri构建安装包(如dmg, exe, AppImage)
npm run tauri build

# 开发模式运行(前端热重载 + Tauri窗口)
npm run tauri dev

架构设计的启示 :Relay采用 多二进制模式 gui-* mcp-* )而非单一进程,实现了关注点分离。GUI可以独立重启更新,MCP服务端保持稳定。两者通过本地文件(端点配置文件)和HTTP进行松耦合通信,这是一种非常健壮的设计模式,值得在需要类似“常驻服务+用户界面”的应用中借鉴。

在我自己深度使用Relay的几个月里,它彻底改变了我与AI编程助手协作的方式。从最初的“看着它干”,变成了真正的“带着它干”。最大的体会是,它并没有降低效率,反而通过减少返工和错误决策,从整体上提升了开发速度和质量。尤其是处理那些模糊的、需要业务理解的任务时,在关键节点介入一下,能省去后面大量的调试时间。它的设计哲学很清晰:AI是强大的执行引擎,但人类才是掌舵的船长。Relay就是那个让你随时能握住方向盘的工具。

更多推荐