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

# QWED CLI reference

> QWED command-line interface reference. Run qwed verify with provider options, model selection, and caching controls for terminal-based LLM verification.

Command-line interface for QWED verification.

## Installation

```bash theme={null}
pip install qwed
```

The `qwed` CLI is automatically available after installation.

***

## Commands

### `qwed init` - onboarding and bootstrap

Onboarding wizard that sets up verification engines, configures your LLM provider, and bootstraps a local API key — all in a single command. Run this once after installing QWED.

```bash theme={null}
qwed init
```

The wizard runs three steps:

1. **Engine readiness** — checks that core verification engines (SymPy, Z3, AST, SQLGlot) are installed, then runs deterministic smoke tests to confirm they work correctly
2. **LLM provider setup** — select a provider, enter credentials with masked input, validate the key format, and test the connection with retry support
3. **API key bootstrap** — starts a local QWED server, creates an organization, and generates a one-time API key you can use immediately

**Supported providers:**

| Provider                   | Slug        | Default model  | Key env variable          |
| -------------------------- | ----------- | -------------- | ------------------------- |
| NVIDIA NIM                 | `nvidia`    | API key        | Any key format            |
| OpenAI                     | `openai`    | API key        | `sk-...` or `sk-proj-...` |
| Anthropic                  | `anthropic` | API key        | `sk-ant-...`              |
| Google Gemini              | `gemini`    | API key        | Google API key            |
| Custom (OpenAI-compatible) | `custom`    | Endpoint + key | Any bearer token          |

**Example session:**

```
$ qwed init

[QWED] Initializing verification engines...
  [ok] SymPy    math engine ready
  [ok] Z3       logic engine ready
  [ok] AST      code engine ready
  [ok] SQLGlot  sql engine ready

Running verification suite...
  [ok] 2+2=5                     -> BLOCKED
  [ok] x>5 AND x<3              -> UNSAT
  [ok] SELECT * FROM users ...   -> BLOCKED
  [ok] os.system(...)            -> BLOCKED

All engines verified. QWED is operational.

-----------------------------------------
Step 1/3: LLM Provider Setup
-----------------------------------------
QWED uses an LLM for natural language translation.
The LLM is treated as an untrusted translator.
All outputs are verified deterministically.

Select provider:
  1. NVIDIA NIM
  2. OpenAI
  3. Anthropic Claude
  4. Google Gemini
  5. Custom Provider  (any OpenAI-compatible API)

Provider: 2

-----------------------------------------
Step 2/3: API Key
-----------------------------------------
OpenAI API key: ****
  Testing connection...
  [ok] Provider connected
  [ok] Model responding
  [ok] Credentials stored (.env, mode 0600)

-----------------------------------------
Step 3/3: Generate QWED API Key
-----------------------------------------
  Starting local server...
  [ok] Local server initialized
  [ok] Organization created

  Your API key: qwed_xxxxxxxxxxxxxxxx
  Warning: Save this key. It is shown only once.

-----------------------------------------
QWED is ready.

Verify an output:
  curl -X POST http://localhost:8000/verify/math \
    -H "x-api-key: qwed_xxxxxxxxxxxxxxxx" \
    -H "Content-Type: application/json" \
    -d '{"expression": "2+2=4"}'

Documentation: https://docs.qwedai.com
-----------------------------------------
```

#### Non-interactive mode (CI/CD)

Use `--non-interactive` to run `qwed init` without prompts. This is useful in CI pipelines, Docker builds, or automated provisioning scripts.

```bash theme={null}
qwed init \
  --non-interactive \
  --provider openai \
  --api-key "$OPENAI_API_KEY" \
  --model gpt-4o-mini \
  --organization-name my-team \
  --skip-tests
```

**All flags:**

