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

# Commands Reference

> Full list of NexSpace CLI commands

# Commands Reference

## Global Flags

| Flag                   | Description                                                                    |
| ---------------------- | ------------------------------------------------------------------------------ |
| `--json` / `--no-json` | Force JSON or human text (JSON is default for non-TTY / `NEXSPACE_CLI_JSON=1`) |
| `--help`               | Show help                                                                      |
| `--version`            | Show version                                                                   |

Authenticate once with `nexspace login` (see [CLI Authentication](/cli/authentication));
commands reuse the stored credential automatically.

### Agent loop

```bash theme={null}
nexspace search "fill open shift"
nexspace mcp schema fillShift
nexspace mcp call fillShift --args '{"shiftId":12,"staffId":7}' --dry-run
nexspace mcp call fillShift --args '{"shiftId":12,"staffId":7}'
nexspace agent playbook
nexspace skill install
```

Errors return `{ "error", "code", "next" }` with exit `2` (auth) or `3` (input).

### Environment

| Variable            | Purpose                                                   |
| ------------------- | --------------------------------------------------------- |
| `NEXSPACE_API_KEY`  | API key when not logged in via config                     |
| `NEXSPACE_BASE_URL` | Override API base (default `https://api.nexspace365.com`) |
| `NEXSPACE_CLI_JSON` | Set to `1` to force JSON output                           |

***

## Auth

### `nexspace login`

Authenticate. Defaults to the browser device-code OAuth flow; pass `--token` to
store an API key/PAT instead. Credentials are saved to the OS keychain when
available (falling back to `~/.nexspace/config.json`).

```bash theme={null}
nexspace login
nexspace login --token nex_pat_xxxxxxxxxxxxxxxxxxxx
```

### `nexspace login-device`

Explicit alias for the OAuth device-code login flow.

```bash theme={null}
nexspace login-device
```

### `nexspace logout`

Remove stored credentials.

```bash theme={null}
nexspace logout
```

### `nexspace whoami`

Print the identity the current credential authenticates as.

```bash theme={null}
nexspace whoami
nexspace whoami --json
```

***

## Discovery

### `nexspace search <query>`

Rank MCP tools by natural-language intent.

| Flag             | Description                                                                |
| ---------------- | -------------------------------------------------------------------------- |
| `--limit <n>`    | Max results (default: 10)                                                  |
| `--suite <name>` | Limit to `scheduling` \| `hr` \| `payroll` \| `crm` \| `ai` \| `messaging` |

```bash theme={null}
nexspace search "fill open shift"
nexspace search "leads" --suite crm --json
```

### `nexspace mcp tools`

List available MCP tools.

| Flag             | Description     |
| ---------------- | --------------- |
| `--suite <name>` | Filter by suite |

```bash theme={null}
nexspace mcp tools
nexspace mcp tools --suite scheduling --json
```

### `nexspace mcp schema <toolName>`

Print `inputSchema` (and `outputSchema` when present) for a tool.

```bash theme={null}
nexspace mcp schema fillShift
```

### `nexspace mcp call <toolName>`

Invoke an MCP tool by name.

| Flag            | Description                                        |
| --------------- | -------------------------------------------------- |
| `--args <json>` | Tool arguments as JSON                             |
| `--dry-run`     | Validate args + auth; never invokes the named tool |

Under `--dry-run` the named tool is **never** called, read-only or not. Where a
preview sibling exists (`runPayroll` → `previewPayrollRun`) the CLI calls that
instead and returns its result under `result`; otherwise it returns
`{ dryRun: true, valid: true, mutating }` with nothing executed.

```bash theme={null}
nexspace mcp call listFacilities
nexspace mcp call fillShift --args '{"shiftId":12,"staffId":7}' --dry-run
nexspace mcp call fillShift --args '{"shiftId":12,"staffId":7}'
```

***

## Context

### `nexspace context use`

Pin a facility so `shifts`, `staff`, and `payroll` commands default to it
instead of repeating `--facility-id` on every call.

```bash theme={null}
nexspace context use --facility-id 12
nexspace context show
nexspace context use --clear
```

There is no `--org-id`. Org scope is derived from the credential you logged in
with and cannot be overridden per-request; the few super-admin REST routes that
accept a narrowing override take it explicitly as
`nexspace api GET /api/crm/... -q orgUnitId=N`.

***

## Facilities

### `nexspace facilities list` / `get`

```bash theme={null}
nexspace facilities list --json
nexspace facilities get --id 12
```

***

## Staff

### `nexspace staff search` / `get` / `find-credentialed` / `credentials-expiring`

