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

# Zenable CLI Reference

> Complete reference for all zenable CLI commands and options

## Quick Installation

<CodeGroup>
  ```bash macOS / Linux theme={null}
  curl -fsSL https://cli.zenable.app/install.sh | bash
  ```

  ```powershell Windows theme={null}
  powershell -ExecutionPolicy Bypass -Command "irm https://cli.zenable.app/install.ps1 | iex"
  ```
</CodeGroup>

For more installation options, see the [Getting Started](/integrations/mcp/getting-started?utm_source=docs\&utm_medium=web) guide.

## Overview

Zenable CLI - conformance checking, IDE management, and hook handling for agentic IDEs.

The `zenable` CLI is the native Go binary for conformance checking, IDE management, and hook handling.

## Global Options

These options are available for all commands:

| Option            | Description                                     |
| ----------------- | ----------------------------------------------- |
| `-v`, `--verbose` | Enable verbose output (repeatable: `-v`, `-vv`) |
| `-h`, `--help`    | Show help message                               |

## Commands

### `install`

Install the Zenable integrations.

```bash theme={null}
zenable install [OPTIONS] [COMMAND] [ARGS]...
```

**Note**: You can use unified commands like `install cursor` or `install claude-code`, or use subcommands like `install mcp cursor` and `install hook claude-code`. The unified commands are simpler and install all features.

#### Options

| Option            | Description                                                                         |
| ----------------- | ----------------------------------------------------------------------------------- |
| `-d`, `--dry-run` | Preview what would be done without actually performing the installation             |
| `-p`, `--project` | Install in the project directory instead of globally                                |
| `--include TEXT`  | Include only directories matching these glob patterns (e.g., `'**/microservice-*'`) |
| `--exclude TEXT`  | Exclude directories matching these glob patterns                                    |
| `--all`           | Install for all supported IDEs, even if not currently installed                     |
| `-h`, `--help`    | Show help message                                                                   |

By default, `zenable install` installs globally so the integration is available across all your projects.

<Note>
  **Want project-level installation?** Run `zenable install --project` from inside a git repository to install only for that project. When using `--project` outside a git repository, the installer will present an interactive TUI to select which repositories to install into.
</Note>

#### Subcommands

##### `install mcp`

Install Zenable MCP server configuration.

**Uses OAuth for secure authentication.**

```bash theme={null}
zenable install mcp [OPTIONS] COMMAND [ARGS]...
```

Additional options:

| Option              | Description                                           |
| ------------------- | ----------------------------------------------------- |
| `--overwrite`       | Overwrite existing Zenable configuration if it exists |
| `--no-instructions` | Don't show post-installation instructions             |

Supported IDE commands:

* `all` - Install MCP for all detected IDEs (default)
* `amp` - Install MCP for [Amp](/integrations/mcp/ide/amp)
* `antigravity` - Install MCP for [Antigravity](/integrations/mcp/ide/antigravity)
* `auggie` (alias: `augment`) - Install MCP for [Auggie](/integrations/mcp/ide/auggie)
* `claude-code` (alias: `claude`) - Install MCP for [Claude Code](/integrations/mcp/ide/claude-code)
* `codex` - Install MCP for [Codex](/integrations/mcp/ide/codex)
* `continue` - Install MCP for the [Continue](/integrations/mcp/ide/continue) IDE\*
* `copilot-cli` - Install MCP for [GitHub Copilot CLI](/integrations/mcp/ide/copilot)
* `cursor` - Install MCP for [Cursor](/integrations/mcp/ide/cursor) IDE and cursor-agent CLI
* `gemini` - Install MCP for [Gemini CLI](/integrations/mcp/ide/gemini)
* `kiro` - Install MCP for [Kiro](/integrations/mcp/ide/kiro)
* `roo` - Install MCP for [Roo Code](/integrations/mcp/ide/roo)
* `vscode` - Install MCP for [Visual Studio Code](/integrations/mcp/ide/vscode)
* `windsurf` - Install MCP for [Windsurf](/integrations/mcp/ide/windsurf) IDE

##### `install hook`

Install hooks for various tools.

```bash theme={null}
zenable install hook [OPTIONS] COMMAND [ARGS]...
```

Supported hook commands:

* `all` - Install hooks for all supported tools
* `claude-code` (alias: `claude`) - Install Claude Code hooks
* `cursor` - Install Cursor hooks

