The Inbox is powered by duckterm-hookd. Run one platform command beside your agents, scan its pairing QR in DuckTerm, and the installer wires supported hooks and starts the service.
Before you start
DuckTerm installed on your phone or tablet (iOS / iPadOS 17+ on Apple devices)
A macOS, Windows 10+, or Linux machine where Claude Code / Codex / Gemini CLI / other agents run
Homebrew on macOS, PowerShell 5.1+ on Windows, or curl and systemd on Linux
1
Open Agent notifications in DuckTerm
Install or open DuckTerm, then go to Settings → Agent notifications. No token or account id needs to be copied.
Install DuckTerm before pairing
The QR scanner is in Settings → Agent notifications. Install or open DuckTerm on your phone before running the host command below.
Run the command for that machine. It installs hookd with a bundled local Web UI and displays a pairing QR. Scan it in DuckTerm to pair, wire supported Agents, and start the background service.
These are complete commands. The installer carries a local Web UI and displays the pairing QR without putting a mobile credential in your shell history.
Ubuntu, Debian & other systemd distros · arm64 / x86_64
hookd setupsh
curl -fsSL https://raw.githubusercontent.com/ducksee/duckterm-hookd-releases/main/install.sh \
| DUCKTERM_PAIR_QR=1 sh
Windows WSL
Ubuntu inside Windows · WSL1 / WSL2 · managed service
hookd setupsh
curl -fsSL https://raw.githubusercontent.com/ducksee/duckterm-hookd-releases/main/install.sh \
| DUCKTERM_PAIR_QR=1 sh
3
Verify
Run duckterm-hookd status, then use the Local push and platform-push buttons in Settings → Agent notifications. Future upgrades and service restarts keep this pairing.
Show details
$ duckterm-hookd status
DuckTerm Agent connection · vX.Y.Z
[ok] Connected to DuckTerm: <this host>
[ok] Background service is running
[ok] Cloud connection is online
[ok] Membership: Pro
[ok] Coding agents connected: Claude Code, Codex
# End-to-end Hookd → cloud → APN / Inbox test
$ duckterm-hookd test-push --note "Setup verification"
test push accepted by local Hookd
source=<this host>
time=<current RFC3339 time>
cwd=<current directory>
Cloud/APN delivery is asynchronous; verify it on the device or in local send records.
Then use Settings → Agent notifications → Verify to send both a local test and a platform-push test. If they arrive on your phone, setup is complete.
4
Upgrade or remove Hookd
Keep hookd and its Web UI current, disconnect Agent hooks, or remove the Homebrew service when this host no longer needs DuckTerm.
Show details
# Homebrew / native Windows: verify, upgrade, and restart Hookd
duckterm-hookd upgrade
# Linux / WSL: upgrade binary, bundled UI, and service
curl -fsSL https://raw.githubusercontent.com/ducksee/duckterm-hookd-releases/main/install.sh | sh
# Upgrade only the independently versioned Web UI
duckterm-hookd ui upgrade
# Disconnect Agent hooks; keep the daemon installed
duckterm-hookd hook uninstall
# Homebrew: remove the service and binary completely
brew services stop duckterm-hookd && brew uninstall duckterm-hookd
duckterm-hookd hook uninstall removes only DuckTerm entries from supported Agent configs. It deliberately keeps the daemon, pairing, and other third-party hooks intact.
5
LAN Direct and the host firewall
For direct phone access over a LAN or VPN, hookd listens on TCP 11434 on every interface (0.0.0.0 / [::]). This does not expose the port to the public Internet: do not add router port forwarding. Every connection still requires the DuckTerm pairing key.
Show details
Windows (native)
Setup adds the install directory to your user PATH; open a new terminal and use duckterm-hookd, or the short alias dhook. It reconciles one inbound TCP port rule across network profiles. If elevation is required, run this in an Administrator PowerShell:
duckterm-hookd firewall install
duckterm-hookd firewall status
macOS
Homebrew installs both duckterm-hookd and the short alias dhook. Choose Allow on the first firewall prompt. If it was denied earlier, these commands allow only the Homebrew-installed Hookd executable:
The installer adds duckterm-hookd and the short alias dhook to /usr/local/bin. When UFW is enabled, allow TCP 11434. Do not configure public router port forwarding:
sudo ufw allow 11434/tcp
duckterm-hookd firewall status
6
Public Direct
Optional · advanced
hookd can open a loopback-only ingress on 127.0.0.1:11435 for an HTTPS/WSS tunnel you run yourself — Cloudflare Tunnel, frp, or a reverse proxy. It never widens the LAN address gate and never includes the Web control panel on port 20080; routeSecret is scanner isolation, not the application key, so pairing authentication is unchanged. Restart hookd after any change.
Show details
# 1 · Enable the loopback ingress (default port 11435) and register the origin
duckterm-hookd access enable
duckterm-hookd access add https://hookd.example.com
duckterm-hookd access list
# 2a · Cloudflare Tunnel — shortest form
cloudflared tunnel --url http://127.0.0.1:11435
# 2b · frp — shortest frpc.toml
# serverAddr = "frps.example.com"
# serverPort = 7000
# [[proxies]]
# name = "hookd"
# type = "https"
# localIP = "127.0.0.1"
# localPort = 11435
# customDomains = ["hookd.example.com"]
# 3 · Public Direct changes only take effect after a restart
duckterm-hookd restart
Per-agent details
Installing hookd wires every supported agent. Some have a first-run step that decides whether events ever reach your phone — the ones below do. After that, run the agent inside tmux (or Herdr) and send one message; Live Preview needs a session to attach to.
OpenCode
OpenCode needs no prompt: the installer writes a DuckTerm plugin into its plugin directory. If you installed hookd before OpenCode existed on this host, re-run the installer so the plugin lands.
Try it
cd tmp
tmux new -s op-prod-main
opencode
TypeWhich model are you? Then check your phone: the message should arrive in the Inbox, and Live Preview should show the session in real time.
Codex
Codex asks whether to trust hooks the first time it starts. Choose to trust all of them — an untrusted hook is never executed, so hookd has nothing to forward and the Inbox stays empty.
Try it
cd tmp
tmux new -s cx-prod-main
codex
TypeWhich model are you? Then check your phone: the message should arrive in the Inbox, and Live Preview should show the session in real time.
Claude Code
Claude Code reads hooks from ~/.claude/settings.json, which the installer writes. Claude Code re-reads that file at startup and flags hook changes for review, so restart any session that was already running — and approve the change when it asks — before expecting events.
Try it
cd tmp
tmux new -s cc-prod-main
claude
TypeWhich model are you? Then check your phone: the message should arrive in the Inbox, and Live Preview should show the session in real time.
DeepSeek Harness
DeepSeek Harness reaches hookd through an out-of-tree hooks bridge, which hookd installs for you. If that step fails, the dsh web UI shows the error — install the bridge yourself with dsh plugin add @deepseek-ai/dsh-hooks-claude-code, re-run the hookd installer, then restart the dsh web UI. The bridge only takes effect after that restart.
Try it
cd tmp
tmux new -s dsh-prod-main
dsh
TypeWhich model are you? Then check your phone: the message should arrive in the Inbox, and Live Preview should show the session in real time.
What gets hooked
hookd verifies workflows for Claude Code, Codex, Grok Build, Antigravity, Cursor, OpenCode, Pi, Devin, Droid, Qoder, Amp, Gemini CLI, Kimi Code, and DeepSeek Harness. Contract v1 defines nine decision schemas: seven native structured adapters, plus guarded one-tap Hook adapters for Antigravity and Grok.
Claude Code Codex Grok Build Antigravity Cursor OpenCode Pi Devin Droid Qoder Amp Gemini DeepSeek Harness Kimi Code
What leaves your machine
hookd builds notification previews from Agent hook events and transcripts; text or code from prompts and output can appear in them. Approvals, replies, and Live Preview or image fallback can also pass through the relay, while terminal traffic remains direct. SSH credentials are never sent to our servers. See the Privacy Policy for storage and retention details.