```bash theme={null}
nexspace staff search --query "Jane"
nexspace staff get 789
nexspace staff find-credentialed --facility-id 12 --specialty RN
nexspace staff credentials-expiring --days-ahead 30 --facility-id 12
```

***

## Shifts

### `nexspace shifts list` / `get` / `fill` / `propose` / `swap` / `coverage`

```bash theme={null}
nexspace shifts list --facility-id 12 --status open
nexspace shifts get --id 456
nexspace shifts fill --shift-id 456 --staff-id 789 --dry-run
nexspace shifts fill --shift-id 456 --staff-id 789
nexspace shifts propose --facility-id 12 --start-date 2026-05-10 --end-date 2026-05-17
nexspace shifts swap --shift-a-id 1 --shift-b-id 2
nexspace shifts coverage --facility-id 12 --start-date 2026-05-10 --end-date 2026-05-17
```

Use `--dry-run` on mutating verbs before the real call.

***

## Credentials

### `nexspace credentials verify`

```bash theme={null}
nexspace credentials verify --credential-id 456
```

***

## Payroll

### `nexspace payroll preview` / `run`

Always preview (or `--dry-run` on `run`) before committing.

```bash theme={null}
nexspace payroll preview --facility-id 12 --period-start 2026-05-01 --period-end 2026-05-15
nexspace payroll run --facility-id 12 --period-start 2026-05-01 --period-end 2026-05-15 \
  --confirmed-by "alice@example.com" --dry-run
nexspace payroll run --facility-id 12 --period-start 2026-05-01 --period-end 2026-05-15 \
  --confirmed-by "alice@example.com"
```

***

## CRM

### `nexspace crm leads-search` / `leads-qualify`

```bash theme={null}
nexspace crm leads-search --query "Acme"
nexspace crm leads-qualify --lead-id 99 --dry-run
```

***

## Notify

### `nexspace notify shift-swap`

```bash theme={null}
nexspace notify shift-swap --shift-id 456 --staff-ids 789,790 --message "Swap confirmed"
nexspace notify shift-swap --shift-id 456 --staff-ids 789 --message "Swap confirmed" \
  --channels push,email --dry-run
```

| Flag                 | Description                                        |
| -------------------- | -------------------------------------------------- |
| `--shift-id <n>`     | Shift the swap applies to (required)               |
| `--staff-ids <list>` | Comma-separated staff ids (required)               |
| `--message <text>`   | Notification body (required)                       |
| `--channels <list>`  | Any of `push`, `sms`, `email` (default `push,sms`) |
| `--dry-run`          | Validate without sending                           |

This verb sends real SMS and push notifications, so it validates strictly rather
than notifying a subset: a non-numeric entry in `--staff-ids` or an unrecognized
`--channels` value exits `3` (`VALIDATION_FAILED`) and sends nothing.

***

## API Keys

### `nexspace api-keys list` / `create` / `revoke`

```bash theme={null}
nexspace api-keys list
nexspace api-keys create --name "CI Pipeline" --scopes "shifts:read,staff:read"
nexspace api-keys create --name "Agent key" --scopes "*:*" --expires-in-days 90
nexspace api-keys revoke 42
```

***

## Webhooks & events

### `nexspace webhooks list` / `create` / `delete` / `test`

```bash theme={null}
nexspace webhooks list
nexspace webhooks create --name "Local" --url https://xxxx.ngrok-free.app/hooks --events shift_filled
nexspace webhooks test --id 42
nexspace webhooks delete --id 42
```

### `nexspace events listen`

Local receiver + temporary subscription. Verifies `X-NexSpace-Signature` when
the create response includes `signingSecret`. Cloud API hosts cannot reach
`127.0.0.1` — pass `--forward-url` (ngrok / cloudflared).

```bash theme={null}
nexspace events listen --max-events 5
nexspace events listen --forward-url https://xxxx.ngrok-free.app/hooks --port 8787
```

### `nexspace events trigger`

Fire a test delivery against an existing subscription.

```bash theme={null}
nexspace events trigger --webhook-id 42
```

See also [Webhooks](/concepts/webhooks).

***

## Approvals, audit & logs

Admin-gated AI action surfaces (same APIs as **Admin → AI Config → Approvals**).
These are **not** the same as `nexspace agents approvals` (headless run
resolution under `agents:approve`).

### `nexspace approvals list` / `approve` / `reject`

```bash theme={null}
nexspace approvals list
nexspace approvals approve --id 42 --reason "Coverage confirmed"
nexspace approvals reject --id 42 --reason "Wrong facility"
```

### `nexspace audit list`

```bash theme={null}
nexspace audit list --limit 20
nexspace audit list --tool-name fillShift --json
nexspace audit list --trajectory-id abc-123
```

### `nexspace logs tail`

