CLAW
Definitive Field Guide β€” 2026 Edition

OpenClaw
on Android

Everything that actually works. Written from real failures, not documentation.
One phone. Ubuntu proot. NordVPN Meshnet. nginx HTTPS. No fluff.

Ubuntu proot mandatory Node.js 22 via NodeSource NordVPN Android app Bare Termux does NOT work scrcpy for PC users

Battery Setup

If this phone is staying plugged in 24/7 as an AI agent, your battery will degrade fast unless you set a charge limit. 85% is the sweet spot β€” your phone stays usable but isn't held at peak voltage constantly.

0% ← ideal range β†’ 85% 100%

Samsung (One UI 4+)

  1. 01

    Settings β†’ Battery and device care β†’ Battery

  2. 02

    Tap More battery settings

  3. 03

    Enable Protect battery β€” this caps charging at 85%

Motorola / Stock Android

  1. 01

    Settings β†’ Battery β†’ Adaptive preferences or Battery health

  2. 02

    Enable Optimized charging or Charge limit

  3. 03

    If no built-in option exists, leave it β€” don't worry about it. Running the phone at moderate temperatures matters more than the charge limit.

Keep the phone somewhere cool and ventilated. Heat is the #1 battery killer β€” more damaging than charge percentage. Don't leave it on a warm surface or under a pillow while it runs.

Expand RAM with Swap

OpenClaw + Ubuntu proot + Node.js 22 can push 1.2–1.8GB of RAM in active use. If your phone has 4GB or less, Android will start killing background processes to reclaim memory, which can take down your gateway mid-session. A swap file on internal storage acts as overflow RAM β€” slower than real RAM, but enough to keep things alive.

Swap doesn't make your phone faster. It's a safety net β€” when RAM fills up, Android moves idle pages to the swap file on storage instead of killing processes outright. For a 24/7 server this is exactly what you want: the gateway stays alive even when Android is under memory pressure. Modern UFS 3.x internal storage is fast enough and rated for many years of this workload.

SWAP β€” No ROOT (Play Store)

No root required, works on most Android phones. Search "SWAP No ROOT" by AllaKore on the Play Store.

  1. 01

    Install SWAP β€” No ROOT by AllaKore from the Play Store.

  2. 02

    Open the app β†’ tap Create SWAP file.

  3. 03

    Set the size. 2GB is the recommended starting point for a dedicated agent phone. Don't exceed 50% of your free internal storage β€” you need space for Ubuntu and OpenClaw files.

  4. 04

    Tap Activate. The swap file is created on internal storage.

  5. 05

    Enable "Activate on boot" in the app so swap persists through reboots.

4GB RAM phone β†’ create 2GB swap. 6GB phone β†’ 1–2GB still useful as a buffer. 8GB+ phone β†’ swap is optional, OpenClaw fits comfortably. Check free storage first: Settings β†’ Storage. Have at least 15GB free before creating swap.

If the app offers to put the swap on an SD card β€” don't. SD card write speeds are far too slow for swap and will hurt performance. Internal UFS storage only.

Verify swap is active inside Ubuntu

Ubuntu prootinside Ubuntu
# Should show your swap file and its size
cat /proc/swaps
free -h

If /proc/swaps shows a swap entry, it's working. free -h will show a Swap: row with your allocated size next to it.

Keep it Cool

Heat is your biggest enemy for 24/7 operation. When the processor gets hot, Android's thermal governor cuts clock speeds β€” sometimes by 50% or more. This is why npm installs take longer than expected, and why a "faster" phone can finish tasks slower than an older one. Keeping the phone cool is the single most impactful hardware optimization you can make.

