- Replace outdated WEBAPP_URL with HAPI_PUBLIC_URL in server and web READMEs - Add CLI version verification steps in prerequisites section - Enhance Cloudflare Tunnel documentation with quick and named tunnel examples - Add --protocol http2 recommendation for tunnel stability - Include pm2 alternative for runner process management - Add Telegram Mini App troubleshooting notes and verification steps
6.2 KiB
Installation
Install the HAPI CLI and set up the server.
Prerequisites
- Claude Code, OpenAI Codex CLI, or Google Gemini CLI installed
Verify your CLI is installed:
# For Claude Code
claude --version
# For OpenAI Codex CLI
codex --version
# For Google Gemini CLI
gemini --version
Install the CLI
npm install -g @twsxtd/hapi
Or with Homebrew:
brew install tiann/tap/hapi
Other install options
npx (no install)
npx @twsxtd/hapi
Prebuilt binary
Download the latest release from GitHub Releases.
xattr -d com.apple.quarantine ./hapi
chmod +x ./hapi
sudo mv ./hapi /usr/local/bin/
Build from source
git clone https://github.com/tiann/hapi.git
cd hapi
bun install
bun build:single-exe
./cli/dist/hapi
Server setup
The server can be deployed on:
- Local desktop (default) - Run on your development machine
- Remote server - Deploy on a VPS, cloud server, or any machine with network access
Default: Public Relay (recommended)
hapi server --relay
The terminal displays a URL and QR code. Scan to access from anywhere.
- End-to-end encrypted with WireGuard + TLS
- No configuration needed
- Works behind NAT, firewalls, and any network
Local Only
hapi server
# or
hapi server --no-relay
The server listens on http://localhost:3006 by default.
On first run, HAPI:
- Creates
~/.hapi/ - Generates a secure access token
- Prints the token and saves it to
~/.hapi/settings.json
Config files
~/.hapi/
├── settings.json # Main configuration
├── hapi.db # SQLite database (server)
├── runner.state.json # Runner process state
└── logs/ # Log files
Environment variables
| Variable | Default | Description |
|---|---|---|
CLI_API_TOKEN |
Auto-generated | Shared secret for authentication |
HAPI_API_URL |
http://localhost:3006 |
Server URL for CLI |
HAPI_LISTEN_HOST |
127.0.0.1 |
HTTP server bind address |
HAPI_LISTEN_PORT |
3006 |
HTTP server port |
HAPI_PUBLIC_URL |
- | Public URL for external access |
HAPI_HOME |
~/.hapi |
Config directory path |
DB_PATH |
~/.hapi/hapi.db |
Database file path |
CORS_ORIGINS |
- | Allowed CORS origins |
ELEVENLABS_API_KEY |
- | ElevenLabs API key for voice |
ELEVENLABS_AGENT_ID |
Auto-created | Custom ElevenLabs agent ID |
CLI setup
If the server is not on localhost, set these before running hapi:
export HAPI_API_URL="http://your-server:3006"
export CLI_API_TOKEN="your-token-here"
Or use interactive login:
hapi auth login
Authentication commands:
hapi auth status
hapi auth login
hapi auth logout
Each machine gets a unique ID stored in ~/.hapi/settings.json. This allows:
- Multiple machines to connect to one server
- Remote session spawning on specific machines
- Machine health monitoring
Operations
Self-hosted tunnels
If you prefer not to use the public relay (e.g., for lower latency or self-managed infrastructure), you can use these alternatives:
Cloudflare Tunnel
https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/
Quick tunnel (temporary URL, changes on restart):
# Install cloudflared: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/
cloudflared tunnel --protocol http2 --url http://localhost:3006
Copy the generated URL and set it:
export HAPI_PUBLIC_URL="https://your-tunnel.trycloudflare.com"
hapi server
Named tunnel (persistent URL):
# Create and configure a named tunnel
cloudflared tunnel create hapi
cloudflared tunnel route dns hapi hapi.yourdomain.com
# Run the tunnel
cloudflared tunnel --protocol http2 run hapi
Note: Use
--protocol http2instead of QUIC (the default) to avoid potential timeout issues with long-lived connections.
Tailscale
https://tailscale.com/download
sudo tailscale up
hapi server
Access via your Tailscale IP:
http://100.x.x.x:3006
Public IP / Reverse Proxy
If the server has a public IP, access directly via http://your-server-ip:3006.
Use HTTPS (via Nginx, Caddy, etc.) for production.
Telegram setup
Enable Telegram notifications and Mini App access:
- Message @BotFather and create a bot
- Set the bot token and public URL
- Start the server and bind your account
export TELEGRAM_BOT_TOKEN="your-bot-token"
export HAPI_PUBLIC_URL="https://your-public-url"
hapi server
Then message your bot with /start, open the app, and enter your CLI_API_TOKEN.
Troubleshooting:
- If binding fails, verify
HAPI_PUBLIC_URLis accessible from the internet - Telegram Mini App requires HTTPS (not HTTP)
Runner setup
Run a background service for remote session spawning:
hapi runner start
hapi runner status
hapi runner logs
hapi runner stop
With the runner running:
- Your machine appears in the "Machines" list
- You can spawn sessions remotely from the web app
- Sessions persist even when the terminal is closed
Alternative: pm2
If you prefer pm2 for process management:
pm2 start "hapi runner start --foreground" --name hapi-runner
pm2 save
Voice assistant setup
Enable voice control:
- Get an API key from elevenlabs.io
- Set the environment variable:
export ELEVENLABS_API_KEY="your-api-key"
hapi server --relay
See Voice Assistant for usage details.
Security notes
- Keep tokens secret and rotate if needed
- Use HTTPS for public access
- Restrict CORS origins in production
Firewall example (ufw)
ufw allow from 192.168.1.0/24 to any port 3006