English install path

Quickstart

Self-hosted mobile Web UI for your real local claude CLI—same agent, same CLAUDE.md, same session. Not a remote desktop, not multi-tenant SaaS.

Source of truth: README.en.md · Full Chinese handbook: docs-site ·

Prerequisites

Official subscription or third-party gateway Web inherits provider settings from the shell that starts the server. Official subscription: no extra env. Gateway/relay: export the required ANTHROPIC_* in that shell, then start. Values in .env for ANTHROPIC_* are stripped at startup and have no effect.

Install and start

  1. Clone and verify the host.
    git clone https://github.com/Ike-li/claude-chat-mobile.git
    cd claude-chat-mobile
    node --version           # need Node ≥ 20
    which claude             # must be installed & logged in
  2. Install runtime deps and run setup.
    npm install --omit=dev   # runtime only; full install if you run UI tests
    npm run setup            # generates AUTH_TOKEN, asks WORK_DIR, writes .env (mode 0600)
    # or: cp .env.example .env and edit by hand
  3. Pre-flight check.
    node scripts/doctor.js
    node scripts/doctor.js --fix  # tighten .env and data JSON → 0600
  4. Start the server.
    npm start                 # http://localhost:3000
    # startup log prints usable URLs with #token=…

Reach it from your phone

ScenarioWhat to do
Same Wi‑Fi Set a non-empty AUTH_TOKEN in .env, then open the LAN URL from the startup log: http://<lan-ip>:3000/#token=…. Without a token the server binds 127.0.0.1 only—phones cannot connect (intentional).
Temporary public / PWA https In another terminal: cloudflared tunnel --url http://localhost:3000. Open the random HTTPS host with #token=. Token is stored in localStorage on first load, then cleared from the address bar.
Fixed production Named tunnel + Cloudflare Access 2FA + a long-running process. See the Chinese handbook page 生产部署 and repo docs/deployment.md.

First non-local connection: device trust (TOFU)

A valid token alone is not enough for the first non-loopback client. Approve the device once on the host:

node scripts/device.js list
node scripts/device.js approve <ID>
Security This is a remotely reachable code-execution channel into your shell. Single-user per instance. Read the security model before exposing anything beyond your LAN: English Security Model · 中文安全模型 · README.en.md.

Security iron rules (quotable)

  1. One user per instance — not multi-tenant SaaS; anyone who passes auth has terminal-equivalent power.
  2. No AUTH_TOKEN → bind 127.0.0.1 only — phones and tunnels cannot reach it until you set a token.
  3. CLI allow-list is inherited — no second “Web super-allowlist”; audit ~/.claude/settings.json before public exposure.
  4. Device trust (TOFU) — first non-local client needs device.js approve (Access JWT can skip).
  5. Not Anthropic’s official app — independent open source; drives your local CLI via the Claude Agent SDK.

Full write-up: English Security Model.

If something fails

SymptomLikely causeWhat to try
Phone cannot open the page on LAN No AUTH_TOKEN (server on loopback only) Set token in .env, restart, use the URL with #token=… from the log
Token works but UI stays locked Device TOFU pending node scripts/device.js list then approve <ID> on the host
doctor flags gateway / model ANTHROPIC_* only in .env Export vars in the same shell that runs npm start
Port 3000 already in use Existing daemon or old process Do not stack a second npm start; stop the resident service or change PORT
claude missing / not logged in Host CLI not ready Fix which claude and open a terminal conversation first

Optional

Already running a production daemon on port 3000? Do not start a second npm start against the same port for “just checking.” Use the Chinese ops page 运维与排错 or stop the daemon first.

Next