Skip to content

Agent Push Setup

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. 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.

  2. 2

    Run one command and scan its QR

    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.

    macOS

    Homebrew · Apple silicon & Intel
    hookd setup
    brew install ducksee/tap/duckterm-hookd && \
    "$(brew --prefix duckterm-hookd)/bin/duckterm-hookd" setup --qr

    Windows

    Native PowerShell / CMD · Windows 10 / 11 · x64 / arm64
    PowerShell
    irm https://raw.githubusercontent.com/ducksee/duckterm-hookd-releases/main/install.ps1 | iex
    Command Prompt
    curl.exe -fsSL https://raw.githubusercontent.com/ducksee/duckterm-hookd-releases/main/install.cmd -o install.cmd && install.cmd

    Linux

    Ubuntu, Debian & other systemd distros · arm64 / x86_64
    hookd setup
    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 setup
    curl -fsSL https://raw.githubusercontent.com/ducksee/duckterm-hookd-releases/main/install.sh \
      | DUCKTERM_PAIR_QR=1 sh
  3. 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. 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. 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:

    sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add \
      "$(brew --prefix duckterm-hookd)/bin/duckterm-hookd"
    sudo /usr/libexec/ApplicationFirewall/socketfilterfw --unblockapp \
      "$(brew --prefix duckterm-hookd)/bin/duckterm-hookd"

    Linux / WSL

    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. 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

Type Which 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

Type Which 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

Type Which 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

Type Which 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.

Privacy Policy

Trouble?

Check the Support page for common issues, or email us — we answer fast.