Physical setup

  1. 01

    Remove the case. Phone cases trap heat. Running caseless can drop surface temps by 5–10Β°C.

  2. 02

    Stand the phone upright or prop it on its side. Flat on a surface traps heat underneath.

  3. 03

    Point a small USB fan at it. Even a cheap desk fan dramatically improves sustained CPU performance. This is the most effective and cheapest hardware upgrade for a phone server.

  4. 04

    Don't stack both phones together β€” they'll heat each other. Keep at least 10cm between them.

  5. 05

    Don't put them inside a drawer, cabinet, or any enclosed space.

Software tweaks

  1. 01

    Set screen timeout to minimum (15 or 30 seconds). The display is a significant heat source β€” keeping it off while the gateway runs lowers temps noticeably.

  2. 02

    Set display refresh rate to 60Hz in Settings β†’ Display. 90/120Hz increases GPU and CPU load even when you're not actively looking at the screen.

  3. 03

    Lower brightness to minimum when not using the phone actively.

  4. 04

    On Samsung: Settings β†’ Developer options β†’ Rendering β†’ Disable HW overlays β€” reduces GPU workload slightly.

A healthy 24/7 phone server runs at 35–45Β°C surface temperature. If the back of the phone feels too hot to hold comfortably for 10 seconds, it's throttling. Add a fan or remove the case first.

PC Control via scrcpy

If you have a PC, use scrcpy to control your phone from your desktop. This is strongly recommended for the installation process β€” you can paste long commands from your PC clipboard directly into Termux without typing everything on the phone screen.

Download scrcpy from github.com/Genymobile/scrcpy/releases β€” get the win64 zip, extract it anywhere.

Connect your phone

Enable USB Debugging on your phone: Settings β†’ About phone β†’ tap Build number 7 times β†’ Developer options β†’ USB debugging ON. Then plug in via USB and run:

Windows CMDPC
# Single phone
scrcpy.exe --prefer-text

# If you have multiple phones connected, specify by serial
scrcpy.exe -s YOUR_DEVICE_SERIAL --prefer-text

# Find serials if needed
adb devices

--prefer-text is required if you're on a Finnish/Nordic keyboard layout. Without it, characters like Γ₯, Γ€, ΓΆ get mangled or dropped entirely when pasting into the terminal.

Pasting into the phone terminal

Keyboard Shortcuts
Alt + Shift + V
Inject PC clipboard text into the phone β€” use this for pasting commands
Alt + V
Sync clipboards and paste (alternative)
Ctrl + C
Copy on PC as normal, then Alt+Shift+V to inject

scrcpy truncates pastes that are too long β€” commands over ~120 characters get cut off mid-paste. If this happens, paste the command one line at a time, or use nano to type multi-line config files directly on the phone.

Permissions & Wake Lock

Android aggressively kills background apps to save battery. Without the right permissions, Termux and NordVPN get killed the moment the screen turns off β€” which kills your OpenClaw gateway and drops the Meshnet.

Battery optimization β€” must disable for both apps

  1. 01

    Settings β†’ Apps β†’ Termux β†’ Battery β†’ Set to Unrestricted (Samsung) or Don't optimize (Moto/stock)

  2. 02

    Do the same for NordVPN

  3. 03

    On Samsung: also go to Settings β†’ Device care β†’ Battery β†’ Background usage limits β†’ make sure Termux is NOT in the sleeping apps list

Termux wake lock (keep CPU running)

Run this inside Termux once and it keeps your session alive even with the screen off:

Termuxphone
termux-wake-lock

Also install Termux:Boot from F-Droid. This lets Termux auto-start after a reboot without you having to manually open it. Critical for a 24/7 setup.

Install Termux

Install Termux from F-Droid, NOT the Google Play Store. The Play Store version is outdated (stopped being updated in 2020) and silently breaks npm installs, package signing, and more. Go to f-droid.org, install the F-Droid app, then search for Termux.

While you're in F-Droid, also install Termux:Boot for auto-start on reboot.

First run

Termuxphone
# Update the package index first β€” always
pkg update && pkg upgrade -y

# Install proot-distro β€” this is the only thing we need from Termux pkg
pkg install proot-distro curl -y

