Docs

Pairling, documented.

Start

two installs, one pairing

The Pairling CLI runs in the macOS environment where your agents work. The Pairling app runs on your iPhone. Install the CLI with npm, get the app from TestFlight, then scan one QR code.

1 · On your Mac

$ npm install -g pairling
$ pairling setup

Run the two commands separately. Install runs no code. Setup previews every change, starts the local runtime, and shows a QR code for scoped pairing.

Published with provenance. Inspect every file with npm pack pairling --dry-run, or verify signatures with npm audit signatures.

2 · On your iPhone

Pairling for iPhone is in open beta on TestFlight. Install it, open Pairling, choose setup, and scan the QR code that pairling setup shows on your Mac.

Join the beta on TestFlight

Requires the free TestFlight app. Nearby discovery and manual address entry are local fallback options for same-Wi-Fi bootstrap or recovery.

3 · Control from anywhere

One scan pairs the phone to that Mac, scoped and stored in Keychain. See live sessions, approve what needs you, interrupt what doesn't. Pairling Connect keeps a private path to the machine when you leave the desk.

Pairling manages multiple paired Macs with per-Mac routes; switch the active machine from Settings.

Pairling Connect

the private route between phone and Mac

Pairling Connect runs a WireGuard-encrypted tailnet node inside the app, built on Tailscale's tailnet technology. No separate VPN app and no system VPN profile. It forwards allowed Pairling endpoints to the local daemon — not arbitrary localhost traffic — and holds a session over cellular.

Route order

The app prefers the tailnet route, falls back to same-Wi-Fi discovery, and uses an App Attest-gated relay only as a last resort. The iPhone shows route health honestly when the machine is unreachable.

Diagnostics

Treat remote access as beta: check route readiness with pairling doctor before relying on a session away from the machine. For a machine-readable setup report when support asks, run pairling doctor --first-run --json.

Status without secrets

Status reports avoid auth URLs, request bodies, transcripts, tokens, provider keys, and proof material. Bearer tokens, request proof, and scoped pairing stay enforced by the daemon on every hop.

The Agent Control Protocol

every endpoint the phone can reach, as enforced

Everything the iPhone can reach on the paired Mac goes through one scoped HTTP and SSE surface served by the local Pairling daemon. That surface is Pairling's Agent Control Protocol. When Pairling Connect carries the route, its bridge enforces this path allowlist in code; requests outside it never leave the phone. This reference is generated from that allowlist, not from intentions.

enforced in the Connect bridge bearer token still required tailnet hosts only

MCP

Connects agents to tools. The Model Context Protocol gives an agent its hands: tools, data, and context.

A2A

Connects agents to agents. Agent-to-agent protocols let autonomous workers delegate and coordinate among themselves.

ACP

Connects agents to you. Scoped visibility, scoped input, scoped interrupts. Enforced, not promised.

Pre-pair policy

Before scoped pairing completes, only these are reachable. Defense in depth: after pairing, every request still carries the per-device bearer token, and the daemon enforces scoped pairing independently of the bridge.

MethodPathPurpose
GET/health · /healthzLiveness
GET/readyzReadiness
GET/routezRoute state
GET/manifestDaemon manifest
POST/pair/claimClaim a pairing

Read surface

MethodPathPurpose
Health & route
GET/health · /healthz · /readyz · /routezLiveness, readiness, route state
GET/health-streamLive route health
GET/power-stateMac power state
GET/statusDaemon status
Sessions
GET/sessions · /sessions-visibleList sessions
GET/sessions-stream · /session-live-eventsLive session events
GET/recent-projectsRecent project paths
GET/filesystem/directoriesDirectory picker source
GET/session-source-diagnosticsSession source health
GET/sessions/:id/exportExport a session
Transcript & turns
GET/transcript · /transcript-streamStructured transcript, live
GET/turn-state-streamTurn phase stream
Terminal
GET/terminal-stream · /terminal-stream-diagnosticsRaw PTY stream
GET/terminal-surface-v2 · /terminal-surface-stream(-v2)Rendered terminal surface
GET/terminal-workspace(-stream)Terminal workspace
GET/session-runtime-truth(-stream)Runtime ground truth
Commands & activity
GET/commands(-stream)Command catalog, live
GET/invocations(-stream)Command invocations
GET/activity(-stream)Session activity
Workers & orchestration
GET/workers · /worker-statsWorker list and stats
GET/orchestrationsOrchestration runs
GET/provider-statusProvider availability
Gateway
GET/aperture-cli/status · /providers · /launch-contextsGateway state and launch contexts
Push
GET/push/statusPush registration state
PairDrop
GET/pairdrop/files · /pairdrop/files/:idVault contents
GET/pairdrop/eventsVault events
Pickers
GET/pickers/resume(/preview)Resume picker
GET/pickers/permissions · /hooks · /memory · /mcpLocal config pickers

Control surface

MethodPathPurpose
Pairing lifecycle
POST/pair/claim · /pair/revoke · /pair/rotate-tokenClaim, revoke, rotate
Session input
POST/send-textSend a prompt
POST/terminal-controlRaw terminal input
POST/sigint · /sigtermInterrupt / terminate the turn
POST/spawn-sessionLaunch a session
POST/uploadAttach a file
Push
POST/push/preferences · /push/testPreferences, test push
POST/push/live-activity-token · /push/live-activity-testLive Activity plumbing
Orchestration
POST/orchestrations · /orchestrations/:id/stopLaunch, stop
PairDrop
POST/pairdrop/files · /pairdrop/files/:id/attachAdd, attach to a session
POST/pairdrop/uploads · /uploads/:id/completeResumable uploads
POST/pairdrop/maintenance/cleanup-partialsClean partial uploads
Pickers
POST/pickers/permissions · /hooks · /memoryApply picker choices
POST/pickers/mcp/:name/restartRestart an MCP server

Narrow writes

Deliberately narrow: file bytes for resumable PairDrop uploads, and PairDrop item deletion. Nothing else.

MethodPathPurpose
PUT/pairdrop/uploads/:id/bytesUpload bytes
DELETE/pairdrop/files/:id · /pairdrop/uploads/:idDelete a vault item / upload

What the perimeter buys you

No arbitrary forwarding

The route forwards allowed Pairling endpoints to the local daemon only. It is not a tunnel to localhost or the wider machine.

Tailnet targets only

The bridge refuses to dial anything that is not a Pairling tailnet host, so a compromised page or link cannot redirect it elsewhere.

Auth on every hop

Path allowlisting happens in the bridge. Bearer tokens, request proof, and scoped pairing are enforced by the daemon independently.

Why "control," not "communication"

Other protocols share the acronym — IBM's Agent Communication Protocol and Zed's Agent Client Protocol are agent-to-agent and agent-to-editor plumbing. Pairling's ACP is the human-command layer.

The argument for this layer, at essay length: The Third Protocol.

FAQ

the questions we would ask too

Support

setup and pairing help

Setup issues

Start with the CLI in the paired macOS environment: pairling doctor reports route state, provenance, the last successful check, and a recovery step.

Provider and gateway sessions

When Claude Code, Codex, Aperture CLI, or another gateway is configured in the paired environment, Pairling can launch and observe the session. The provider or gateway remains responsible for model access, policy, and routing.

Sending a report

Use pairling doctor --first-run --json when support asks for a machine-readable report, and review it before sending. Do not send raw bearer tokens, proof secrets, provider keys, APNs tokens, signed screenshot URLs, unredacted environment variables, or full diagnostic payloads.

Contact

Email support@pairling.dev with your iPhone model, macOS version, Pairling build number, and the output from pairling doctor --json.