---
title: "CLI Reference"
description: "Run Cloud Link in the foreground, manage exposed services, download verified tools, and use environment variables on headless Linux."
canonical: "https://opencodecloud.link/docs/cli/"
lastUpdated: "2026-10-19"
---
The `opencode-cloudlink` CLI and the desktop tray app share the same Rust core.
Use the CLI for headless Linux, service mode, scripts, and local service
management.

Running the binary without a subcommand starts the connector, equivalent to
`opencode-cloudlink run`.

## `run`

Starts the connector in the foreground.

```sh
opencode-cloudlink run --working-directory /srv/project
```

On startup it may show a QR code and wait for a phone claim. When a device
claims the pairing, the terminal asks:

```text
A device "Pixel 9" wants to connect. Approve this pairing? [y/N]
```

Answer `y` to approve. Any other input denies the claim. The request expires
with the pairing TTL.

### Global options

These options are accepted by `run`, `tools`, and `services`.

| Option | Purpose |
| --- | --- |
| `--control-plane <url>` | Override the control plane; default `https://api.opencodecloud.link` |
| `--name <name>` | Machine display name |
| `--opencode-port <port>` | Local managed OpenCode port |
| `--adopt-opencode` | Trust an existing loopback OpenCode server; saved opt-in |
| `--proxy-port <port>` | Local Cloud Link proxy port |
| `--tunnel <mode>` | Tunnel mode; production uses `named` |
| `--opencode <path>` | Explicit OpenCode executable |
| `--cloudflared <path>` | Explicit cloudflared executable |
| `--working-directory <path>` | Folder OpenCode starts in |
| `--pairing-json <path>` | Write pairing data to a file for automation |
| `--reset` | Forget the saved pairing before starting |
| `--service` | Foreground service mode; requires paired state |
| `--no-download` | Do not download missing tools |

Environment variables:

- `CLOUDLINK_CONTROL_PLANE_URL`
- `CLOUDLINK_MACHINE_NAME`
- `CLOUDLINK_TUNNEL_MODE`
- `CLOUDLINK_CONFIG_DIR`

Configuration precedence is explicit flag, environment, saved setting, then
default. `CLOUDLINK_BOOTSTRAP_SECRET` and quick tunnels are not supported.

## `services`

Manage local services exposed through the tunnel. The connector must be stopped
because it holds the installation lock.

```sh
opencode-cloudlink services list

opencode-cloudlink services add <id> \
  --target 127.0.0.1:3000 \
  [--port <service-port>] \
  [--path </prefix>] \
  [--name <display-name>] \
  [--public] \
  [--keep-prefix] \
  [--enable]

opencode-cloudlink services enable <id>
opencode-cloudlink services disable <id>
opencode-cloudlink services remove <id>
```

- A path service defaults to port `8443`.
- A root service needs an explicit `--port`.
- `--public` allows anonymous access. The default is private.
- `--keep-prefix` forwards the full path instead of stripping the prefix.
- `--enable` makes the service active immediately.

The same validation as the desktop UI applies: loopback targets only,
unprivileged ports, reserved ports excluded, and the `/_cloudlink` prefix
reserved. See [Exposed services](/docs/exposed-services/).

## `tools`

Download the pinned tools without starting the connector.

```sh
opencode-cloudlink tools --destination ./tools
opencode-cloudlink tools --destination ./tools --lite
```

`--lite` downloads cloudflared only. `--os` and `--arch` can select a target
other than the host. Release packaging uses this command; normal users receive
the tools inside their installer or archive.

## Service mode

`run --service` is intended for a systemd user service or another supervisor.
It:

- requires saved pairing state;
- runs in the foreground without a graphical session;
- disables automatic downloads;
- relies on the service manager for restart limits.

Pair interactively before enabling the unit. See
[Linux and headless](/docs/install/linux/) for the unit setup.

## Examples

```sh
# Standard headless run.
opencode-cloudlink run --working-directory /srv/project

# Pair again after changing the proxy port.
opencode-cloudlink run --reset --proxy-port 4100

# Adopt an existing, trusted loopback server.
opencode-cloudlink run --adopt-opencode

# Start from a supervisor after pairing.
opencode-cloudlink run --service

# List services while the connector is stopped.
opencode-cloudlink services list
```

## State and exit behavior

State is stored in the platform's `opencode-cloudlink` directory:

- macOS: `~/Library/Application Support/opencode-cloudlink`
- Linux: `~/.config/opencode-cloudlink`
- Windows: `%APPDATA%\opencode-cloudlink`

Metadata is `rust-state.json`. macOS and Windows use native credential storage;
Linux uses a protected `rust-secrets.json`.

`Ctrl+C` and `SIGTERM` stop the connector and wait for owned child processes.
An unexpected exit may be restarted by the OS login item or systemd. Invalid
credentials never cause an automatic reset; use `--reset` or the desktop
**Remove saved connection** action.

## Related

- [Install on Linux and headless servers](/docs/install/linux/)
- [Settings reference](/docs/settings/)
- [Exposed services](/docs/exposed-services/)
- [Troubleshooting](/docs/troubleshooting/)