# Local control protocol `phonecamd` listens on `$XDG_RUNTIME_DIR/phonecamd.sock`. The socket mode is `0600`. Messages are newline-delimited JSON objects; each non-watch connection carries one request and one response. Request: ```json {"action":"connect","args":{"device_id":"adb:ABC123","trust":true}} ``` Success response: ```json {"ok":true,"result":{"schema_version":1,"state":"streaming"}} ``` Error response: ```json {"ok":false,"error":{"code":"device_not_ready","message":"Pixel is not ready.","hint":"Unlock the phone and approve USB debugging."}} ``` Supported actions are `status`, `devices`, `refresh`, `diagnostics`, `connect`, `disconnect`, `set`, `trust`, `forget`, `pair`, `wifi_connect`, and `snapshot`. The public compatibility surface is `phonecamctl`; direct socket consumers should check `schema_version`. `snapshot` grabs one JPEG from the permanent output. If no phone is streaming, it starts the selected or first ready device, waits for frames, then captures. Photos land in `$OMACAM_SNAPSHOT_DIR/Omacam`, `$OMARCHY_SCREENSHOT_DIR/Omacam`, or `~/Pictures/Omacam`. `watch` is the exception to the one-response rule. It immediately returns the current status as a bare JSON object, then emits another bare object whenever meaningful status changes: ```json {"action":"watch","args":{}} ``` This is the stream consumed by `Service.qml`. The watcher contains no camera or ADB logic and may reconnect across daemon restarts without affecting an active stream.