# Remote Control

> **Beta**: The Remote Control feature is currently in Beta. Functionality and interfaces may change in future releases. Feel free to try it out and share your feedback.

With Remote Control, you can access a locally running CodeBuddy Code session from your phone, tablet, or any browser. The session always runs on your local machine — the Web UI is simply a remote window.

## Overview

Remote Control starts a Gateway service locally and exposes a Web UI through a Cloudflare Tunnel or LAN, allowing you to connect to a running CodeBuddy Code session from any device.

With Remote Control, you can:

- **Use your full local environment remotely**: File system, MCP servers, and tool configurations all remain available
- **Interact with the Agent via Web UI**: Send messages, view conversations, and monitor tool execution in the browser
- **Connect from multiple devices**: Scan a QR code from your phone to connect, with both LAN and public network access supported
- **Manage sessions from the terminal**: Work simultaneously in the terminal and the Web UI, with conversations kept in sync

## Prerequisites

- CodeBuddy Code installed and logged in (run `codebuddy` and use `/login` to log in)
- For public network access, install [cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/) (optional)

## Starting Remote Control

Use the `/gateway` command in a CodeBuddy Code session to start the Remote Control service:

```
/gateway
```

Once started successfully, the terminal displays connection information:

```
Gateway started

  ├─ Status   connected
  ├─ Mode     tunnel
  ├─ Local    http://127.0.0.1:8321
  ├─ Tunnel   https://xxx-xxx-xxx.trycloudflare.com
  ├─ Web UI   https://xxx-xxx-xxx.trycloudflare.com/?password=<token>
  └─ Webhook  https://xxx-xxx-xxx.trycloudflare.com/gateway/webhook/:platform

  Scan to open Web UI:

  [QR Code]
```

### Connection Methods

After the Gateway starts, you can connect from other devices in the following ways:

- **Scan the QR code**: Scan the QR code displayed in the terminal with your phone to open the Web UI directly
- **Copy the Web UI link**: Open the URL with the authentication token in any browser
- **LAN access**: Devices on the same network can access the Local address directly (e.g., `http://10.x.x.x:8321`)

### Subcommands

| Command | Description |
|:-----|:-----|
| `/gateway` | Start the Gateway (with Tunnel by default) |
| `/gateway status` | View the current Gateway status |
| `/gateway stop` | Stop the Gateway |
| `/gateway token` | Regenerate the authentication token |
| `/gateway tunnel` | Start the Gateway with Tunnel |

## Network Modes

The Gateway supports two network modes to accommodate different use cases:

### Tunnel Mode (Default)

Automatically assigns a temporary public domain (`*.trycloudflare.com`) through Cloudflare Quick Tunnel, allowing public network access without any additional configuration.

Use cases:
- Accessing remotely from an external network (e.g., mobile data)
- No need to configure port forwarding or VPN

Requires `cloudflared` to be installed:

```bash
# macOS
brew install cloudflared

# Debian/Ubuntu
curl -L https://pkg.cloudflare.com/cloudflared-stable-linux-amd64.deb -o cloudflared.deb
sudo dpkg -i cloudflared.deb

# Windows
winget install Cloudflare.cloudflared
```

### LAN Mode

When `cloudflared` is not installed or the Tunnel fails to start, the Gateway automatically falls back to LAN mode. In this mode, only devices on the same network can access it.

- Default listening port: `8321`
- Listening address: `127.0.0.1` by default (localhost only); use `--host 0.0.0.0` to listen on all network interfaces

## Security

### Authentication

When the Gateway starts, it automatically generates a random password (token). Both Web UI and API access require authentication. The following authentication methods are supported:

| Method | Description |
|:-----|:-----|
| URL parameter | `?password=<token>`, suitable for quickly sharing links |
| Cookie | Automatically set after login; subsequent visits do not require re-authentication |
| Bearer Token | `Authorization: Bearer <token>`, suitable for API calls |

The password can be regenerated using the `/gateway token` command. Once regenerated, the previous password is immediately invalidated.

### Login Rate Limiting

To prevent brute-force attacks, the authentication middleware includes built-in login rate limiting:

- A maximum of 2 failed attempts per minute
- An additional 12 failed attempts allowed per hour
- Login requests are temporarily rejected once limits are exceeded

### Permissions

Tasks executed via Remote Control automatically run in `bypassPermissions` mode, meaning tool executions do not require individual approval. This is because interactive approval is not possible in remote scenarios. Make sure you only share the access link with trusted individuals.

### CORS Policy

By default, the Gateway allows cross-origin requests from the following origins:

- Loopback addresses (`localhost`, `127.0.0.1`, `[::1]`)
- The public address assigned by the Tunnel
- Additional origins configured via `gateway.corsOrigins`

Three configuration modes are supported:

- **Exact match**: `https://example.com`
- **Subdomain wildcard**: `https://*.example.com` (matches all subdomains, including multi-level subdomains such as `a.b.example.com`)
- **Allow all**: `*`