# Lock the CPU awake
termux-wake-lock

The vim/neovim package in Termux is called neovim, NOT nvim. Many online guides have this wrong and it causes a confusing error. pkg install neovim if you want an editor β€” though you won't need one for this guide.

Ubuntu proot

This is the most important decision in the entire guide: Ubuntu proot is not optional. Bare Termux uses Android's Bionic libc which is incompatible with how Node.js native modules compile. OpenClaw's core dependency (koffi) will fail to build every single time in bare Termux, no matter what flags you use.

Bare Termux fails because Android's Bionic libc is not binary-compatible with Linux glibc. The koffi module (which OpenClaw needs to call system functions) compiles for glibc and crashes immediately on Bionic. Ubuntu proot gives you real glibc, proper /tmp, and a real Linux filesystem. There is no workaround β€” use Ubuntu.

Termuxphone
# Download and install Ubuntu β€” takes a minute on first run
proot-distro install ubuntu

# Enter Ubuntu β€” run this every time you open Termux
proot-distro login ubuntu

Your prompt will change from $ to root@localhost:~#. Everything from this point forward runs inside Ubuntu unless stated otherwise.

Ubuntu prootinside Ubuntu
# Update Ubuntu package lists
apt update && apt upgrade -y

# Install build tools and deps
apt install -y curl git build-essential tmux lsof nano

Node.js 22

Use the NodeSource installer to get Node.js 22 inside Ubuntu. Do not use apt install nodejs directly β€” the version in Ubuntu's default repos is too old and will break OpenClaw.

Ubuntu prootinside Ubuntu
# Add NodeSource repo for Node 22
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -

# Install Node.js
apt install -y nodejs

# Verify β€” should show v22.x.x
node -v
npm -v

You should see v22.22.0 (or similar) and 10.9.x for npm. If node -v shows v24 or higher, you have the wrong version β€” run the NodeSource setup script again.

Install OpenClaw

Ubuntu prootinside Ubuntu
# Install OpenClaw globally
npm install -g openclaw@latest

You will see many npm warn deprecated messages during install. These are completely harmless β€” they're notices about outdated sub-dependencies inside packages that OpenClaw uses. The install is working correctly. Wait for it to complete (3–5 minutes on a phone). It's done when you see added 847 packages in Xm.

If you get a compilation error about koffi, sharp, or canvas, use --ignore-scripts to skip optional native builds. This skips Discord voice and image processing β€” neither is needed for basic agent use:

Ubuntu proot β€” fallbackinside Ubuntu
npm install -g openclaw@latest --ignore-scripts
Ubuntu prootinside Ubuntu
# Verify install
openclaw --version

If a newer/faster phone finishes npm install slower than an older one β€” this is normal. The "faster" phone may be thermally throttling (gets hot under sustained CPU load and slows down). Don't cancel the install.

Android Network Fix

OpenClaw calls os.networkInterfaces() at startup. On Android/proot this call behaves oddly and can cause a crash or hang. A tiny script patches it before OpenClaw loads.

Ubuntu prootinside Ubuntu
# Create the patch script
cat <<'EOF' > /root/hijack.js
const os = require('os');
os.networkInterfaces = () => ({});
EOF

# Load it automatically on every session + fix tmp path
cat >> ~/.bashrc <<'EOF'
export NODE_OPTIONS="-r /root/hijack.js"
export TMPDIR=/tmp
EOF

source ~/.bashrc

If you see "Cannot find module '/root/hijacks.js'" β€” note the extra s. A stale NODE_OPTIONS from a previous failed attempt is pointing to the wrong file. Fix it: unset NODE_OPTIONS, then recreate hijack.js as shown above.

Onboarding Wizard

Run the setup wizard once. This configures your API key, port, and initial settings. You won't need to run it again after this.

Ubuntu prootinside Ubuntu
openclaw onboard

Wizard answers

