内容
# 热线
Claude Code 的一个消息通道。热线是一个 MCP 服务器,它将 Claude Code 会话中继到 Telegram,这样你就可以像与朋友发短信一样与你的代理进行对话:短消息气泡、反应、可点击的按钮、照片。
它使用 Claude Code 的实验性双向通道协议(`claude/channel`)。这使得它目前特定于 Claude Code。今天,其他适配器如果采用该协议,或者热线为它们添加支持,则可以使用。
## 消息体验
Claude 以气泡的形式回复,每个气泡代表一个想法,并带有打字指示器和自然的间隔。Claude 会用表情符号反应,当收到 👍 时,会编辑自己的消息以显示进度,并在需要你选择时提供内联按钮。
实际交流如下:
> **你:** 构建又失败了 😤
>
> **Claude:** 啊,又失败了?
> **Claude:** 让我看看
> **Claude:** 是的,是那个不稳定的集成测试,不是你的代码
> **Claude:** 你要我重试吗?
> `[ 重试 🔁 ]` `[ 深入了解 ]`
你可以点击一个按钮,选择内容会像你输入的一样返回到会话中,键盘就会清空,以免被回答两次。
## 安装
```sh
brew install 1broseidon/tap/hotline
```
二进制文件随每个标记版本发布。或者从源代码构建:
```sh
go install github.com/1broseidon/hotline/cmd/hotline@latest # -> $(go env GOPATH)/bin/hotline
```
源代码构建需要 Go 1.26+。
## 快速入门
1. 从 [@BotFather](https://t.me/BotFather) 获取机器人令牌,然后保存它(一次,机器范围):
```sh
hotline setup --telegram-token 123456789:AA…
```
运行 `hotline setup` 不带标志以提示,`hotline setup --show` 以查看已配置的内容。
2. 在您要文本的项目中注册通道:
```sh
cd your-project
hotline init
```
这安装了热线 Claude Code 插件并为项目启用它(`.claude/settings.json`)。添加 `--providers telegram,signal` 以获取额外的传输, `--voice` 以获取启动 `HOTLINE.md`, `--mcp-json` 以注册原始 `.mcp.json` 服务器。
3. 启动 Claude Code 并加载通道:
```sh
hotline start # 额外的 claude 标志在 -- 之后,例如 hotline start -- --continue
hotline start --yolo # 添加 --dangerously-skip-permissions;权限中继永远不会触发
```
4. 给你的机器人发消息。来自未知发送者的第一个消息会返回一个 6 位十六进制配对代码。从终端批准它:
```sh
hotline pair <code>
```
就这样。你的会话现在是一个 Telegram 聊天。
## 访问模型
没有人可以在你同意的情况下与你的代理交谈。入站门控根据发送者决定,而不是聊天:陌生人允许的群组仍然被丢弃。
| 策略 | 行为 |
|---|---|
| `pairing` (默认)| 未知 DM 发送者获得配对代码;你从终端批准或拒绝 |
| `allowlist` | 仅列出的用户 ID 被发送;其他人保持沉默 |
| `disabled` | 完全没有 DM |
群组按群组 ID 选择加入,具有可选的 `requireMention` (仅当机器人被提及、回复或 `mentionPatterns` 正则表达式匹配时才发送)和可选的群组发送者允许列表。
配置存储在 `~/.config/hotline/access.json` 中,并在每个入站消息上重新读取,因此编辑立即生效:
```jsonc
{
"dmPolicy": "pairing", // pairing(默认)| allowlist | disabled
"allowFrom": ["412587349"], // 数值用户 ID
"groups": {
"-1001234567890": { "requireMention": true, "allowFrom": [] }
},
"mentionPatterns": ["^hey claude"],
"ackReaction": "👀", // 收到消息的表情符号反应("" 禁用)
"replyToMode": "first", // first | all | off
"textChunkLimit": 4096,
"chunkMode": "newline", // newline | length
"bubbleMode": "paced" // paced | instant
}
```
配对代码 24 小时后过期。要删除已批准的发送者,请运行 `hotline revoke <sender-id>` (`hotline status` 显示的确切 ID 或唯一前缀);它从 `allowFrom` 中删除发送者并清除他们可能仍有的任何待处理配对。批准仅在终端进行:Claude 永远不会批准配对或编辑访问,因为聊天消息要求它这样做。
出站也被门控。每个工具调用在触摸 Telegram API 之前都会检查目标聊天是否符合相同的规则,因此 Claude 只能给能与它聊天的聊天发送消息。该通道还拒绝附加自己的状态文件,并在消息元数据进入之前净化上传者控制的文件名。
## 工具
| 工具 | 功能 |
|---|---|
| `reply` | 发送 `bubbles`(短消息数组,间隔发送)或 `text`(单个消息,超过 4096 个字符时分段)。可选 `reply_to`、`files`(图片内联,其他作为文档,每个 50MB)、`buttons`(最多 12 个内联选项)、`format`(`text`、`markdownv2`、`html`) |
| `react` | 设置表情符号反应(Telegram 的固定白名单) |
| `edit_message` | 编辑机器人发送的消息,用于临时进度。编辑不会推送通知 |
| `download_attachment` | 通过 `file_id` 获取非照片附件到收件箱;返回本地路径(Telegram 的 20MB 下载上限适用) |
按钮点击作为普通入站消息返回,其内容是点击的标签,原样返回,因此值永远不会被 Telegram 的回调数据限制截断。点击授权镜像入站门控。
每个方向的消息都追加到 `<stateDir>/transcript.jsonl`。Telegram 没有历史 API,Claude Code 会话会压缩或重启,因此转录是助手在重置过程中回忆线程的方式。它以 0600 写入,目前无限制。
## 语音
通道指令附带默认角色:一个尖锐、温暖的朋友,以短消息气泡的形式发送文本。可以通过 `HOTLINE.md` 文件替换它。第一个匹配的文件优先:
1. `./HOTLINE.md` 在 Claude Code 运行的目录中,用于每个仓库的语音
2. `HOTLINE.md` 在状态目录中(默认为 `~/.config/hotline`),您的全局默认语音
3. 内置语音
该文件仅在启动时读取。编辑后,重启 Claude Code。空文件将被跳过。
Claude Code 将 MCP 服务器指令限制在 2048 个字符。热线优先考虑机制,并为语音留下约 630 个字符;较长的语音会在词边界处截断,并带有 stderr 警告。
语音仅更改语气。工具合同、入站消息处理和安全规则(操作员仅配对批准、注入立场)是编译的,始终优先,并在任何语音下应用。
```markdown
<!-- HOTLINE.md -->
你是一个海盗在休假。每个气泡都带有咸味。
称呼他们为“船长”。最多两个气泡,否则他们会被扔到船外。
```
或者用于工作:
```markdown
<!-- HOTLINE.md -->
简洁和专业。没有表情符号,没有感叹号。
除非答案确实需要两个气泡,否则只使用一个气泡。
```
## 多个提供商,多个机器人
热线建立在内部提供商接口和源路由器上。Telegram 是第一个提供商。配置提供商使用 `HOTLINE_PROVIDERS`,一个以逗号分隔的 `kind[:instance]` 条目列表:
```sh
HOTLINE_PROVIDERS=telegram # 默认
HOTLINE_PROVIDERS=telegram:work # 命名实例
HOTLINE_PROVIDERS=telegram,discord # 一个通道上的两个传输
HOTLINE_PROVIDERS=telegram,discord,signal # 所有三个
```
`HOTLINE_PROVIDERS` 从进程环境中读取,而不是状态 `.env`。在插件路径上,这是项目的 `.claude/settings.json` 中的 `env` 块 - Claude Code 将其应用于会话,插件启动的服务器继承它(`hotline init --providers telegram,signal` 为您写入此内容):
```json
{
"enabledPlugins": { "hotline@hotline": true },
"env": { "HOTLINE_PROVIDERS": "telegram,signal" }
}
```
在原始路径上,它是 `.mcp.json` 的 `env` 块:
```json
{
"mcpServers": {
"hotline": {
"command": "hotline",
"args": ["run"],
"env": { "HOTLINE_PROVIDERS": "telegram,signal" }
}
}
}
```
令牌和帐户保留在状态 `.env` 中,如下所示。
使用一个提供程序配置时,工具模式与上述单提供程序相同。当有多个提供程序时,每个工具都需要一个必需的 `source` 参数,与入站消息上的 `source` 属性匹配。
命名实例是运行多个会话的一种方式。一个机器人令牌允许恰好一个 Telegram 轮询器,因此每个并发会话都有自己的机器人。 `--bot work` 是 `HOTLINE_PROVIDERS=telegram:work` 的简写。每个命名机器人都在 `<stateDir>/bots/<name>/` 下隔离存储,并在共享的 `.env` 中从 `TELEGRAM_BOT_TOKEN_<NAME>` 读取其令牌:
```sh
# ~/.config/hotline/.env
TELEGRAM_BOT_TOKEN=111:AA… # 默认机器人
TELEGRAM_BOT_TOKEN_WORK=222:BB… # telegram:work
```
`--bot` 适用于每个子命令(`hotline status --bot work`、`hotline pair <code> --bot work`)。
当未来传输缺少某个功能时,适配器会降低它,而不是代理:在不支持内联按钮的传输上,按钮呈现为编号的文本选项,编号的选择通过相同的方式路由回来。工具合同在所有地方保持不变。
## Discord
Discord 作为第二个提供程序与 Telegram 一起运行,或单独运行。相同的工具,相同的访问模型,原生按钮。
设置:
1. 在 https://discord.com/developers/applications 创建一个应用程序,然后在其下添加一个 Bot。
2. 在 Bot 页面上,在特权网关意图下启用 **消息内容意图**。如果没有它,机器人将收到空消息体。
3. 将机器人令牌复制到共享的 `.env` 中:
```sh
# ~/.config/hotline/.env
DISCORD_BOT_TOKEN=您的机器人令牌
DISCORD_BOT_TOKEN_WORK=… # discord:work,如果您运行命名实例
```
4. 使用 `bot` 作用域的 OAuth2 URL 邀请机器人。 对于 DM,不需要额外的权限。 对于服务器通道,请授予发送消息、读取消息历史、添加反应和附加文件:
```
https://discord.com/oauth2/authorize?client_id=<APP_ID>&scope=bot&permissions=100416
```
5. 启用提供程序并运行:
```sh
HOTLINE_PROVIDERS=telegram,discord hotline
```
6. 给机器人发消息。它会回复一个配对代码;从终端批准它:
```sh
hotline pair <code> --provider discord
```
`--provider discord` 将 pair/deny/status 指向 Discord 状态(`<stateDir>/discord/`);命名实例使用 `--provider discord:work`,状态存储在 `<stateDir>/discord/instances/work/` 下。
行为说明:
- 按钮是原生的 Discord 消息组件。点击返回一个带有点击标签的入站消息,按钮被清除,因此问题无法被回答两次。
- 权限中继的工作原理与 Telegram 的完全一样:允许/拒绝/更多按钮发送 DM 给允许列表的用户,`yes <code>` / `no <code>` 文本回复也接受。
- 气泡与 Discord 的打字指示器同步。消息在 Discord 的 2000 字符限制下拆分。
- 服务器通道作为群组按频道 ID 编号:添加频道到 Discord `access.json` 中的群组,并使用 `requireMention` 仅在 @-mention 时唤醒机器人。
- 入站图像预加载到收件箱;其他附件显示一个 CDN URL 作为 `attachment_file_id` 以获取 `download_attachment`(Discord CDN 仅限 50MB 限制)。
- 来自机器人(包括其自身)的消息永远不会中继。
## 信号
Signal 作为提供程序与 Telegram 和 Discord 一起运行,或单独运行。相同的工具,相同的访问模型。没有 API:hotline 与本地运行的 [signal-cli](https://github.com/AsamK/signal-cli) 守护进程通信,链接到您的 Signal 帐户作为辅助设备。signal-cli 是第三方客户端,不是官方 Signal 产品。
设置:
1. 安装 signal-cli。在 macOS 上:`brew install signal-cli`。在 Linux 上,从 https://github.com/AsamK/signal-cli/releases 下载一个版本(不在 apt 中),并将 `signal-cli` 放入您的 PATH 中。需要 Java 17+。
```sh
signal-cli link -n hotline
```
它会打印一个 `sgnl://linkdevice?...` URI。将它渲染为二维码(`qrencode -t ansiutf8 'sgnl://...'`) 并从您的手机在设置 → 已链接的设备下扫描。
3. 运行守护进程(保持它运行:tmux,或 systemd 用户服务与 `ExecStart=signal-cli -a +15551234567 daemon --http 127.0.0.1:8080`):
```sh
signal-cli -a +15551234567 daemon --http 127.0.0.1:8080
```
4. 在共享的 `.env` 中指向它:
```sh
# ~/.config/hotline/.env
SIGNAL_ACCOUNT=+15551234567 # 链接的帐户,E.164
SIGNAL_DAEMON_URL=http://127.0.0.1:8080 # 默认情况下,这是默认值
SIGNAL_ACCOUNT_WORK=… // signal:work,如果您运行命名实例
```
5. 启用提供程序并运行:
```sh
HOTLINE_PROVIDERS=http://telegram,discord,signal hotline
```
6. 给账户发消息。未知发送者会收到一个配对代码;从终端批准:
```sh
hotline pair <code> --provider signal
```
`--provider signal` 将 pair/deny/status 指向 Signal 状态(`<stateDir>/signal/`);命名实例使用 `--provider signal:work`,状态存储在 `<stateDir>/signal/instances/work/` 下。
行为说明:
- 发送者按电话号码(E.164)识别;允许列表保存号码。聊天 ID 是对方的号码,群组聊天 ID 是 `group:<id>`;将它们添加到 Signal `access.json` 中的群组。
- Signal 没有内联按钮。按钮呈现为编号的文本选项,回复编号发送所选标签。相同的往返旅程,输入而不是点击。
- 权限中继仅限文本:提示作为消息到达,答案为 `yes <code>` 或 `no <code>`。
- 反应和编辑是原生的(`signal-cli sendReaction` 和 `send --edit-timestamp`)。气泡由 Signal 的打字指示器同步。消息在 2000 个字符处拆分,Signal 客户端切换到长文本附件。
- 消息 ID 是 Signal 时间戳(Signal 的消息身份);入站 ID 携带作者为 `<timestamp>:<number>`,因此反应目标正确。
- 入站图像从守护程序获取到收件箱;其他附件显示一个 ID 以获取 `download_attachment`(50MB 限额双向)。
- 守护程序的 HTTP 端点没有身份验证;请将其保留在 127.0.0.1。
## 权限中继
当配置了令牌时,hotline 声明 `claude/channel/permission` 功能。Claude Code 的权限提示通过中继到允许列表的 DM(绝非群组)与 **See more / Allow / Deny** 按钮。您也可以用文本回复 `yes <code>` 或 `no <code>`;这些回复被拦截并转换为判决而不是被中继为聊天。
## 命令行界面
```
hotline setup 将凭证保存到共享 .env(运行一次)
hotline init 安装 hotline 插件并为此仓库启用它
hotline start 启动带有加载通道的 Claude Code
hotline [run] 启动 MCP 服务器 + Telegram 轮询器(默认)
hotline pair <code> 批准待处理配对代码
hotline deny <code> 拒绝待处理配对代码
hotline revoke <id> 从允许列表中删除已批准的发送者
hotline status 打印状态目录 / 令牌 / 访问摘要
```
`pair`、`deny`、`revoke` 和 `status` 采用 `--provider kind[:instance]` 以选择要操作的提供程序(默认为 telegram)。
## 状态和环境
状态位于 `${XDG_CONFIG_HOME:-~/.config}/hotline`。在第一次运行过程中,会自动复制旧默认位置 `~/.config/hotline` 中找到的状态;旧目录保留不变,以便仍在运行旧二进制版本的会话继续工作。hotline 曾被称为 `tele-go`;`TELE_GO_*` 变量作为回退适用于一个版本。
| 变量 | 用途 |
|---|---|
| `TELEGRAM_BOT_TOKEN` | 机器人令牌(实际环境变量优先于 `.env`);`TELEGRAM_BOT_TOKEN_<NAME>` 适用于每个命名实例 |
| `HOTLINE_PROVIDERS` | 提供商列表,逗号分隔的 `kind[:instance]`(默认为 `telegram`) |
| `HOTLINE_BOT` | 命名机器人选择器,与 `--bot` 相同(旧版:`TELE_GO_BOT`) |
| `HOTLINE_STATE_DIR` | 状态目录覆盖(旧版:`TELE_GO_STATE_DIR`,然后 `TELEGRAM_STATE_DIR`) |
| `TELEGRAM_ACCESS_MODE` | `static` 快照访问启动;与 `allowlist` 一起使用(配对需要实时写入) |
| `DISCORD_BOT_TOKEN` | Discord 机器人令牌;`DISCORD_BOT_TOKEN_<NAME>` 适用于每个命名实例(`DISCORD_ACCESS_MODE` 镜像 Telegram 版本) |
| `SIGNAL_ACCOUNT` | 链接的 Signal 帐户(E.164);`SIGNAL_ACCOUNT_<NAME>` 适用于每个命名实例(`SIGNAL_ACCESS_MODE` 镜像 Telegram 版本) |
| `SIGNAL_DAEMON_URL` | signal-cli HTTP 守护进程基准 URL(默认为 `http://127.0.0.1:8080`);`SIGNAL_DAEMON_URL_<NAME>` 适用于每个命名实例 |
在操作上,hotline 保持其阵地:一个 PID 守护进程在启动前终止一个陈旧的轮询器(Telegram 允许每个令牌一个 `getUpdates` 消费者),轮询循环以指数方式退避并遵守 429,关闭在 stdin EOF、信号和孤立的看门狗之间统一。
## 协议
hotline 是一个标准 IO MCP 服务器(官方 `github.com/modelcontextprotocol/go-sdk`),额外声明 Claude Code 的实验性 `claude/channel` 功能,并使用令牌配置 `claude/channel/permission`。入站消息通过 `notifications/claude/channel` 到达 Claude,带有 `<channel source="telegram" ...>` 块;权限提示通过同一连接流向另一端。
该协议是实验性的,是 Claude Code 的专有协议。今天,这意味着 hotline 与 Claude Code 一起工作,而与其他协议不兼容。如果其他框架采用通道协议,或者 hotline 为它们增长适配器,则该协议会发生变化。
## 路线图
Discord 作为第二个提供程序,Signal 作为第三个。Matrix 正在考虑中。没有日期。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器