Parlour

The iOS app

A client in your pocket, with HomeKit, QR pairing, local discovery and a model on the phone.

The iOS app puts Parlour on the phone you already carry. It records, sends the recording home and plays the answer back, just as a satellite does. Everything that thinks, holds a key or touches the house still runs on the Mac at home. The phone adds HomeKit, which it knows about without any setup, and a small model of its own for when the house cannot be reached.

The app has three tabs: Talk, where you hold the button and speak; House, your HomeKit rooms and accessories; and Settings, which server, which room and what the app is allowed to do.

The app lives in apps/ios and uses only the public routes in Clients: /health to check, /v1/models to confirm the token, /voice for a recording and /ask for text. Anything the app does, you could build against those routes too.

Building it

The Xcode project is generated from apps/ios/project.yml instead of being checked in, because nobody can review a .pbxproj.

brew install xcodegen
pnpm exec nx run ios:app          # generate the project and open it
pnpm exec nx run ios:xcodebuild   # compile for the simulator
pnpm exec nx run ios:xcodetest    # run ParlourTests

Parlour for iOS is not on the App Store yet, so for now you build it yourself. It needs iOS 18 or newer. Signing is up to you. Set PARLOUR_DEVELOPMENT_TEAM before generating, or pick a team in Xcode once. HomeKit and the local network both need a real device, not the simulator.

The first run

A fresh install walks you through setup before it shows the talk button, in the same order and words as the menu bar app, so it takes about a minute with the Mac nearby:

  1. Connect. Scan the pairing code. The servers Bonjour found, and typing an address and token by hand, are folded away until you ask. The app checks the server there and then, so a wrong token shows up now rather than on your first question.
  2. Voice. Allow the microphone, and say which room the phone usually lives in, so "lights off" means the lights in there.
  3. Extras. Answering on the phone when home is out of reach. A phone that cannot run the on-device model skips this step.
  4. Finish. What was set.

Settings has Run setup again at the bottom. A phone that was already paired before setup existed counts as set up.

What it asks for

You should know what a voice assistant is allowed to do before you trust it. So the Settings tab lists the four permissions it relies on, with a mark against each and an Ask button for any not yet granted, and every prompt says what the permission gives you.

PermissionWhat it gives youAsked for when
MicrophoneRecording while you hold the talk buttonThe Voice step of setup, or the first time you hold the button
Local networkFinding the server with Bonjour, then talking to itThe app opens
HomeKitThe rooms and accessories on the House tabYou open that tab
Speech recognitionUnderstanding a request on the phone when the server cannot be reachedThe phone first has to answer by itself, with the on-device answer switched on
CameraScanning the pairing code on the MacYou tap Scan pairing code, in setup or in Settings

HomeKit and multicast networking are entitlements as well as prompts. Apple grants multicast to the team, so a build signed with another team needs it left out of Parlour.entitlements or its own grant. If you say no to the local network, iOS does not ask again, so Settings and setup offer Open Settings, where the Local Network switch is. NSAllowsLocalNetworking allows plain HTTP to the house, and only on the local network, because the server sits on a private address and speaks HTTP. The phone page makes the same trade. It is also why a reverse proxy is worth having if you want to reach the house from outside.

Pairing with your Mac

The quickest way to connect is a QR code. Run parlour pair on the Mac, or open Pair a phone on the menu bar app's Status tab, then tap Scan pairing code in the app's Settings. The Camera app reads the code too and hands it to Parlour. One code carries the server's address and its access token together, so the two can never come from different servers. The token goes into the phone's keychain, never into a backup, and Settings checks the server straight away.

A pairing link can also arrive from outside the app: from the Camera, or from any web page or message with a parlour://pair link in it. So before taking one, the app asks whether to pair with the server it names and shows the address everything you say would go to. Only pair with a code your own server showed you.

Finding the server

Without a code, the app finds the server the same way a satellite does. It browses for _parlour._tcp. Bonjour returns a service rather than an address, so the app opens a connection to the service and reads the host and port off the resolved path. Anything it finds appears in Settings.

An address you type in, pick from that list or take from a pairing code wins over anything found. From then on, it is the only server the app talks to, just as a satellite pins the first server it trusts. You can also name the room the phone is in, so a follow-up lands in the right one.

Browsing is also what raises the local network prompt. So the prompt appears as the app opens, not while someone is trying to say something.

Managing the server

The Server tab manages the Mac from the phone, over the routes in Managing the server:

  • Model servers. Whether the local model and whisper are running, with buttons to start, stop and restart them. Stopping one asks first, because the house cannot answer the same way without it.
  • Pipeline. How many requests run at once, how many can wait per room, how many tasks one request can become, when to give up, and whether to read requests first. Saving restarts the agent so the change takes effect, and the steppers stop at the same limits the server enforces.
  • Maintenance. Runs the doctor, shows the end of any of the three logs, and restarts the agent.

The server has the final say on every change and explains any refusal in its own words. For example, it refuses to start a model that is too big for the Mac, or to restart something that was restarted a moment ago.

The model on the phone

The app can answer on its own using Apple's Foundation Models, which need iOS 26 and Apple Intelligence switched on. It is off by default, and it is a fallback, not a first stop. The phone has no tools, so it cannot switch anything on, read a sensor or look anything up. The phone defers to the house for the same reason the house tries its local model first.

When it is on and the server cannot be reached, the phone transcribes the recording with on-device speech recognition and answers it on the device. The answer is labelled as coming from the phone, not from home. Nothing in that path leaves the handset. When the model is unavailable, Settings says why: too old an iOS, a phone without it, Apple Intelligence switched off, or the model still downloading.

HomeKit

The House tab shows the homes, rooms and accessories HomeKit already knows about, and can switch anything with a power state. It is deliberately not how Parlour controls the house. The agent's tools go through Home Assistant on the server, the one place that knows what is connected to what. The House tab is a second opinion in your pocket, and a screen that still works when the Mac at home is off.

On this page