Polls `GET /api/ai/audit` as JSONL (there is no general HTTP request-log API).

```bash theme={null}
nexspace logs tail --no-follow --max-events 20
nexspace logs tail --follow --interval 2
```

***

## Agents

Headless agent runs (distinct from admin AI `approvals` above). Requires
`agents:run` / `agents:approve` / `agents.manage` as noted. See also
[Agent runs](/concepts/agent-runs).

### `nexspace agents run <agentId>`

Start a headless agent run and stream its events to completion. Backed by
`POST /api/agents/{id}/runs` + the run SSE stream
(`GET /api/agents/{id}/runs/{runId}/stream`); requires the `agents:run` scope.

| Flag                       | Description                                                                   |
| -------------------------- | ----------------------------------------------------------------------------- |
| `-m, --message <text>`     | Seed message / task for the run (required to start)                           |
| `--resume-session-id <id>` | Continue a prior agent session (multi-turn)                                   |
| `--output-format <fmt>`    | `json` (default, prints the final result) or `stream-json` (NDJSON per event) |
| `--resume-run`             | Resume an existing run stream instead of starting a new one (with `--run-id`) |
| `--run-id <id>`            | Existing `runId` to resume                                                    |
| `--last-event-id <id>`     | Last SSE event id seen, to replay missed events on resume                     |

In `stream-json` mode each event is emitted as one JSON object per line —
ideal for agents/CI that consume the run incrementally. A `run_started` line is
emitted first, then one line per `status` / `assistant` / `tool_call` / `result`
/ `done` event. The command exits non-zero if the run ends in `error` or
`rejected`.

```bash theme={null}
# Print the final result as JSON
nexspace agents run 12 --message "Summarize open shifts for facility 3"

# Stream every event as NDJSON (agent/CI friendly)
nexspace agents run 12 -m "Qualify new leads" --output-format stream-json

# Reconnect to a dropped stream and replay from the last event id
nexspace agents run 12 --resume-run --run-id run_abc --last-event-id 4 --output-format stream-json
```

### `nexspace agents runs <list|get|cancel|approvals>`

Inspect and control runs after they start. All require the `agents:run` scope
and only operate on runs owned by the credential's user.

| Command                                   | Backed by                                     | Purpose                                                   |
| ----------------------------------------- | --------------------------------------------- | --------------------------------------------------------- |
| `agents runs list <agentId>`              | `GET /api/agents/{id}/runs`                   | List runs (newest first). `--status`, `--limit`, `--json` |
| `agents runs get <agentId> <runId>`       | `GET /api/agents/{id}/runs/{runId}`           | Current state of a single run. `--json`                   |
| `agents runs cancel <agentId> <runId>`    | `DELETE /api/agents/{id}/runs/{runId}`        | Soft-cancel a `running` run                               |
| `agents runs approvals <agentId> <runId>` | `GET /api/agents/{id}/runs/{runId}/approvals` | List approvals a paused run raised                        |

```bash theme={null}
nexspace agents runs list 12 --status pending_approval
nexspace agents runs get 12 run_abc --json
nexspace agents runs approvals 12 run_abc
nexspace agents runs cancel 12 run_abc
```

### `nexspace agents approvals <approve|reject> <approvalId>`

Resolve a `pending_approval` action raised by one of your runs. Requires the
`agents:approve` scope. Approving executes the deferred tool and resumes the run
once all its approvals are terminal; rejecting terminates the run as `rejected`.

| Flag              | Description                            |
| ----------------- | -------------------------------------- |
| `--reason <text>` | Optional note recorded on the decision |
| `--json`          | Emit the `ApprovalResolution` payload  |

```bash theme={null}
nexspace agents approvals approve 1001 --reason "verified coverage"
nexspace agents approvals reject 1001 --reason "out of budget"
```

### `nexspace agents triggers <list|create|update|delete|toggle|run-now>`

Manage automation triggers that fire an agent on a cron schedule or business
event through the durable headless-run path. Requires the `agents.manage`
permission and the `ai` suite.

| Command                                                               | Backed by                              | Purpose                              |
| --------------------------------------------------------------------- | -------------------------------------- | ------------------------------------ |
| `agents triggers list <agentId>`                                      | `GET /api/agent-builder/{id}/triggers` | List an agent's triggers             |
| `agents triggers create <agentId>`                                    | `POST …/triggers`                      | Create a `schedule`/`event` trigger  |
| `agents triggers update <agentId> <triggerId>`                        | `PATCH …/triggers/{triggerId}`         | Partial update                       |
| `agents triggers delete <agentId> <triggerId>`                        | `DELETE …/triggers/{triggerId}`        | Remove a trigger                     |
| `agents triggers toggle <agentId> <triggerId> --active <true\|false>` | `POST …/toggle`                        | Enable/disable                       |
| `agents triggers run-now <agentId> <triggerId>`                       | `POST …/run-now`                       | Dispatch immediately (`409` if busy) |