###### Options

| Option           | Description                                                                         |
| ---------------- | ----------------------------------------------------------------------------------- |
| `--dry-run`      | Preview what would be done without actually performing the installation             |
| `--include TEXT` | Include only directories matching these glob patterns (e.g., `'**/microservice-*'`) |
| `--exclude TEXT` | Exclude directories matching these glob patterns                                    |
| `-h`, `--help`   | Show help message                                                                   |

#### Examples

```bash theme={null}
# Install globally for all detected IDEs (recommended)
zenable install

# Install for a specific IDE using unified command (recommended)
zenable install cursor
zenable install claude-code

# Install in the current project only
zenable install --project

# Preview what would be done without installing
zenable install --dry-run

# Advanced: Install only MCP (without hooks) for all detected IDEs
zenable install mcp

# Advanced: Install only MCP for a specific IDE
zenable install mcp cursor

# Advanced: Install only hooks
zenable install hook
zenable install hook claude-code
zenable install hook cursor
```

### `uninstall`

Remove Zenable integrations from your system.

```bash theme={null}
zenable uninstall [OPTIONS]
```

Launches an interactive TUI to select which integrations to remove.

#### Options

| Option            | Description                                                          |
| ----------------- | -------------------------------------------------------------------- |
| `-d`, `--dry-run` | Preview what would be done without actually performing the uninstall |
| `-p`, `--project` | Uninstall from the project directory instead of globally             |
| `--all`           | Uninstall from all IDEs without interactive selection                |
| `-h`, `--help`    | Show help message                                                    |

### `check`

Check the provided files against your conformance tests.

```bash theme={null}
zenable check [OPTIONS] [PATTERNS]...
```

Automatically detects files from IDE context when no patterns are provided.
Supports glob patterns like `**/*.py` to check all Python files recursively.
Accepts piped input via stdin from `git status --short` or plain file lists.
Files are processed in batches of 5 for optimal performance.

#### Arguments

* `PATTERNS`: Glob patterns for files to check (e.g., `'**/*.py'`, `'src/**/*.js'`)
  * If no patterns are provided, auto-detects the last edited file, subject to filtering. Use `--verbose` for filtering details

#### Stdin

When input is piped to `zenable check`, it reads file paths from stdin. This supports:

* **`git status --short`** output — status prefixes are automatically stripped, deleted files are skipped, and renames use the new path
* **Plain file lists** — one file path per line

#### Options

| Option                  | Description                                                                                                                                       |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--exclude TEXT`        | Patterns to exclude from checking                                                                                                                 |
| `--base-path DIRECTORY` | Base directory for pattern matching (defaults to current directory)                                                                               |
| `--branch`              | Check all files changed on the current branch compared to the base branch                                                                         |
| `--base-branch TEXT`    | Base branch to compare against when using `--branch` (default: `$ZENABLE_CHECK_BASE_BRANCH` or `main`)                                            |
| `--dry-run`             | Show which files would be sent without actually checking them                                                                                     |
| `--format TEXT`         | Output format(s): `text`, `json`, `sarif`, or `html`. Supports multiple formats and file paths (e.g. `text,sarif=results.sarif`). Default: `text` |
| `--skip-ai-review`      | Skip AI review (overrides config and env var)                                                                                                     |
| `--skip-semgrep`        | Skip semgrep guardrails (overrides config and env var)                                                                                            |
| `-h`, `--help`          | Show help message                                                                                                                                 |

#### Configuration

The `check` command supports configuration via environment variables:

| Environment Variable        | Description                                                  | Default |
| --------------------------- | ------------------------------------------------------------ | ------- |
| `ZENABLE_CHECK_BASE_BRANCH` | Default base branch to compare against when using `--branch` | `main`  |

##### Example

```bash theme={null}
# Set default base branch to develop
export ZENABLE_CHECK_BASE_BRANCH=develop

# Now --branch uses develop instead of main
zenable check --branch

# CLI option still overrides env var
zenable check --branch --base-branch feature/base
```

#### Examples

```bash expandable theme={null}
# Check a single file
zenable check example.py

# Check all Python files recursively
zenable check '**/*.py'

# Check multiple patterns
zenable check 'src/**/*.js' 'tests/**/*.js'

# Pipe git status to check modified/untracked files
git status --short | zenable check

