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 startcalls thestart_sessionMCP tool, stores theMcp-Session-Idin~/.haptix-session- All device commands read from
~/.haptix-sessionautomatically haptix session endcallsend_sessionand 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