自建方案
tmux、mosh 与 Tailscale:在手机上使用编程智能体的自建方案
在手机上运行 Claude Code 或 Codex 的经典做法是:一个终端应用、一个私有网络、一条能扛住网络切换的连接,再加一个能扛住其他一切的会话。每一部分都免费,而且成熟可靠。下面给出带完整命令的配置方法,并如实说明它在哪些地方让人头疼。
简要回答
在服务器和手机上安装 Tailscale,然后开启 tailscale set --ssh,让服务器只能通过你的私有 tailnet 访问。在 tmux new -A -s main 里运行智能体,这样连接断开后它也不会停。为了 Claude Code,把 set -g allow-passthrough on 和 extended-keys 相关配置加入 ~/.tmux.conf。在 Blink、Termius 或 Termux 中用 mosh 连接(mosh dev@server -- tmux new -A -s main)。这套方案效果不错,弱点在于小屏幕上的全屏 TUI,以及除非你自己加钩子,否则没有推送通知。
如果你搜过怎么在手机上用 Claude Code,大概已经在十几篇博客里见过这套组合了。原因很简单:它确实管用。Tailscale 让手机通过一条私有的加密通道访问服务器,无需开放任何端口。mosh 能在你从 Wi-Fi 切到 4G 或锁屏时保持连接。tmux 则在连接真的断开时让智能体继续运行。下面介绍如何把三者正确地组合起来。
整体架构
| 层 | 工具 | 解决什么问题 | 什么情况下可以省略 |
|---|---|---|---|
| 网络 | Tailscale(Tailscale SSH) | 私密地访问服务器,即使在 NAT 后面也行;无需公开 SSH 端口;基于 SSO 的访问控制 | 服务器已有加固过的公网 SSH,而且你对此满意 |
| 传输 | mosh | 扛得住网络切换、休眠和信号差;本地回显掩盖延迟 | 你只在稳定的网络下连接 |
| 会话 | tmux | 断开连接后智能体继续运行;每个项目可开多个窗口 | 任何时候都不该省。这是最重要的一层。 |
| 客户端 | Blink、Termius、Termux… | 手机上的终端 | — |
配置 tmux
安装 tmux,并启动一个可以从任何地方重新接入的命名会话:
sudo apt install tmux # Debian/Ubuntu (dnf / apk elsewhere)
tmux new -A -s main # attach to "main", or create it
cd ~/src/my-app && claude # or: codex, agy, opencode…
# detach with Ctrl-b then d — the agent keeps running
有了 -A,同一条命令第一次和以后每次都能用,很适合在手机终端应用里存成一个快捷片段。接下来给 tmux 加上智能体需要的设置。Anthropic 的终端配置文档指出,在 tmux 里,Shift+Enter 会直接提交而不是换行,通知也永远到不了外层终端——除非你加上这几行:
# ~/.tmux.conf
set -g allow-passthrough on
set -s extended-keys on
set -as terminal-features 'xterm*:extkeys'
# quality of life on a phone
set -g mouse on # scroll and pick panes with your finger
set -g history-limit 50000 # agents print a lot
用 tmux source-file ~/.tmux.conf 让配置生效。即使开启了扩展按键,很多手机键盘也根本发不出 Shift+Enter。Claude Code 还支持用 Ctrl+J,或 \ 加回车来换行,两者在任何终端里都能用。
每个项目或每个智能体用一个 tmux 窗口。Ctrl-b c 新建窗口,Ctrl-b n 切到下一个。如果同一个代码仓库要开多个会话,就给每个会话分配独立的 git worktree。24/7 运行指南介绍了这一点以及重启时会发生什么。tmux 会话扛不住重启。
mosh 与 ssh
普通 SSH 跑在一条 TCP 连接上。手机切换网络,或者 iOS 把应用挂起一段时间,这条连接就断了,你得重新连接、重新接入。mosh 先通过 SSH 登录,在服务器上启动 mosh-server,然后切换到自己的 UDP 协议,能在 IP 变化和休眠后继续工作。它还会在本地回显你的输入,所以 200 ms 的延迟用起来也很跟手。
# on the server
sudo apt install mosh # Fedora: sudo dnf install mosh · Alpine: apk add mosh
# from a client
mosh dev@my-server -- tmux new -A -s main
mosh 使用 UDP 端口 60000–61000。如果走公网 IP,你需要在防火墙中开放这些端口,例如 sudo ufw allow 60000:61000/udp,云服务商的防火墙也要放行。通过 Tailscale 时流量留在 tailnet 内部,不需要任何公开端口。有一个局限:mosh 只同步当前可见的屏幕,所以 mosh 本身没有回滚历史。mosh 自己的文档也建议用 tmux 或 screen 来保留历史,这又是两者搭配使用的一个理由。
Tailscale SSH
Tailscale 把你的服务器和手机放进一个私有的 WireGuard 网络(即 tailnet)。Tailscale SSH 更进一步:由 Tailscale 用你的 tailnet 身份完成 SSH 认证,所以你根本不需要分发 SSH 密钥。
# on the server (Linux)
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up # log in to your tailnet
sudo tailscale set --ssh # enable Tailscale SSH
根据 Tailscale 的文档,tailscale set --ssh 会让 tailscaled 接管来自你 tailnet 的 22 端口流量。之后任何普通 SSH 客户端都可以用机器的 MagicDNS 名称,通过 ssh dev@my-server 连接。一些细节:
- 检查模式。默认策略使用
"action": "check",所以你会不时被要求在浏览器中重新认证。终端里出现登录链接是正常的。 - 服务器平台。Linux 完全支持。在 macOS 上,只有开源的
tailscale+tailscaledCLI 版本才能充当 Tailscale SSH 服务器,所以装了 App Store 版应用的 Mac mini 应该通过 tailnet 使用普通 SSH。 - 关闭公网端口。确认能通过 tailnet 访问服务器后,在服务商的防火墙中关闭公网 22 端口。务必按这个顺序操作,并保持另一个会话开着,以免把自己锁在外面。
在手机上安装 Tailscale 应用,登录同一个 tailnet 并保持连接。之后你的终端应用就能像访问局域网一样访问 my-server。
iOS 和 Android 客户端
| 客户端 | 平台 | mosh | 说明 |
|---|---|---|---|
| Blink Shell | iPhone、iPad | 支持 | 围绕 mosh 打造;在 iPad 上对硬件键盘支持出色。据 blink.sh,两周试用后为 $19.99/年。 |
| Termius | iOS、Android、桌面端 | 支持 | 免费的 Starter 版包含 SSH 和 mosh;跨设备同步需要 Pro(据 termius.com/pricing,按年付费合 $10/月) |
| Termux | Android | 支持(pkg install openssh mosh) | 手机上的完整 Linux 用户空间;免费开源 |
| JuiceSSH | Android | 支持 | mosh.org 将其列为 mosh 客户端 |
无论选哪个客户端,都要设置一行包含 Esc、Ctrl、Tab 和方向键的额外按键。Claude Code 用 Esc 中断操作,用 Shift+Tab 切换权限模式,而手机自带的键盘上这两个都没有。
痛点在哪里
这套方案本身很可靠。麻烦出在可靠性之外的所有地方。
- 6 英寸屏幕上的桌面 TUI。Claude Code、Codex 和 agy 都是为 100 列以上的终端设计的。在手机上,你得看折行的 diff,用拇指滚动工具输出,还要四处找输入行。
- 没有推送通知。智能体完成任务或需要批准时,除非你加了钩子,否则什么都不会提醒你。终端只在应用处于前台时才能通知你。我们的在手机上批准权限请求指南介绍了大家额外加装的 ntfy 钩子。
- 审批淹没在滚动历史里。权限请求只是繁忙窗格中的几行字。过一小时再回来,你得先找到它、读完,再用方向键作答。
- 后台问题。你一离开终端应用,iOS 很快就会把它挂起。回来时 mosh 能恢复连接,但应用在后台时没法替你盯着会话。
- 复制粘贴。在 tmux、mosh 和手机终端之间选择文本非常痛苦。长 URL(比如登录链接)是最糟糕的情况。
- 多台服务器、多个智能体。每多一台服务器,就多一个 Tailscale 节点、一条主机记录和一套要记住的 tmux 布局。
这些都不是放弃这套方案的理由。它免费,适用于所有智能体,每一部分都由你掌控。只是你应该清楚自己选的是什么。我们的 SSH 终端应用与 Maude 对比详细讨论了其中的取舍。
或者用一个专门为此打造的应用
在智能体工作上,Maude 取代了客户端层和会话层。服务器上的一个小型守护进程持有会话,所以不用 tmux 它们也能持续运行;应用把它们显示为聊天界面,附带工具卡片、diff、带“允许 / 拒绝”的推送通知和收件箱。你可以继续用 Tailscale:Maude 支持 tailnet 和局域网内的服务器,因为服务器会主动连接 Maude 的中继,SSH 作为备用方式。需要 shell 时,每个会话都有一个真正的终端。它支持 Claude Code、Codex、OpenCode、Grok Build 和 Antigravity。
常见问题
Claude Code 该用 tmux 还是 screen?
allow-passthrough 和 extended-keys),它更容易分屏和编写脚本,而且大多数手机终端教程都默认使用它。