# Pipe a file list from any command
find src -name '*.py' | zenable check

# Exclude test files from checking
zenable check '**/*.py' --exclude '**/test_*.py'

# Specify base directory for pattern matching
zenable check '*.py' --base-path ./src

# Check all files changed on current branch compared to main
zenable check --branch

# Check all files changed on current branch compared to develop
zenable check --branch --base-branch develop

# Check only Python src files changed on current branch
zenable check --branch '**/*.py' --exclude '**/test_*.py'

# Dry run to see which files would be checked
zenable check '**/*.py' --dry-run

# Output results in SARIF format to a file (e.g. for CI integration)
zenable check '**/*.py' --format sarif=results.sarif

# Output results in JSON format to a file
zenable check '**/*.py' --format json=results.json

# Output text to terminal and write SARIF + JSON to files
zenable check '**/*.py' --format text,sarif=results.sarif,json=results.json

# Output HTML report to a file
zenable check '**/*.py' --format html=report.html

# Output multiple formats to stdout
zenable check '**/*.py' --format sarif,json

# Skip AI review and only run semgrep guardrails
zenable check '**/*.py' --skip-ai-review
```

### `hook`

Handle calls from the hooks of Agentic IDEs.

```bash theme={null}
zenable hook [OPTIONS]
```

This command is specifically designed for IDE integrations like Claude Code and Cursor.
It reads hook input from stdin, processes the files, and returns appropriate
exit codes and formatted responses for the IDE to handle.

To manually run a scan, use the `check` command instead.

#### Options

| Option         | Description       |
| -------------- | ----------------- |
| `-h`, `--help` | Show help message |

<Note>
  **Reverted files are not reviewed.** When an agent modifies a file and then reverts it back to match the base branch (e.g., via `git checkout`), the hook will report "No files to process" because there is no net change compared to the base branch. This is expected behavior — Zenable reviews the *diff*, not individual edits, so if the final state matches what's already on the base branch, there's nothing new to review.
</Note>

### `triage`

Fetch and address unresolved review comments on a pull request or merge request.

```bash theme={null}
zenable triage [OPTIONS]
```

Auto-detects the PR (GitHub) or MR (GitLab) for the current branch and fetches every commentable surface — line-level review threads, PR-level issue comments, and submitted-review summary bodies — in a single XML payload aimed at AI coding agents. By default only comments from the Zenable AI guardrails bot are returned; flags loosen that filter.

The default output embeds an `<instructions>` block telling the agent how to process each thread (commit per thread, push, then reply). Use `--reply` to post a response to a single thread, or `--report-only` to emit a read-only research-report prompt that produces no commits, pushes, or replies.

#### Modes

| Mode           | Flag            | What it does                                                                                                                                 |
| -------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| List (default) | *none*          | Print threads + an `<instructions>` block guiding the agent to fix, commit, push, and reply.                                                 |
| Reply          | `--reply`       | Post a single reply to a thread, either referencing a commit (`--commit`) or with a custom body (`--comment`).                               |
| Report-only    | `--report-only` | Emit a prompt that has the agent research each comment and print a structured markdown report to stdout — no commits, no pushes, no replies. |

#### Options

| Option                 | Description                                                                                                                                                                                                       |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--pr INTEGER`         | GitHub PR number (auto-detected from current branch if omitted). Mutually exclusive with `--mr`.                                                                                                                  |
| `--mr INTEGER`         | GitLab MR number (auto-detected from current branch if omitted). Mutually exclusive with `--pr`.                                                                                                                  |
| `--all-bots`           | Include comments from all bots, not just the Zenable AI guardrails bot.                                                                                                                                           |
| `--all-authors`        | Include comments from all authors (humans and bots).                                                                                                                                                              |
| `--include-resolved`   | Include resolved review threads. Only applies to line-level threads; issue comments and review summaries have no resolve concept.                                                                                 |
| `--format TEXT`        | Output format: `xml` (default), `json`, or `text`.                                                                                                                                                                |
| `--push-strategy TEXT` | How commits and replies are sequenced in default-mode instructions: `batch` (default — commit per thread, push once, then reply) or `each` (commit, push, reply per thread). Ignored when `--report-only` is set. |
| `--reply`              | Reply to a single thread. Requires `--thread-id` and one of `--commit`/`--comment`. Mutually exclusive with `--report-only`.                                                                                      |
| `--thread-id TEXT`     | Thread ID to reply to (used with `--reply`).                                                                                                                                                                      |
| `--commit TEXT`        | Commit hash that addresses the thread (used with `--reply`). Mutually exclusive with `--comment`.                                                                                                                 |
| `--comment TEXT`       | Custom reply body (used with `--reply`). Mutually exclusive with `--commit`.                                                                                                                                      |
| `--report-only`        | Emit a read-only research-report prompt; no commits, pushes, or replies. Mutually exclusive with `--reply`.                                                                                                       |
| `-h`, `--help`         | Show help message.                                                                                                                                                                                                |