PromptWhat to choose
Gateway Bind0.0.0.0 β€” needed for Meshnet and browser access
Gateway Port18789 (default) β€” or pick anything above 1024
Auth modeToken (default)
Model providerOpenRouter (free tier available at openrouter.ai)
API KeyYour OpenRouter key β€” starts with sk-or-v1-
Default modelopenrouter/arcee-ai/trinity-large-preview:free (or any free model)
Telegram channelSkip β€” configure manually after, wizard has a bug
Skills installYes β€” let it run, brew/go failures are expected and harmless

"Gateway service install not supported on android" at the very end is completely normal β€” not an error. Android has no systemd. You'll run the gateway manually in tmux instead.

"telegram plugin not available" during onboarding is a known bug. Telegram is a channel in OpenClaw, not a plugin β€” the wizard incorrectly tries to configure it under plugins. Skip it in the wizard and configure it manually in ~/.openclaw/openclaw.json after setup:

Manual Telegram config~/.openclaw/openclaw.json
{
  "channels": {
    "telegram": {
      "enabled": true,
      "botToken": "YOUR_BOT_TOKEN_FROM_BOTFATHER",
      "dmPolicy": "pairing"
    }
  }
}

Running the Gateway

The gateway is what keeps OpenClaw alive. Run it inside a tmux session so it stays running when you close the Termux window or the screen turns off.

Ubuntu prootinside Ubuntu
# Start a named tmux session
tmux new -s openclaw

# Inside tmux, start the gateway
openclaw gateway --verbose

# ─────────────────────────────────────────────────
# To DETACH (leave gateway running): Ctrl+B, then D
# To REATTACH later:
tmux attach -t openclaw

When the gateway is running you'll see log lines like [gateway] listening on ws://0.0.0.0:18789. That means it's working.

Killing and restarting

You cannot use openclaw gateway restart β€” systemd isn't available in proot and it fails. Kill by PID instead:

Ubuntu prootinside Ubuntu
# Find what's running on your port
lsof -i :18789

# Kill by PID from above output
kill <PID>

# Or kill by name
pkill -f "openclaw gateway"

Reconnecting after phone reboot

After any rebootphone
# In Termux
proot-distro login ubuntu

# In Ubuntu
tmux attach -t openclaw

# If session is gone, start fresh
tmux new -s openclaw
openclaw gateway --verbose

If you get "sessions should be nested with care" β€” you're already inside a tmux session. Run unset TMUX && tmux attach -t openclaw instead.

NordVPN Meshnet

NordVPN cannot run inside Ubuntu proot. It requires kernel-level networking and systemd β€” proot has neither. Attempting to install it inside Ubuntu gives "couldn't find nordvpnd.sock". Use the Android app instead. The Meshnet IP created by the Android app is automatically reachable from within Ubuntu proot.

  1. 01

    Install NordVPN from the Google Play Store on your phone.

  2. 02

    Sign in. Go to Products β†’ Meshnet and toggle it ON. This feature is free β€” you don't need a paid VPN subscription.

  3. 03

    Your phone gets a stable Meshnet IP in the 100.64.x.x range. Find it in the Meshnet screen.

  4. 04

    Add other devices by linking them to your Nord account, or using the invite system.

  5. 05

    Grant "Local network access" to each peer in the Meshnet devices list.

  6. 06

    Disable "Local network discovery" in NordVPN settings. This sounds counterintuitive but it's required for cross-device Meshnet connections to work reliably.

Set NordVPN's battery optimization to Unrestricted in Android settings, same as Termux. If Android kills NordVPN in the background, your Meshnet drops and the phone becomes unreachable from other devices.

Once Meshnet is active, your OpenClaw gateway is reachable at your Meshnet IP β€” but only as HTTP. To access the dashboard remotely you need HTTPS, which is the next step.

nginx HTTPS Proxy

