CLI Reference

The haptix command-line tool gives you full control over the Haptix platform from your terminal. Everything your AI agent can do via MCP, you can do from the CLI — the same 22 tools, the same endpoint (localhost:4278/mcp).

URL for agents: If you're an AI agent reading this, the CLI docs are at https://docs.haptix.dev/cli


Installation

The haptix binary lives inside Haptix.app/Contents/Helpers/haptix. During onboarding (or from Settings → Command Line Tool), a symlink is created at /usr/local/bin/haptix.

haptix --version

Quick start

haptix session start
haptix tap --label "Settings"
haptix screenshot
haptix session end

That's the core loop: start a session → interact with the device → end the session.

start_session auto-discovers USB devices and auto-selects if only one is connected. You don't need list_devices or select_device unless you have multiple devices.


Architecture

The CLI talks to the haptix-server daemon through two channels:

Channel Transport Commands
Control API Unix socket (~/Library/Application Support/Haptix/haptix.sock) status, sessions, devices, logs, start, stop, health
MCP endpoint Streamable HTTP (POST http://localhost:4278/mcp) All device interaction commands

Device interaction commands construct JSON-RPC tools/call requests, track the Mcp-Session-Id header for session affinity, and format responses for the terminal.


Session management

Device commands require an active MCP session. The CLI manages this automatically.

haptix session start                    # start session, prints session ID
haptix session start --name "testing"   # start with a description
haptix tap 200 300                      # uses the active session
haptix screenshot                       # uses the active session
haptix session end                      # end session, clean up

How sessions work

  • haptix session start calls the start_session MCP tool, stores the Mcp-Session-Id in ~/.haptix-session
  • All device commands read from ~/.haptix-session automatically
  • haptix session end calls end_session and removes the file
  • If no session exists and a device command is run, a session is auto-created

Global flags

Flag Description
--json Output raw JSON instead of human-friendly formatting
--session <id> Use a specific MCP session ID instead of the stored one

Admin commands

These talk to the daemon's control API over the Unix socket.

haptix status

Server state, port, uptime, and session count.

$ haptix status
Haptix MCP Server
  State:    running
  Port:     4278
  Uptime:   2h 15m
  Sessions: 3
  Logs:     142

haptix sessions

Active MCP sessions.

$ haptix sessions
ID       CODE   AGENT                TRANSPORT    STATE
a3d1f2b8 A3D1   cursor               streamable   active
b7e9c4d1 B7E9   claude-code          streamable   idle

haptix devices

Discovered USB devices.

haptix logs [--last N] [--follow]

Recent server log entries.

Flag Description
--last N Number of entries to show (default: 50)
--follow Stream new entries as they arrive (Ctrl+C to stop)

haptix start

Start the daemon via launchd. If already running, prints a message and exits.

haptix stop

Graceful daemon shutdown.

haptix health

Liveness check. Exits 0 if healthy, 1 if not.

haptix trial

Start a free trial. Creates a trial license key and activates it on this machine. One trial per machine.

$ haptix trial
Starting free trial...
  Key:     HPTX-TRIAL-A7K3-M9P2
  Expires: 2026-03-07
  Days:    3

Trial activated. Full access to all features.

haptix license <KEY>

Activate a purchased license key on this machine.

haptix license HPTX-XXXX-XXXX-XXXX

Device commands

These send MCP tool calls to the daemon via Streamable HTTP.

haptix select <device>

Bind the session to a device. Matches against service name, bundle ID, or app name (case-insensitive, partial match).

haptix select MyApp
haptix select "com.example.myapp"

haptix device-info

Device model, screen size, orientation, app details, debugger status.

haptix device-status

Connection status and session state.


Screenshots and inspection

haptix screenshot [options]

Capture the device screen.

Flag Description
--annotated Overlay accessibility bounding boxes and labels
--format <png|jpeg> Image format (default: jpeg)
--output <path> Save to file (default: screenshot_<timestamp>.jpg)
--filter <type> Filter annotations: interactive, button, text, input, image
--highlight <id> Highlight a single element by accessibility identifier
haptix screenshot                              # save to current dir
haptix screenshot --annotated --output ui.png   # annotated PNG
haptix screenshot --highlight "submitBtn"       # highlight one element

haptix tree [--mode compact|full]

Get the accessibility tree.

Flag Description
--mode <compact|full> compact (default): flat list. full: nested hierarchy

haptix console [options]

Get recent app console output (print, NSLog, os_log).

Flag Description
--limit N Max entries (default: 100)
--contains <text> Filter by substring
--source <stdout|stderr|os_log> Filter by source
--level <debug|info|notice|error|fault> Filter by log level

Gesture commands

All coordinates are in screen points (not pixels), origin (0, 0) at top-left.

haptix tap [options]

Single tap. Three targeting modes:

haptix tap 200 300                    # by coordinates
haptix tap --label "Submit"           # by accessibility label
haptix tap --id "submitButton"        # by accessibility identifier

haptix double-tap [options]

Double tap. Same targeting as tap.

haptix long-press [options]

Long press. Same targeting as tap, plus --duration <seconds> (default: 1.0).

haptix swipe <startX> <startY> <endX> <endY> [--duration <seconds>]

Swipe between two points. Use for picker wheels, dismissing sheets, reveal actions.

haptix swipe 200 400 200 200              # swipe up
haptix swipe 200 300 200 250 --duration 0.1

haptix drag <startX> <startY> <endX> <endY> [options]

Drag with dwell phase. Use for reordering lists, moving items.

Flag Description
--hold <seconds> Hold at start before moving (default: 0.15)
--duration <seconds> Movement duration (default: 1.0)

haptix scroll <direction> [options]

Page scroll. No coordinates needed.

Flag Description
--amount <size> small, medium (default), large, full_page
--id <identifier> Target a specific scrollable element
haptix scroll down
haptix scroll up --amount large

haptix pinch <centerX> <centerY> <scale> [--duration <seconds>]

Pinch gesture. Scale greater than 1 zooms in, less than 1 zooms out.

haptix rotate <centerX> <centerY> <angle> [--duration <seconds>]

Two-finger rotation. Positive angle is clockwise.


Text commands

haptix type <text>

Type text into the focused input field. The keyboard must be visible.

haptix type "hello world"
haptix type "user@example.com"

haptix clear-text

Clear all text in the focused input field.


Annotation commands

haptix annotate [options]

Draw annotations on the device screen. Annotations appear in screenshots.

Flag Description
--accessibility Auto-render bounding boxes from the accessibility tree
--filter <type> Filter: interactive, adjustable, button, text, input, image
--highlight <id> Highlight one element by identifier
--add Layer on top of existing annotations (default replaces)
--lock Persist through multiple screenshots

haptix clear-annotations

Remove all annotations.


Notes commands

Agent learning persistence across sessions.

haptix note <content> [--scope app|universal]

Store a learning.

haptix note "Login button is at the bottom of the scroll view"
haptix note "Always dismiss keyboard before tapping nav bar" --scope universal

haptix notes [--scope app|universal|all]

Recall stored learnings.

haptix consolidate <summary> [--scope app|universal]

Replace scattered notes with a consolidated summary.


Examples

Quick screenshot workflow

haptix screenshot --annotated --output annotated.jpg
haptix tree
haptix tap --label "Settings"
haptix screenshot --output after-tap.jpg

Scripted test flow

haptix session start --name "login test"
haptix tap --id "emailField"
haptix type "test@example.com"
haptix tap --id "passwordField"
haptix type "secret123"
haptix tap --label "Sign In"
haptix screenshot --output login-result.jpg
haptix session end

Machine-readable output

haptix tree --json | jq '.elements[] | select(.traits | contains("button"))'
haptix device-info --json