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

Auth

nullspace auth login --api-url https://18.140.200.84.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 or NULLSPACE_TOKEN with NULLSPACE_API_URL directly for scripts, CI, and coding agents.

Functions

nullspace dev
nullspace deploy --dry-run --json
nullspace deploy --json
nullspace run repo-review-agent --input input.json --json
nullspace shell repo-review-agent --run fnrun_123 --cmd "pwd"

nullspace functions init
nullspace functions deploy --dry-run --json
nullspace functions deploy --json
nullspace functions deploy --rebuild --json
nullspace functions deploy --no-cache --json
nullspace environment create staging
nullspace environment list --json
NULLSPACE_ENVIRONMENT=staging nullspace functions deploy --json
nullspace functions list --env staging --json
nullspace functions get repo-review-agent --env staging --json
nullspace functions history repo-review-agent --env staging --json
nullspace functions run repo-review-agent --env staging --input input.json --json
nullspace functions run repo-review-agent --env staging --route /review --input input.json --json
nullspace functions spawn repo-review-agent --env staging --input input.json --json
nullspace functions run repo-review-agent --retain-on-failure --retention-seconds 3600
nullspace functions logs repo-review-agent --run fnrun_123 --json
nullspace functions outputs repo-review-agent --run fnrun_123 --json
nullspace functions status repo-review-agent --run fnrun_123 --json
nullspace functions url repo-review-service
nullspace functions status repo-review-agent --service fnsvc_123 --json
nullspace functions shell repo-review-agent --run fnrun_123 --cmd "pwd"
nullspace functions machine repo-review-agent --run fnrun_123
nullspace functions checkpoint repo-review-agent --run fnrun_123 --label before-change --json
nullspace functions branch repo-review-agent --run fnrun_123 --checkpoint-id chk_123 --count 3 --json
nullspace functions checkpoint repo-review-service --service fnsvc_123 --json
nullspace functions branch repo-review-service --service fnsvc_123 --checkpoint-id chk_456 --count 2 --json
nullspace functions tree repo-review-agent --json
nullspace functions rollback repo-review-agent --version-id fnv_123 --json
nullspace functions rollback repo-review-agent --checkpoint-id chk_123 --json
nullspace functions stop repo-review-agent --run fnrun_123 --reason "superseded" --json
nullspace functions stop repo-review-agent
nullspace functions stop repo-review-service --service fnsvc_123 --retain-machine --json
nullspace functions restart repo-review-service
nullspace functions proxy-auth create repo-review-service --env prod --name client-a --route /invoke --json
nullspace functions proxy-auth list repo-review-service --env prod --json
nullspace functions proxy-auth revoke repo-review-service fnpauth_123 --env prod --json
nullspace functions schedule list repo-review-agent --json
nullspace functions schedule create repo-review-agent --cron "0 8 * * 1" --timezone UTC --json
nullspace functions schedule create repo-review-agent --cron "0 8 * * 1" --route /report --json
nullspace functions schedule create repo-review-agent --seconds 21600 --json
nullspace functions schedule run repo-review-agent fnsch_123 --json
nullspace functions schedule fires repo-review-agent --trigger-id fnsch_123 --json
nullspace functions webhook create repo-review-agent --route /review --signing-secret "$WEBHOOK_SECRET" --json
nullspace functions webhook list repo-review-agent --json
nullspace functions webhook signature "$WEBHOOK_SECRET" '{"event":"push"}'
nullspace functions delete repo-review-agent --yes
nullspace functions template list
nullspace functions template build --from-python-image 3.12 --name repo-review-env
The top-level dev, deploy, run, and shell commands are the first-class Function workflow. The functions ... group exposes deployment, run/service, debugging, trigger, rollback, and proxy-auth operations. functions template ... is a nested alias for the same implementation as template ...; use it when a Function workflow needs a custom machine environment. functions deploy --dry-run performs local config detection and bundle planning without an API key. Real deploy creates or reuses a named function and stores a metadata-only version record with the local bundle manifest; binary bundle upload and runtime execution are handled by the function runtime path. Functions run as finite jobs or long-running services. Jobs create run records, logs, outputs, and backing machine access. Services create service instances with URL, readiness, logs, and backing machine access. Current Function modes are job and service. worker, triggered, workspace, and interactive are reserved for future Function modes. Lifecycle webhooks are machine lifecycle subscriptions, not agent trigger webhooks. Named routes let one Function version expose multiple entrypoints. Use --route /name on run, spawn, schedule create, webhook create, and run-branch commands to target a route-specific command. Function environments scope names, secrets, version history, and name-based run/spawn/rollback lookups. Use nullspace environment create/list, NULLSPACE_ENVIRONMENT, or command-level --env / --environment selectors to route deploys and runtime commands to default, staging, prod, or another environment. A bare --env staging selects the Function environment; --env NAME=value remains a runtime env-var override. Function build cache status is reported by functions 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 function 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. Use checkpoint, branch, tree, and rollback for snapshot-based Function lineage. Checkpoints can be captured from job runs or service instances; branch creates child runs or child services; rollback changes the active version for future work. functions proxy-auth create/list/revoke manages edge-enforced Function endpoint credentials for versions deployed with requires_proxy_auth=True. Create output includes the proxy-auth secret once; list output never returns the secret. functions schedule ... manages cron/period triggers that create normal Function runs, and functions webhook ... manages inbound HMAC-verified Function webhook triggers. Lifecycle webhooks are outbound machine lifecycle subscriptions, not inbound Function triggers.

Secrets

nullspace secret create openai OPENAI_API_KEY="$OPENAI_API_KEY"
nullspace secret create warehouse --env prod --from-dotenv .env.prod
nullspace secret list --json
nullspace secret delete warehouse --env prod --json
Secret command output shows names, environments, and key names only. Values are write-only on create and are injected into functions that reference the named secret from function.py.

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 mch_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
Queued code runs are available through machine code run-job create, get, wait, cancel, and list.

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]"
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
The same template parser is also available under nullspace functions template .... 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