关于 relay-mcp
relay-mcp 是面向 Claude 多个工作界面的可自托管会话中继,让 Claude Code、Cowork 和 Claude.ai 通过共享消息线程传递上下文。它定位为临时协作白板,而非日志或记忆存储。
主要功能
- 01创建、列出和归档线程
- 02在线程中发布与读取消息
- 03仅检查上次读取后的新消息
- 04标记消息来源界面和会话
- 05支持 Bearer 身份验证与 OAuth 2.1
适用场景
- 01将 Claude Code 的调试上下文交给 Claude.ai
- 02让 Cowork 定时任务为后续会话留言
- 03在多个 Claude 工作界面间共享临时消息
- 04按话题整理并查阅跨会话讨论
MCP 相关
MCP 服务通过 streamable HTTP 暴露六个线程与消息工具,并支持静态 Bearer 身份验证及用于 Claude.ai 连接器的 OAuth 2.1。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
relay-mcp
此仓库是开源参考实现。作者在另一个 URL 上运行着一个私有部署的实例,但建议你部署自己的实例用于生产环境。
为 Claude 提供的可自托管会话中继。当你在多个 Claude 界面(Code、Cowork、Claude.ai 连接器)之间工作时,每个界面都处于各自的上下文窗口中。中继会为它们提供一个共享消息线程,所有界面都可以在其中发布和读取消息,因此 Code 会话可以将状态交接给 Chat 会话,无需复制粘贴;定时运行的 Cowork 任务也可以留下便笺,供你早上的 Chat 会话读取。它是一个轻量级白板,不是日志或记忆存储。
工具
该服务提供六种 MCP 工具。
| 工具 | 描述 |
|---|---|
relay_list_threads | 列出线程及其最近活动时间和消息数。 |
relay_create_thread | 创建一个命名线程。 |
relay_post_message | 在线程中发布消息。如果线程不存在,则自动创建。 |
relay_read_thread | 读取最新消息,按时间倒序排列。可选更新游标。 |
relay_check_new | 仅返回自该读取者上次检查后收到的消息。 |
relay_archive_thread | 软归档线程。历史记录会保留。 |
每条消息都带有一个 surface 字段(chat、cowork、code、other)和一个可选的自由文本 session_tag,让线程在多个并行会话间保持清晰易读。
架构
-
Cloudflare Worker,位于
src/index.ts。无状态。通过/mcp提供可流式传输的 HTTP MCP。 -
Supabase Postgres,用于存储线程、消息和读取游标。包含三张表,名称均以
relay_开头。已启用 RLS,但没有任何策略;只有 Worker 的服务角色密钥可以读取或写入。 -
同一服务上的两种身份验证方式:
- 静态 Bearer,用于 Claude Code 和 Cowork:
Authorization: Bearer <RELAY_API_KEY>。尽可能简单,无需浏览器流程。 - OAuth 2.1,带动态客户端注册,用于 Claude.ai 自定义连接器。Worker 提供
/.well-known/oauth-authorization-server、/register、/authorize和/token。访问令牌是使用RELAY_API_KEY签名的 HS256 JWT。无状态,无需 KV 或 Durable Objects。访问令牌有效期为 90 天,刷新令牌有效期为 365 天。
有关身份验证、轮换和威胁模型的完整说明,请参阅安全。
- 静态 Bearer,用于 Claude Code 和 Cowork:
-
v1 为单租户。Worker 从
RELAY_USER_ID密钥读取一个硬编码的用户 UUID。在src/oauth.ts中修改一个文件并进行一次 RLS 策略迁移,即可支持多用户;架构已包含user_id列。
部署自己的实例
自托管大约需要十分钟。你需要一个 Cloudflare 账户(Workers 免费套餐即可)、一个 Supabase 项目,以及本地安装的 Node 20+。
1. 克隆并安装
git clone https://github.com/zhowe-designs/relay-mcp.git
cd relay-mcp
npm install
2. 创建 Supabase 项目并运行迁移
在 supabase.com 创建一个新项目。在 SQL 编辑器中粘贴并运行 migrations/001_initial.sql。这会创建 relay_threads、relay_messages、relay_read_cursors,设置索引,启用 RLS 但不添加任何策略,并撤销 anon 和 authenticated 的授权。
在项目设置 → API中,复制:
- 项目 URL(形式如
https://abcdef.supabase.co)。 - service_role 密钥。请将其视为数据库密码。
3. 选择租户 UUID
生成一个 UUID(使用 uuidgen、crypto.randomUUID() 或任何 UUID v4 生成器)。这是 v1 服务绑定的唯一用户。之后可以轮换,但在一个 UUID 下发布的所有内容,在另一个 UUID 下都不可见。
4. 设置 Worker 密钥
npx wrangler login
npx wrangler secret put RELAY_API_KEY # any random 32+ char string, your bearer
npx wrangler secret put SUPABASE_URL # https://<project-ref>.supabase.co
npx wrangler secret put SUPABASE_SERVICE_KEY # service_role key from step 2
npx wrangler secret put RELAY_USER_ID # UUID from step 3
5. 部署
npx wrangler deploy
Wrangler 会输出部署后的 URL,例如 https://relay-mcp.<your-subdomain>.workers.dev。该 URL 加上 /mcp 即为 MCP 端点。
6. 可选:自定义域名
编辑 wrangler.toml 并取消 routes 块的注释,将 relay-mcp.example.com 替换为你所拥有的 Cloudflare 区域中的主机名。重新运行 npx wrangler deploy。Wrangler 会自动创建 CNAME。
7. 冒烟测试
RELAY_URL=https://relay-mcp.<your-subdomain>.workers.dev RELAY_API_KEY=<your-key> \
node --experimental-strip-types scripts/smoke.ts
包含 OAuth 流程在内的 40 项断言。全部通过即表示服务已上线。
配置客户端
将 <RELAY_URL> 替换为部署后的 URL,并将 <RELAY_API_KEY> 替换为你在上文设置的密钥。
Claude Code
将配置添加到项目根目录的 .mcp.json,或添加到 ~/.claude.json 以供全局使用。
{
"mcpServers": {
"relay": {
"type": "http",
"url": "<RELAY_URL>/mcp",
"headers": {
"Authorization": "Bearer <RELAY_API_KEY>"
}
}
}
}
重启 Claude Code,运行 /mcp,并确认 relay 显示了 6 个工具。
Cursor
将配置添加到项目根目录的 .cursor/mcp.json,或添加到 ~/.cursor/mcp.json 以供全局使用。
{
"mcpServers": {
"relay": {
"type": "http",
"url": "<RELAY_URL>/mcp",
"headers": {
"Authorization": "Bearer <RELAY_API_KEY>"
}
}
}
}
重启 Cursor,打开 MCP 设置,并确认 relay 显示了 6 个工具。
注意:relay 配置块必须放在 mcpServers 对象 内部。Cursor 会静默忽略文件顶层定义的任何服务。如果工具没有显示,首先检查这一点。
Cowork 定时任务
在任何需要访问 relay 的任务提示词中添加 mcp_servers 配置块。
mcp_servers:
relay:
type: http
url: <RELAY_URL>/mcp
headers:
Authorization: "Bearer <RELAY_API_KEY>"
Claude Desktop
Claude Desktop 的 MCP 支持需要 stdio 命令,而不是远程 HTTP URL。若要连接远程 relay,请使用 mcp-remote 桥接工具,它可以将通过 stdio 启动的进程适配为远程 HTTP MCP 服务。
打开 claude_desktop_config.json(Windows:%APPDATA%\Claude\claude_desktop_config.json;macOS:~/Library/Application Support/Claude/claude_desktop_config.json)并添加:
{
"mcpServers": {
"relay": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"<RELAY_URL>/mcp",
"--header",
"Authorization: Bearer <RELAY_API_KEY>"
]
}
}
}
完全退出 Claude Desktop(不只是关闭窗口)后重新打开。relay 应会显示在工具菜单中,并包含 6 个工具。
注意:Claude Desktop 会在某些会话生命周期事件中重写 claude_desktop_config.json,可能会静默清除手动添加的 mcpServers 配置。如果 relay 在会话之间消失,请重新添加配置块,并在 Claude Desktop 配置目录以外的位置保留一份备份,以便粘贴恢复。如果可以使用下方的 Claude.ai 自定义连接器,则能完全避免此问题,因此更推荐使用它。
Claude.ai 自定义连接器
Claude.ai 使用 OAuth 2.1 和动态客户端注册,relay 支持该功能。
- 在 Claude.ai 中,打开 设置 → 连接器 → 添加自定义连接器。
- 名称:任意填写,例如
Relay。 - 远程 MCP 服务 URL:
<RELAY_URL>/mcp。 - 将高级 OAuth 字段留空。Claude.ai 会自动处理注册。
- 点击添加。浏览器标签页会打开到 Worker 的
/authorize页面。 - 将你的
RELAY_API_KEY粘贴到唯一的输入框中,然后点击授权。 - 浏览器会重定向回 Claude.ai。连接器会列出 6 个工具。
访问令牌的有效期为 90 天,并会自动刷新,因此你很少需要重新授权。如果授权失败,请移除连接器后重新添加。
故障排除
真实部署中的常见故障模式,以及每种故障首先应检查的事项。
冒烟测试失败,返回 401 Unauthorized。 本地环境中的 RELAY_API_KEY 与部署到 Worker 的密钥不匹配。重新运行 npx wrangler secret put RELAY_API_KEY,然后在运行冒烟测试的 shell 中重新导出相同的值。设置密钥后,Wrangler 不会显示密钥值,因此如有疑问,请在两端都轮换为新值。
Worker 在任何工具调用时都返回 5xx。 几乎总是因为未设置 Supabase service-role 密钥,或误将 anon 密钥设为该密钥。使用 Supabase Project Settings -> API -> service_role 中的值,重新运行 npx wrangler secret put SUPABASE_SERVICE_KEY。同时确认 SUPABASE_URL 是项目 URL(末尾没有 /mcp,也没有路径),且 RELAY_USER_ID 是有效的 UUID v4。
自定义域名返回 530。 Cloudflare 530 表示 DNS 解析失败,通常是 CNAME 尚未传播。等待几分钟后重试。如果问题仍然存在,请确认 wrangler.toml 中的主机名属于你实际拥有的 Cloudflare 区域,并且 npx wrangler deploy 报告路由已关联。
Cursor 看不到中继工具。 relay 块位于 .cursor/mcp.json 的顶层,而不是 mcpServers 对象内。Cursor 会静默忽略顶层条目。将该块移入 mcpServers,然后重启 Cursor。
Claude Desktop 看不到中继工具。 可能有两个原因。第一,缺少 mcp-remote,或者 npx 启动时无法获取它(Claude Desktop 会吞掉 stderr);在终端中运行一次 npx -y mcp-remote --help,以预热缓存并显示任何安装错误。第二,Claude Desktop 覆盖了 claude_desktop_config.json,并清除了你的 mcpServers 条目;从备份中重新添加该条目,然后完全退出并重新打开应用。
Claude.ai 上的 OAuth 流程会返回授权页面,陷入循环。 浏览器阻止了 Worker 域上的第三方 Cookie,或者你粘贴的 RELAY_API_KEY 前后带有空格。尝试使用新的浏览器配置文件,仔细粘贴密钥,并查看 Worker 日志(npx wrangler tail)以获取实际错误。
用法
连接后,描述你的意图。模型会选择合适的工具。以下是一些可用的句子示例:
- “将最后一条错误、迁移差异和我的推测发布到中继线程
migration-debug,surface 设为 code。” - “读取
daily-standup,显示 Cowork 今天早上发布的所有内容。” - “从
migration-debug获取最近十条消息。”
线程命名
使用简短、以连字符分隔且限定主题的名称。用 migration-debug,不要用 april_migration_issues_2026。每个主题一个线程,而不是每天一个线程。线程会不断累积;对话可以持续数周。首次向线程发布内容时会自动创建该线程,因此开始使用时无需任何额外步骤。
好:migration-debug、daily-standup、pricing-notes、scratch。
不好:april-18-bugs、thread-1、general。
必须标记来源界面
始终将 surface 设为 chat、cowork、code 或 other。六个月后,当你翻阅某个线程时,知道一条消息来自计划执行的 Cowork 任务还是实时的 Chat 对话,会影响你对它的重视程度。使用 session_tag 在同一界面内通过自由文本进行分组(例如,每个调试会话使用一个标签)。
归档已结束的线程
主题结束后,调用 relay_archive_thread。归档的线程不会显示在默认的 list_threads 输出中,但仍可通过 include_archived 查询。把它想成 Slack 频道,而不是 Git 分支。归档会保留历史记录,不会删除内容。
边界规则:临时层,而非权威状态
Relay 是会话之间的对话层。它不是日志、决策记录,也不是记忆库。任何一周后仍然重要的内容,都应存放在真正的权威记录系统中(决策日志、任务跟踪工具、文档、代码注释等)。Relay 记录的是当时说了什么,而不是做出了什么决定。如果 relay 帖子记录了一项真正的决定,请先将它写入某个持久存储,再继续。
绝不转发机密
这与任何聊天工具的规则相同。API 密钥、服务角色令牌、OAuth 密钥、数据库凭据,都应存放在 Wrangler secrets 或密码管理器中。绝不能将它们放入 relay 消息中。Relay 数据库不是保险库。哪些内容不得发布,请参阅安全。
安全
本节汇总了 relay 的身份验证模型、密钥轮换流程、内容规则和威胁模型。
身份验证模型
静态 Bearer。 Claude Code 和 Cowork 使用 Authorization: Bearer <RELAY_API_KEY> 进行身份验证。Worker 会在每次请求时将请求头与 RELAY_API_KEY 密钥进行比较。没有浏览器流程、令牌交换或刷新机制。持有该密钥的人可以完全访问已配置 RELAY_USER_ID 下的所有线程。
带 DCR 的 OAuth 2.1。 Claude.ai 自定义连接器通过 /register、/authorize 和 /token 使用 OAuth 2.1 与动态客户端注册。用户在 Worker 的授权页面中粘贴一次 RELAY_API_KEY;Worker 会验证该密钥,并使用同一个 RELAY_API_KEY 签发以 HS256 签名的 JWT。访问令牌有效期为 90 天,刷新令牌有效期为 365 天。没有服务端会话存储、KV 或 Durable Objects。
密钥轮换操作手册
使用以下命令轮换 RELAY_API_KEY:
npx wrangler secret put RELAY_API_KEY
需要预先考虑的后果:
- 所有 OAuth 令牌都会失效。 令牌是使用
RELAY_API_KEY签名的 JWT,因此更改该密钥会破坏所有现有签名。每位 Claude.ai 连接器用户都必须移除并重新添加连接器,然后使用新密钥重新授权。 - 静态 Bearer 客户端在重新配置前无法使用。 使用新密钥更新
.mcp.json、.cursor/mcp.json、claude_desktop_config.json,以及任何 Cowork 任务中的mcp_servers配置块。每个客户端完成更新前,都会返回 401。
如果怀疑密钥已泄露、拥有访问权限的队友离开,或者威胁模型要求定期轮换,请进行轮换。
不得发布的内容
线程会持久保存在 Supabase 中,任何持有 RELAY_API_KEY 的人都可以查看。请将 relay 视为共享白板,而非保险库。请勿发布:
- API 密钥、服务角色令牌、OAuth 客户端密钥、刷新令牌。
- 数据库密码,或包含嵌入式凭据的连接字符串。
- 客户个人身份信息、受监管数据,或任何受保密协议约束的内容。
- 如果 relay 后端、Supabase 项目或任何存有 API 密钥的客户端配置遭到入侵,就会造成问题的任何内容。
机密应存放在 Wrangler secrets 或密码管理器中。Relay 数据库不是保险库。
威胁模型
v1 中的 relay 是单租户服务。它假定运营者信任每个持有 RELAY_API_KEY 的会话,因为任何持有者都可以读取和写入已配置 RELAY_USER_ID 下的所有线程。它没有按会话划分的访问范围,除 Worker 日志外没有审计记录,并且 Worker 与 Supabase 之间没有策略层。多用户或多租户部署需要额外的身份验证层(每位用户使用独立密钥、限定范围的令牌、基于 user_id 的 RLS 策略);此处未提供这些功能。架构已包含 user_id 列,便于实现此扩展,但需要你自行构建。
开发
# Typecheck
npm run typecheck
# Local dev (requires .dev.vars, see .dev.vars.example)
npx wrangler dev
# Smoke test
RELAY_URL=<your-url> RELAY_API_KEY=<your-key> npm run smoke:remote
# Rotate a secret (see Security for consequences)
npx wrangler secret put RELAY_API_KEY
架构
共 3 张表,名称均以 relay_ 为前缀。迁移文件位于 migrations/001_initial.sql。
relay_threads。每位用户的每个命名线程对应一行。relay_messages。每条已发布的消息对应一行。按(thread_id, created_at desc)建立索引。relay_read_cursors。每个(thread_id, reader_tag)对应一行。记录“此读者上次查看的时间”。
仅限服务角色访问。已启用 RLS,且未配置任何策略;已撤销 anon 和 authenticated 的权限。只有 Worker 的服务角色密钥可以读取或写入。
目录结构
src/
index.ts Worker entry, MCP JSON-RPC protocol, routes
oauth.ts OAuth 2.1 facade (metadata, register, authorize, token)
jwt.ts HS256 JWT sign, verify, PKCE check
db.ts Supabase client factory
types.ts
tools/
threads.ts list, create, archive, get_or_create
messages.ts post, read, check_new
migrations/
001_initial.sql three tables + indexes + RLS lockdown
scripts/
smoke.ts end-to-end smoke test, includes OAuth
wrangler.toml
package.json
server.json MCP Registry metadata
贡献
这不是一个积极维护的社区项目。欢迎提交用于修复错误、改进文档和添加明显提升易用性功能的 PR。为保持项目精简,较大的功能或重构很可能会被拒绝。如果你想讨论较大的改动,请先创建 issue。
许可证
MIT。请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。