| Flag                  | Description                                                                 | Default                                                  |
| --------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------- |
| `--provider`          | Provider to configure (`nvidia`, `openai`, `anthropic`, `gemini`, `custom`) | Interactive prompt (or `nvidia` in non-interactive mode) |
| `--api-key`           | Provider API key (placeholder values are ignored)                           | Read from environment                                    |
| `--base-url`          | Base URL for custom/OpenAI-compatible providers                             | Provider default                                         |
| `--model`             | Default model for the provider                                              | Provider default                                         |
| `--organization-name` | Organization name for API key bootstrap                                     | Interactive prompt (or auto-generated)                   |
| `--server-url`        | Local QWED server URL                                                       | `http://localhost:8000`                                  |
| `--non-interactive`   | Run without prompts (CI-friendly)                                           | `false`                                                  |
| `--skip-tests`        | Skip the engine smoke tests                                                 | `false`                                                  |

<Note>
  API keys are never logged or displayed in full. The `.env` file is written atomically with owner-only permissions (`0600` on Unix) and symlink protection. A `QWED_JWT_SECRET_KEY` is generated automatically for local server authentication.
</Note>

**Local server runtime directory:**

During Step 3, `qwed init` starts a local API server and needs a writable location for the SQLite bootstrap database (`qwed.db`). The CLI resolves the runtime directory as follows:

1. **Current working directory** — used if it is writable
2. **`~/qwed-demo/`** — created and used as a fallback when the current directory is read-only (e.g., inside a container, a mounted volume, or a system-managed path)

The server process starts with its working directory set to this runtime directory, and `DATABASE_URL` is explicitly set to `sqlite:///<runtime_dir>/qwed.db`. This ensures bootstrap writes never target a read-only path.

<Note>
  If you previously encountered `sqlite3.OperationalError: attempt to write a readonly database` during `qwed init`, upgrade to v4.0.0 or later. The fix automatically resolves a writable directory so Step 3 succeeds regardless of where you run the command.
</Note>

**Security guarantees:**

* Keys are entered with masked input and never displayed in full
* Keys are never written to logs
* `.env` is written with `0600` permissions (owner-read/write only on Unix)
* `.gitignore` protection is enforced before writing secrets — the command aborts if `.env` cannot be gitignored
* Atomic file writes prevent partial credential exposure
* Symlink targets are refused to prevent path traversal
* `.gitignore` protection is enforced before writing secrets

**Placeholder API key detection:** During onboarding, `qwed init` automatically detects and ignores common placeholder or dummy API key values. If your environment variable or `--api-key` argument contains a placeholder value, QWED treats it as empty and prompts you for a real key. Recognized placeholders include `your-api-key`, `changeme`, `placeholder`, `xxx`, and short NVIDIA keys such as `nvapi-xxxx`. This prevents silent failures caused by example values left in `.env` files or CI templates.

The following patterns are rejected:

* Generic placeholders: `test`, `dummy`, `sample`, `example`, `placeholder`, `changeme`, `null`, `none`
* Wildcard-style values: strings made entirely of `x`, `*`, or `.` characters (e.g. `xxx`, `****`)
* Template values: strings starting with `your-` or `replace-` that contain `key`
* Short NVIDIA keys: `nvapi-` prefixed values shorter than 20 characters

In non-interactive mode, the CLI checks three key sources: CLI argument, environment variable, and NVIDIA fallback. If all three resolve to a placeholder, the command reports that the key is required and exits. You get a clear error instead of a cryptic provider failure downstream.

**Re-running `qwed init`:** Running the command again merges new values into your existing `.env` file. Existing variables that you don't reconfigure are preserved.

***

### `qwed doctor` - system health check

Run a local health check that reports the status of verification engines, LLM provider connectivity, the QWED server, and the database. Use this after installation or when verification calls fail unexpectedly.

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

**What it checks:**

| Check            | Description                                         |
| ---------------- | --------------------------------------------------- |
| Required engines | SymPy (math), Z3 (logic), AST (code), SQLGlot (SQL) |
| Optional engines | OpenCV (image verification)                         |
| Provider         | Connectivity to the configured LLM provider         |
| Server           | Whether the QWED API server is reachable            |
| Database         | Health of the configured database                   |