## Web UI

The Web UI provides a complete CodeBuddy Code interaction interface, including:

- **Conversation interface**: Send messages, view Agent replies, and monitor tool calls
- **Terminal panel**: Built-in web terminal for operating the remote terminal directly in the browser
- **Instance management**: View and manage multiple CodeBuddy Code instances
- **Theme switching**: Supports light/dark themes
- **Multi-language**: Supports Chinese/English interface switching

The Web UI communicates with the local Agent via ACP (Agent Client Protocol), ensuring an experience fully consistent with terminal interaction.

## Configuration

### Settings Configuration

You can configure Gateway-related options in `~/.codebuddy/settings.json`:

```json
{
  "gateway": {
    "auth": "password",
    "password": "your-custom-password",
    "corsOrigins": ["https://your-domain.com", "https://*.example.com"],
    "maxConnections": 5,
    "tokenTtlMs": 86400000
  }
}
```

| Key | Description | Default |
|:------|:-----|:------|
| `auth` | Authentication mode, `"password"` or `"none"` | `"none"` |
| `password` | Custom password. Auto-generated on first start if empty | Auto-generated |
| `corsOrigins` | List of additional allowed CORS origins. Supports exact origins, `*.domain` subdomain wildcards, and `*` to allow all | `[]` |
| `maxConnections` | Maximum concurrent ACP connections | `5` |
| `tokenTtlMs` | ACP Session Token TTL in milliseconds | `86400000` (24 hours) |

### Environment Variables

| Environment Variable | Description |
|:---------|:-----|
| `CODEBUDDY_CODE_CORS_ORIGINS` | Additional allowed CORS origins (comma-separated). Supports exact origins, `*.domain` subdomain wildcards, and `*` to allow all. e.g., `https://*.example.com,https://specific.com` |

## Instance Management

When you run CodeBuddy Code in multiple project directories, each instance automatically registers with the local instance registry (`~/.codebuddy/instances.json`). The Web UI's instance management panel lets you view all active instances and switch between them.

Instance information includes:

- Working directory
- Local/Tunnel address
- Operating system and architecture
- Start time and running status

## Third-Party Platform Integration (Webhook)

The Gateway provides a Webhook endpoint for integrating with enterprise communication platform bots:

```
{gateway-url}/gateway/webhook/:platform
```

Supported platform adapters:

| Platform | Identifier |
|:-----|:-----|
| WeCom | `wecom` |
| DingTalk | `dingtalk` |
| Feishu (Lark) | `feishu` |
| Generic | `generic` |

After configuring the enterprise bot's Webhook callback URL to the above endpoint, you can send messages to CodeBuddy Code and receive replies through the enterprise communication platform.

## Connection and Security

- The Gateway only starts an HTTP service locally and does not open inbound ports on your machine
- Public access is achieved through Cloudflare Tunnel's outbound connections
- All Tunnel traffic is encrypted via Cloudflare's TLS
- When started with a fixed port, the Quick Tunnel domain can persist across CLI restarts (see [Keeping the Tunnel Domain Stable](#keeping-the-tunnel-domain-stable))

## Limitations

- **One Gateway per session**: Each CodeBuddy Code instance supports only one Gateway service at a time
- **Terminal must remain running**: The Gateway runs as a local process. Remote connections will be lost if the terminal is closed or the CodeBuddy Code process is stopped. Use `/gateway` to restart
- **Quick Tunnel domain is temporary**: The Quick Tunnel domain remains the same as long as the cloudflared process is alive. Starting with a fixed port allows the cloudflared process to be reused across CLI restarts (see [Keeping the Tunnel Domain Stable](#keeping-the-tunnel-domain-stable)). If the cloudflared process exits (e.g., machine restart), a new domain will be assigned. For a permanently fixed domain, use a Named Tunnel (requires a Cloudflare account)
- **LAN mode limitation**: Without `cloudflared` installed, access is limited to devices on the same network

## Keeping the Tunnel Domain Stable

By default, Quick Tunnel assigns a new random domain each time cloudflared starts. By specifying a fixed port, the domain can remain the same across multiple CLI restarts.

### Using a Fixed Port

Use the `--port` flag to start the CLI with a fixed port:

```bash
codebuddy --port 8321
```

This ensures the same port is used each time, and `/gateway` will automatically reuse the previous cloudflared process and domain.

> If `--port` is not specified, the system assigns a random port, and the different port each time prevents matching an existing cloudflared process.

### Stopping the Tunnel

Running `/gateway stop` terminates the cloudflared process and cleans up its state. A new domain will be assigned on the next start.

If you only exit the CLI (Ctrl+C or `/exit`), the cloudflared process continues running, waiting to be reused the next time the CLI starts.

## Related Documentation

- [Settings Configuration](settings.md): Configure Gateway-related options
- [Hooks](hooks.md): Configure custom commands before and after tool execution
- [Permission Management](iam.md): Learn about permission modes and rules
