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

# Set up ValarCode

> Install the Valar CLI, create a coding key, and connect Claude Code, Claude Desktop, Cursor, Codex, Pi, or VS Code

Getting an engineer onto ValarCode takes three steps: install the CLI, create a **coding key**, and run one connect command. After that, routing applies on its own. There are no config files to edit by hand.

## Prerequisites

* One of the supported harnesses installed locally: Claude Code, the Claude Desktop app, Cursor, Codex, Pi, or VS Code (via GitHub Copilot Chat).
* Access to the [Valar Dashboard](https://app.valarhq.ai) to create a coding key.
* macOS, Linux, or WSL for the CLI.

## Install the CLI

The `valar` CLI is a single, dependency-free binary. One line installs it, with no runtime to set up:

```bash theme={"system"}
curl -fsSL https://raw.githubusercontent.com/valarhq/valar-code-cli/main/install.sh | sh
```

Confirm it is on your path:

```bash theme={"system"}
valar --version
```

## Create a coding key

In the [Valar Dashboard](https://app.valarhq.ai), open **ValarCode** and create a coding key. Coding keys are scoped to agentic harnesses like Claude Code, Cursor, Codex, and Pi, and they carry your routing split. They use the `vlrcode_` prefix, and the token is shown once, so copy it before you leave the page.

<Note>
  A new key works right away. Until you set a split, it routes on Auto — Valar picks the target model — so it is safe to connect before you have tuned anything. See [Model routing](/valarcode/routing).
</Note>

Run `valar configure` once to store the key locally so you can drop `--api-key` from later commands:

```bash theme={"system"}
valar configure --api-key <your-coding-key>
```

The key is resolved from, in order: `--api-key`, then `$VALAR_API_KEY`, then `~/.valar/config.json`, then an interactive prompt.

## Connect a harness

Each engineer runs the connect command once per machine. Pick your harness for the full walkthrough and the behind-the-scenes detail:

<CardGroup cols={3}>
  <Card title="Claude Code" icon="code" href="/valarcode/claude-code">
    `valar claude on`
  </Card>

  <Card title="Claude Desktop" icon="desktop" href="/valarcode/claude-desktop">
    `valar claude-desktop on`
  </Card>

  <Card title="Cursor" icon="command" href="/valarcode/cursor">
    `valar cursor on`
  </Card>

  <Card title="Codex" icon="terminal" href="/valarcode/codex">
    `valar codex on`
  </Card>

  <Card title="Pi" icon="microchip" href="/valarcode/pi">
    `valar pi on`
  </Card>

  <Card title="VS Code" icon="window" href="/valarcode/vscode">
    `valar copilot on`
  </Card>
</CardGroup>

<Note>
  Routing Cursor requires a paid Cursor plan (Pro, Business, or Enterprise) — `valar cursor on` fails on the free plan or when Cursor is not signed in. `valar cursor` routes the Cursor **editor** (the desktop app); the Cursor CLI (`cursor-agent`) is not supported. VS Code routing goes through GitHub Copilot Chat's custom-endpoint provider, so it needs a signed-in Copilot and a recent VS Code. `valar vscode` and `valar copilot` are the same command.
</Note>

## Per-engineer attribution

To attribute usage and keep each engineer on a stable cohort, the CLI attaches a **client id** to every request. Most harnesses (Claude Code, Claude Desktop, Codex, Pi, and VS Code/Copilot) send it as an `X-Valar-Client-Id` header; Cursor, which cannot set custom headers, rides it as a token suffix (`<coding-key>~<client-id>`).

By default the client id is your **OS username** (normalized to lowercase `a-z 0-9 . _ - @ +`, capped at 64 characters), so the analytics leaderboard shows real engineers rather than opaque strings. Change how it is derived with `--user-id`:

| `--user-id` value         | Client id                                                                      |
| ------------------------- | ------------------------------------------------------------------------------ |
| *(omitted)* or `USERNAME` | Your OS username (the default)                                                 |
| `HOSTNAME`                | The machine hostname                                                           |
| `RANDOM`                  | An opaque `vc_…` hash of `username@hostname`, with no raw identity on the wire |
| any other value           | Used verbatim as the id (normalized the same way)                              |

The chosen id is recorded on `on`, so you can print it any time:

```bash theme={"system"}
valar id            # e.g. jdoe  (or vc_a713f7e67f3e8c06 under RANDOM)
```

<Note>
  A plain key with no client id still works, but those requests are not attributed to an engineer. The client id is supplied by the client and is used only for attribution and routing. It is not a security boundary; access is gated on the coding key itself.
</Note>

## CLI reference

The CLI follows a harness-first grammar. `on` is the default subcommand, so `valar claude` is the same as `valar claude on`.

```text theme={"system"}
valar <harness> [on|off|status] [flags]              # harness is claude, claude-desktop, cursor, codex, pi, or vscode
valar status                                         # stored defaults + which harnesses are routed
valar configure [--api-key <key>] [--user-id <id>]   # store defaults at ~/.valar/config.json
valar models [list|refresh]                          # show the offered models / re-pin the list in routed harnesses
valar usage [--window mtd|7d|30d]                    # your spend + savings vs Anthropic list prices
valar upgrade [--check]                              # self-update to the latest release (alias: valar update)
valar id                                             # print the recorded client id
valar version                                        # print the CLI version
```

`vscode` is an accepted alias for `copilot` (the editor is how users refer to it; the tool inside it is Copilot Chat).

**Per-harness commands**

| Command                  | What it does                                                         |
| ------------------------ | -------------------------------------------------------------------- |
| `valar <harness> on`     | Route the harness through Valar (keeps model names unchanged)        |
| `valar <harness> off`    | Restore the harness's original settings from the pre-enable snapshot |
| `valar <harness> status` | Show the current routing state (endpoint, masked key, client id)     |

**Flags**

| Flag              | Applies to                  | Meaning                                                                               |
| ----------------- | --------------------------- | ------------------------------------------------------------------------------------- |
| `--api-key <key>` | `on`, `configure`, `models` | Your Valar coding key (see resolution order above)                                    |
| `--user-id <id>`  | `on`, `configure`           | How to derive the client id: `USERNAME` (default), `HOSTNAME`, `RANDOM`, or a literal |
| `--force`         | `cursor`, `claude-desktop`  | Quit the app, apply the change, and relaunch it, instead of prompting                 |
| `--check`         | `upgrade`                   | Report whether a newer release exists without installing it                           |

## Keeping the CLI current

`valar upgrade` replaces the binary in place with the latest release, verifying the download's SHA256 before installing; `valar upgrade --check` only reports whether a newer version exists.

You rarely need to run it by hand. When a newer release is out, every interactive run offers to upgrade (`[Y/n]`, default yes) *before* it runs your command, then re-runs the command on the new version; a non-interactive run just prints a note. The check runs at most once a day. Set `VALAR_NO_UPDATE_CHECK=1` to silence it.

## Managing keys

* Revoke a coding key from the dashboard at any time. Requests using it stop resolving.
* Issue a separate key per team or experiment to run different splits side by side. The same engineer can land in different cohorts under different keys.

## Next steps

<CardGroup cols={2}>
  <Card title="Model routing" icon="route" href="/valarcode/routing">
    Set the split and choose target models.
  </Card>

  <Card title="Analytics & savings" icon="chart-line" href="/valarcode/analytics">
    Watch usage and savings come in per engineer.
  </Card>
</CardGroup>
