# 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:
```bash
# For Claude Code
claude --version
# For OpenAI Codex CLI
codex --version
# For Google Gemini CLI
gemini --version
```
## Architecture
HAPI has three components:
| Component | Role | Required |
|-----------|------|----------|
| **CLI** | Wraps AI agents (Claude/Codex/Gemini), runs sessions | Yes |
| **Server** | Central hub: persistence, real-time sync, remote access | Yes |
| **Runner** | Background service for remote session spawning | Optional |
### How they work together
```
┌─────────────────────────────────────────────────────┐
│ Your Machine │
│ │
│ ┌─────────┐ Socket.IO ┌─────────────┐ │
│ │ CLI │◄───────────────►│ Server │ │
│ │+ Agent │ │ + SQLite │ │
│ └─────────┘ └──────┬──────┘ │
│ ▲ │ SSE │
│ │ spawn ▼ │
│ ┌────┴────┐ ┌─────────────┐ │
│ │ Runner │◄────RPC────────►│ Web App │ │
│ │(背景) │ └─────────────┘ │
│ └─────────┘ │
└─────────────────────────────────────────────────────┘
│
[Tunnel / Public URL]
│
┌─────▼─────┐
│ Phone/Web │
└───────────┘
```
- **CLI**: Start a session with `hapi`. The CLI wraps your AI agent and syncs with the server.
- **Server**: Run `hapi server`. Stores sessions, handles permissions, enables remote access.
- **Runner**: Run `hapi runner start`. Lets you spawn sessions from phone/web without keeping a terminal open.
### Typical workflows
**Local only**: `hapi server` → `hapi` → work in terminal
**Remote access**: `hapi server --relay` → `hapi runner start` → control from phone/web
## Install the CLI
```bash
npm install -g @twsxtd/hapi
```
Or with Homebrew:
```bash
brew install tiann/tap/hapi
```
## Other install options
npx (no install)
```bash
npx @twsxtd/hapi
```
Prebuilt binary
Download the latest release from [GitHub Releases](https://github.com/tiann/hapi/releases).
```bash
xattr -d com.apple.quarantine ./hapi
chmod +x ./hapi
sudo mv ./hapi /usr/local/bin/
```
Build from source
```bash
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)
```bash
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
```bash
hapi server
# or
hapi server --no-relay
```
The server listens on `http://localhost:3006` by default.
On first run, HAPI:
1. Creates `~/.hapi/`
2. Generates a secure access token
3. 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`:
```bash
export HAPI_API_URL="http://your-server:3006"
export CLI_API_TOKEN="your-token-here"
```
Or use interactive login:
```bash
hapi auth login
```
Authentication commands:
```bash
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):
```bash
# 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:
```bash
export HAPI_PUBLIC_URL="https://your-tunnel.trycloudflare.com"
hapi server
```
**Named tunnel** (persistent URL):
```bash
# 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 http2` instead of QUIC (the default) to avoid potential timeout issues with long-lived connections.
Tailscale
https://tailscale.com/download
```bash
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:
1. Message [@BotFather](https://t.me/BotFather) and create a bot
2. Set the bot token and public URL
3. Start the server and bind your account
```bash
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_URL` is accessible from the internet
- Telegram Mini App requires HTTPS (not HTTP)
### Runner setup
Run a background service for remote session spawning:
```bash
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:
```bash
pm2 start "hapi runner start --foreground" --name hapi-runner
pm2 save
```
### Voice assistant setup
Enable voice control:
1. Get an API key from [elevenlabs.io](https://elevenlabs.io/app/settings/api-keys)
2. Set the environment variable:
```bash
export ELEVENLABS_API_KEY="your-api-key"
hapi server --relay
```
See [Voice Assistant](./voice-assistant.md) 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)
```bash
ufw allow from 192.168.1.0/24 to any port 3006
```