openclaw fix beginner 10 minutes

OpenClaw Nodes Are Not Agent Messaging

The agent reached for the native feature and got it wrong. But honestly, the mistake was understandable — when you tell an agent to 'send a message over Tailscale to another machine,' OpenClaw does have a built-in that connects machines. It just does something completely different.

 Tony (chief of staff agent) was asked to send a task to  Mel (engineering agent on a separate VPS) using a custom HTTP setup built over Tailscale. The setup was real, working, and documented in the agent registry.

 Tony’s response:

“No nodes showing up. The Tailscale node pairing might not be configured yet on my end.”

Wrong feature. The right one didn’t exist — because OpenClaw doesn’t have built-in agent-to-agent messaging.

What Nodes Actually Are

OpenClaw nodes are peripheral devices — macOS, iOS, Android, or headless Linux machines — that connect to a Gateway and extend what it can reach. Camera. Screen capture. Sensors. Remote shell execution via system.run.

The architecture is Gateway-centric: the model talks to the Gateway, the Gateway routes tool calls to the connected node. Nodes are “peripherals, not gateways” — they don’t run their own gateway service. They extend the one that’s already running.

So yes, a node can run a shell command on a remote machine. But that’s not the same as two agents exchanging structured messages. There’s no TASK payload, no STATUS response, no queue. A node gives your agent a longer arm — it doesn’t give it a correspondent.

Why the Agent Got Confused

The confusion is understandable. Ask an agent to “send a message to another machine over Tailscale” and it reaches for the native feature that connects machines. Nodes are that feature. The mapping is wrong but the logic is sound.

This is the general failure mode: the agent pattern-matches on concept rather than reading the specific mechanism you built. “Another machine” → nodes. Never mind that nodes solve a different problem.

The Fix

Two changes. Both in workspace files read at startup.

1. Add an explicit correction to AGENTS.md:

| 2026-03-04 | Sending tasks to @Mel does NOT use OpenClaw nodes/node pairing.
Nodes are for device peripherals (camera, shell, screen) — not agent messaging.
Use a plain curl POST: `source ~/.env && curl -s -X POST "$MEL_URL/message"
-H "X-Shared-Secret: $SHARED_SECRET" -H "Content-Type: application/json"
-d '{"type":"TASK","payload":{...}}'`. Credentials in .env. No pairing needed. |

Three elements that matter:

  • “does NOT use nodes” — rules out the native path
  • A one-line explanation of what nodes actually are — closes the conceptual gap so the agent doesn’t re-derive the wrong answer
  • The exact curl command — nothing left to interpret

2. Name the section in your registry explicitly:

### @Tony → @Mel: Exact Command   ← not "Sending a Message"

“Exact Command” signals there’s something specific to run here, not something to reason about.

Building Agent-to-Agent Messaging

Since OpenClaw doesn’t provide this natively, here’s the pattern that works:

Receiving agent ( Mel’s machine) runs a FastAPI server bound to a private network interface:

@app.post("/message")
async def receive_message(payload: dict, x_shared_secret: str = Header(None)):
    if x_shared_secret != SHARED_SECRET:
        raise HTTPException(status_code=401)
    await handle(payload)
    return {"status": "received"}

Bind to your Tailscale IP, not 0.0.0.0. Port only reachable from the tailnet.

Sending agent ( Tony’s machine) posts via shell:

source ~/.env
curl -s -X POST "$MEL_URL/message" \
  -H "X-Shared-Secret: $SHARED_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"type": "TASK", "payload": {"objective": "..."}}'

Both agents have shell access. That’s the whole transport layer.

For the return direction —  Mel sending status back to  Tony — configure OpenClaw’s remote gateway:

openclaw config set gateway.remote.url wss://tony-tailscale-hostname
openclaw config set gateway.remote.token your-gateway-token

Then from  Mel’s machine:

openclaw agent --agent main -m '{"type":"STATUS","from":"mel","payload":{...}}'

Key Takeaway

OpenClaw nodes are for extending your gateway’s reach to hardware — camera, screen, remote shell. They’re not an agent messaging bus. If you need two autonomous agents on separate machines to exchange structured messages, you build that: FastAPI on the receiver, curl on the sender, shared secret for auth.

The agent will reach for nodes when you describe the problem in terms of “other machine.” The fix is workspace instructions specific enough to name the mechanism, explain why nodes don’t apply, and include the exact command — so the agent intercepts the wrong path before it starts walking it.

FAQ

What are OpenClaw nodes for?

Nodes are peripheral devices — macOS, iOS, Android, or headless Linux machines — that connect to a Gateway and expose hardware surfaces like camera, screen capture, sensors, and remote shell execution. They extend what the gateway can reach, but they're not a messaging layer between agents.

How do I send a structured task from one OpenClaw agent to another on a different machine?

OpenClaw doesn't have a built-in agent-to-agent messaging system. The pattern is: run a FastAPI server on the receiving machine bound to a private network interface (Tailscale works well), and POST to it from the sending agent via curl. The sending agent has shell access — that's all it needs.

Why did my agent try to use node pairing when I asked it to message another agent?

Nodes are the only OpenClaw native feature for connecting to another machine, so the agent mapped 'send to another machine' to that concept. The fix is an explicit correction in AGENTS.md that names the actual mechanism — exact curl command, explicit 'not nodes' — so the agent intercepts the wrong path at startup.

Can I use OpenClaw nodes to run shell commands on a remote machine?

Yes — that's one of their intended uses. A node host running on a remote machine exposes system.run calls through the gateway. But this is for running commands on demand, not for passing structured messages between two autonomous agents.