The command exits with code `0` when all required checks pass (status `OPERATIONAL`) and code `1` when any required check fails (status `DEGRADED`). Optional engines that are missing do not cause a degraded status.

#### `.env` override behavior

The `doctor` command loads your `.env` file with **override mode enabled**. This means values in your `.env` file take precedence over variables already set in the current shell environment.

For example, if your shell has `ACTIVE_PROVIDER=ollama` but your `.env` file contains `ACTIVE_PROVIDER=openai_compat`, the doctor report reflects the `.env` value (`openai_compat`). This ensures the health report matches the configuration your application actually uses at runtime.

#### Database URL resolution

When checking database health, `doctor` prefers the `DATABASE_URL` environment variable (including values loaded from `.env`) over the application settings default. The resolution order is:

1. **`DATABASE_URL` from environment / `.env`** — used if present and non-empty
2. **Application settings** — the `DATABASE_URL` from your QWED configuration
3. **Default** — falls back to `sqlite:///./qwed.db`

This ensures the doctor report checks the database your deployment actually connects to, even when `DATABASE_URL` is set via environment variables rather than application config.

**Example output:**

```
$ qwed doctor

[QWED] System Health Check

Engines:
  [ok] SymPy    1.13.3   math engine ready
  [ok] Z3       4.13.4   logic engine ready
  [ok] AST      built-in code engine ready
  [ok] SQLGlot  26.30.0  sql engine ready
  [x]  OpenCV   missing  image verification
    -> pip install qwed[vision]

Provider:
  [ok] OpenAI - Connected (gpt-4o-mini)

Server:
  [ok] Running on http://localhost:8000

Database:
  [ok] src/qwed.db (healthy)

Status: OPERATIONAL (1 optional engine missing)
```

#### JSON output (CI/CD)

Use `--json` for machine-readable output. Useful in CI pipelines or monitoring scripts.

```bash theme={null}
qwed doctor --json
```

```json theme={null}
{
  "status": "OPERATIONAL",
  "optional_missing_count": 1,
  "engines": [
    { "name": "SymPy", "ready": true, "detail": "math engine ready", "version": "1.13.3" },
    { "name": "Z3", "ready": true, "detail": "logic engine ready", "version": "4.13.4" }
  ],
  "provider": { "ok": true, "label": "OpenAI", "message": "Connected (gpt-4o-mini)" },
  "server": { "running": true, "url": "http://localhost:8000" },
  "database": { "healthy": true, "location": "src/qwed.db" }
}
```

**Options:**

| Flag     | Description                                                       | Default |
| -------- | ----------------------------------------------------------------- | ------- |
| `--json` | Print the full report as JSON instead of the human-readable table | `false` |

<Tip>
  Run `qwed doctor --json` in CI to gate deployments on system health. A non-zero exit code means at least one required component is degraded.
</Tip>

***

### `qwed test` - deterministic verification tests

Run the built-in deterministic test suite across the Math, Logic, SQL, and Code engines. Every test case has a known expected result and does not depend on an LLM, so outcomes are fully reproducible.

```bash theme={null}
qwed test
```

Use this command to confirm that verification engines are working correctly after installation, upgrades, or environment changes.

**What it tests:**

| Engine | Test cases                                                                       |
| ------ | -------------------------------------------------------------------------------- |
| Math   | Valid expression (`2+2=4`), invalid expression (`2+2=5`), large computation      |
| Logic  | Contradictions (`x>5 AND x<3`), satisfiable constraints, conflicting assignments |
| SQL    | Valid SELECT, `OR 1=1` injection detection, stacked `DROP TABLE` detection       |
| Code   | Safe function, `eval(input())` detection, `curl \| bash` detection               |

The command exits with code `0` when all tests pass and code `1` when any test fails.

**Example output:**

