> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monolex.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# VPNCLI

> Connect machines for AI work with P2P shell, command execution, file copy, TCP/UDP tunnels, mosh, port sharing, presence, and supervised services.

VPNCLI is Monolex's direct machine-connectivity CLI. A small `vpncli` client
controls the `vpnclid` daemon to provide interactive shell, one-shot execution,
file transfer, TCP/UDP tunneling, roaming mosh sessions, and port sharing across
machines without making SSH the product control plane. The 0.1.48 dispatcher
contains **21 operational root commands**; `vpnclid` is the companion daemon,
not a second user command surface.

*Published contract: `vpncli 0.1.48`, OpenCLIs build
`2026-07-18-235157`. The executing macOS, Linux, and Windows x86-64 binaries,
registry, and public CDN metadata agree on this release. The Windows payloads
report Authenticode `NotSigned`; that is a signature diagnostic, not a
publication gate.*

## Quick Start

```bash theme={null}
openclis install vpncli
openclis update vpncli

vpncli --version
vpncli login
vpncli service install
vpncli status
vpncli ls
```

On a machine that should accept shells, run `vpncli shell host` once or install
the service while logged in so shell hosting starts automatically.

## Connect and Control

| Command                            | What it does                                                                 | Important transport or effect                                                                                                             |
| ---------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `shell <target>`                   | Opens an interactive remote terminal.                                        | Tries WebRTC P2P, then direct TCP, then WebSocket relay.                                                                                  |
| `shell host`                       | Registers a persistent shell worker on this machine.                         | Survives daemon/service restarts; stop with `shell host --stop`.                                                                          |
| `cp <src> <dst>`                   | Copies a file to or from `MACHINE:/path`.                                    | Product contract is one local and one remote side. Remote-to-remote is unsupported and 0.1.48 does not reject it cleanly.                 |
| `exec <target> <command>`          | Runs a non-interactive command and captures stdout, stderr, and exit code.   | Prefer this for deterministic automation rather than scraping an interactive shell.                                                       |
| `tunnel <target> <port>`           | Carries raw TCP over the P2P connection.                                     | Works as an SSH `ProxyCommand`; `--listen <local-port>` exposes a local listener.                                                         |
| `tunnel ... --udp --listen <port>` | Carries UDP datagrams for mosh, DNS, or similar traffic.                     | `--mux` implies UDP and multiplexes concurrent DNS/QUIC-style flows. UDP always requires `--listen`.                                      |
| `mosh <target>`                    | Bootstraps `mosh-server` through `exec` and carries SSP over the UDP tunnel. | `--port` defaults to 60001; a malformed value silently falls back to that default. Requires local `mosh-client` and remote `mosh-server`. |

```bash theme={null}
vpncli ping studio
vpncli exec studio "uname -a; uptime"
vpncli shell studio
vpncli cp ./report.md studio:/tmp/report.md
vpncli tunnel studio 22 --listen 2222
```

Set `VPNCLI_SHELL_TRANSPORT=relay` only for transport diagnosis when you need to
force the relay lane. It is not a performance default.

## Node and Presence Management

| Command                                     | What it does                                                     | State boundary                                                                         |
| ------------------------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `up`                                        | Registers this node and marks it online.                         | `--machine-name <name>` overrides the local name; the daemon heartbeat keeps it fresh. |
| `down`                                      | Explicitly marks this node offline.                              | `--deregister` instead removes its registry row and clears local node state.           |
| `ls`                                        | Lists visible nodes.                                             | Read-only registry view.                                                               |
| `status`                                    | Shows local auth, daemon, node, session, and connectivity state. | First local diagnosis command.                                                         |
| `resolve <target>`                          | Resolves a machine name or node id and prints exact details.     | Read-only identity proof.                                                              |
| `ping <target>`                             | Tests whether the target is currently reachable.                 | Reachability now, not historical availability.                                         |
| `node remove <target>` / `node rm <target>` | Removes the stalest matching record by name or an exact node id. | Refuses this machine and any fresh-online target.                                      |

Presence states have precise meanings:

| State     | Meaning                                                      |
| --------- | ------------------------------------------------------------ |
| `online`  | Daemon is alive and its heartbeat is newer than two minutes. |
| `stale`   | Heartbeat is missing or older than two minutes.              |
| `offline` | The process is dead or the node was explicitly marked down.  |