Browsers block device identity APIs on plain HTTP connections. To access the OpenClaw dashboard from another device via Meshnet, you need HTTPS. nginx provides a self-signed HTTPS proxy in front of OpenClaw, bound specifically to the Meshnet interface.

Step 1 β€” Install nginx and generate a certificate

Ubuntu prootinside Ubuntu
# Install nginx and openssl
apt install -y nginx openssl

# Remove the default site (it tries to bind port 80 which proot blocks)
rm /etc/nginx/sites-enabled/default

# Create cert directory and generate self-signed certificate
mkdir -p /etc/nginx/certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/certs/openclaw.key \
  -out /etc/nginx/certs/openclaw.crt \
  -subj "/CN=openclaw"

Step 2 β€” Create the nginx config

Use nano to type this directly β€” do not try to paste it via scrcpy as long multiline pastes get truncated. Replace YOUR_MESHNET_IP with your actual Meshnet IP (e.g. 100.69.xxx.xxx).

Ubuntu prootinside Ubuntu
nano /etc/nginx/sites-available/openclaw
nginx config β€” type this in nano/etc/nginx/sites-available/openclaw
server {
    listen YOUR_MESHNET_IP:8443 ssl;
    ssl_certificate /etc/nginx/certs/openclaw.crt;
    ssl_certificate_key /etc/nginx/certs/openclaw.key;
    location / {
        proxy_pass http://127.0.0.1:18789;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection upgrade;
        proxy_set_header Host $host;
    }
}

Save with Ctrl+X, Y, Enter.

Step 3 β€” Enable and start nginx

Ubuntu prootinside Ubuntu
ln -s /etc/nginx/sites-available/openclaw /etc/nginx/sites-enabled/
nginx -t && nginx

# If nginx is already running from a previous attempt, reload instead:
nginx -s reload

By binding nginx to your specific Meshnet IP (not 0.0.0.0), only traffic coming through the Meshnet interface can reach it. Combined with NordVPN's device allowlist, only devices you've explicitly linked can access your gateway. Your OpenRouter API key and agent data stay private.

Dashboard Access

Step 1 β€” Allow token auth and set origins

Detach from tmux first (Ctrl+B, D), then run:

Ubuntu prootinside Ubuntu
# Allow token-based login over HTTPS
openclaw config set gateway.controlUi.allowInsecureAuth true

# Allow requests from your Meshnet HTTPS address
openclaw config set gateway.controlUi.allowedOrigins \
  '["https://YOUR_MESHNET_IP:8443"]'

# Get your auth token
openclaw config get gateway.auth.token

# Verify the setting saved
cat ~/.openclaw/openclaw.json | grep -i insecure

Step 2 β€” Restart the gateway to apply settings

Ubuntu prootinside Ubuntu
pkill -f "openclaw gateway"
tmux attach -t openclaw
openclaw gateway --verbose

# Detach again: Ctrl+B, D

Step 3 β€” Access the dashboard

Open a browser on any Meshnet-linked device and go to:

Browser URL β€” token injected directly
https://YOUR_MESHNET_IP:8443/#token=YOUR_TOKEN_HERE

Accept the self-signed certificate warning (tap Advanced β†’ Proceed). The dashboard loads and you're in.

Step 4 β€” Approve device pairing

The first time you connect from a new browser, OpenClaw requires pairing approval. Visit the dashboard URL, then immediately run:

Ubuntu prootinside Ubuntu
# List pending device requests
openclaw devices list

# Approve (use the full ID from the list β€” no spaces)
openclaw devices approve <requestId>

Pairing request IDs expire when the gateway restarts. If you get "unknown requestId", visit the dashboard URL again to generate a new request, then immediately run openclaw devices list and approve before restarting anything.

You can always access the dashboard locally on the phone itself without HTTPS at http://localhost:18789 β€” localhost bypasses all the browser security restrictions. The nginx HTTPS setup is only needed for access from other devices.

Troubleshooting

