Skip to content

Companion Remote

Nemu-x edited this page Jul 14, 2026 · 1 revision

Remote Control & Companion

🌐 English · Русский · 中文

Control a proxy client running on another device — typically ClashFest on an Android TV, or SlothClash on a headless box — from your desktop, over your local network. Turn its VPN on/off, push a subscription to it, see its status, and rename it. No accounts, no cloud, no relay — everything stays on your Wi-Fi.

Here SlothClash is the controller; the other device runs a companion agent.


What you can do

  • Discover agents on your LAN by a friendly name (Living Room, Bedroom, …).
  • Pair securely with a PIN (desktop has no camera, so it uses the code the agent shows — or you paste the agent's pairing string).
  • Toggle the agent's VPN on / off.
  • Share one of your subscriptions to the agent in one action.
  • See status (running / active profile / traffic) and rename the device.
  • Unpair to revoke access instantly.

Set it up

On the agent (e.g. the TV)

  1. Open its app → the Remote control entry.
  2. Enable Allow remote control. This is off by default — like turning on debugging, you opt in deliberately.
  3. Choose Show pairing PIN — a 6-digit code, valid for a short window. (It also shows a QR and its ip:port.)

On the desktop (the controller)

  1. Open SlothClash → Companion.
  2. Enter the agent's PIN (or paste its clashctl-pair://… string).
  3. Paired! The device appears in your list, and you can immediately share your active subscription to it.

Both devices must be on the same local network. Pairing requires you to physically see the agent's screen (PIN/QR) — that presence is the security proof.

Troubleshooting

  • "Unreachable" right after pairing — make sure both devices are on the same Wi-Fi (not guest isolation / different VLANs).
  • Nothing discovered — some routers block mDNS/multicast; pair directly with the PIN or the pasted pairing string.
  • Agent moved / reinstalled — re-open its remote-control screen for a fresh PIN and pair again.

Security model

Mechanism Why
Default OFF — explicit opt-in on the agent No silent network exposure
PIN / QR pairing carries ip:port + token + TLS fingerprint Requires physically seeing the agent = presence proof
TLS (self-signed, pinned) by the pairing fingerprint Traffic (including shared subscriptions) is encrypted; MITM impossible
Per-device bearer token, revoked by un-pairing One compromised controller ≠ all; easy revocation
The core's REST API stays bound to 127.0.0.1 The gateway is the single auditable LAN entry point

For developers — protocol (v1)

The companion is a thin, secure LAN gateway in front of the agent's controls (VPN toggle, subscription import).

  • Discovery: mDNS service _clashctl._tcp. TXT keys: app (clashfest|slothclash), id, name, ver, fp (TLS fingerprint).
  • Pairing string: clashctl-pair://<ip>:<port>?id=<deviceId>&name=<name>&app=<app>&fp=<sha256>&token=<token>
  • Transport: HTTPS (self-signed, pinned). Authorization: Bearer <token> on every request.
  • Endpoints (v1):
    • GET /v1/status{ running, activeProfile, uploadTotal, downloadTotal, mode }
    • POST /v1/power { "action": "on" | "off" | "toggle" }
    • POST /v1/subscription { "url", "name" } or { "payload": "<yaml>" }
    • POST /v1/rename { "name" }
    • POST /v1/pair { "pin" } → issues a bearer token

The shared wire contract lives in the clash-companion repo, so ClashFest, SlothClash, and any future controller speak byte-for-byte the same protocol.

Clone this wiki locally