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

# Service Installation

> Install NullClaw as a system service with auto-start

NullClaw supports native service integration on macOS (launchd), Linux (systemd), and Windows (SCM).

## Overview

The service manager installs, starts, stops, and monitors the NullClaw gateway as a background daemon.

Supported platforms:

* **macOS**: launchd (LaunchAgents)
* **Linux**: systemd user services
* **Windows**: Service Control Manager (sc.exe)

## Installation

<Steps>
  <Step title="Install service">
    ```bash theme={null}
    nullclaw service install
    ```

    This creates a service unit file with:

    * Auto-start on boot
    * Auto-restart on failure
    * Logging to \~/.nullclaw/logs/
  </Step>

  <Step title="Start service">
    ```bash theme={null}
    nullclaw service start
    ```
  </Step>

  <Step title="Check status">
    ```bash theme={null}
    nullclaw service status
    ```
  </Step>
</Steps>

## Commands

### Install

```bash theme={null}
nullclaw service install
```

Creates the service unit file and enables auto-start. Does not start the service immediately.

### Start

```bash theme={null}
nullclaw service start
```

Starts the gateway service. Loads the service if not already loaded.

### Stop

```bash theme={null}
nullclaw service stop
```

Stops the running gateway service.

### Status

```bash theme={null}
nullclaw service status
```

Shows service state and unit file path:

```
Service state: active
Unit: /Users/alice/.config/systemd/user/nullclaw.service
```

### Uninstall

```bash theme={null}
nullclaw service uninstall
```

Stops the service, removes the unit file, and disables auto-start.

## macOS (launchd)

On macOS, the service is installed as a LaunchAgent.

### Unit File Location

```
~/Library/LaunchAgents/com.nullclaw.daemon.plist
```

### Configuration

```xml theme={null}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.nullclaw.daemon</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/nullclaw</string>
    <string>gateway</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>KeepAlive</key>
  <true/>
  <key>StandardOutPath</key>
  <string>/Users/alice/.nullclaw/logs/daemon.stdout.log</string>
  <key>StandardErrorPath</key>
  <string>/Users/alice/.nullclaw/logs/daemon.stderr.log</string>
</dict>
</plist>
```

### Manual Management

```bash theme={null}
# Load service
launchctl load -w ~/Library/LaunchAgents/com.nullclaw.daemon.plist

# Unload service
launchctl unload -w ~/Library/LaunchAgents/com.nullclaw.daemon.plist

# Start service
launchctl start com.nullclaw.daemon

# Stop service
launchctl stop com.nullclaw.daemon

# Check if running
launchctl list | grep nullclaw
```

## Linux (systemd)

On Linux, the service is installed as a systemd user service.

### Unit File Location

```
~/.config/systemd/user/nullclaw.service
```

### Configuration

```ini theme={null}
[Unit]
Description=nullclaw gateway runtime
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/nullclaw gateway
Restart=always
RestartSec=3
EnvironmentFile=-/home/alice/.nullclaw/.env

[Install]
WantedBy=default.target
```

### Manual Management

```bash theme={null}
# Reload systemd configuration
systemctl --user daemon-reload

# Enable service (auto-start)
systemctl --user enable nullclaw.service

# Start service
systemctl --user start nullclaw.service

# Stop service
systemctl --user stop nullclaw.service

# Check status
systemctl --user status nullclaw.service

# View logs
journalctl --user -u nullclaw.service -f
```

<Warning>
  **systemd user services require a login session.** If you log out, the service stops.

  To keep the service running after logout, enable lingering:

  ```bash theme={null}
  loginctl enable-linger $USER
  ```
</Warning>

## Windows (Service Control Manager)

On Windows, the service is installed using `sc.exe`.

### Service Name

```
nullclaw
```

### Configuration

```
Display Name: nullclaw gateway runtime
Binary Path: C:\Path\To\nullclaw.exe gateway
Start Type: Automatic
```

### Manual Management

