Reach a self-hosted assistant from your phone or another computer.
A self-hosted assistant runs on one computer, and by default that is the only place you can talk to it. Two pieces of setup let another device reach it:
You connect through your own address, not through vellum.ai. The tunnel URL serves the Vellum web app pointed at your assistant, so a paired device talks straight to your machine. Conversations never pass through Vellum's servers.
On the computer that hosts your assistant:
vellum ps to check, vellum wake to start it. No assistant yet? See Local hosting.brew install nginx on macOS, sudo apt install nginx on Linux.ngrok gives your assistant a public https address, so any phone or laptop can open it with nothing installed on that device.
Tailscale keeps the address off the public internet, which is more private but costs you two things. Every device you pair needs Tailscale installed and signed in, phone included. And a Tailscale address can't receive inbound webhooks, so channels like Telegram and Twilio still need a public tunnel alongside it. Vellum leaves an existing one in place and uses the Tailscale address for pairing only.
Either way, a device still has to be paired and approved before it can do anything. If you're not sure, start with ngrok.
brew install ngrok/ngrok/ngrok on macOS, or sudo snap install ngrok on Linux.ngrok config add-authtoken <your-token>vellum wake all restart it. Note the domain you pick; you'll pass it to Vellum in the next section.brew install tailscale), and run tailscale up to sign in. Your machine gets a stable name like your-mac.tailnet-name.ts.net.Run this on the computer hosting the assistant. For ngrok, pass the domain you reserved:
vellum tunnel --provider ngrok --domain your-assistant.ngrok.appFor Tailscale:
vellum tunnel --provider tailscaleEither way the command prints Tunnel established: followed by the address your devices will use, and saves that address so the pairing steps below fill it in for you.
The tunnel has to stay up for as long as you want remote access. To keep it running without leaving a terminal open, add -d:
vellum tunnel --provider ngrok -dIt waits for the tunnel to come up, then prints the address, where it is logging, and the kill command that stops it again. Vellum remembers your ngrok domain after the first run, which is why this one doesn't repeat --domain.
The last step is to pair the device, and the easiest route is the desktop app on the host computer. Open Vellum there and go to Settings → General → Pair a device.
The card confirms your tunnel is reachable, then Generate pairing QR gives you a QR code to scan from a phone and a link you can open on another computer. Codes work once and expire after 10 minutes, so generate a fresh one per device.
Scanning finishes the job. The host approved that code when it created it, so there is nothing to confirm and no code to type. With the Vellum mobile app installed, the page offers to hand the pairing over to it.
The card only appears on the machine running the assistant, since being there is what authorizes the pairing. Once paired, a device stays paired across reloads, though only while the tunnel is up: pairing grants access to your tunnel address, not a separate route in.
Start from the device itself. Open your tunnel address on the device. It lands on the pairing page, shows a short code, and waits. On the host, the request appears under Pairing requests in the same card. Check that code against the device's screen before approving: the match is what proves the request came from your device. Or approve from a shell with vellum pair --web-approve <code>.
No desktop app on the host. If you hatched the assistant over SSH on a VPS, pair from the CLI instead. It prints a pairing link and the same link as a QR code, using the address from vellum tunnel:
vellum pairAdd --app to point the QR at the mobile app instead of a browser, --url to pair against a different address, --label to name the pairing, or --json for scripting.
Pair another computer. A second machine with the vellum CLI joins with that link rather than a browser, and vellum pair prints the exact command to run under it. The link already carries an approved code, so the import finishes right away and registers the assistant locally for vellum client:
vellum connect import "https://your-assistant.ngrok.app/assistant/pair#device_code=..."No link handy? Give it your tunnel address on its own. That machine mints its own code, prints it, and waits for you to approve it on the host, from Pairing requests in the card or with vellum pair --web-approve <code>:
vellum connect import https://your-assistant.ngrok.appCtrl+C on the waiting machine stops only that side. The request stays in the host's pending list, still approvable, until it expires 10 minutes after it was minted. To withdraw it sooner, click Deny beside it in the Pair a device card; the CLI has no deny command.
Revoking happens on the host. To see what's paired to it:
vellum devicesEach row shows the device type, pairing and last-used dates, and a hashed id. That hash is what you revoke with:
vellum devices revoke 3f9a1c...Confirm the prompt (--yes skips it) and that device loses access immediately; it has to be paired again to return. The row marked This machine is the host's own credential and can't be revoked.
Two things that look like revoking but aren't:
vellum unpair <name> runs on the paired machine and only forgets the connection there. The host still trusts it.A Paired devices list with the same revoke button is rolling out in the Pair a device card. Until it reaches your build, use the CLI.
--domain, and pair again.localhost address, which would point the phone back at itself.tailscale up.vellum pair.