Skip to main content

Overview

Headless mode allows Antigravity Manager to run on servers without a graphical desktop environment. It provides full functionality through a Web-based interface and API endpoints.
Headless mode is automatically enabled when using Docker or running with the --headless flag.

Headless vs Desktop Mode

Headless Mode

  • Web-based management UI
  • API-first design
  • No GUI dependencies
  • Perfect for servers/containers
  • Lower resource usage

Desktop Mode

  • Native desktop application
  • System tray integration
  • Tauri-based GUI
  • Local OAuth callbacks
  • Auto-update support

Running Headless Mode

Direct Binary Execution

# Download or build the binary
./antigravity-tools --headless

With Environment Variables

export API_KEY="sk-your-secure-key"
export WEB_PASSWORD="admin-password"
export LOG_LEVEL="info"
export PORT="8045"

./antigravity-tools --headless

Systemd Service (Linux)

Create a systemd service for automatic startup:
/etc/systemd/system/antigravity-manager.service
[Unit]
Description=Antigravity Manager Headless Service
After=network.target

[Service]
Type=simple
User=antigravity
WorkingDirectory=/opt/antigravity
ExecStart=/opt/antigravity/antigravity-tools --headless

# Environment variables
Environment="API_KEY=sk-your-secure-key"
Environment="WEB_PASSWORD=your-admin-password"
Environment="LOG_LEVEL=info"
Environment="ABV_BIND_LOCAL_ONLY=false"

# Security
NoNewPrivileges=true
PrivateTmp=true

# Restart policy
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable antigravity-manager
sudo systemctl start antigravity-manager
sudo systemctl status antigravity-manager

Headless-Specific Configuration

Environment Variables

API_KEY
string
required
API key for authenticating API requests from AI clients.Also accepts: ABV_API_KEY
WEB_PASSWORD
string
Password for Web UI login. If not set, uses API_KEY.Also accepts: ABV_WEB_PASSWORD
AUTH_MODE
string
default:"AllExceptHealth"
Authentication mode in headless:
  • AllExceptHealth: Auth required except /health (default in headless)
  • Strict: Auth required for all endpoints
  • Off: No authentication (dangerous!)
  • Auto: Automatically determined
Also accepts: ABV_AUTH_MODE
ABV_BIND_LOCAL_ONLY
boolean
default:"false"
  • true: Bind to 127.0.0.1 (localhost only)
  • false: Bind to 0.0.0.0 (all network interfaces)
In Docker/headless mode, defaults to false to allow LAN access.
PORT
integer
default:"8045"
Port for the Web UI and API endpoints.
ABV_MAX_BODY_SIZE
integer
default:"104857600"
Maximum request body size (bytes). Default: 100MB for large image uploads.
ABV_DIST_PATH
string
default:"/app/dist"
Path to frontend static files. Pre-configured in Docker images.
ABV_PUBLIC_URL
string
Public URL for OAuth callbacks when behind reverse proxy.Example: https://antigravity.example.com
LOG_LEVEL
string
default:"info"
Logging verbosity: debug, info, warn, error
RUST_LOG
string
default:"info"
Rust-specific logging. Overrides LOG_LEVEL for Rust components.

Code Reference

Headless mode initialization is in src-tauri/src/lib.rs:109-289:
let args: Vec<String> = std::env::args().collect();
let is_headless = args.iter().any(|arg| arg == "--headless");

if is_headless {
    info!("Starting in HEADLESS mode...");
    // ... headless initialization
}

Web UI Access

In headless mode, access the management interface at:
http://localhost:8045
Or from another device on the network (if ABV_BIND_LOCAL_ONLY=false):
http://192.168.1.100:8045

Web UI Features

1

Account Management

Add, edit, and remove Google accounts via OAuth flow
2

Quota Monitoring

Real-time quota tracking and account health status
3

API Configuration

Configure proxy settings, model routing, and API keys
4

Logs and Monitoring

View API request logs, token usage, and system status
5

Settings

Configure security, IP whitelisting, and advanced options

Security Considerations

Headless mode forces auth_mode to AllExceptHealth if it was Off or Auto.

Authentication Flow

  1. Web UI Login: Uses WEB_PASSWORD (or API_KEY if not set)
  2. API Requests: Use API_KEY in Authorization header
  3. Health Endpoint: Always accessible at /health (no auth)

