python -m pip install "nullspace-sdk[cli]==1.0.0"
nullspace --help

Auth

nullspace auth login --api-url https://api.13-215-85-171.sslip.io
nullspace doctor
nullspace quickstart
The CLI reads environment variables, project .env, ~/.config/nullspace/config.json, then legacy ~/.nullspace/config.json. SDK constructors also accept explicit api_key= and base_url= arguments. Use NULLSPACE_API_KEY and NULLSPACE_API_URL directly for scripts, CI, and coding agents.

Agent deployments

nullspace agent init
nullspace agent deploy --dry-run --json
nullspace agent deploy --json
nullspace agent deploy --rebuild --json
nullspace agent deploy --no-cache --json
nullspace agent list --json
nullspace agent get repo-review-agent --json
nullspace agent run repo-review-agent --input input.json --json
nullspace agent run repo-review-agent --retain-on-failure --retention-seconds 3600
nullspace agent logs repo-review-agent --run adrun_123 --json
nullspace agent outputs repo-review-agent --run adrun_123 --json
nullspace agent status repo-review-agent --run adrun_123 --json
nullspace agent url repo-review-agent
nullspace agent status repo-review-agent --service adsvc_123 --json
nullspace agent shell repo-review-agent --run adrun_123 --cmd "pwd"
nullspace agent machine repo-review-agent --run adrun_123
nullspace agent stop repo-review-agent
nullspace agent restart repo-review-agent
nullspace agent delete repo-review-agent --yes
agent deploy --dry-run performs local config detection and bundle planning without an API key. Real deploy creates or reuses a named deployment and stores a metadata-only version record with the local bundle manifest; binary bundle upload and runtime execution are handled by the deployment runtime path. Current Agent Deployment modes are job and service. worker, triggered, workspace, and interactive are reserved config words for future deployment models; dry-run can show them for local planning, but live deploy/runtime commands reject them until the API, SDK, CLI, and runtime support those modes. Agent deployment build cache status is reported by agent deploy in human output and in the JSON cache object. The default auto policy reports cache eligibility and falls back to per-run install when no ready artifact is available. Use --rebuild to build a fresh reusable deployment artifact during upload, or --no-cache to bypass cache lookup and artifact writes for that deploy. Use a custom template for heavy system dependencies or slow base setup. Failed job runs can opt into retained debugging with --retain-on-failure; retained runs expose a normal machine_id, so existing nullspace machine ... commands work for files, exec, PTY, URLs, snapshots, and manual destroy. Lifecycle webhooks are machine lifecycle subscriptions, not agent trigger webhooks.

Machines

nullspace machine create --template base --cwd /workspace
nullspace machine create --template base --metadata-json '{"team":"eval"}'
nullspace machine create --template base --env API_MODE=test --env-json '{"TRACE":"1"}'
nullspace machine create --template base --network-json '{"allow_out":["203.0.113.0/24"]}'
nullspace machine create --snapshot-id snap_123 --timeout 300
nullspace machine create --template desktop --resolution 1280x720 --dpi 144 --display :1
nullspace machine create --template base --no-internet-access
nullspace machine create --template base --on-timeout pause --auto-resume
nullspace machine create --template base --volume ref=team-data,mount=/data,subpath=/datasets,ro=true
nullspace machine create --template team/review-api:stable --warm-pool twp_review_api_small --warm-pool-mode prefer --warm-pool-wait 1500 --json
nullspace machine list --state running --template base --metadata team=eval
nullspace machine get mch_123
nullspace machine exec mch_123 --shell "echo hello"
nullspace ssh mch_123 -- python --version
nullspace machine ssh-access mch_123 --print-command
nullspace machine host mch_123 8080
nullspace machine url mch_123 8080 --websocket
nullspace machine url mch_123 8080 --wait --json
nullspace machine preview-url get mch_123 8080
nullspace machine preview-url get mch_123 8080 --websocket --raw
nullspace machine preview-url create mch_123 8080 --expires 15m --wait --json
nullspace machine preview-url list mch_123 --port 8080 --json
nullspace machine preview-url revoke mch_123 pvg_123 --json
nullspace machine preview-proxy-target create mch_123 8080 --transport http --transport websocket
nullspace machine metrics mch_123 --json
nullspace machine timeout set mch_123 --seconds 120 --action hibernate
nullspace machine pause mch_123
nullspace machine resume snap_123
nullspace machine fork mch_123
nullspace machine kill mch_123
High-value create flags include --idempotency-key, --cwd, --env, --env-json, --metadata, --metadata-json, --network-json, --snapshot-id, --internet-access/--no-internet-access, --on-timeout, --auto-resume/--no-auto-resume, --warm-pool, --warm-pool-mode, --warm-pool-wait, desktop flags, and repeatable --volume ref=<name-or-id>,mount=<path>[,subpath=<subpath>][,ro=true]. Prefer --on-timeout pause for create-time pause/hibernate behavior. The lower-level --timeout-action flag exists for raw API parity, but most CLI workflows should use --on-timeout at create time and machine timeout set --action ... for existing machines. Use nullspace ssh when a local tool requires OpenSSH; it mints a short-lived certificate for the Nullspace SSH relay.

