Send iPhone screenshots to Codex Desktop.
[ 01 ]
Host · Mac relay
Run the installer on the Mac with Codex Desktop. It starts the relay and prints a private QR.
-
01
Run this on the Mac that has Codex Desktop open.
Terminal$ curl -fsSL https://cmd.avmil.xyz/install.sh | bashWhen the relay is ready, Terminal prints the QR for your iPhone to scan.
Prefer to inspect first?
$ curl -fsSL https://cmd.avmil.xyz/install.sh -o install.sh $ less install.sh
Then run bash install.sh.
Inspect the install script
#!/usr/bin/env bash set -euo pipefail APP_NAME="cmd+cmd Relay.app" INSTALL_DIR="${INSTALL_DIR:-$HOME/Library/Application Support/cmdcmd-relay}" APP_PATH="$INSTALL_DIR/$APP_NAME" RELAY_EXECUTABLE="$APP_PATH/Contents/MacOS/CmdCmdRelayApp" LAUNCH_AGENT_LABEL="app.cmdcmd.relay" LAUNCH_AGENT_PLIST="$HOME/Library/LaunchAgents/$LAUNCH_AGENT_LABEL.plist" LOG_DIR="$HOME/Library/Logs" OUT_LOG="$LOG_DIR/cmdcmd-relay.log" ERR_LOG="$LOG_DIR/cmdcmd-relay.err.log" RELAY_HEALTH_URL="http://127.0.0.1:8787/healthz" RELEASE_BASE_URL="${CMDCMD_RELAY_RELEASE_URL:-https://cmd.avmil.xyz/dl}" ARCHIVE_NAME="${CMDCMD_RELAY_ARCHIVE_NAME:-CmdCmdRelay-macOS-20260605-3.zip}" REVIEW_MODE="0" SCRIPT_SOURCE="${BASH_SOURCE[0]:-}" if [[ -n "$SCRIPT_SOURCE" && "$SCRIPT_SOURCE" != bash ]]; then ROOT_DIR="$(cd "$(dirname "$SCRIPT_SOURCE")/.." && pwd)" else ROOT_DIR="$(pwd)" fi LOCAL_ARCHIVE="$ROOT_DIR/dist/cmdcmd-relay/$ARCHIVE_NAME" TMP_DIR="$(mktemp -d)" cleanup() { rm -rf "$TMP_DIR" } trap cleanup EXIT usage() { cat <<'USAGE' Usage: install.sh [--review-mode] Installs the cmd+cmd Relay bundle, starts the private background relay, waits until it is ready, and prints a QR code for the iOS app to scan. Options: --review-mode Save screenshots to a local Review Inbox instead of pasting into Codex Desktop. Environment: INSTALL_DIR Override destination bundle directory. CMDCMD_RELAY_RELEASE_URL Override release download base URL. CMDCMD_RELAY_REVIEW_MODE Set to 1 to enable review mode. USAGE } case "${CMDCMD_RELAY_REVIEW_MODE:-0}" in 1|true|TRUE|yes|YES) REVIEW_MODE="1" ;; esac for arg in "$@"; do case "$arg" in -h|--help) usage exit 0 ;; --review-mode) REVIEW_MODE="1" ;; *) echo "Unknown argument: $arg" >&2 usage exit 64 ;; esac done download_archive() { local archive="$TMP_DIR/$ARCHIVE_NAME" local checksum="$TMP_DIR/$ARCHIVE_NAME.sha256" if [[ -f "$LOCAL_ARCHIVE" ]]; then cp "$LOCAL_ARCHIVE" "$archive" if [[ -f "$LOCAL_ARCHIVE.sha256" ]]; then cp "$LOCAL_ARCHIVE.sha256" "$checksum" fi else curl -fsSL "$RELEASE_BASE_URL/$ARCHIVE_NAME" -o "$archive" curl -fsSL "$RELEASE_BASE_URL/$ARCHIVE_NAME.sha256" -o "$checksum" || true fi if [[ -f "$checksum" ]]; then local expected local actual expected="$(awk '{print $1}' "$checksum")" actual="$(shasum -a 256 "$archive" | awk '{print $1}')" if [[ "$expected" != "$actual" ]]; then echo "Checksum mismatch for $ARCHIVE_NAME" >&2 exit 1 fi fi echo "$archive" } stop_existing_relay() { local pids local legacy_pids launchctl bootout "gui/$(id -u)" "$LAUNCH_AGENT_PLIST" >/dev/null 2>&1 || true pids="$(pgrep -f "cmd\\+cmd Relay\\.app/Contents/MacOS/CmdCmdRelayApp" || true)" if [[ -n "$pids" ]]; then kill $pids >/dev/null 2>&1 || true fi legacy_pids="$(ps ax -o pid=,command= | awk '/\/(CodexShot|CmdCmd)\/relay\/src\/index\.js/ {print $1}' || true)" if [[ -n "$legacy_pids" ]]; then kill $legacy_pids >/dev/null 2>&1 || true fi } prepare_pairing() { if [[ ! -x "$RELAY_EXECUTABLE" ]]; then echo "Could not find relay executable." >&2 exit 1 fi if [[ "$REVIEW_MODE" == "1" ]]; then "$RELAY_EXECUTABLE" --prepare-review-pairing else "$RELAY_EXECUTABLE" --prepare-pairing fi RELAY_HEALTH_URL="$("$RELAY_EXECUTABLE" --print-health-url)" } install_launch_agent() { mkdir -p "$(dirname "$LAUNCH_AGENT_PLIST")" "$LOG_DIR" cat > "$LAUNCH_AGENT_PLIST" <<PLIST <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>$LAUNCH_AGENT_LABEL</string> <key>ProgramArguments</key> <array> <string>$RELAY_EXECUTABLE</string> <string>--serve</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>ProcessType</key> <string>Background</string> <key>StandardOutPath</key> <string>$OUT_LOG</string> <key>StandardErrorPath</key> <string>$ERR_LOG</string> </dict> </plist> PLIST launchctl bootout "gui/$(id -u)" "$LAUNCH_AGENT_PLIST" >/dev/null 2>&1 || true launchctl bootstrap "gui/$(id -u)" "$LAUNCH_AGENT_PLIST" launchctl kickstart -k "gui/$(id -u)/$LAUNCH_AGENT_LABEL" >/dev/null 2>&1 || true } wait_for_relay() { for _ in {1..40}; do if curl -fsS "$RELAY_HEALTH_URL" 2>/dev/null | grep -q "cmdcmd-native"; then return 0 fi sleep 0.25 done echo "Relay did not become reachable on $RELAY_HEALTH_URL." >&2 echo "Recent relay log:" >&2 if [[ -f "$ERR_LOG" ]]; then tail -n 20 "$ERR_LOG" >&2 || true else echo "No error log yet at $ERR_LOG" >&2 fi exit 1 } request_accessibility() { if [[ "$REVIEW_MODE" == "1" ]]; then echo "Review mode enabled. Codex Desktop and Accessibility are not required." return fi if "$RELAY_EXECUTABLE" --accessibility-status >/dev/null 2>&1; then echo "Accessibility permission already granted." return fi echo "Requesting Accessibility permission for screenshot delivery..." "$RELAY_EXECUTABLE" --request-accessibility || true } print_pairing_qr() { if [[ ! -x "$RELAY_EXECUTABLE" ]]; then echo "Could not find relay executable for pairing QR." >&2 exit 1 fi "$RELAY_EXECUTABLE" --print-pairing-qr } ARCHIVE="$(download_archive)" ditto -x -k "$ARCHIVE" "$TMP_DIR/unpacked" FOUND_APP="$(find "$TMP_DIR/unpacked" -maxdepth 2 -name "$APP_NAME" -type d | head -n 1)" if [[ -z "$FOUND_APP" ]]; then echo "Could not find relay bundle in archive." >&2 exit 1 fi stop_existing_relay mkdir -p "$INSTALL_DIR" rm -rf "$APP_PATH" ditto "$FOUND_APP" "$APP_PATH" if codesign --verify --deep --strict "$APP_PATH" >/dev/null 2>&1; then echo "Signature verified." else echo "Installed bundle is not signed or signature verification failed." >&2 fi prepare_pairing install_launch_agent wait_for_relay request_accessibility print_pairing_qr if [[ "$REVIEW_MODE" == "1" ]]; then cat <<EOF Installed: $APP_PATH Background service: $LAUNCH_AGENT_LABEL Logs: $ERR_LOG Next: 1. Open cmd+cmd on iPhone. 2. In Settings, tap Scan Desktop QR and scan the QR above. 3. Send a screenshot. This Mac opens the local Review Inbox. EOF else cat <<EOF Installed: $APP_PATH Background service: $LAUNCH_AGENT_LABEL Logs: $ERR_LOG Next: 1. Open cmd+cmd on iPhone. 2. In Settings, tap Scan Desktop QR and scan the QR above. 3. Send screenshots to Codex Desktop. EOF fi -
02
The QR contains this Mac's local relay address and private token. Scan it; do not type those values by hand.
-
03
Grant macOS Accessibility permission once so the relay can paste screenshots into Codex Desktop.
[ 02 ]
Phone · Pair & send
Open cmd+cmd, scan the terminal QR, then send from your phone.
-
01
Install and open cmd+cmd on iPhone.
-
02
In Settings, tap Scan Desktop QR and scan the QR shown in Terminal.
-
03
Send from the Share sheet, a Shortcut, or Back Tap. The screenshot lands in Codex Desktop.
- Endpoint
- http://127.0.0.1:8787/v1/capturesSimulator only. iPhones should scan the terminal QR so the Mac address and token are correct.
- Bearer token
- CMDCMD_RELAY_TOKENEncoded in the terminal QR.