Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/agent0ai/space-agent/llms.txt

Use this file to discover all available pages before exploring further.

Running Space Agent in production is straightforward once you understand its two-layer model: the source checkout provides the firmware (L0), while a separate writable directory — controlled by CUSTOMWARE_PATH — holds all group and user state. Keeping these apart means you can update the application code without touching anyone’s data, and node space supervise handles that handoff automatically with zero-downtime traffic switching.
Do not run the server as root. Create a dedicated system user (e.g. space-agent) and ensure it owns the CUSTOMWARE_PATH directory. Running as root exposes your entire filesystem if the server process is ever compromised.

Full Production Walkthrough

1

Clone and install

Clone the repository and install Node.js dependencies. No build step is required — Space Agent runs directly from source.
git clone https://github.com/agent0ai/space-agent.git
cd space-agent
npm install
Verify the installation by checking the version:
node space version
2

Set CUSTOMWARE_PATH

Before creating any users or groups, set CUSTOMWARE_PATH to an absolute directory outside the source checkout. This is where all writable L1 (group) and L2 (user) state lives. When you later update the source checkout with node space update, user data at this path is never touched.
node space set CUSTOMWARE_PATH=/srv/space/customware
Create the directory and give it to your service account:
sudo mkdir -p /srv/space/customware
sudo chown space-agent:space-agent /srv/space/customware
Setting CUSTOMWARE_PATH via node space set writes it to the project .env file so every subsequent serve, supervise, and user/group CLI command picks it up automatically. A launch-time override (node space serve CUSTOMWARE_PATH=...) only applies to that single process.
3

Create an admin user

Create your first admin account. The --groups _admin flag adds the user to the built-in _admin group, which grants full read/write access across all L1 and L2 paths.
node space user create admin \
  --password "strong-password" \
  --full-name "Admin" \
  --groups _admin
Replace "strong-password" with a genuinely strong, unique password before going live. Admin accounts have unrestricted write access to all group and user data on the server.
You can change the password at any time:
node space user password admin --password "new-strong-password"
4

Configure server parameters

Set the network bind address, port, and worker count in the project .env. These values persist across restarts.
# Bind to all interfaces (required to receive traffic from a reverse proxy)
node space set HOST=0.0.0.0

# TCP port (default is already 3000)
node space set PORT=3000

# Number of parallel HTTP worker processes
node space set WORKERS=4
WORKERS=4 runs a clustered runtime with one authoritative primary process (which owns watchdog and state) plus four HTTP workers handling requests in parallel. For a single-CPU or low-traffic machine, WORKERS=1 (the default) keeps everything in one process.Review all current parameter values at any time:
node space get
5

Start with the supervisor

For production use node space supervise, which runs a stable reverse-proxy in front of replaceable space serve child processes. It checks for source updates every five minutes by default and performs a zero-downtime switch: new traffic routes to the replacement child only after it passes a readiness check.
node space supervise CUSTOMWARE_PATH=/srv/space/customware
Common supervisor options:
# Disable automatic update checks (crash-restart only)
node space supervise --auto-update-interval 0 CUSTOMWARE_PATH=/srv/space/customware

# Explicit branch tracking with a custom update interval
node space supervise \
  --branch main \
  --auto-update-interval 600 \
  CUSTOMWARE_PATH=/srv/space/customware

# Multi-worker production setup
node space supervise \
  HOST=0.0.0.0 PORT=3000 WORKERS=8 \
  CUSTOMWARE_PATH=/srv/space/customware
The supervisor normalizes CUSTOMWARE_PATH to an absolute path before injecting it into every child process, so all release checkouts share the same writable roots regardless of where the supervisor itself is started from.
The supervisor process sets its OS title to space-supervise, while child processes appear as space-serve, space-serve-p (clustered primary), or space-serve-w1space-serve-wN (clustered workers). These titles make it easy to identify processes in htop or ps.
6

Verify the deployment

Open a browser and navigate to your server’s address. You should see the Space Agent login screen. You can also check the health endpoint directly:
curl http://localhost:3000/api/health
A successful response confirms the server is running and accepting requests. Log in with the admin credentials you created in step 3 and open /admin to confirm admin mode is accessible.

Additional Configuration

CUSTOMWARE_PATH and update safety

CUSTOMWARE_PATH defaults to an empty string. When it is empty, all writable L1 and L2 state lives inside the source checkout at app/L1/ and app/L2/. That is fine for local development or a single-person installation, but it means an update that replaces the source checkout directory would touch user data. For any server where updates matter, always point CUSTOMWARE_PATH to a directory outside the checkout before creating users. When CUSTOMWARE_PATH is set to an absolute path, the logical paths resolve as follows:
Logical pathOn-disk location
L0/...<repo>/app/L0/... (read-only firmware)
L1/<group>/...CUSTOMWARE_PATH/L1/<group>/...
L2/<username>/...CUSTOMWARE_PATH/L2/<username>/...
This means node space update (or node space supervise’s automatic update) only touches the source checkout. All group configuration and user data at CUSTOMWARE_PATH is never modified by an update.

Disabling background file watching

In container environments the default fs.watch listeners and periodic reconcile loop can produce unwanted noise. Set CUSTOMWARE_WATCHDOG=false to disable background watching while keeping startup indexing and the explicit clustered mutation path active:
node space set CUSTOMWARE_WATCHDOG=false
Or pass it as a launch-time override:
node space supervise CUSTOMWARE_WATCHDOG=false CUSTOMWARE_PATH=/srv/space/customware

Per-user disk quotas

USER_FOLDER_SIZE_LIMIT_BYTES caps each user’s L2/<username>/ folder on disk. Set to 0 (the default) to disable. For example, to cap each user at 500 MB:
node space set USER_FOLDER_SIZE_LIMIT_BYTES=524288000
When a folder exceeds the cap, only mutations that reduce its size are allowed until it drops back below the limit.

Git backend preference

For production use, prefer the native Git backend when git is installed on the host. It falls back to isomorphic automatically when native Git is unavailable:
node space set GIT_BACKEND=native
The default auto mode already follows this fallback order (native -> isomorphic), so you only need to set this explicitly if you want to force one backend for testing or troubleshooting.

GitHub token for private update sources

If your production instance pulls from a private GitHub repository during node space update or supervised auto-updates, set SPACE_GITHUB_TOKEN in the environment before running the supervisor:
export SPACE_GITHUB_TOKEN=ghp_...
node space supervise CUSTOMWARE_PATH=/srv/space/customware

Development server

For local development and testing, use npm run dev instead of node space serve. It starts the server with auto-reload on source changes and can attach a VS Code debugger to the spawned process:
npm run dev
Open the checked-in VS Code launch entry Dev Server (npm run dev) when you want breakpoints in server/ code. It launches the same watcher and auto-attaches to the spawned node space serve process across restarts.

Desktop app (zero-config single-user)

If you only need a personal installation with no server management, download the latest desktop app from GitHub Releases. It packages everything into one app with no terminal required — the server runs locally with SINGLE_USER_APP=true so all requests resolve to an implicit admin principal without any login step.

Build docs developers (and LLMs) love