`create`/`update` accept: `--type`, `--cron`, `--timezone`, `--event-type`,
`--event-filters` (JSON), `--run-as-user-id`, `--facility-id`, `--seed-message`,
`--no-activate` (create only). Schedule triggers need `--cron`; event triggers
need `--event-type`.

```bash theme={null}
# Daily 9am summary (Central time)
nexspace agents triggers create 12 --type schedule \
  --cron "0 9 * * *" --timezone America/Chicago \
  --seed-message "Summarize yesterday's open shifts"

# Fire on a no-call/no-show for facility 3
nexspace agents triggers create 12 --type event \
  --event-type shift.ncns --event-filters '{"facilityId":3}'

nexspace agents triggers list 12
nexspace agents triggers toggle 12 34 --active false
nexspace agents triggers run-now 12 34
```

***

## Fixtures & conformance

### `nexspace fixtures`

Sandbox / webhook helpers for agent demos.

```bash theme={null}
nexspace fixtures list
nexspace fixtures sandbox-reset --facility-id 1   # session auth only — not API keys
nexspace fixtures webhook-test --webhook-id 12
```

See [Sandbox](/concepts/sandbox).

### `nexspace conformance run`

Runs the Governance Conformance Suite (Vitest) from a NexSpace checkout.

```bash theme={null}
nexspace conformance run
nexspace conformance run --repo /path/to/NexSpace
```

Exits non-zero when the suite fails, in every output mode — safe to use as a CI
gate. The JSON payload also reports coverage, because a green suite is not the
same as a fully enforced one:

| Field            | Meaning                                                         |
| ---------------- | --------------------------------------------------------------- |
| `passedClauses`  | Clauses asserted and passing                                    |
| `pendingClauses` | Clauses still stubbed as `it.todo` — declared but unenforced    |
| `fullyEnforced`  | `true` only when the suite passed **and** `pendingClauses` is 0 |

Gate on `fullyEnforced` rather than the exit code alone if you need every clause
actually enforced; the exit code ignores pending clauses.

***

## Agent helpers

### `nexspace skill install`

Install the `nexspace-operations` skill for Cursor and/or Claude Code.

```bash theme={null}
nexspace skill install
nexspace skill install --cursor --project
nexspace skill install --claude
```

### `nexspace agent playbook`

Print the short search → schema → dry-run → call reminder.

```bash theme={null}
nexspace agent playbook
```

### `nexspace run`

Inline agent scripting with injected `execute`, `search`, `api`, and `schema`.
Useful for fan-out; **not** a production runtime SLA — prefer MCP/REST for
stable integrations.

```bash theme={null}
nexspace run -e 'console.log(await search("credential"))'
nexspace run --file ./workflow.mjs
nexspace run -e 'await execute("searchStaff",{query:"a"})' --dry-run
```

`--dry-run` matches `mcp call --dry-run`: every `execute()` returns a
`{ dryRun: true, skipped: true }` envelope instead of running the tool — including
read-only tools, so a mis-classified verb can't slip through. The injected
`api()` helper still performs `GET`s (discovery stays useful) but short-circuits
`POST` / `PUT` / `PATCH` / `DELETE` the same way. `search()` and `schema()` are
unaffected.

***

## Escape hatch

### `nexspace api <METHOD> <PATH>`

Authenticated passthrough to any API endpoint.

| Flag                | Description              |
| ------------------- | ------------------------ |
| `-d, --data <json>` | JSON request body        |
| `-q, --query <k=v>` | Query param (repeatable) |

```bash theme={null}
nexspace api GET /api/shifts -q facilityId=1 -q status=open
nexspace api POST /api/webhooks -d '{"url":"https://x.dev/hook","events":["shift_filled"]}'
nexspace api DELETE /api/webhooks/42
```

Paths are resolved against the base URL you logged in with. You may pass an
absolute URL, but it must share that origin — the CLI refuses to attach your
bearer token to a foreign host rather than leaking the credential:

```bash theme={null}
$ nexspace api GET https://evil.example/x
Refusing to send credentials to https://evil.example: the configured API base
is https://api.nexspace365.com. Use `nexspace login --base-url <url>` to target
a different host.
```

***

## `nexspace update`

Update a standalone (Homebrew/curl) install to the latest release. npm installs
update with `npm i -g @nexspace/cli`; Homebrew with `brew upgrade nexspace`.

```bash theme={null}
nexspace update
```