```
$ qwed test

[QWED] Running verification test suite...

Math:
  [ok] 2+2=4                  -> VALID
  [ok] 2+2=5                  -> BLOCKED
  [ok] 997*997-3*997+2        -> 994010994 (verified)

Logic:
  [ok] x>5 AND x<3            -> UNSAT (contradiction)
  [ok] x>3 AND x<10           -> SAT {x=4}
  [ok] approval=1 AND approval=0 -> UNSAT (contradiction)

SQL:
  [ok] Valid SELECT            -> SAFE
  [ok] OR 1=1 injection       -> BLOCKED
  [ok] DROP TABLE stacked     -> BLOCKED

Code:
  [ok] Safe function           -> SAFE
  [ok] eval(input)             -> BLOCKED (CRITICAL)
  [ok] curl | bash             -> BLOCKED (CRITICAL)

12/12 tests passed. All engines operational.
```

#### Verbose mode

Use `--verbose` to show additional detail per test case, such as computed values and internal status codes.

```bash theme={null}
qwed test --verbose
```

```
Math:
  [ok] 2+2=4                  -> VALID
    computed=4
  [ok] 2+2=5                  -> BLOCKED
    computed=4
```

**Options:**

| Flag        | Description                                          | Default |
| ----------- | ---------------------------------------------------- | ------- |
| `--verbose` | Show per-case detail (computed values, status codes) | `false` |

***

### `qwed verify` - one-shot verification

Verify a query and exit.

```bash theme={null}
qwed verify "What is 2+2?"
qwed verify "derivative of x^2" --provider openai
qwed verify "Is (p AND q) satisfiable?" --model llama3
```

**Options:**

* `--provider, -p` - LLM provider (`openai`, `anthropic`, `gemini`)
* `--model, -m` - Model name (e.g., `gpt-4o-mini`, `llama3`)
* `--base-url` - Custom API endpoint (for Ollama: `http://localhost:11434/v1`)
* `--api-key` - API key (or use `QWED_API_KEY` env var)
* `--no-cache` - Disable caching
* `--quiet, -q` - Minimal output (for scripts)
* `--mask-pii` - Mask PII (emails, phone numbers, etc.) before sending queries to the LLM

**Examples:**

```bash theme={null}
# Ollama (auto-detected)
qwed verify "2+2"

# OpenAI
qwed verify "factorial of 5" --provider openai --api-key sk-...

# Custom endpoint
qwed verify "x^2 derivative" --base-url http://localhost:11434/v1 --model mistral

# Quiet mode
qwed verify "2+2" --quiet  # Just outputs: ✅ VERIFIED: 4
```

***

### `qwed interactive` - interactive mode

Start an interactive REPL session.

```bash theme={null}
qwed interactive
qwed interactive --provider openai
qwed interactive --model llama3
```

**Usage:**

```bash theme={null}
$ qwed interactive

🔬 QWED Interactive Mode
Type 'exit' or 'quit' to quit

> What is 2+2?
🔬 QWED Verification | Math Engine
📝 LLM Response: 4
✅ VERIFIED → 4

> stats
📊 Cache Statistics
Hits: 0
Misses: 1
Hit Rate: 0.0%

> exit
```

**Special commands:**

* `stats` - Show cache statistics
* `exit`, `quit`, `q` - Exit interactive mode

***

### `qwed cache` - cache management

Manage verification result cache.

#### `qwed cache stats`

Show cache statistics.

```bash theme={null}
$ qwed cache stats

📊 Cache Statistics
Hits: 156
Misses: 44
Hit Rate: 78.0%
Total Entries: 42/1000
Cache Size: 12.3 KB
```

#### `qwed cache clear`

Clear all cached results.

```bash theme={null}
$ qwed cache clear
Are you sure you want to clear the cache? [y/N]: y
✅ Cache cleared!
```

***

### `qwed pii` - PII detection

Test PII detection on arbitrary text. Requires the `qwed[pii]` extra.

