cc-haha/docs/en/desktop/06-h5-access.md
2026-07-23 20:46:33 +08:00

4.2 KiB

H5 Access

H5 is an optional browser entry point to the same local chat UI used by Desktop. It is intended for a trusted LAN or a reverse proxy you control.

It is not a public SaaS authentication system. Anyone with the reachable service URL and current H5 token can access the exposed chat capabilities.

Enable H5

  1. Open Settings → H5 Access.
  2. Enable H5.
  3. Generate a token.
  4. Set the LAN access host or public base URL used to generate a launch link and QR code.
  5. Choose the current port, or configure a fixed port when you need a stable bookmark or reverse proxy.

Desktop same-origin access automatically allows the origin derived from the configured public base URL. allowedOrigins is an advanced local-server API option for custom cross-origin deployments; it is not a field in the Desktop H5 settings page.

For a same-origin LAN deployment, a typical public base URL is:

http://192.168.1.20:3456

The generated launch URL contains the server URL and token. Treat it like an API credential and do not post it publicly.

H5 settings are stored in ~/.claude/cc-haha/settings.json. The full token is persisted so paired devices can reconnect after restart. Only trusted local control surfaces should be able to read it back.

Enable H5 without the Desktop UI

Build the Web UI, then start the server from the repository root:

cd desktop
bun run build
cd ..
SERVER_HOST=0.0.0.0 SERVER_PORT=3456 bun run src/server/index.ts

The server serves desktop/dist. If it is started outside the repository root, set CLAUDE_H5_DIST_DIR to the absolute desktop/dist path.

From another terminal on the server itself, generate a token:

curl -sS -X POST http://127.0.0.1:3456/api/h5-access/enable

Configure exact origins and an optional public base URL:

curl -sS -X PUT http://127.0.0.1:3456/api/h5-access \
  -H 'Content-Type: application/json' \
  --data '{
    "allowedOrigins": ["https://cc.example.com"],
    "publicBaseUrl": "https://cc.example.com"
  }'

Read the current configuration and full token only from server loopback:

curl -sS http://127.0.0.1:3456/api/h5-access

If SSH port forwarding is sufficient, keep the service on 127.0.0.1 and use the headless installation path instead of enabling H5.

Browser launch URL

For same-origin hosting, the page and API share the public server root:

https://cc.example.com/?serverUrl=https%3A%2F%2Fcc.example.com

The generated QR link also includes h5Token. On first connection, a manually opened page can ask for:

Field Meaning
Server URL Reachable Desktop server or reverse-proxy URL
H5 Token Current token generated by the trusted local settings surface

The browser stores the Server URL and token in its local storage and sends authorization with REST and WebSocket traffic.

Reverse proxy requirements

Use HTTPS and proxy all required routes, including:

  • /api/*
  • /proxy/*
  • /ws/* with WebSocket upgrade
  • the built Web UI

Preserve the public Host and normal proxy information. For example:

proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

Do not rewrite Host to loopback while stripping every forwarding header. The server needs enough information to distinguish a remote proxied request from a trusted local request.

Mobile scope

H5 prioritizes the chat flow:

  • session navigation uses a compact drawer;
  • composer, stop, attachments, and permission actions remain touch accessible;
  • @ file results adapt to mobile width;
  • desktop-only workspace and terminal panels are not the primary mobile surface;
  • Desktop pets do not run in H5.

Security checklist

  • Keep H5 disabled unless it is needed.
  • Use exact allowed origins; do not use a wildcard.
  • Use HTTPS outside a trusted LAN.
  • Share the token separately from the public URL.
  • Regenerate the token when access should be revoked.
  • Do not expose H5 directly to the public internet as if it were a multi-user account service.

Disabling H5 blocks remote access but keeps the current token for a later re-enable. Regenerating the token revokes the old token and QR links immediately.