OpenClaw Nodes: Connecting Your AI Agent to Physical Devices
Your AI agent lives on a gateway. The gateway talks to Slack, Discord, or Telegram. But what if you want the agent to see through a camera, grab your phone's location, snap a screenshot, or run a shell command on a remote server? That's what nodes are for.
A node is a companion device — iOS, Android, macOS, or any headless Linux machine — that connects to the OpenClaw Gateway over WebSocket and exposes a command surface. Once paired, your agent can invoke those commands as naturally as any other tool call. No polling loops, no bespoke APIs. Just pairing and using.
This guide covers everything: what nodes actually are, how pairing works, what commands are available on each platform, and how to set up a remote headless node host for distributed exec. It's one of the most powerful and underused parts of OpenClaw.
What Is a Node?
In OpenClaw's architecture, the gateway is the always-on brain — it receives messages, runs the model, routes tool calls. A node is a peripheral device that connects to that gateway via WebSocket with role: node.
Nodes are not gateways. They don't process messages or run models. They just expose a command surface. When the agent calls a node command, the gateway forwards the request to the paired device, the device executes it, and the result comes back. Clean, simple, powerful.
Here's what that means in practice:
- Your agent can snap a photo from your phone's front or back camera.
- It can get your real-time GPS location.
- It can read your Android notifications and act on them.
- It can run shell commands on a remote Linux server.
- It can push content to a WebView canvas on any paired device.
- It can record a short screen clip for debugging.
The macOS menubar app also connects as a node automatically — so if you're running OpenClaw on a Mac, you already have a node available without doing anything extra.
How Pairing Works
Nodes use device pairing — an explicit owner-approval step before any device can connect. This is OpenClaw's security gate. No unrecognized device can join your gateway network without your approval.
Here's the typical flow:
Pair via Telegram (recommended for iOS/Android)
If you have the device-pair plugin configured, the simplest path is from Telegram:
- Message your Telegram bot:
/pair - The bot replies with a setup code (base64 JSON containing the gateway WebSocket URL and a single-use bootstrap token).
- Open the OpenClaw iOS or Android app → Settings → Gateway.
- Paste the setup code and connect.
- Back in Telegram:
/pair approve
Treat that setup code like a password — it's a live bootstrap token until it's used or expires.
Pair via CLI
For headless nodes or manual approval flows:
# On the gateway host — check pending device requests
openclaw devices list
# Approve a specific request
openclaw devices approve <requestId>
# Check which nodes are online
openclaw nodes status
# Get details about a specific node
openclaw nodes describe --node <idOrNameOrIp> Once a node is approved and connected, you can verify it's online with openclaw nodes status. You'll see the node name, platform, and available command families.
Camera: Snap Photos and Record Video
iOS and Android nodes expose a full camera API. Your agent can capture a photo from either camera on demand:
# List available cameras on the node
openclaw nodes camera list --node <idOrName>
# Snap from both front and back cameras
openclaw nodes camera snap --node <idOrName>
# Snap from front camera only
openclaw nodes camera snap --node <idOrName> --facing front
# Record a 10-second video clip
openclaw nodes camera clip --node <idOrName> --duration 10s
# Record without audio
openclaw nodes camera clip --node <idOrName> --duration 3000 --no-audio A few practical notes:
- The node must be foregrounded (app in the foreground). Background calls return
NODE_BACKGROUND_UNAVAILABLE. - Video clips are capped at 60 seconds to avoid oversized payloads.
- Android will prompt for camera and microphone permissions if not already granted.
This is genuinely useful. I use a camera snap to verify a physical setup — point the phone at a server rack, ask the agent "what does that screen say?", and get an answer. The agent calls camera snap, gets the image, runs vision analysis, and responds. No human in the loop.
Location: Real-Time GPS
When Location is enabled in the OpenClaw app settings, nodes expose a location.get command:
# Basic location query
openclaw nodes location get --node <idOrName>
# High-accuracy with custom timeout
openclaw nodes location get --node <idOrName> \
--accuracy precise \
--max-age 15000 \
--location-timeout 10000 The response includes latitude, longitude, accuracy in meters, and a timestamp. Location is off by default and requires explicit permission — "Always" mode requires system-level permission on both iOS and Android.
Use cases: agents that know where you are, geofence-triggered automations, travel tracking without installing anything custom.
Android: Notifications, Contacts, Calendar
Android nodes can expose a rich set of personal data commands when the relevant capabilities are enabled in the app. Available command families:
- device.status / device.info / device.health — battery, connectivity, device metadata
- notifications.list / notifications.actions — read and act on notifications
- photos.latest — retrieve recent photos from the gallery
- contacts.search / contacts.add — query and update contacts
- calendar.events / calendar.add — read and create calendar events
- motion.activity / motion.pedometer — step counts, activity type
- sms.send — send SMS (requires telephony + permission)
These are invoked at low level via:
openclaw nodes invoke --node <idOrName> \
--command notifications.list \
--params '{}'
openclaw nodes invoke --node <idOrName> \
--command device.status \
--params '{}'
openclaw nodes invoke --node <idOrName> \
--command photos.latest \
--params '{"limit": 3}' From the agent side (via the nodes tool), these are surfaced as first-class calls — no raw RPC needed. The agent just uses the tool with the right action and node name.
Canvas: Push Content to Any Device
Every connected node can display a Canvas — a WebView that the agent controls. You can present URLs, local files, or A2UI layouts:
# Show a URL on the node's canvas
openclaw nodes canvas present --node <idOrName> --target https://example.com
# Take a screenshot of what's currently shown
openclaw nodes canvas snapshot --node <idOrName> --format png
# Run JavaScript inside the WebView
openclaw nodes canvas eval --node <idOrName> --js "document.title"
# Navigate to a new URL
openclaw nodes canvas navigate https://newpage.com --node <idOrName>
# Hide the canvas
openclaw nodes canvas hide --node <idOrName> Screen recordings also work on nodes that support it:
openclaw nodes screen record --node <idOrName> --duration 10s --fps 10 This opens interesting use cases: push a dashboard to a wall-mounted iPad, let the agent drive a browser on a remote device, or capture what's on someone's screen during a debugging session.
Remote Command Execution: The Node Host
This is where nodes get truly powerful for developer workflows. OpenClaw supports a headless node host — a lightweight process you run on any machine (Linux server, CI box, another Mac) that exposes system.run to the agent.
Once configured, your agent can run shell commands on that remote machine:
# On the remote machine — start the node host
openclaw node run \
--host <gateway-host> \
--port 18789 \
--display-name "Build Server" If your gateway binds to loopback (the default in local mode), you'll need an SSH tunnel:
# Terminal A — keep this running
ssh -N -L 18790:127.0.0.1:18789 user@gateway-host
# Terminal B — start the node host through the tunnel
export OPENCLAW_GATEWAY_TOKEN="<your-gateway-token>"
openclaw node run --host 127.0.0.1 --port 18790 --display-name "Build Server" To run as a persistent background service:
openclaw node install \
--host <gateway-host> \
--port 18789 \
--display-name "Build Server"
openclaw node restart Approvals and the Allowlist
Remote exec isn't wide open — it's gated by an approval system. Commands must be approved before they can run. On the gateway host, add trusted commands to the node's allowlist:
openclaw approvals allowlist add --node "Build Server" "/usr/bin/uname"
openclaw approvals allowlist add --node "Build Server" "/usr/bin/git"
openclaw approvals allowlist add --node "Build Server" "/usr/local/bin/npm" Approvals live on the node host at ~/.openclaw/exec-approvals.json. This is intentional — the node host controls what runs on it, not the gateway. Defense in depth.
Point Agent Exec at the Node
Configure the agent to route exec calls to the node by default:
openclaw config set tools.exec.host node
openclaw config set tools.exec.security allowlist
openclaw config set tools.exec.node "Build Server" Or override per-session:
/exec host=node security=allowlist node=Build Server Once set, every exec call from the agent runs on the remote machine. The agent doesn't need to know it's remote — it just gets results back. This is how I run build commands, check server logs, and tail processes from a chat interface without SSH-ing in manually.
Naming and Managing Nodes
Nodes can be named at connection time with --display-name, or renamed later:
# Rename a paired node
openclaw nodes rename --node <id|name|ip> --name "Home iPad" The --display-name flag persists in ~/.openclaw/node.json on the node machine. The gateway rename override takes precedence and is stored gateway-side.
When you have multiple nodes, targeting is by name, ID, or IP in any tool call:
openclaw nodes camera snap --node "Home iPad"
openclaw nodes location get --node "iPhone 15"
openclaw nodes screen record --node "Build Server" --duration 5s macOS Node: You Probably Already Have One
If you run OpenClaw on a Mac with the menubar app, your Mac is already a node. The app connects to the gateway WS server with role: node automatically, exposing canvas controls, screen recording, and system.run (gated by exec approvals in Settings).
Check it:
openclaw nodes status You should see your Mac listed. From there, openclaw nodes run --node <mac-name> routes shell commands through the menubar app, subject to whatever exec approval policy you've configured.
Permissions Map
Nodes report their permission state in node.list and node.describe — a map of permission names (e.g., screenRecording, accessibility, camera, location) to boolean values. This lets the agent know what's available before attempting a command, and lets you audit what's granted without opening the device settings.
Real Workflow: Agent as Physical Operator
Here's a concrete example of how this fits together. I have a home office setup where:
- OpenClaw runs on a Mac mini (gateway + mac node).
- An iPhone is paired as a mobile node.
- A Raspberry Pi runs a headless node host connected via SSH tunnel.
The agent can:
- Snap a photo from the iPhone to check if a package arrived.
- Get the iPhone's location to know if I'm home or out.
- Run
systemctl statuson the Pi to check a service. - Push a status dashboard to the mac node canvas.
All from a single Slack message. The agent orchestrates across all three devices, collects results, synthesizes them, and replies. No app switching, no SSH, no manual checking.
That's the actual value proposition: your agent stops being limited to what it can do in text. It becomes a physical operator with eyes, location awareness, and the ability to act on remote machines.
Security Notes
A few things worth knowing before you pair everything in sight:
- Every node requires explicit approval. The gateway rejects unrecognized device connections. No drive-by pairing.
- Setup codes are one-time-use tokens. Treat them like passwords while they're valid.
- Remote exec is allowlist-gated by default. Commands not on the allowlist require per-call approval.
- Dangerous env vars are stripped. Node hosts strip
DYLD_*,LD_*,NODE_OPTIONS, and similar shell-override vars from exec calls. You can't bypass the approval system by injecting env vars. - Clip duration is capped at 60 seconds. This prevents runaway payloads from overwhelming the gateway.
For a deep dive on the security model, see the OpenClaw security post. The short version: the design assumes nodes are untrusted until approved, and exec permissions are layered so neither the gateway nor the model can unilaterally run arbitrary code on a remote machine.
Getting Started
If you haven't set up any nodes yet, here's the minimal path:
- Install the OpenClaw app on your phone (iOS or Android).
- From Telegram (or your configured channel), send
/pairto your bot. - Paste the setup code into the app and connect.
- Approve from CLI:
openclaw devices list→openclaw devices approve <id> - Verify:
openclaw nodes status
That's it. Your agent can now reach your phone. Add camera snaps, location queries, or Android notification reading from there — each capability is enabled in the app settings per-permission.
For a headless node host on a server, follow the SSH tunnel approach above. Takes about 10 minutes to set up and opens up a whole class of remote operations your agent couldn't do before.
The Raspberry Pi setup guide covers the full headless node host installation flow if you want a dedicated always-on physical node on cheap hardware.
Want the complete guide to running OpenClaw with full multi-device node support? Get The OpenClaw Playbook — $9.99 for the full config templates, node setup scripts, and step-by-step walkthroughs.