#### Examples

```bash expandable theme={null}
# List unresolved bot review comments (auto-detect PR/MR)
zenable triage

# List comments for a specific GitHub PR
zenable triage --pr 123

# List comments for a specific GitLab MR
zenable triage --mr 456

# Include comments from all authors, not just the bot
zenable triage --all-authors

# Include resolved threads as well
zenable triage --include-resolved

# Switch to per-thread commit + push + reply cycles
zenable triage --push-strategy each

# Reply to a thread by referencing a commit
zenable triage --reply --thread-id PRRT_abc123 --commit abc123f

# Reply to a thread with a custom comment
zenable triage --reply --thread-id PRRT_abc123 --comment "Intentional, see docs"

# Emit a read-only research-report prompt — no commits, no replies
zenable triage --report-only

# Same, but as JSON for downstream tooling
zenable triage --report-only --format json
```

<Note>
  **Resolve state only applies to line-level review comments.** Issue comments (PR-level conversation) and review summaries (the body of a submitted review) have no resolve/unresolve concept, so `--include-resolved` is a no-op for them.
</Note>

### `login`

Authenticate with Zenable via OAuth.

```bash theme={null}
zenable login
```

Opens a browser to complete the OAuth authentication flow. Credentials are cached locally for future commands. If already authenticated, skips re-authentication.

### `logout`

Clear local OAuth credentials.

```bash theme={null}
zenable logout [OPTIONS]
```

#### Options

| Option  | Description                                             |
| ------- | ------------------------------------------------------- |
| `--all` | Also open Auth0 logout in browser to end remote session |

### `sync`

Sync guardrails from Zenable to local disk.

```bash theme={null}
zenable sync
```

Downloads and caches semgrep guardrails locally for faster conformance checks. Uses ETag-based caching to avoid re-downloading unchanged guardrails. Requires authentication.

### `logs`

View zenable logs.

```bash theme={null}
zenable logs [OPTIONS]
```

#### Options

| Option                  | Description                                             |
| ----------------------- | ------------------------------------------------------- |
| `-f`, `--follow`        | Follow log output (like `tail -f`)                      |
| `-r`, `--raw`           | Show raw log entries instead of just messages           |
| `-n`, `--lines INTEGER` | Number of lines to show (from end of file, default: 50) |
| `--clear`               | Clear the log file (cannot be used with other options)  |
| `-h`, `--help`          | Show help message                                       |

#### Examples

```bash theme={null}
# View recent logs
zenable logs

# Follow logs in real-time
zenable logs --follow

# Show last 50 lines
zenable logs -n 50

# Clear logs
zenable logs --clear
```

### `doctor`

Diagnose and troubleshoot installation and client issues.

```bash theme={null}
zenable doctor
```

Displays diagnostic information including OS details, terminal environment, Zenable environment variables (sensitive values redacted), dependency status, authentication state, custom guardrail validation status, and recent log entries.

The Custom Guardrails section reports each configured custom guardrail file by absolute path with one of the following statuses:

* `✓` — passed both upstream syntax and Zenable schema checks
* `✗` — failed Zenable schema validation
* `?` — partially or not yet validated; run `zenable guardrail validate <engine> <file>` for more details

### `guardrail`

Inspect and validate custom guardrail rules. The first positional argument selects the engine (`opengrep` or `semgrep`) — the server never infers it from the rule body. Subsequent arguments are file paths or glob patterns.

```bash theme={null}
zenable guardrail [SUBCOMMAND]
```

#### `guardrail validate`

Validate one or more custom guardrail rule files. Runs the engine's native `validate` command (catches YAML / pattern syntax errors) and the Zenable schema check (catches the field-level rules that protect the findings API). Validation results are cached locally by SHA-256 of the rule body, so re-running is free for unchanged files.