```bash theme={null}
qwed pii "My email is john@example.com"
qwed pii "Card: 4532-1234-5678-9010"
```

**Example output:**

```
Original: My email is john@example.com
Masked:   My email is [EMAIL_REDACTED]

Detected: 1 entities
  - EMAIL: 1
```

<Note>
  Install PII support with `pip install 'qwed[pii]'` and download the spaCy model: `python -m spacy download en_core_web_lg`.
</Note>

***

## Environment variables

### `ACTIVE_PROVIDER`

Set by `qwed init`. Tells the CLI which provider to use when no `--provider` or `--base-url` flag is given.

```bash theme={null}
# Set automatically by qwed init, or manually:
export ACTIVE_PROVIDER=openai
```

Valid values: `openai`, `anthropic`, `gemini`, `openai_compat`.

### Provider-specific variables

These are written to `.env` by `qwed init` and loaded automatically via `python-dotenv`:

| Variable              | Provider            | Description                                                                                    |
| --------------------- | ------------------- | ---------------------------------------------------------------------------------------------- |
| `OPENAI_API_KEY`      | OpenAI              | Your OpenAI API key                                                                            |
| `OPENAI_MODEL`        | OpenAI              | Model name (default: `gpt-4o-mini`)                                                            |
| `ANTHROPIC_API_KEY`   | Anthropic           | Your Anthropic API key                                                                         |
| `ANTHROPIC_MODEL`     | Anthropic           | Model name (default: `claude-sonnet-4-20250514`)                                               |
| `GOOGLE_API_KEY`      | Google Gemini       | Your Google API key                                                                            |
| `GEMINI_MODEL`        | Google Gemini       | Model name (default: `gemini-1.5-pro`)                                                         |
| `CUSTOM_BASE_URL`     | NVIDIA NIM / Custom | Endpoint URL (required for custom; default `https://integrate.api.nvidia.com/v1` for NVIDIA)   |
| `CUSTOM_API_KEY`      | NVIDIA NIM / Custom | API key for the endpoint                                                                       |
| `CUSTOM_MODEL`        | NVIDIA NIM / Custom | Model name (default: `nvidia/nemotron-3-super-120b-a12b` for NVIDIA, `gpt-4o-mini` for custom) |
| `QWED_JWT_SECRET_KEY` | All                 | JWT secret for local server authentication (auto-generated by `qwed init`)                     |

The recommended way to set these is via `qwed init`, which writes them to a `.env` file automatically. You can also export them manually.

### `DATABASE_URL`

Override the default database connection used by QWED. When set, `qwed doctor` uses this value for its health check instead of the application settings default.

```bash theme={null}
export DATABASE_URL="postgresql://user:pass@db.example.com:5432/qwed"
```

Supported schemes include `sqlite`, `postgresql`, `mysql`, and `mariadb`. For SQLite, use the `sqlite:///` prefix (e.g., `sqlite:///./qwed.db` for a relative path or `sqlite:////absolute/path/qwed.db` for an absolute path).

### `QWED_API_KEY`

Fallback API key when a provider-specific key is not set.

```bash theme={null}
export QWED_API_KEY="sk-proj-..."
qwed verify "2+2"
```

### `QWED_QUIET`

Disable colorful branding output.

```bash theme={null}
export QWED_QUIET=1
qwed verify "2+2"  # Minimal output
```

***

## Configuration

### Provider priority

When you run `qwed verify` without explicit flags, the CLI resolves the provider in this order:

1. **Command-line flags** — `--provider` or `--base-url` take highest precedence
2. **`ACTIVE_PROVIDER` env var** — set by `qwed init` or manually in `.env`
3. **Ollama default** — falls back to `http://localhost:11434/v1` with model `llama3`

If you have run `qwed init`, the `ACTIVE_PROVIDER` value in your `.env` determines which provider and credentials are used automatically.

### Default models