```powershell theme={null}
# Create service
sc.exe create nullclaw binPath= "C:\Path\To\nullclaw.exe gateway" start= auto DisplayName= "nullclaw gateway runtime"

# Start service
sc.exe start nullclaw

# Stop service
sc.exe stop nullclaw

# Query status
sc.exe query nullclaw

# Delete service
sc.exe delete nullclaw
```

## Auto-Start Configuration

All platforms enable auto-start by default:

* **macOS**: `RunAtLoad=true` in plist
* **Linux**: `WantedBy=default.target` in unit file
* **Windows**: `start=auto` in service config

The service starts automatically:

* On system boot
* On user login (systemd user services)
* After crash (auto-restart enabled)

## Restart Behavior

### macOS

```xml theme={null}
<key>KeepAlive</key>
<true/>
```

launchd automatically restarts the service if it exits.

### Linux

```ini theme={null}
Restart=always
RestartSec=3
```

systemd restarts the service after 3-second delay if it exits.

### Windows

Windows Service Manager does not auto-restart by default. Configure recovery actions:

```powershell theme={null}
sc.exe failure nullclaw reset= 86400 actions= restart/3000/restart/3000/restart/3000
```

This restarts the service after 3 seconds on first three failures.

## Logging

### macOS

Logs are written to:

```
~/.nullclaw/logs/daemon.stdout.log
~/.nullclaw/logs/daemon.stderr.log
```

View logs:

```bash theme={null}
tail -f ~/.nullclaw/logs/daemon.stdout.log
```

### Linux

Logs are captured by journald:

```bash theme={null}
journalctl --user -u nullclaw.service -f
```

View last 100 lines:

```bash theme={null}
journalctl --user -u nullclaw.service -n 100
```

### Windows

Check Event Viewer:

```
Event Viewer > Windows Logs > Application
```

Filter by source: `nullclaw`

## Environment Variables

### Linux

The systemd unit file loads environment variables from:

```
~/.nullclaw/.env
```

Example `.env` file:

```bash theme={null}
NULLCLAW_API_KEY=sk-...
NULLCLAW_GATEWAY_PORT=3000
NULLCLAW_DEFAULT_PROVIDER=openrouter
```

The `EnvironmentFile=-...` directive (with `-` prefix) makes the file optional.

### macOS/Windows

Set environment variables in the service configuration or use the config file at `~/.nullclaw/config.json`.

## Troubleshooting

### Service won't start (Linux)

Check if systemd user services are available:

```bash theme={null}
systemctl --user status
```

If you see "Failed to connect to bus", systemd user services are not enabled. This is common in:

* Docker containers
* Minimal Linux distributions
* SSH sessions without lingering

Enable lingering:

```bash theme={null}
loginctl enable-linger $USER
```

### Service stops after logout (Linux)

Systemd user services stop when the user session ends. Enable lingering:

```bash theme={null}
loginctl enable-linger $USER
```

### Permission denied (Windows)

Service installation requires administrator privileges. Run as administrator:

```powershell theme={null}
Start-Process cmd -Verb RunAs
nullclaw service install
```

### Cannot find systemctl

If `systemctl` is not available on Linux, you cannot use systemd user services. Run the gateway manually or use Docker.

## Implementation

The service manager is implemented in `src/service.zig`:

```zig theme={null}
pub const ServiceCommand = enum {
    install,
    start,
    stop,
    status,
    uninstall,
};

pub fn handleCommand(
    allocator: std.mem.Allocator,
    command: ServiceCommand,
    config_path: []const u8,
) !void {
    return switch (command) {
        .install => install(allocator, config_path),
        .start => startService(allocator),
        .stop => stopService(allocator),
        .status => serviceStatus(allocator),
        .uninstall => uninstall(allocator),
    };
}
```

Platform-specific implementations use child process execution to interact with:

* `launchctl` (macOS)
* `systemctl` (Linux)
* `sc.exe` (Windows)

See `~/workspace/source/src/service.zig` for full implementation.