An online daemon advertises reachability, while shell and share capabilities
come from daemon workers. If `ping` fails, inspect `service status` and daemon
logs on the target before changing client-side aliases.

## Port Sharing

| Command          | What it does                                                                  | Scope or effect                                                                                                                                    |
| ---------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `share <port>`   | Exposes one local port through the HTTP relay and keeps a share worker alive. | Defaults to `--scope private --expires 3600`; `--force` skips the loopback port probe and `--record-only` creates metadata without starting relay. |
| `shares`         | Lists shares owned by this machine/account.                                   | Read-only.                                                                                                                                         |
| `unshare <id>`   | Revokes one share.                                                            | Network exposure mutation.                                                                                                                         |
| `ports <target>` | Lists shares advertised by a remote node.                                     | Read-only remote view.                                                                                                                             |

## Authentication, Daemon, and Service

| Command                                    | What it does                                                           | Effect                                                                               |
| ------------------------------------------ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `login`                                    | Runs interactive email OTP authentication.                             | Writes session credentials.                                                          |
| `login send` / `login verify --code <otp>` | Splits OTP request and completion across processes.                    | Persists pending-login context between the two steps.                                |
| `login --api-key <key>`                    | Performs non-interactive agent login.                                  | Avoid shell history and logs when supplying a key.                                   |
| `login import-monolex`                     | Imports compatible authentication from the Monolex desktop app.        | Shared local credential mutation.                                                    |
| `logout`                                   | Clears local authentication and node state.                            | Disconnecting mutation.                                                              |
| `daemon start`                             | Starts `vpnclid` in the background.                                    | Process lifecycle mutation.                                                          |
| `daemon status`                            | Shows daemon pid and current state.                                    | Read-only liveness proof.                                                            |
| `daemon logs [--tail <N>]`                 | Prints runtime log lines; default is 40.                               | Diagnostic read; invalid tail values fail.                                           |
| `daemon stop`                              | Stops the daemon and all hosted workers.                               | Terminates shells/shares owned by that daemon.                                       |
| `service install`                          | Registers auto-start for `vpnclid` and, when logged in, shell hosting. | Persistent OS service mutation.                                                      |
| `service uninstall`                        | Removes service registration.                                          | Persistent service removal.                                                          |
| `service status`                           | Shows supervisor registration beside live daemon state.                | Both layers must be healthy for reboot persistence.                                  |
| `upgrade`                                  | Downloads the latest payload and restarts the daemon.                  | Executable and process mutation; verify version, service, and a real ping afterward. |

`login`, API-key login, and Monolex import accept `--force` when existing local
auth should be replaced. OTP shapes also support explicit email/device identity
options. `logout` stops the local daemon before clearing device, pending-login,
node, and inventory state.

Service installation follows the current-user supervisor: the macOS service
backend, a systemd user service on Linux, or a Scheduled Task on Windows. It
points at the stable `.openclis/bin/vpnclid` path and enables shell-host
autostart only when login state already exists.

## Identity and Parser Behavior

| Invocation                                        | Result                                                   |
| ------------------------------------------------- | -------------------------------------------------------- |
| `vpncli`, `vpncli --help`, `vpncli -h`            | Root guide, exit 0                                       |
| `vpncli <command> --help`                         | The same root guide, exit 0; no subcommand-specific help |
| `vpncli version`, `vpncli -V`, `vpncli --version` | Version identity                                         |
| `vpncli help`, `vpncli -v`, `vpncli docs`         | Unknown command, exit 1                                  |

The dispatcher scans later argv for `--help`/`-h` before any operational
handler, so `vpncli share --help` does not publish a share. Other flags are
parsed manually by each handler. A malformed TCP `--listen` can fall back to
stdio mode; use a validated numeric value in automation.

## Security and Transport Boundary

Data-plane commands use DTLS peer-to-peer protection when their WebRTC lane is
active. Interactive shell adds P-256 ECDH plus AES-GCM application encryption,
so shell bytes remain end-to-end protected on direct-TCP and relay-data
fallbacks as well. Registry, presence, share, and auth commands use the HTTPS
control plane rather than a WebRTC data channel. The control plane can cache
recently validated JWTs; installed clients prefer the dedicated
`vpncli-api-key` vault entry for node operations when available.

