On this page
🛡️ Why Signal?
| Advantage | Details |
|---|---|
| True E2E encryption | Signal Protocol — the gold standard. Even Signal's servers can't read your messages. |
| Minimal metadata | Signal collects almost nothing: no contact lists, no message timestamps, no group metadata. |
| Open-source protocol | Every component is auditable. No trust-me-bro security. |
| No phone number sharing | With usernames enabled, contacts don't need your phone number to message you. |
🔄 How it works
OpenClaw doesn't embed Signal directly. Instead, it connects to signal-cli, a separate Java application that implements the Signal Protocol:
┌──────────────┐ HTTP JSON-RPC ┌─────────────┐ Signal Protocol ┌─────────┐
│ OpenClaw │◄──────────────►│ signal-cli │◄────────────────►│ Signal │
│ Gateway │ + SSE events │ (Java) │ │ Servers │
└──────────────┘ └─────────────┘ └─────────┘
- OpenClaw sends commands via JSON-RPC
- Incoming messages arrive via Server-Sent Events (SSE)
- signal-cli handles all encryption/decryption locally
- Your OpenClaw instance operates as a linked device on your Signal account
📋 Prerequisites
- Java 17+ — signal-cli requires the JVM
- signal-cli — the Signal Protocol CLI tool
- A Signal account — either your personal number or a dedicated bot number
- A phone with Signal — needed to link the device
# Check Java version
java -version
# Should show 17 or higher
# Install Java if needed
# macOS:
brew install openjdk@17
# Ubuntu/Debian:
sudo apt install openjdk-17-jre
📦 Install signal-cli
# Download latest release
# https://github.com/AsamK/signal-cli/releases
# Extract to a directory in your PATH
# macOS (Homebrew):
brew install signal-cli
# Linux (manual):
wget https://github.com/AsamK/signal-cli/releases/download/v0.13.x/signal-cli-0.13.x.tar.gz
tar xf signal-cli-0.13.x.tar.gz
sudo mv signal-cli-0.13.x /opt/signal-cli
sudo ln -s /opt/signal-cli/bin/signal-cli /usr/local/bin/signal-cli
# Verify:
signal-cli --version
🔗 Link to your Signal account
# Generate a link QR code
signal-cli link --name "OpenClaw"
# A QR code appears in the terminal
# On your phone:
# Signal → Settings → Linked Devices → Link New Device
# Scan the QR code
After linking, signal-cli stores credentials locally. The link persists until you unlink the device from Signal settings.
⚙️ Configure OpenClaw
// ~/.openclaw/openclaw.json
{
"channels": {
"signal": {
"enabled": true,
"dmPolicy": "pairing",
"allowFrom": ["uuid:123e4567-e89b-12d3-a456-426614174000"]
}
}
}
Signal uses UUIDs for sender identification (not phone numbers like WhatsApp). After pairing, check the logs for uuid:<id> format.
DM policies (same as all channels)
| Policy | Behavior |
|---|---|
pairing | Default — unknown senders get a code to approve (expires 1 hour) |
allowlist | Only UUIDs in allowFrom can message |
open | ⚠️ Anyone can message |
🔄 Run signal-cli as daemon
JVM cold starts are slow (~5-10 seconds). Run signal-cli as a persistent daemon to eliminate startup latency:
# Start signal-cli daemon
signal-cli daemon --http --receive-mode=on-connection
# Point OpenClaw at it
{
"channels": {
"signal": {
"httpUrl": "http://127.0.0.1:8080"
}
}
}
This keeps the JVM warm and ready. OpenClaw connects to the HTTP endpoint instead of auto-spawning signal-cli.
channels.signal.startupTimeoutMs to a higher value if auto-spawning is too slow on your hardware.✨ Supported features
| Feature | Status | Notes |
|---|---|---|
| Text messages | ✅ Full | Chunked at 4000 chars by default |
| Attachments | ✅ Full | Images, files, audio (8MB default cap) |
| Typing indicators | ✅ Full | Refreshed while agent is replying |
| Read receipts | ✅ Configurable | Enable with sendReadReceipts: true |
| Reactions | ✅ Full | Send/remove reactions with emoji |
| Group chats | ✅ Full | Isolated sessions per group |
| Slash commands | ✅ Full | /status, /model, /reset |
| Voice notes | ⚠️ Receive | Transcribed via STT, but sending voice not supported |
| Disappearing messages | ⚠️ Respected | Signal's disappearing timer applies |
👥 Group chats
Signal groups get isolated sessions (agent:<agentId>:signal:group:<groupId>):
{
"channels": {
"signal": {
"groupPolicy": "allowlist",
"groups": {
"*": {
"requireMention": true
}
}
}
}
}
Group reactions require targetAuthor or targetAuthorUuid in addition to the message ID.
🔧 Troubleshooting
| Problem | Fix |
|---|---|
| signal-cli not found | Ensure it's in your PATH. Check which signal-cli and Java version. |
| Slow initial response | JVM cold start. Run signal-cli as a daemon (see above) to keep it warm. |
| “device not linked” | Re-link: signal-cli link --name "OpenClaw" and scan QR from phone. |
| Messages from self are ignored | This is loop protection — if the bot uses your personal number, it won't respond to your own messages. Use a dedicated bot number. |
| UUID not recognized | Signal uses UUIDs, not phone numbers. Check openclaw logs --follow for the uuid:<id> format. |
| Large messages truncated | Signal has a ~4000 char limit. Set chunkMode: "newline" for paragraph-aware splitting. |