我手机上想用 Claude Code 这事折腾了半年。
说白了 5 件事得满足:Claude Code 和 Codex 都得能用、Mac 和手机的会话要连得上、服务端得自己说了算、别让我在手机上敲 terminal、相册里的图能直接发。
我把 GitHub 翻了一圈,能全做到的就一个:slopus/happy。
为啥国内用户我会特意推荐这个。Claude 官方的 iOS app、Codex 官方 app 都是直连 Anthropic 和 OpenAI 的,手机上不挂 VPN 根本打不开。Happy 不一样,手机只跟你自己的服务器说话,服务器放国内(阿里云、腾讯云、家里 NAS 走公网穿透都行),跨境那一段是 Mac 帮你扛了。所以手机上你什么也不用做,地铁里掏出来就能用。
选型
我对比过这几个:
| 项目 | 我的 5 项 | Stars | E2E 加密 | 备注 |
|---|---|---|---|---|
| slopus/happy | 5/5 | 20.9k | AES-256-GCM | iOS 原生 + CLI + Web |
| siteboon/claudecodeui | 4/5 | 11.1k | — | 100% 自托管 PWA,跨设备要自己解决 |
| amantus-ai/vibetunnel | 3/5 | 4.5k | — | 终端转发,UI 还是 terminal |
| JessyTsui/Claude-Code-Remote | 2/5 | 1.2k | — | 邮件/IM 桥,异步模式 |
Happy 还有一个我比较在乎的点是 E2E 加密。message 和 file 在客户端 AES-256-GCM 加密好了才上传,服务端拿到的就是它自己也解不开的密文。所以即便你暂时还没自托管,先用官方的服务也不慌。
架构
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
│ iOS App │◀───WSS──│ happy-server │──WSS───▶│ Mac daemon │
│ │ E2E │ + PG + Redis │ E2E │ + CC/Codex │
└─────────────┘ └──────────────────┘ └─────────────┘
你自己的 VPS
Mac 上 happy daemon start-sync 这个常驻进程盯着本地的 Claude Code / Codex session,加密之后推到服务器。iOS 端从服务器拉密文回来本地解密渲染。服务器本身根本不知道你们在聊啥。
部署同步服务器
一台 2GB 的 VPS 就够,我自己跑下来内存稳定在 80MB 以内。前置假设你有 Ubuntu 22.04+,装好了 PostgreSQL、Redis、nginx、Node 20+。
1. 拉源码 + 建 PG
cd ~
git clone https://github.com/slopus/happy.git happy-server
sudo -u postgres psql <<'SQL'
CREATE USER happy_user WITH PASSWORD '<强密码>';
CREATE DATABASE happy_db OWNER happy_user;
SQL
happy 仓库是 monorepo,我们要的服务端在 packages/happy-server/ 这个子包里。
2. 写 .env.production
packages/happy-server/.env.production:
NODE_ENV=production
PORT=3005
DB_PROVIDER=postgres
DATABASE_URL=postgresql://happy_user:<密码>@127.0.0.1:5432/happy_db
REDIS_URL=redis://:<redis密码>@127.0.0.1:6379/3
HANDY_MASTER_SECRET=<openssl rand -hex 32>
PUBLIC_URL=https://happy.example.com
说明一下:HANDY_MASTER_SECRET 是服务端自己签 token 用的密钥,不是用来加解密用户数据的。用户数据该怎么加密还是怎么加密。
3. 装依赖 + 跑 migration
cd ~/happy-server
pnpm install
cd packages/happy-server
pnpm prisma migrate deploy
4. systemd 单元
/etc/systemd/system/happy-server.service:
[Unit]
Description=happy-server (Happy Coder sync server, E2E encrypted)
After=network.target postgresql.service redis-server.service
[Service]
Type=simple
User=deploy
Group=deploy
WorkingDirectory=/home/deploy/happy-server/packages/happy-server
EnvironmentFile=/home/deploy/happy-server/packages/happy-server/.env.production
Environment="PATH=/home/deploy/.nvm/versions/node/v20.20.2/bin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/home/deploy/.nvm/versions/node/v20.20.2/bin/pnpm start
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/deploy/happy-server
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictNamespaces=true
LockPersonality=true
RestrictRealtime=true
RestrictSUIDSGID=true
MemoryMax=256M
[Install]
WantedBy=multi-user.target
5. nginx vhost(WebSocket 反代)
server {
server_name happy.example.com;
location /.well-known/acme-challenge/ { root /var/www/html; }
location / {
proxy_pass http://127.0.0.1:3005;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket upgrade(Happy 的实时同步走 WS)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
client_max_body_size 100M;
}
listen 80;
}
这里 WS upgrade header 千万别漏。漏了的话表现特别迷惑:连接是上的,消息就是不来,也不报错。我第一次部署就在这卡了半小时。
6. 起服务 + 上证书
sudo systemctl daemon-reload
sudo systemctl enable --now happy-server
sudo certbot --nginx -d happy.example.com
# 验证
curl -sI https://happy.example.com | head -1
sudo systemctl status happy-server
Mac 端:CLI + LaunchAgent 开机自启
npm install -g happy-coder
export HAPPY_SERVER_URL=https://happy.example.com # 写进 ~/.zshrc
happy # 第一次会弹 QR,用 iOS app 扫码配对
每次开机都要手动跑一遍太烦了,封成 LaunchAgent 让它自己跑。~/Library/LaunchAgents/net.example.happy-daemon.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>net.example.happy-daemon</string>
<key>ProgramArguments</key>
<array>
<string>/Users/yourname/.nvm/versions/node/v22.15.1/bin/happy</string>
<string>daemon</string>
<string>start-sync</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>ThrottleInterval</key><integer>10</integer>
<key>EnvironmentVariables</key>
<dict>
<key>HAPPY_SERVER_URL</key><string>https://happy.example.com</string>
<key>PATH</key><string>/Users/yourname/.nvm/versions/node/v22.15.1/bin:/usr/local/bin:/usr/bin:/bin</string>
<key>HOME</key><string>/Users/yourname</string>
</dict>
<key>StandardOutPath</key><string>/Users/yourname/.happy/logs/launchagent-stdout.log</string>
<key>StandardErrorPath</key><string>/Users/yourname/.happy/logs/launchagent-stderr.log</string>
<key>WorkingDirectory</key><string>/Users/yourname</string>
<key>ProcessType</key><string>Background</string>
</dict>
</plist>
launchctl load ~/Library/LaunchAgents/net.example.happy-daemon.plist
launchctl list | grep happy
ProgramArguments第一个值一定要写 happy 的绝对路径。LaunchAgent 是不读~/.zshrc的,PATH 默认是空的。如果你用 nvm,每次升 Node 版本这条路径就废了,记得回来改一下 plist。
iOS 端
App Store 搜 “Happy Coder”。注意国区还没上架,得切到美区或港区 Apple ID 才下得到(顺便说一句,Claude 和 Codex 官方 app 国区下不到,也是因为这个)。
装好后进 Settings,找到 “Relay Server URL” 这一项(app 里写的是这个英文,意思就是你刚搭的同步服务器),填上 https://happy.example.com。然后在 Mac 上跑 happy auth 会弹个二维码,30 秒内扫掉就配上了。
配好之后 iOS 里就能直接看到 Mac 上正在跑的会话,续聊、传图、传文件都行。
维护
更新我一般一两周做一次:
cd ~/happy-server && git pull
pnpm install
cd packages/happy-server && pnpm prisma migrate deploy
sudo systemctl restart happy-server
备份的话,所有用户数据(虽然都是加密的)都在 happy_db 这个数据库里,我自己已经有 pg_dumpall 的 cron,加一个不加一个都一样,自动备进去了。
要看日志:
sudo journalctl -u happy-server -f
tail -f ~/.happy/logs/launchagent-stderr.log # Mac 端
用了一阵之后
「手机上用 AI Coding」这件事其实有好几条路,我都试过:
| 方案 | 手机要挂 VPN? | 手机端 UX |
|---|---|---|
| Claude 官方 iOS app | 要 | 只能聊 claude.ai 本身,没法接本地工程 |
| Codex 官方 iOS app | 要 | 同上 |
| Termius / Blink SSH 进 Mac | 不要 | 在手机上敲 terminal,传图传文件很别扭 |
| Tailscale + web IDE | 不要 | 浏览器里凑合用,不是原生 app |
| Happy Coder + 国内服务器 | 不要 | iOS 原生 chat,接本地 CC/Codex,相册直传 |
Happy 比较合我胃口的地方是,本地 AI 工具的能力没缩水,手机上又不用挂 VPN,UX 还是 iOS 原生 app 的感觉。这三件事我之前一直没找到能同时给齐的方案。
什么人适合用:你本来就在 Mac 上跑 Claude Code 或 Codex CLI,想多设备切来切去;或者你不想把代码会话过第三方 SaaS;又或者你想给团队几个人搭一台共享的同步服务器,每人独立账号互相看不到。一台便宜的国内 VPS(2 核 2G 那种最低配)就够了。
什么人不适合:你从来只在 Mac 前面用,那 Happy 对你就是多余的一层;你想要的是浏览器里写代码跑命令那种 web IDE,可以看看 siteboon/claudecodeui;你既不想自托管又对官方服务不放心,那干脆别用更省事。
最后说一句心里话。我本来是想自己做一个翻译层 + 移动端 chat UI 的小产品,调研完才发现,认真做出一个能用的东西要 2 个月起,而 Happy 已经有 20.9k stars 在那里了,我做不到比它更好。后来把那两个月省下来,自己的服务器 10 分钟就搭好了,每个月也基本不用维护。
相关:
- 项目:github.com/slopus/happy
- 文档:happy.engineering/docs
- 替代品:siteboon/claudecodeui(11.1k)、amantus-ai/vibetunnel(4.5k)、JessyTsui/Claude-Code-Remote(1.2k)
评论 · Comments
评论由 Giscus 提供,需用 GitHub 账号登录;留言会同步到这个仓库的 Discussions 里。