ErrorCauseFix
Cannot find module '/root/hijacks.js' Stale NODE_OPTIONS pointing to wrong filename (note the extra 's') unset NODE_OPTIONS then recreate hijack.js
koffi build failed / CMake not found Compiling in bare Termux (Bionic libc incompatibility) Must use Ubuntu proot β€” no workaround
E: Unable to locate package nvim Wrong package name Package is called neovim, not nvim
[FAIL] Not running in Termux ($PREFIX not set) Running the myopenclawhub bash installer (doesn't work) Use npm install method only β€” skip the bash installer
npm warn deprecated (many lines) Normal β€” just warnings, not errors Wait for install to complete β€” it's working fine
Gateway service not supported on android No systemd in proot Normal β€” expected, use tmux instead
Gateway already running / port in use Previous gateway still alive lsof -i :18789 β†’ kill <PID>
nginx bind() failed (13: Permission denied) Trying to bind port 80 β€” proot blocks ports below 1024 rm /etc/nginx/sites-enabled/default
nginx bind() failed (98: Address already in use) nginx already running from previous attempt nginx -s reload instead of starting a new instance
control ui requires device identity Accessing dashboard over HTTP from another device Use nginx HTTPS proxy β€” access via https:// not http://
origin not allowed allowedOrigins not set or doesn't include your HTTPS address openclaw config set gateway.controlUi.allowedOrigins '["https://IP:8443"]'
telegram plugin not available Known wizard bug β€” Telegram is a channel, not a plugin Skip in wizard, configure manually in openclaw.json
sessions should be nested with care Already inside a tmux session unset TMUX && tmux attach -t openclaw
NordVPN: couldn't find nordvpnd.sock Trying to run NordVPN inside Ubuntu proot Use the NordVPN Android app β€” not the terminal installer
Skills failing to install (brew, go) Homebrew and Go not available on Android Normal β€” core skills install fine, ignore brew/go failures
unknown requestId when approving pairing Request expired when gateway restarted Visit dashboard URL β†’ immediately run devices list β†’ approve quickly
scrcpy paste truncated / cuts off Command too long for scrcpy injection buffer Paste one line at a time, or type multi-line configs in nano directly

Quick Commands

Daily startup sequence

Every time you open Termux
# Enter Ubuntu
proot-distro login ubuntu

# Reattach to running gateway
tmux attach -t openclaw

# If gateway died, restart it
tmux new -s openclaw
openclaw gateway --verbose

# Detach and leave it running
# Ctrl+B, D

Config management

Ubuntu proot
# View full config
cat ~/.openclaw/openclaw.json

# Get a specific value
openclaw config get gateway.auth.token

# Set a value (detach from tmux first)
openclaw config set gateway.controlUi.allowInsecureAuth true

# Check what port the gateway is on
openclaw config get gateway.port

Killing gateway cleanly

Ubuntu proot
# Find running gateway
lsof -i :18789

# Kill by PID
kill <PID>

# Or kill by process name
pkill -f "openclaw gateway"

nginx management

Ubuntu proot
# Reload config (use this after editing nginx config)
nginx -s reload

# Test config before applying
nginx -t

# Start fresh (only if nginx isn't running)
nginx

Dashboard URL format

Browser β€” from any Meshnet device
# Via Meshnet HTTPS (from another device)
https://YOUR_MESHNET_IP:8443/#token=YOUR_TOKEN

# Locally on the same phone (no HTTPS needed)
http://localhost:18789/#token=YOUR_TOKEN

# Chat endpoint (alternative to full dashboard)
https://YOUR_MESHNET_IP:8443/chat?session=main

scrcpy launch commands (PC)

Windows CMDPC
# Single device
scrcpy.exe --prefer-text

# Specific device by serial
scrcpy.exe -s YOUR_DEVICE_SERIAL --prefer-text

# Find device serials
adb devices

# Once scrcpy window is open, to paste from PC clipboard:
# Press Alt + Shift + V