Firewall Configuration

# Allow port 8045 from specific IP
sudo ufw allow from 192.168.1.0/24 to any port 8045

# Or allow from anywhere (less secure)
sudo ufw allow 8045

Logging and Monitoring

Log Locations

  • Application Data: ~/.antigravity_tools/
  • Logs: ~/.antigravity_tools/logs/ (if configured)
  • Configuration: ~/.antigravity_tools/gui_config.json

View Logs

# Real-time logs
sudo journalctl -u antigravity-manager -f

# Last 100 lines
sudo journalctl -u antigravity-manager -n 100

# Since boot
sudo journalctl -u antigravity-manager -b

Health Check Endpoint

curl http://localhost:8045/health
Response:
{
  "status": "ok",
  "version": "4.1.27"
}
Use this for monitoring tools like Prometheus, Uptime Kuma, or Nagios.

OAuth in Headless Mode

OAuth callbacks work in headless mode through the Web UI’s built-in OAuth handler.

Standard OAuth Flow

  1. Access Web UI at http://your-server:8045
  2. Navigate to Accounts → Add Account → OAuth
  3. Copy the generated authorization URL
  4. Open URL in any browser (can be on different device)
  5. Complete Google OAuth authorization
  6. Browser redirects to callback URL
  7. Web UI automatically completes the flow

Behind Reverse Proxy

If behind a reverse proxy, set the public URL:
export ABV_PUBLIC_URL="https://antigravity.example.com"
This ensures OAuth callbacks redirect to your public domain instead of localhost:8045.

Headless-Specific Features

Automatic Admin Server

Headless mode automatically starts the admin server on port 8045 to serve the Web UI:
// From lib.rs:356-373
if let Ok(config) = modules::config::load_app_config() {
    // Ensure admin server is running
    if let Err(e) = commands::proxy::ensure_admin_server(
        config.proxy.clone(),
        &state,
        integration.clone(),
        Arc::new(cf_state.inner().clone()),
    ).await {
        error!("Failed to start admin server: {}", e);
    }
}

No Tray Icon

Headless mode automatically disables system tray:
let tray_enabled = should_enable_tray();
// Returns false in headless mode

Graceful Shutdown

Headless mode handles Ctrl+C for clean shutdown:
// Wait for Ctrl-C
tokio::signal::ctrl_c().await.ok();
info!("Headless mode shutting down");

Performance Tuning

Resource Limits

For systemd services:
/etc/systemd/system/antigravity-manager.service
[Service]
# Memory limit
MemoryLimit=1G

# CPU quota (50% of one core)
CPUQuota=50%

# Max open files
LimitNOFILE=4096

Concurrency Settings

Adjust in gui_config.json:
{
  "proxy": {
    "max_connections": 100,
    "request_timeout": 30,
    "max_retries": 3
  }
}

Troubleshooting

  1. Check ABV_BIND_LOCAL_ONLY is false:
    grep allow_lan_access ~/.antigravity_tools/gui_config.json
    
  2. Verify firewall allows port 8045:
    sudo netstat -tlnp | grep 8045
    
  3. Test from server:
    curl http://localhost:8045/health
    
  1. Ensure admin server is running:
    curl http://localhost:8045
    
  2. If behind reverse proxy, set ABV_PUBLIC_URL
  3. Check firewall allows callback port
  1. Check for excessive logging:
    export LOG_LEVEL=warn
    
  2. Review background tasks in logs:
    journalctl -u antigravity-manager | grep -i "background\|task\|scheduler"
    
  3. Smart scheduler is disabled by default (v4.1.24+)
  1. Check systemd status:
    sudo systemctl status antigravity-manager
    
  2. Review recent logs:
    sudo journalctl -u antigravity-manager -n 50
    
  3. Verify binary path and permissions:
    ls -la /opt/antigravity/antigravity-tools
    

Next Steps

Reverse Proxy Setup

Add HTTPS and custom domain with Nginx or Caddy

API Integration

Connect Claude CLI, OpenCode, and other clients

Security Best Practices

Configure IP whitelisting, rate limiting, and authentication

Monitoring

Set up Prometheus, Grafana, or other monitoring tools

Build docs developers (and LLMs) love