> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/ai-workbench/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/ai-workbench/_mcp/server.

# Using the CLI Binary for Scripts and Agents

## Overview

**Scripts and agents call the CLI binary directly instead of the** `nvwb` **shell wrapper.**

The binary is found at `~/.nvwb/bin/nvwb-cli` on macOS and Linux, as well as in the WSL distribution on Windows.

The shell wrapper is a bash function that is only available in interactive shells that have sourced `.bashrc`.
A script or agent's execution environment does not guarantee that.

**The binary does not use** `activate`**,** `deactivate`**,** `open` **or** `close`**.**

Those commands manage shell session state for interactive use through the `nvwb` wrapper.
Script and agent commands run in their own process, so they don't inhereit session state.

Instead, you need to pass the location and project to the command explicitly using the `-c` and `-p` flags, as
well as setting the output flag like `-o json`.

**Not all commands require the contect and project flag.**

Not every command needs all three flags.

For example the `list contexts` command doesn't require any flags, nor do the integration commands.

Others, for example `list projects` and `list bases` require a location flag with `-c` but not a project with `-p`.

**The CLI does not change its output format when piped.**

The default table output is identical whether stdout is a terminal or a pipe.
`-o json` is required for any command whose output you want to parse.

## Key Concepts

**Calling convention**

Projects: `~/.nvwb/bin/nvwb-cli -c <context> -p <project-path> <command> [args] -o json`.

Location but no project: `~/.nvwb/bin/nvwb-cli -c <context> <command> [args] -o json`.

Targeting AI Workbench itself `~/.nvwb/bin/nvwb-cli <command> [args] -o json`.

**Context flag** `-c`

Replaces `activate` when calling the binary.
Does not start the service on the location, and the location must already be running

Not needed for commands that do not target a specific location, such as `list contexts` or integration commands.

**Project flag** `-p`

Replaces `open` when calling the binary and takes the absolute path to the project directory on the location.

Not needed for commands that do not target a specific project, such as `list projects` or `create project`.

**JSON output** `-o json`

Returns structured JSON instead of styled table output.
Required for parsing command results.

## Calling Convention

**Pass** `-c` **and** `-p` **where relevant, and** `-o json` **when you need to parse the output.**

```bash
#!/bin/bash
# Define the binary path and context once
NVWB="$HOME/.nvwb/bin/nvwb-cli"
CONTEXT="local"
PROJECT="/home/workbench/nvidia-workbench/my-project"

# Commands that target AI Workbench itself (no -c or -p)
$NVWB list contexts -o json
$NVWB list integrations -o json
$NVWB connect integration Github

# Commands that target a location (-c only)
$NVWB list projects -c "$CONTEXT" -o json
$NVWB list bases -c "$CONTEXT" -o json

# Commands that target a project (-c and -p)
$NVWB status -c "$CONTEXT" -p "$PROJECT" -o json
$NVWB build -c "$CONTEXT" -p "$PROJECT"
```

<Note title="On Windows you can use a WSL command to call the CLI or you can do it in the WSL distribution.">

If you are scripting or using an agent from the Windows side, you can wrap them in a call to the proper WSL distribution.

Example: `wsl -d NVIDIA-Workbench -u workbench -- /home/workbench/.nvwb/bin/nvwb-cli <arguments>`

</Note>

## JSON Response Shapes

**Every JSON response from the CLI is one of four shapes.**

**List and query commands return** `{"result": [...]}`**.**

The result is always an array, even for a single item.
Access items with `.result[]` in `jq`.

```bash
# Extract all project paths
$NVWB list projects -c local -o json | jq -r '.result[].Path'
```

**The** `status` **command returns** `{"result": {...}}`**.**

The result is a single object, not an array.
Access fields directly with `.result.FieldName`.

```bash
# Get build state
$NVWB status -c local -p "$PROJECT" -o json | jq -r '.result.Environment.BuildState'
```

**The** `create project` **and** `clone project` **commands return** `{"messages": [...]}`**.**

Each message has `message` and `detail` fields.
The project path is embedded in the message string, not a dedicated field.
Use the `--projectPath` you passed to the command rather than parsing the message.

**All errors return** `{"error": "...", "detail": "..."}`**.**

This shape is consistent across every command.
Exit code 1 accompanies every error response.

```bash
#!/bin/bash
# Check for errors in the response
RESPONSE=$($NVWB status -c local -p "$PROJECT" -o json)

ERROR=$(echo "$RESPONSE" | jq -r '.error // empty')
if [ -n "$ERROR" ]; then
  DETAIL=$(echo "$RESPONSE" | jq -r '.detail // empty')
  echo "Error: $ERROR — $DETAIL"
  exit 1
fi
```

## Project State Machine

**Many commands require the project to be in a specific state before they succeed.**

Check the project state with `status` before running commands that have preconditions.

**Build states:**

- `NO_BUILD` — Build has never run or was reset.
- `BUILDING` — Build is in progress.
- `BUILD_COMPLETE` — Built and the project container is available.
- `BUILD_ERROR` — Last build failed.

**Run states:**

- `CONTAINER_NOT_CREATED` — The project container does not exist.
- `RUNNING` — The project container is running.
- `STOPPED` — The project container exists but is stopped.

**Preconditions by operation:**