```bash theme={null}
zenable guardrail validate <engine> <file-or-glob>...
```

##### Arguments

* `<engine>` — required; one of `opengrep` or `semgrep`. Explicit by design; the server never infers it from the rule body.
* `<file-or-glob>...` — one or more file paths or glob patterns. Globs expand relative to the current working directory. Excludes and config-driven skip-filenames do NOT apply: this command validates exactly what you point it at.

##### Options

* `--format <format>` — `text` (default) or `json`

##### Examples

```bash theme={null}
# Validate one file
zenable guardrail validate opengrep ~/.zenable/custom_guardrails/semgrep/custom-no-eval.yaml

# Validate every YAML rule in a directory
zenable guardrail validate semgrep '~/.zenable/custom_guardrails/semgrep/*.yaml'

# Machine-readable output for CI
zenable guardrail validate opengrep '**/*.yaml' --format json | jq
```

##### Exit Codes

* `0` — all files passed (or were partial-pass)
* `1` — at least one file failed validation
* `2` — bad arguments (unknown engine, no files matched)

### `version`

Show the zenable version.

```bash theme={null}
zenable version
```

Will also notify you if an update is available.

## Configuration Files

### MCP Server Configuration

The tool creates MCP server configuration in IDE-specific locations, appropriate for that individual IDE. For instance:

```json theme={null}
{
  "mcpServers": {
    "zenable": {
      "type": "http",
      "url": "https://mcp.zenable.app/"
    }
  }
}
```

### Hook Configuration (Claude Code)

Hooks are configured in Claude Code settings (`.claude/settings.json`):

```json expandable theme={null}
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "zenable hook"
          }
        ]
      }
    ]
  }
}
```

### Hook Configuration (Cursor)

Hooks are configured in Cursor hooks file (`.cursor/hooks.json`):

```json expandable theme={null}
{
  "version": 1,
  "hooks": {
    "afterFileEdit": [
      {
        "command": "zenable hook"
      }
    ]
  }
}
```

## Exit Codes

| Code | Meaning                  |
| ---- | ------------------------ |
| 0    | Success                  |
| 2    | Conformance issues found |
| 3    | Handler conflict         |
| 4    | No hook input            |
| 12   | No files specified       |
| 13   | No files found           |
| 14   | File read error          |
| 15   | Invalid parameters       |
| 16   | File write error         |
| 20   | API error                |
| 21   | Authentication error     |
| 51   | Installation error       |
| 52   | Partial success          |
| 130  | User interrupt           |

## File Patterns

### Glob Pattern Examples

```bash expandable theme={null}
# All Python files recursively
'**/*.py'

# Multiple extensions
'**/*.{js,ts,jsx,tsx}'

# Specific directory
'src/**/*.py'

# All files in current directory
'*'

# All files recursively
'**/*'

# Specific depth
'*/*.py'  # One level deep
'*/*/*.py'  # Two levels deep
```

### Common Exclusions

```bash expandable theme={null}
# Python
--exclude '**/{__pycache__,venv,.venv,migrations}/**'

# JavaScript/Node
--exclude '**/{node_modules,dist,build,.next}/**'

# General
--exclude '.git/**'
--exclude '**/*.min.js'
--exclude '**/*.map'
--exclude '**/vendor/**'
```

## Troubleshooting

### Debug Mode

Enable debug output for troubleshooting:

```bash theme={null}
# Maximum verbosity
zenable -vv install

# Run a check with verbose output
zenable -v check '**/*.py'

# View debug logs
zenable logs --lines 100

# Run diagnostics
zenable doctor
```

### Dry Run Mode

Preview changes without applying:

```bash theme={null}
# Preview installation
zenable install --dry-run

# Preview with specific IDE
zenable install mcp cursor --dry-run
```

\*Continue users may experience issues until Continue adds [support for streamable HTTP](https://github.com/continuedev/continue/issues/6282).

## See Also

* [Getting Started](/integrations/mcp/getting-started?utm_source=docs\&utm_medium=web)
* [Troubleshooting](/integrations/mcp/troubleshooting?utm_source=docs\&utm_medium=web)
* [Use Cases](/use-cases/preventing-ai-mistakes?utm_source=docs\&utm_medium=web)