WebRTC success, daemon heartbeat, hosted capability, and command success are
separate proofs. For a deployment smoke, verify `service status`, `status`,
`resolve`, `ping`, and one real `exec` or `cp` operation.

## Published Payload Matrix

| Platform            | Payloads                    | Archive SHA-256                                                    | 0.1.48 status                                                                                                                           |
| ------------------- | --------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| macOS Apple Silicon | `vpncli`, `vpnclid`         | `d4ea4c0818db7086a2811d3dcb230e3173d102a750626cee3db01ecdd2d50343` | Published as `darwin-aarch64`; notarized and both installed binaries pass strict Developer ID verification                              |
| Linux ARM64         | `vpncli`, `vpnclid`         | `dfc513df3917f196f62a5729bf3d3fb2f2b2b215f496ae3ef6bf6927c7091787` | Published as static `linux-aarch64`; both binaries executed on the native ARM64 CI runner                                               |
| Linux x86-64        | `vpncli`, `vpnclid`         | `e51b4df67f78820e0f28a1edd9b76228fb7691eb21a0839921346cf5299dfc96` | Published as static `linux-x86_64`; both binaries executed after an OpenCLIs install in Ubuntu 24.04 WSL                                |
| Windows x86-64      | `vpncli.exe`, `vpnclid.exe` | `151d829526c64fc45e667475f4c896e53aedb152761d130119c75c7892fcd588` | Published as `windows-x86_64`; CI smoke, OpenCLIs install, both executables, and the Scheduled Task service were verified on Windows 11 |

The archive-extracted payload hashes are independently pinned below.

| Platform key     | `vpncli` payload SHA-256                                           | `vpnclid` payload SHA-256                                          |
| ---------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------ |
| `darwin-aarch64` | `76926508e6f0e5da4cbed127475081d868822c71cefe960d21dd560a4fa78dec` | `825204ad9527646bd361deec31bf1c1e94d2f8f4890b32631ee72b94f565e444` |
| `linux-x86_64`   | `13cc733172e547daebf51b43c778d5f21d61f0f8bc87112d7e25da2d8e9ef8e3` | `a61ef92cc3b7df92a14c69996bf05dcf150e4694050003e064d27a95e2782557` |
| `linux-aarch64`  | `076c44c3e79677fcd4d970281738aa76614dc9bfac3089e217c94d977b1e33f9` | `a76b94b1f045abe1e71990517b4c26d90b8656525cc5c399ac22fa9b692fb514` |
| `windows-x86_64` | `82333999e592044e46002eab41c6879e11e51b53f92fc5fc9d6499a493d400dc` | `fd11c62d3c89b10579047c274bb1a1a5eedf87f95f5dacbea343ff610f275128` |

There is no macOS Intel or Windows ARM64 artifact in this build. Windows 11
Smart App Control or WDAC can reject an unsigned new hash on a particular host
even when its SHA-256 and runtime smokes pass. The 0.1.48 Windows executables
report Authenticode `NotSigned`, but this does not make the artifact unavailable
and no longer blocks publication. Keep host execution policy, CDN availability,
installation success, and runtime identity as separate proof layers.

Source tag `v0.1.48` points to commit
`016ef3c648036757324909dcd02ef20c779eac38`. This release predates the
`source_commit` fields now used by newer OpenCLIs metadata, so tag ancestry,
archive hashes, runtime versions, code signatures, and real transport smokes
remain separate proof layers.

## Relationships

| Tool                                          | Ownership                                                                                                             |
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| [Monosystem](/ai-clis/monosystem)             | Gateway-based estate auth, headless presence, frame relay, and typed baseline diagnostics; it does not require VPNCLI |
| [Monolex Headless](/ai-clis/monolex-headless) | Owns Monolex PTY sessions; VPNCLI can reach arbitrary hosted shells and ports                                         |
| [OpenCLIs Vault](/ai-clis/openclis-vault)     | Stores stable API-key and session credential material used by installed estate tools                                  |
| [MonoLog](/ai-clis/monolog)                   | Persists terminal activity for later search; VPNCLI owns live transport                                               |