Preview URLs

nullspace machine preview-url get mch_123 8080
nullspace machine preview-url create mch_123 8080 --expires 15m --wait
nullspace machine preview-url create mch_123 8080 --websocket --json
nullspace machine preview-url list mch_123 --port 8080
nullspace machine preview-url revoke mch_123 pvg_123
nullspace machine preview-proxy-target create mch_123 8080 --transport http --transport websocket
The preview-url commands cover direct browser links, signed grants, inventory, and revocation. Human output redacts token-bearing URLs by default; use --raw only for an explicit secret-bearing display action. --json emits raw automation-ready values plus stable metadata such as selected transport, expiry, auth mode, readiness when --wait is used, and token-redacted usage counters when listing grants. Use preview-proxy-target create for customer-run reverse proxies. It returns marker-only upstream URLs plus HTTP/WebSocket header tokens that the proxy must forward as x-nullspace-preview-proxy-token; human output redacts those header tokens unless --raw is supplied. See Token model for how preview URL tokens, preview proxy tokens, private traffic tokens, and API keys differ.

Files and processes

nullspace machine upload mch_123 ./dist/app.tar.gz /workspace/app.tar.gz
nullspace machine upload mch_123 ./large.bin /data/large.bin --resumable always --checksum auto --concurrency 4
nullspace machine upload mch_123 ./large.bin /data/large.bin --resume upload_...
nullspace machine file read mch_123 /workspace/app.tar.gz
nullspace machine file read mch_123 /workspace/app.tar.gz --encoding base64 --json
printf "hello" | nullspace machine file write mch_123 /workspace/hello.txt
nullspace machine file write-files mch_123 '[["/workspace/a.txt","a\n"],["/workspace/b.txt","b\n"]]'
nullspace machine file list mch_123 /workspace --depth 1 --json
nullspace machine file exists mch_123 /workspace/hello.txt
nullspace machine file info mch_123 /workspace/hello.txt
nullspace machine file mkdir mch_123 /workspace/archive
nullspace machine file mv mch_123 /workspace/hello.txt /workspace/archive/hello.txt
nullspace machine file chmod mch_123 /workspace/hello.txt 0644
nullspace machine file rm mch_123 /workspace/old.txt
nullspace machine file find mch_123 /workspace "TODO"
nullspace machine file search mch_123 /workspace "*.py"
nullspace machine file replace mch_123 "old" "new" /workspace/app.py
nullspace machine file upload-url mch_123 /workspace/input.bin
nullspace machine file download-url mch_123 /workspace/app.tar.gz
nullspace machine file watch mch_123 /workspace --recursive --timeout 30
nullspace machine process list mch_123
nullspace machine process logs mch_123 1234
printf "q" | nullspace machine process stdin mch_123 1234
nullspace machine process stream mch_123 python -c "print('hi')"
nullspace machine process attach mch_123 1234
nullspace machine process kill mch_123 1234

Desktop, code, PTY, and git

nullspace machine desktop screenshot mch_123 --output screen.png
nullspace machine desktop click mch_123 320 240
nullspace machine desktop type mch_123 "hello"
nullspace machine desktop clipboard get mch_123
nullspace machine desktop launch executable mch_123 firefox https://example.com
nullspace machine desktop stream start mch_123 --view-only
nullspace machine desktop recording start mch_123 --name demo

nullspace machine code run mch_123 "print('hello')" --json
nullspace machine code context create mch_123 --cwd /workspace
nullspace machine code artifact download mch_123 art_123 --output result.png

nullspace machine pty create mch_123 --cols 120 --rows 30
nullspace machine pty list mch_123
nullspace machine git clone mch_123 https://github.com/acme/repo /workspace
nullspace machine git status mch_123 --path /workspace
nullspace machine git commit mch_123 "update files" --path /workspace
machine code run-job list is available for read-only hosted beta inspection. machine code run-job create, get, cancel, and wait are not part of the hosted private beta launch surface because remote host-agent routing for queued code runs is not implemented yet.

Snapshots

nullspace snapshot create mch_123
nullspace snapshot list --machine-id mch_123 --metadata purpose=checkpoint
nullspace snapshot get snap_123
nullspace snapshot delete snap_123
nullspace machine snapshot create mch_123

Lifecycle

nullspace lifecycle events --limit 20
nullspace lifecycle stream --machine-id mch_123 --live-only
nullspace lifecycle webhooks create \
  --url https://example.com/nullspace/lifecycle \
  --operation create \
  --operation destroy \
  --signing-secret whsec_...
