TL;DR
If security matters (it does), this is the best setup:
-
Run OpenClaw on your server (
bind: loopback)
-
Use Tailscale to create a private network between your devices
-
Expose OpenClaw safely over Tailscale Serve (tailnet-only HTTPS)
-
Connect Clawken using your
wss://<server>.ts.net URL + auth token
No public open port to the internet. No random bots scanning your VPS.
What is Tailscale (in normal human terms)?
Tailscale is basically a private, encrypted network for your devices.
Think of it like this:
- Your Mac and your server join the same private club (your tailnet)
- Devices can talk securely as if they're on the same local network
- Everything is encrypted
- You can avoid exposing your service to the whole internet
So instead of:
"Hey world, here's my server IP and open port, please be nice."
You do:
"Only devices in my private Tailscale network can reach this."
Way better.
Why Clawken uses Tailscale
Because we want:
- Secure remote control
- Easy setup for normal users
- No constant SSH tunnels
- No public attack surface
OpenClaw stays local on the server (127.0.0.1), and Tailscale handles safe remote access.
This gives you the convenience of a desktop app with security that doesn't make your infra cry.
Architecture (what's actually happening)
Clawken Desktop (Mac)
|
| encrypted
v
Tailscale Serve URL (https/wss on .ts.net)
|
v
OpenClaw Gateway on server (loopback :18789)
Important point: OpenClaw is not directly exposed on the public internet.
Prerequisites
You need Tailscale installed and logged in on both:
- Your OpenClaw server (VPS, Hetzner, etc.)
- Your Mac running Clawken
Use the same Tailscale account on both.
Step-by-step setup
1
Install Tailscale on the server & login
Follow the Tailscale install docs for your Linux distro, then run:
tailscale up
tailscale status
You should see your server online in the output.
2
Install Tailscale on your Mac & login
Install the Tailscale app, sign in with the same account, then verify:
tailscale status
You should see both Mac and server in the same tailnet.
3
Make sure OpenClaw is running on the server
openclaw status
Confirm the gateway is running (typically on 127.0.0.1:18789).
4
Configure OpenClaw for secure mode
In ~/.openclaw/openclaw.json, make sure gateway looks like this:
{
"gateway": {
"mode": "local",
"bind": "loopback",
"port": 18789,
"auth": {
"mode": "token",
"token": "<your-long-random-token>"
},
"http": {
"endpoints": {
"chatCompletions": { "enabled": true }
}
},
"tailscale": {
"mode": "serve"
}
}
}
Important: The chatCompletions endpoint must be enabled. Clawken's broker uses POST /v1/chat/completions to communicate with your instance. Without it, you'll get a 405 Method Not Allowed error.
Then restart the gateway:
openclaw gateway restart
5
Enable Tailscale Serve on the server
If serve is not enabled for your tailnet yet, Tailscale will give you a one-time approval link. Open it and approve. Then run:
tailscale serve --bg http://127.0.0.1:18789
tailscale serve status
You should see something like:
https://your-server-name.tailXXXX.ts.net/
proxy to http://127.0.0.1:18789
That .ts.net URL is what Clawken uses.
6
Verify connectivity before app setup
From your Mac:
tailscale ping <your-server>.tailXXXX.ts.net
curl -i https://<your-server>.tailXXXX.ts.net/
Expected:
-
Ping succeeds
-
curl returns
200 (or at least reaches the service)
If this fails, app connection will fail too. Fix this first.
7
Get your OpenClaw token
On the server, if you don't already know it:
node -e "const fs=require('fs');\
const j=JSON.parse(\
fs.readFileSync(\
process.env.HOME+'/.openclaw/openclaw.json','utf8'\
)\
);\
console.log(j.gateway?.auth?.token||'NO_TOKEN');"
Copy this token carefully.
8
Connect in Clawken Desktop
In the app, enter:
Instance Name
anything friendly (Hetzner, Home Server, etc.)
Gateway URL
wss://<your-server>.tailXXXX.ts.net
Token
gateway token from step 7
Click Test Connection then Save & Continue.
Boom. You're connected.
Why this is the best security-first approach
Better than opening public ports directly
If you expose 95.x.x.x:18789 to the internet, you're depending on firewall rules + auth + luck + no mistakes.
With Tailscale:
- Access is tailnet-only by default
- Traffic is encrypted
- Identity/access is tied to your Tailscale account/devices
- OpenClaw can remain loopback-only
Less blast radius. Less regret.
Common problems (and fixes)
"Connection failed: error sending request..."
Usually means the network path failed before auth. Check:
-
Is Tailscale running on Mac? (
tailscale status)
-
Is Mac online in tailnet?
-
Is server online in tailnet?
-
Is Tailscale Serve active on server? (
tailscale serve status)
-
Can Mac
curl https://<ts-url>/?
Mac sees server, app still fails
-
Recheck URL uses
wss://...ts.net
-
Recheck token copied exactly
-
Restart OpenClaw gateway:
openclaw gateway restart
-
Re-run serve:
tailscale serve --bg http://127.0.0.1:18789
Tailscale says "Serve is not enabled on your tailnet"
-
Open the approval link Tailscale prints
-
Approve serve for that node
-
Re-run
tailscale serve --bg ...
405 Method Not Allowed
This means your OpenClaw gateway's chat completions HTTP endpoint is disabled. Clawken's broker depends on POST /v1/chat/completions to work.
Fix (server-side)
Enable it in your OpenClaw config:
{
"gateway": {
"http": {
"endpoints": {
"chatCompletions": { "enabled": true }
}
}
}
}
Then restart:
openclaw gateway restart
Fast way via CLI
If your OpenClaw build supports config set:
openclaw config set gateway.http.endpoints.chatCompletions.enabled true
openclaw gateway restart
openclaw status --deep
If the config set command isn't available on your build, edit ~/.openclaw/openclaw.json manually and restart.
Why this happens: Clawken connects to your OpenClaw instance via the built-in HTTP chat route (POST /v1/chat/completions) for maximum portability — no custom plugins or tools required on the user instance. But that endpoint needs to be explicitly enabled in your gateway config.
Server
tailscale up
openclaw status
openclaw gateway restart
tailscale serve --bg \
http://127.0.0.1:18789
tailscale serve status
Mac
tailscale status
tailscale ping \
<your-server>.tailXXXX.ts.net
curl -i \
https://<server>.tailXXXX.ts.net/
Token (server)
node -e "const fs=require('fs');\
const j=JSON.parse(\
fs.readFileSync(\
process.env.HOME+\
'/.openclaw/openclaw.json',\
'utf8'));\
console.log(\
j.gateway?.auth?.token\
||'NO_TOKEN');"
In Clawken
URL
wss://<server>.tailXXXX.ts.net
Token
<gateway-auth-token>
Final words
You're not doing this to be fancy. You're doing this so your AI control plane is actually usable and not wide open to the internet.
Tailscale gives you remote access without turning your server into a public piñata.
That's the move.