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

# Client Utilities

> Access files and a browser on your local machine from inside a boxd VM.

boxd client tools run on your Mac (Windows support coming soon) and bridge local resources into your VMs. Once enabled, you can paste images into Claude Code, read files from your local filesystem, and control a local Chrome browser — all from inside a VM.

## Enable

The client utilities are built into the `boxd` CLI from the [Quickstart](/quickstart#1-install) — there's no separate download. They're **off by default**; turn them on once per machine with:

```bash theme={"theme":"github-dark"}
boxd config set client-utils.enable true
```

This installs a small background agent (a launchd agent on macOS) and registers this device with boxd. Manage it any time with:

```bash theme={"theme":"github-dark"}
boxd config get client-utils.enable         # is it enabled and running?
boxd config set client-utils.enable false   # stop and remove the agent
```

<Info>
  Currently available for macOS (Apple Silicon) only.
</Info>

## How it works

`boxd config set client-utils.enable true` registers your machine under a device id and starts a background agent that keeps a connection open to boxd. Every VM you enter with `boxd connect` or `ssh <vm>.boxd` carries that device id, so the `boxd local` commands inside the VM route back to your machine through boxd — no per-connection setup, and it keeps working across reconnects.

Run `boxd config get client-utils.enable` to confirm it's enabled and running.

## Clipboard and image pasting

With client tools enabled, you can paste images from your Mac's clipboard directly into Claude Code running inside a VM. This works via an `xclip` shim that intercepts clipboard reads and routes them through boxd to your Mac's clipboard.

This is especially useful for sharing screenshots, diagrams, or UI mockups with Claude Code without manually transferring files.

## Reading local files

List and read files on your local machine from inside a VM:

```bash theme={"theme":"github-dark"}
boxd local ls                              # List your home directory
boxd local ls Documents                    # Relative to home
boxd local ls /Users/you/Desktop           # Absolute path
boxd local read ~/notes.txt                # Read a file
boxd local read ~/app.log --tail=50        # Last 50 lines
boxd local read ~/app.log --head=20        # First 20 lines
boxd local read ~/app.log --range=10:30    # Lines 10 through 30
```

Output from `ls` shows absolute paths with type and size:

```
dir   /Users/you/Documents
file  /Users/you/.bashrc (1234 bytes)
```

All commands accept `--json` for structured output.

### Path access

For security, only files under your home directory are accessible. Paths outside it are blocked.

## Browser

Launch and control a Chrome instance on your Mac, with the Chrome DevTools Protocol (CDP) forwarded into the VM. This lets tools like Puppeteer or Playwright running inside a VM control a real browser on your local machine.

```bash theme={"theme":"github-dark"}
boxd local browser open                    # Launch Chrome
boxd local browser open --headless         # Launch headless
boxd local browser info                    # Check status and CDP URL
boxd local browser close                   # Close the browser
```

### Connecting via CDP

`boxd local browser open` (and `boxd local browser info`) print the CDP WebSocket URL — it points at boxd's device ingress (`…/device/<id>/browser/ws`) and is forwarded to the Chrome instance on your machine. Pass that URL to Puppeteer or Playwright.

Connect from Puppeteer:

```javascript theme={"theme":"github-dark"}
const puppeteer = require('puppeteer-core');
const { execSync } = require('child_process');

// Launches Chrome on your machine and prints "CDP WebSocket: <url>".
const out = execSync('boxd local browser open', { encoding: 'utf8' });
const wsUrl = out.match(/CDP WebSocket: (\S+)/)[1];

const browser = await puppeteer.connect({ browserWSEndpoint: wsUrl });
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'screenshot.png' });
```

Or from Playwright:

```javascript theme={"theme":"github-dark"}
const { chromium } = require('playwright-core');
const { execSync } = require('child_process');

const out = execSync('boxd local browser open', { encoding: 'utf8' });
const wsUrl = out.match(/CDP WebSocket: (\S+)/)[1];

const browser = await chromium.connectOverCDP(wsUrl);
```

Or straight from chrome using the pre-installed and pre-configured [chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp):

```bash theme={"theme":"github-dark"}
claude
# open my local browser and search for cat pictures on google
```

### Session persistence

The browser uses a fixed session directory on your Mac (`~/.boxd/browser-sessions/default/`). Cookies, localStorage, and login state persist across `open`/`close` cycles.

Only one browser instance runs at a time. Calling `open` when a browser is already running returns the existing session.

## Updating

Re-run the [boxd install command](/quickstart#1-install) to update — it upgrades the `boxd` CLI in place. The next time you run `boxd`, the client agent automatically restarts on the new version.

If `boxd local` commands inside a VM show a message about updating, it means the agent on your machine is missing features available in the latest version.