nullspace lifecycle webhooks list
nullspace lifecycle webhooks get wh_123
nullspace lifecycle webhooks update wh_123 --disabled
nullspace lifecycle webhooks delete wh_123
nullspace lifecycle webhooks deliveries wh_123
nullspace lifecycle webhooks delivery wh_123 del_123

Monitor, schema, and MCP

nullspace monitor stream --include-processes --interval-ms 1000
nullspace schema
nullspace schema machine desktop screenshot
nullspace completion zsh
nullspace doctor --json
nullspace docs install --agent all
nullspace mcp serve
nullspace mcp serve requires the MCP extra:
uv pip install "nullspace-sdk[cli,mcp]==1.0.0"
nullspace docs install --agent all installs project-local Markdown docs and agent config for Claude Code and Codex. It does not require an API key and does not edit user-level configuration files.

Templates

nullspace template init
nullspace template list
nullspace template list --fields id,canonical_ref,visibility
nullspace template get template-ref
nullspace template get template-ref --fields id,canonical_ref
nullspace template exists template-ref
nullspace template build --from-ubuntu-image 22.04 --name demo-template --cpu-count 4 --memory-mb 2048 --skip-cache
nullspace template build --from-python-image 3.12 --name offline-template --no-internet-access
nullspace template build --from-dockerfile ./Dockerfile --name docker-template --build-secret-env npm_token=NPM_TOKEN
nullspace template build --from-python-image 3.12 --name demo-template --background
nullspace template render json --from-ubuntu-image 22.04 --apt-install git
nullspace template render dockerfile --from-ubuntu-image 22.04 --apt-install git --name demo-template
nullspace template build-status tb_123 --offset 10
nullspace template logs tb_123
nullspace template wait tb_123 --poll-interval-ms 500 --log-format jsonl
nullspace template reserve team/template
nullspace template rename old-ref new-name
nullspace template namespace get team
nullspace template claim release tclm_...
nullspace template tag assign template-ref stable prod
nullspace template tag list template-ref
nullspace template tag remove template-ref old
nullspace template alias list template-ref
nullspace template alias remove template-ref old-alias
nullspace template visibility set template-ref private
nullspace template delete template-ref
nullspace template warm-pool create team/review-api:stable --name review-api-small --min-ready 2 --max-ready 4 --json
nullspace template warm-pool list --template team/review-api:stable --status ready --json
nullspace template warm-pool get twp_review_api_small --json
nullspace template warm-pool wait twp_review_api_small --min-ready 2 --json
nullspace template warm-pool scale twp_review_api_small --min-ready 3 --max-ready 6 --json
nullspace template warm-pool enable twp_review_api_small --json
nullspace template warm-pool disable twp_review_api_small --json
nullspace template warm-pool drain twp_review_api_small --json
nullspace template warm-pool reconcile twp_review_api_small --json
nullspace template warm-pool delete twp_review_api_small --json
template build mirrors the Python builder surface for base images, Dockerfiles, registry auth, files, package installs, build/runtime envs, start commands, readiness probes, build CPU/memory/internet access, optional --backend buildkit for Dockerfile builds, BuildKit request-time secrets, tags, aliases, and visibility. Dry-run and render JSON redact registry credentials and BuildKit secret values. template warm-pool commands manage tenant-owned ready capacity for a template. Machine create --warm-pool-mode prefer cold-falls back on a miss, require returns warm_pool_unavailable, and bypass forces cold create. Dockerfile builds use BuildKit. --backend native is rejected for Dockerfile builds.

Volumes

nullspace volume create team-data
nullspace volume list
nullspace volume list --fields id,name,mount_count,used_bytes
nullspace volume get team-data
nullspace volume get team-data --fields id,status
nullspace volume ls-files team-data /
nullspace volume read team-data /models/manifest.json
printf "hello" | nullspace volume write team-data /hello.txt
nullspace volume write-files team-data '[["/a.txt","a\n"],["/b.txt","b\n"]]'
nullspace volume cat team-data /models/manifest.json
nullspace volume stat team-data /models/model.bin
nullspace volume info team-data /models/model.bin
nullspace volume exists team-data /models/model.bin
nullspace volume mkdir team-data /models
nullspace volume chmod team-data /models/model.bin 0644
nullspace volume rm team-data /tmp/old.bin
nullspace volume mv team-data /models/old.bin /models/new.bin
nullspace volume find team-data /models "weights"
nullspace volume search team-data /models "*.bin"
nullspace volume replace team-data "old" "new" /models/config.json --dry-run
nullspace volume upload-url team-data /models/model.bin
nullspace volume download-url team-data /models/model.bin
nullspace volume watch team-data /models --recursive
nullspace volume upload team-data ./model.bin /models/model.bin
nullspace volume upload team-data ./model.bin /models/model.bin --resumable always --concurrency 4
nullspace volume download team-data /models/model.bin ./model.bin --force
nullspace volume download team-data /datasets ./datasets.tar --archive --json
nullspace volume delete vol_12345678