- `build` — Any build state. Re-runs if already built.
- `start <app>` — Build state must be `BUILD_COMPLETE`. All sensitive environment variables must be configured.
- `stop <app>` — Run state must be `RUNNING`.
- `add/remove` environment variables, mounts, or secrets — Run state must be `CONTAINER_NOT_CREATED` or `STOPPED`.
- `delete project` — Run state must be `CONTAINER_NOT_CREATED` or `STOPPED`.

**Check state before acting.**

```bash
#!/bin/bash
# Only build if the project has not been built
NVWB="$HOME/.nvwb/bin/nvwb-cli"
PROJECT="/home/workbench/nvidia-workbench/my-project"

STATE=$($NVWB status -c local -p "$PROJECT" -o json \
  | jq -r '.result.Environment.BuildState')

if [ "$STATE" = "NO_BUILD" ] || [ "$STATE" = "BUILD_ERROR" ]; then
  $NVWB build -c local -p "$PROJECT"
fi
```

## Useful Status Fields

**The** `status` **command returns detailed project information.**

Use `jq` to extract the fields you need.

```
result.Path                           Absolute path (use with -p)
result.Name                           Registered name (from spec.yaml)
result.Environment.BuildState         See build states above
result.Environment.RunState           See run states above
result.Applications[].name            Application name for start/stop
result.Applications[].info.runState   NOT_RUNNING or RUNNING
result.Applications[].info.url        null when stopped, URL when running
result.RepoState.CommitsAhead         Integer
result.RepoState.CommitsBehind        Integer
result.CurrentGitBranch.Name          Current branch name
result.Resources.GPUsRequested        Integer
```

## Use the Project Path, Not the Name

**Always identify projects by absolute path, not by name.**

The registered project name comes from `spec.yaml` inside the repository, not from the directory name.
Cloning a project into `--projectPath .../my-dir` may register it under a completely different name.
The absolute path is stable and unambiguous.

```bash
#!/bin/bash
# Correct: use the path you specified
$NVWB clone project https://github.com/org/repo \
  --projectPath /home/workbench/nvidia-workbench/my-project \
  -c local

# Subsequent commands use the same path
$NVWB build -c local -p /home/workbench/nvidia-workbench/my-project
```

## Patterns

**Check state, build, and start an application.**

```bash
#!/bin/bash
NVWB="$HOME/.nvwb/bin/nvwb-cli"
CONTEXT="local"
PROJECT="/home/workbench/nvidia-workbench/my-project"

# Check current build state
BUILD_STATE=$($NVWB status -c "$CONTEXT" -p "$PROJECT" -o json \
  | jq -r '.result.Environment.BuildState')

# Build if needed
if [ "$BUILD_STATE" = "NO_BUILD" ] || [ "$BUILD_STATE" = "BUILD_ERROR" ]; then
  $NVWB build -c "$CONTEXT" -p "$PROJECT"
fi

# Check run state before starting
RUN_STATE=$($NVWB status -c "$CONTEXT" -p "$PROJECT" -o json \
  | jq -r '.result.Environment.RunState')

if [ "$RUN_STATE" != "RUNNING" ]; then
  APP_NAME=$($NVWB status -c "$CONTEXT" -p "$PROJECT" -o json \
    | jq -r '.result.Applications[0].name')

  $NVWB start "$APP_NAME" -c "$CONTEXT" -p "$PROJECT" --no-browser
fi
```

**Iterate over all projects in a location.**

```bash
#!/bin/bash
# Get status for every project in a location
NVWB="$HOME/.nvwb/bin/nvwb-cli"

$NVWB list projects -c local -o json \
  | jq -r '.result[].Path' \
  | while read path; do
      $NVWB status -c local -p "$path" -o json \
        | jq '{name: .result.Name, build: .result.Environment.BuildState, run: .result.Environment.RunState}'
    done
```

**Set a sensitive variable from stdin.**

```bash
#!/bin/bash
# Pipe a value from a vault or environment into a sensitive env var
echo "$SECRET_VALUE" | $NVWB create environment-variable API_KEY - \
  --is-sensitive -c local -p "$PROJECT" -o json
```

**Create a project with a specific base environment.**

```bash
#!/bin/bash
NVWB="$HOME/.nvwb/bin/nvwb-cli"

# Look up the base environment ID
BASE_ID=$($NVWB list bases -c local -o json \
  | jq -r '.result[] | select(.Name == "Python Basic") | .Id')

# Create the project
$NVWB create project my-project \
  --base-environment-id "$BASE_ID" \
  --projectPath /home/workbench/nvidia-workbench/my-project \
  -c local

# Build using the known path
$NVWB build -c local -p /home/workbench/nvidia-workbench/my-project
```

## Related Topics

- [AI Workbench Command Line Interface (CLI) Reference](/ai-workbench/reference/user-interface/cli) - CLI command reference (command index, output formats, behavioral notes)
- [Output Formats](/ai-workbench/reference/user-interface/cli#output-formats) - JSON response shapes and output format details
- [Project State Machine](/ai-workbench/reference/user-interface/cli#project-state-machine) - Project state machine and preconditions
- [Interactive CLI Use](/ai-workbench/how-to/cli/cli-interactive) - Interactive CLI use
- [Setting Up an Agent Skill](/ai-workbench/how-to/cli/cli-agents) - Setting up agent skills for the CLI