| Provider                   | Default model                       |
| -------------------------- | ----------------------------------- |
| NVIDIA NIM                 | `nvidia/nemotron-3-super-120b-a12b` |
| OpenAI                     | `gpt-4o-mini`                       |
| Anthropic                  | `claude-sonnet-4-20250514`          |
| Google Gemini              | `gemini-1.5-pro`                    |
| Custom (OpenAI-compatible) | `gpt-4o-mini`                       |

***

## Output formats

### Colorful output (default)

```
🔬 QWED Verification | Math Engine
📝 LLM Response: 4
✅ VERIFIED → 4

────────────────────────────────────────────────────────
✨ Verified by QWED | Model Agnostic AI Verification
💚 If QWED saved you time, give us a ⭐ on GitHub!
👉 https://github.com/QWED-AI/qwed-verification
────────────────────────────────────────────────────────
```

### Quiet output (`--quiet`)

```
✅ VERIFIED: 4
```

### Error output

```
❌ Error: Ollama not running. Either:
1. Start Ollama: ollama serve
2. Or specify provider explicitly
```

***

### `qwed provider` - custom provider management

Manage custom LLM providers defined in `~/.qwed/providers.yaml`. See [Custom providers](/getting-started/custom-providers) for the full guide.

#### `qwed provider import <url>`

Import a community provider definition from a URL. The YAML file is downloaded, validated, and saved locally.

```bash theme={null}
qwed provider import https://raw.githubusercontent.com/my-org/qwed-providers/main/groq.yaml
```

**Example output:**

```
ℹ️  Downloading provider from https://raw.githubusercontent.com/my-org/qwed-providers/main/groq.yaml...
✅ Successfully imported provider 'groq'!
   You can now run 'qwed init' and select it from the interactive menu.
```

After importing, the new provider appears as a selectable option when you run `qwed init`.

<Note>
  Only `http` and `https` URLs are accepted. The imported YAML must contain `base_url` and `api_key_env` fields. Downloads time out after 10 seconds.
</Note>

***

## Use cases

### 1. Quick verification

```bash theme={null}
qwed verify "Is 17 a prime number?"
```

### 2. Scripting

```bash theme={null}
#!/bin/bash
export QWED_QUIET=1
export QWED_API_KEY="sk-..."

result=$(qwed verify "2+2" --provider openai)
if [[ $result == *"VERIFIED"* ]]; then
    echo "Math checks out!"
fi
```

### 3. Local development

```bash theme={null}
# Start Ollama
ollama serve

# Verify without API costs
qwed interactive

> What is the derivative of x^3?
✅ VERIFIED → 3*x**2
```

### 4. Cache performance testing

```bash theme={null}
# First run (cache miss)
time qwed verify "complex calculation"  # ~2 seconds

# Second run (cache hit)
time qwed verify "complex calculation"  # ~0.1 seconds!
```

***

## Troubleshooting

### "Ollama not running"

```bash theme={null}
# Check Ollama status
curl http://localhost:11434/v1/models

# Start Ollama
ollama serve
```

### "API key required"

```bash theme={null}
# Set env var
export QWED_API_KEY="sk-..."

# Or pass directly
qwed verify "query" --api-key sk-...
```

### "Module not found"

```bash theme={null}
# Install missing LLM clients
pip install openai anthropic google-generativeai

# Install verification engines
pip install sympy z3-solver
```

***

## Advanced features

### Caching behavior

* **Default:** Enabled (24h TTL)
* **Disable:** `--no-cache` flag
* **Clear:** `qwed cache clear`
* **Stats:** `qwed cache stats`

### Multiple providers

```bash theme={null}
# Compare results across providers
qwed verify "2+2" --provider openai
qwed verify "2+2" --base-url http://localhost:11434/v1
qwed verify "2+2" --provider anthropic
```

***

## Related docs

* [QWEDLocal guide](/advanced/qwed-local) — Python API for local verification
* [Ollama integration](/advanced/ollama) — use free local LLMs
* [LLM configuration](/getting-started/llm-configuration) — provider setup details
