Remote hosts

Coming soon. Remote hosts are part of the iPhone and iPad app, which is in development and not yet available. This page describes the current design, which may change before release.

The iOS app does not run Claude Code itself. It connects to computers you already use (a desktop, a home server) over SSH, shows their sessions, and opens terminals on them.

What the app does

  • Inbox first. The first tab on iPhone lists what needs you across every connected machine: permission requests, questions, finished and failed sessions.
  • Approve and deny. With smaltid on the host, a permission request can be approved or denied from the app, after it shows the exact command. Push notifications carry the same buttons (Approve needs Face ID or your passcode), encrypted end to end so the relay that delivers them cannot read the command, and a Live Activity and widgets show the fleet at a glance.
  • Factory. The Conductor's mission view, with dictation for messages to it.
  • Shortcuts and Siri. What Needs Me, Open Inbox, and Approve Oldest Request (which asks for authentication and confirmation).
  • Sessions, runs and machines. Transcripts, CI runs, and each machine's load with its running and waiting agents. On iPad, a canvas with the same keyboard shortcuts as the Mac.

Reaching your machines

A host is a name, a hostname, a login user, a port (22 by default) and a key. Hosts are expected to be reachable from anywhere, which in practice means Tailscale: a MagicDNS name such as desk.your-tailnet.ts.net or a 100.x.y.z address. Smalti does not include or configure Tailscale; the Tailscale app on the device provides the connection. The host form warns when a hostname will only work at home: .local names, private LAN addresses, and short names that depend on a MagicDNS search domain.

Keys

  • Smalti generates an Ed25519 key pair on the device, or imports an existing OpenSSH private key.
  • The private key is stored in the iOS Keychain with the accessibility class kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, so connections can resume while the phone is locked. It is not synced to iCloud and is never sent anywhere.
  • The public key is shown as an authorized_keys line, with its SHA256 fingerprint, for you to add to ~/.ssh/authorized_keys on each host.
  • The host's key is pinned the first time you connect (trust on first use). If it later changes, the connection is refused.

Sessions on a host

Each host has a projects folder, ~/.claude/projects by default. Smalti lists the transcripts there over SSH and downloads only those whose size or modification time changed, then parses them on the device in the same way as the Mac app. Sessions from all configured hosts are shown in the app.

Terminals and tmux

A terminal panel on iOS is a shell on the host, run inside a tmux session named smalti- followed by eight characters of the panel's ID. When the connection drops (switching from Wi-Fi to cellular, or iOS suspending the app), the shell keeps running on the host, and Smalti reattaches to the same tmux session when it reconnects. A heartbeat every 20 seconds detects dead connections sooner than TCP would. If tmux is not installed on the host, Smalti starts a plain shell and prints a warning that it will not survive a dropped connection.

All commands Smalti runs on a host are POSIX sh scripts, so they behave the same whether your login shell is bash, zsh or fish. Each poll is one round trip that lists tmux panes, the working directory of each claude process, and the process table, which Smalti uses to link panes to sessions.

Host requirements

  • An SSH server that accepts Ed25519 public keys.
  • tmux, recommended, for terminals that survive disconnects.
  • Claude Code, for sessions to appear.
  • A Linux or macOS host. Process lookups use /proc where it exists and lsof otherwise.