Tickles iPhone Setup

Step-by-step guide to turn Brad's iPhone 16 Pro Max into the tickles fleet agent. No app install beyond Tailscale. Total time: ~15 minutes.

When you finish, the phone will POST a heartbeat to the broker every hour and show up green in the Carl console Fleet tab.


Part 1 — Prerequisites (5 min)

1.1 Install Tailscale on the iPhone

  1. Open the App Store, search Tailscale, install.
  2. Open Tailscale, tap Sign In, use the same account that signs in carl-ded7626-server, phoenix-air, etc. (ruffledfeathers@rfpsinc.com).
  3. Tap Connect. Allow the VPN profile when iOS prompts.
  4. Confirm connection: top of the Tailscale app should show Connected with your tailnet IP (looks like 100.x.x.x).

1.2 Sanity check: broker is reachable

  1. Open Safari on the iPhone.
  2. Go to: http://100.125.254.10:8788/api/fleet/status
  3. You should see a big chunk of JSON listing agents. If you see a timeout or "can't reach server", Tailscale isn't active — go back and re-enable it, then retry.

Part 2 — Build the Heartbeat Shortcut (7 min)

2.1 Create the shortcut

  1. Open the Shortcuts app (built into iOS).
  2. Tap the + in the top right to start a new shortcut.
  3. Tap the shortcut's title at the top → rename to Tickles Heartbeat.

2.2 Action 1 — Get battery level (optional but useful)

  1. Tap Add Action (or the search bar at the bottom).
  2. Search Get Battery Level. Tap it to add.
  3. It appears as a block: Get Battery Level — leave defaults.

2.3 Action 2 — Build the payload dictionary

  1. Tap Add Action below the previous block.
  2. Search Dictionary. Tap it to add.
  3. In the Dictionary block, tap Add new item seven times to add seven key/value rows. For each, tap the left cell for the key and the right cell for the value. Keep Text as the value type unless noted.
Key Value
agent tickles
host brad-iphone17
model claude-haiku-4-5
status idle
uptime_seconds change type to Number, value 0
current_task (leave blank)
battery tap the value cell → tap the variable suggestion Battery Level from the blue bar above the keyboard

2.4 Action 3 — POST to the broker

  1. Tap Add Action.
  2. Search Get Contents of URL. Tap to add.
  3. In the block's URL field, paste: http://100.125.254.10:8788/api/fleet/heartbeat
  4. Tap the > to expand options on that block.
  5. Method: tap and change from GET to POST.
  6. Request Body: tap and change from Form to JSON.
  7. Below Request Body, tap Add new field → set field to Dictionary → tap the value chip → pick the Dictionary variable from the previous step (it'll show as a purple chip labeled "Dictionary").
  8. Headers: tap Add new header: - Key: Content-Type - Value: application/json

2.5 Action 4 — Show success (optional, helps debug once)

  1. Tap Add Action.
  2. Search Show Notification. Tap to add.
  3. In the body field, type: Tickles heartbeat sent and tap the variable chip to append Contents of URL from the previous step. (After you confirm it works, you can delete this action so it stops pinging you every hour.)

2.6 Test it

  1. Tap the play button (▶) at the bottom of the shortcut editor.
  2. You should see a notification containing something like: {"ok":true,"agent":"tickles","received_at":1776...}
  3. If you see an error, re-check the URL, Method=POST, Body=JSON, and that Tailscale is still connected.

2.7 Confirm from the server side

  1. On your Mac (or wherever you check Carl), open the Fleet tab — or run this on the server: bash curl -s http://127.0.0.1:8788/api/fleet/status/tickles | python3 -m json.tool
  2. color should be green and last_seen should be within the last few seconds. host should say brad-iphone17.

Part 3 — Run it automatically every hour (3 min)

3.1 Create the Automation

  1. In the Shortcuts app, tap the Automation tab at the bottom.
  2. Tap + (top right) → Create Personal Automation.
  3. Scroll to Time of Day and tap it.
  4. Set any time, e.g. 9:00 AM. Under Repeat, pick Hourly. (iOS labels this "Time of Day" but the Hourly option means it fires every hour at the chosen minute.)
  5. Tap Next.

3.2 Attach the shortcut

  1. Tap Add Action.
  2. Search Run Shortcut. Tap it.
  3. Tap the chip that says Shortcut in the action → pick Tickles Heartbeat.
  4. Tap Next.

3.3 Make it silent

  1. Toggle Ask Before Running OFF. Confirm Don't Ask when prompted.
  2. (iOS 17+) If you see Notify When Run, toggle it OFF too — otherwise you get a banner every hour. The heartbeat will still fire.
  3. Tap Done.

Part 4 — Validate (2 min)

Wait ~90 seconds past the next hour mark, then from anywhere:

curl -s http://100.125.254.10:8788/api/fleet/status/tickles \
  | python3 -m json.tool

You should see: - "color": "green" - "host": "brad-iphone17" - "model": "claude-haiku-4-5" - "last_seen" timestamp within the last minute or two

If color is red and last_seen is 0, the automation hasn't fired yet (wait), or Tailscale dropped (reopen Tailscale app), or the shortcut errored (run it manually from Part 2.6 to see the error).


Troubleshooting

Shortcut run returns "could not connect": Tailscale is down. Open the Tailscale app, tap Connect.

"Invalid JSON" from broker: The Dictionary action has a typo or the uptime_seconds cell is still a Text type — change it to Number.

Automation doesn't fire while phone is locked: iOS 17+ should run it anyway. On iOS 16 or older, Personal Automations for Time of Day can be gated behind "Ask Before Running" even if you toggled it off — update iOS or upgrade to a 17+ device.

I want Tickles to also receive tasks, not just heartbeat: Tasks come in via WhatsApp (already wired up). When Carl or Forge needs to notify Brad, they run clawdbot message send --channel whatsapp --target 15022952943 ... which produces a WhatsApp push on this phone. Respond to the message in WhatsApp; the existing Twilio webhook picks it up. No further Shortcut work needed for the task path.


How to change the model later

If you want Tickles to use Sonnet 4.6 instead of Haiku 4.5:

  1. Server side (clawdbot config): bash python3 -c " import json p='/root/.clawdbot/clawdbot.json' d=json.load(open(p)) for a in d['agents']['list']: if a['id']=='tickles': a['model']='claude-sonnet-4-6' json.dump(d, open(p,'w'), indent=2) "

  2. iPhone Shortcut: edit Tickles Heartbeat → edit the Dictionary action → change model value from claude-haiku-4-5 to claude-sonnet-4-6 → tap Done.

The next heartbeat will upsert the new model into broker.db.