内容
align="center">
# 📨 tgctl-claude-channel
**通过 Telegram 驱动 Claude Code 代理** — 文本、投票、按钮、媒体和工具审批,都可以在手机上进行。
[](https://github.com/jjuanrivvera/tgctl-claude-channel/actions/workflows/ci.yml)
[](https://github.com/jjuanrivvera/tgctl-claude-channel/releases)
[](https://goreportcard.com/report/github.com/jjuanrivvera/tgctl-claude-channel)
[](go.mod)

[](LICENSE)
[](https://docs.claude.com/en/docs/claude-code)
</div>
一个 [Claude Code 通道](https://docs.claude.com/en/docs/claude-code),它连接了一个 Telegram 机器人到一个 Claude Code 会话 — 通过手机驱动一个持久的代理,拥有完整的交互式工具箱和设备上的权限审批。
它是一个小型 **MCP stdio 服务器**:当您给机器人发送消息时,它会将消息转发到您的 Claude Code 会话;助手回复、反应、发送投票、按钮、媒体,并请求工具权限 — 所有这些都通过 Telegram 进行。每个 Telegram通过 [`tgctl`](https://github.com/jjuanrivvera/tgctl) 命令行界面进行,因此这个过程不会重新实现任何 逻辑,也不会持有令牌本身。
```
Telegram · 您的机器人
│ ▲
入站 │ │ 出站(回复/投票/照片/反应/...)
(长)│ │ + 权限提示
▼ │
┌──────────────────────────────────────────────┐
│ tgctl-claude-channel (MCP stdio 服务器) │
│ • 发送者网关(配对/允许列表) │
│ • 入站 → 通知/claude/channel │─┐ 每次调用
│ • 工具 → tgctl(消息/媒体/API) │ │ 通过
│ • 权限中继 → 在 Telegram 上允许/拒绝 │─┘ tgctl 命令行界面──────────────────────────────────────────────┘
│
▼
Claude Code 会话
```
## 功能
- **双向消息传递**。文本和媒体作为频道回合到达;助手通过文本、内联 **按钮**、**投票**、**骰子**、照片、文档、反应、编辑和固定进行回复。
- **交互式按钮**。提供可点击的选择;点击返回一个回合,因此您可以构建菜单和确认。
- **附件**。入站照片被下载,以便读取它们;文档、音频和视频按需获取。
- **在您的手机上审批权限**。当助手想要使用工具时,您会在 Telegram 上收到 **允许 / 拒绝** 提示 — 因此它在权限沙盒中运行,无需不安全的标志。
- **访问控制**。(无需复制数字 ID)、一个允许列表来锁定和每个提及门控。
- **存在**。在收到时已查看”的反应,并且在助手工作时显示实时的“…”指示器。
## 快速设置
1. **创建机器人**,使用 [@BotFather](https://t.me/BotFather) (`/newbot`) 并复制令牌。
2. **安装 `tgctl`** 并使用该令牌进行身份验证 (`tgctl auth login`)。
3. **在此项目的 `.mcp.json` 中注册此服务器**:
```jsonc
{ "mcpServers":tgctl-claude-channel "command":/to/tgctl-claude-channel" } } }
. **使用通道启动**(首先导出配置):
```sh
export_TOKEN=123456789... # 机器人,tgctl 使用
cldangerously-load-development-ch:tgctl-cl
```
5. **配对**。给您的机器人发送私信 — 它会回复一个 6 位字符的代码。在 Claude Code该代码将自己添加到允许列表中,然后再次给机器人;它就会到达助手那里。
有关始终在线的 VPS 部署(systemd,无头启动),请参见 [`deploy/DEPLOY.md`](deploy/DEPLOY.md)。
## 配置
| 变量 | 是否必需 | 含义 |
|---|---|---|
| `TGCTL_TOKEN` | 是 | 机器人令牌,传递给 `tgctl`(从不记录)。 |
| `TGCTL_CHANNEL_ALLOW` | 否 | 以逗号分隔的 Telegram `user_id`,首次运行时播种允许列表。 |
| `TGCTL_CHANNEL_STATE_DIR` | 否 | `access.json`、收件箱和投票游标存储的位置(默认为 `~/.config/tgctl-claude`)。 |
| `TGCTL_CHANNEL_ACK_REACTION` | 否 | 收到消息时设置的表情符号反应(默认为 `👀`;设置为空以禁用)。 |
| `TGCTL_BIN` | 否 | `tg 二进制文件的路径(默认为 `tgctl`)。 |
##公开的工具
| 工具 | 用途 |
|---|---|
| `reply` |(自动拆分超过 Telegram 限制)。可选内联 **按钮**、文件附件(图像作为照片,其他作为文档)、`parse_mode` 和 `reply_to`。 |
| `react` / `edit` | 使用表情符号反应;编辑机器人发送的消息(进度更新)。 |
| `poll` | 发送原生投票。 |
| `photo` / `document` | 通过 URL、`file_id` 或本地路径发送媒体。dice`、`pin`、`unpin` | 动画骰子;固定/取消固定消息。 |
| `answer_callback` | 回答按钮点击(或警报)。 |
| `download_attachment` | 通过 `file_id` 获取入站附件到本地收件箱,准备读取。 |
## 访问控制
入站消息通过 **发送者的 `user_id`** 进行控制 — 在发出回合之前会丢弃其他所有内容。三种策略:
- **`pairing`**(默认):未知私信会收到一次性代码;操作员批准它以将发送者添加到允许列表中。
- **`allowlist`**:只有列出的 `user_id` 通过;陌生人被静默丢弃。
- **群组**:每个群组选择加入,具有可选的每个群组允许列表和提及要求(机器人仅在被提及时才回答)。
状态存储在 `access.json` 下的状态目录中。出站工具也会受到限制 — 助手只能发送它可以接收的聊天。
## 为什么通过 `tgctl` 路由?
机器人的整个功能集 — 投票、骰子、内联键盘、媒体、文件下载、反应、固定、回调答案 — 只是 [`tgctl`](https://github.com/jjuanrivvera/tgctl) 命令。该通道构建请求并执行;`tgctl` 拥有 Bot-API 接口、凭证(OS 密钥环)和重试。因此,该通道是一个薄的、单一的静态 Go 二进制文件(无需安装运行时),整个 Telegram 工具箱基本上是免费的,`tgctl` 获得的任何动词在此处都立即可用。
##轮询意味着公共端点** —连接到 Telegram,因此没有 Webhook 可以攻击。防御依赖于 **发送者允许列表**( — 它从不开放运行)加上 `tgctl` 拥有令牌(此进程从不直接触摸 Bot API)。工具审批被中继到操作员的设备,因此代理保持其权限沙盒。
## 开发
```sh
make verify # gofmt + go vet + golangci-lint + 测试(竞争)+ 覆盖限
make hooks # 安装预提交钩子
```
MIT 许可。