自作スタック
tmux、mosh、Tailscale:スマホでコーディングエージェントを使う自作スタック
スマホから Claude Code や Codex を動かす定番の方法は、ターミナルアプリ、プライベートネットワーク、ローミングしても切れない接続、そしてそれ以外のすべてを乗り越えるセッションの組み合わせです。どれも無料で、よく知られた道具です。正確なコマンド付きのセットアップと、どこがつらくなるかの正直な評価を紹介します。
簡単な答え
サーバーとスマホに Tailscale をインストールし、tailscale set --ssh を有効にして、サーバーにはプライベートな tailnet からしか届かないようにします。接続が切れても生き残るよう、エージェントは tmux new -A -s main の中で動かします。Claude Code のために、~/.tmux.conf に set -g allow-passthrough on と extended-keys の行を追加します。Blink、Termius、Termux から mosh(mosh dev@server -- tmux new -A -s main)で接続します。これでうまく動きます。弱点は、小さな画面でのフルスクリーンの TUI と、フックを追加しない限りプッシュ通知がないことです。
スマホから Claude Code を使う方法を検索したことがあるなら、このスタックを十数個のブログ記事で目にしているでしょう。それは実際にうまくいくからです。Tailscale は、ポートを開けずに、スマホからサーバーへのプライベートで暗号化された経路を作ります。mosh は、Wi-Fi から 4G に切り替えたりスマホをロックしたりしても接続を保ちます。tmux は、それでも接続が切れたときにエージェントを動かし続けます。この 3 つをきちんと組み合わせる方法を紹介します。
スタックの構成
| 層 | ツール | 解決すること | 省略してよい場合 |
|---|---|---|---|
| ネットワーク | Tailscale(Tailscale SSH) | NAT の内側でもサーバーにプライベートにアクセス。公開の SSH ポートは不要。SSO によるアクセス | サーバーにすでに堅牢化された公開 SSH があり、それで満足している |
| トランスポート | mosh | ローミング、スリープ、弱い電波を乗り越える。ローカルエコーで遅延を隠す | 安定したネットワークからしか接続しない |
| セッション | tmux | 切断してもエージェントが動き続ける。プロジェクトごとに複数のウィンドウ | 省略不可。いちばん重要な層 |
| クライアント | Blink、Termius、Termux など | スマホのターミナル | — |
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 で反映します。extended-keys を有効にしても、多くのスマホのキーボードはそもそも Shift+Enter を送れません。Claude Code は改行として Ctrl+J、または \ のあとに Enter も受け付け、どちらもどのターミナルでも使えます。
tmux のウィンドウは、プロジェクトごと、またはエージェントごとに 1 つ使いましょう。Ctrl-b c で新しいウィンドウを開き、Ctrl-b n で次のウィンドウに移ります。同じリポジトリで複数のセッションを動かすなら、それぞれに専用の git worktree を割り当ててください。そのことと再起動時に起きることは、24 時間稼働のガイドで解説しています。tmux のセッションは再起動を乗り越えられません。
mosh と ssh
素の SSH は 1 本の 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 の中に留まるので、公開ポートは不要です。制限が 1 つあります。mosh が同期するのは見えている画面だけなので、mosh 自体ではスクロールバックできません。mosh 自身のドキュメントも履歴には tmux か screen を勧めており、両方を使う理由がもう 1 つ増えます。
Tailscale SSH
Tailscale は、サーバーとスマホをプライベートな WireGuard ネットワーク(tailnet)に参加させます。Tailscale SSH はさらに一歩進んで、tailnet の ID で SSH の認証を Tailscale が処理するので、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 を実行すると、tailnet から来る通信について tailscaled がポート 22 を引き受けます。あとは普通の SSH クライアントから、マシンの MagicDNS 名を使って ssh dev@my-server で接続できます。いくつか補足します。
- チェックモード。デフォルトのポリシーは
"action": "check"を使うので、ときどきブラウザで再認証を求められます。ターミナルにログイン URL が表示されるのは想定どおりです。 - サーバーのプラットフォーム。Linux は完全にサポートされています。macOS では、オープンソースの
tailscale+tailscaledの CLI 版だけが Tailscale SSH のサーバーになれるので、App Store 版のアプリを入れた Mac mini では、tailnet 越しに通常の SSH を使ってください。 - 公開ポートを閉じる。tailnet 越しにマシンに届くことを確認できたら、プロバイダーのファイアウォールで公開のポート 22 を閉じます。締め出されないよう、2 つ目のセッションを開いたまま、この順番で行ってください。
スマホでは Tailscale アプリをインストールし、同じ tailnet にサインインして、接続したままにしておきます。するとターミナルアプリから、ローカルネットワーク上にあるかのように my-server に届きます。
iOS と Android のクライアント
| クライアント | プラットフォーム | mosh | 備考 |
|---|---|---|---|
| Blink Shell | iPhone、iPad | 対応 | mosh を中心に作られている。iPad ではハードウェアキーボードへの対応が充実。blink.sh によると、2 週間のトライアル後に年 $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 桁以上を前提に作られています。スマホでは、折り返された差分を読み、ツールの出力を親指でスクロールし、入力行を探すことになります。
- プッシュ通知がない。エージェントが終わっても承認を求めても、フックを追加しない限り何も知らせてくれません。ターミナルが通知するのはアプリが前面にあるときだけです。後付けの ntfy フックはスマホから確認に答えるガイドで解説しています。
- スクロールバックに埋もれる承認。権限の確認は、慌ただしいペインの中の数行にすぎません。1 時間後に戻ってきたら、それを探し、読み、矢印キーで答える必要があります。
- バックグラウンドの問題。iOS は、ターミナルアプリから離れるとすぐに一時停止させます。戻れば mosh は回復しますが、バックグラウンドにいる間、アプリがセッションを見張っていてくれることはありません。
- コピー&ペースト。tmux、mosh、スマホのターミナルをまたいでテキストを選択するのは大変です。ログインリンクのような長い URL は最悪のケースです。
- 複数のサーバー、複数のエージェント。マシンが増えるたびに、Tailscale のノード、ホストのエントリー、覚えておくべき tmux のレイアウトも増えます。
どれも、このスタックを避ける理由にはなりません。無料で、どのエージェントでも使え、すべての部品を自分で制御できます。ただ、何を引き受けることになるかは知っておくべきです。トレードオフの詳細は SSH ターミナルアプリと Maude の比較で解説しています。
あるいは、専用のアプリを使う
Maude は、エージェントの作業におけるクライアントとセッションの層を置き換えます。サーバー上の小さなデーモンがセッションを所有するので tmux なしでも動き続け、アプリはそれをチャットとして表示し、ツールカード、差分、許可/拒否付きのプッシュ通知、受信箱を備えています。Tailscale はそのまま使えます。サーバーから Maude のリレーへ接続し、SSH をフォールバックにするので、Maude は tailnet や LAN 上のサーバーでも動きます。シェルが必要なときは、各セッションに本物のターミナルがあります。Claude Code、Codex、OpenCode、Grok Build、Antigravity に対応しています。
よくある質問
Claude Code には tmux と screen のどちらがいいですか?
allow-passthrough と extended-keys)をドキュメント化しており、分割やスクリプト化もしやすく、スマホのターミナルのガイドの多くも tmux を前提にしています。