2026-01-01 15:37:45 +00:00
---
summary: "Signal support via signal-cli (JSON-RPC + SSE), setup, and number model"
read_when:
- Setting up Signal support
- Debugging Signal send/receive
---
2026-01-01 15:43:15 +01:00
# Signal (signal-cli)
2026-01-07 00:25:16 +01:00
Status: external CLI integration. Gateway talks to `signal-cli` over HTTP JSON-RPC + SSE.
2026-01-01 15:43:15 +01:00
2026-01-11 02:40:28 +01:00
## Quick setup (beginner)
1) Use a **separate Signal number** for the bot (recommended).
2) Install `signal-cli` (Java required).
3) Link the bot device and start the daemon:
- `signal-cli link -n "Clawdbot"`
4) Configure Clawdbot and start the gateway.
Minimal config:
```json5
{
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"]
}
}
```
2026-01-07 00:25:16 +01:00
## What it is
- Signal provider via `signal-cli` (not embedded libsignal).
- Deterministic routing: replies always go back to Signal.
2026-01-11 02:52:50 +00:00
- DMs share the agent's main session; groups are isolated (`agent:<agentId>:signal:group:<groupId>` ).
2026-01-01 15:37:45 +00:00
2026-01-07 00:25:16 +01:00
## The number model (important)
- The gateway connects to a **Signal device** (the `signal-cli` account).
- If you run the bot on **your personal Signal account** , it will ignore your own messages (loop protection).
- For "I text the bot and it replies," use a **separate bot number** .
2026-01-01 15:37:45 +00:00
2026-01-07 00:25:16 +01:00
## Setup (fast path)
1) Install `signal-cli` (Java required).
2) Link a bot account:
- `signal-cli link -n "Clawdbot"` then scan the QR in Signal.
3) Configure Signal and start the gateway.
2026-01-01 15:43:15 +01:00
2026-01-07 00:25:16 +01:00
Example:
2026-01-01 15:37:45 +00:00
```json5
{
signal: {
enabled: true,
2026-01-07 00:25:16 +01:00
account: "+15551234567",
2026-01-01 15:37:45 +00:00
cliPath: "signal-cli",
2026-01-07 00:25:16 +01:00
dmPolicy: "pairing",
allowFrom: ["+15557654321"]
2026-01-01 15:37:45 +00:00
}
}
```
2026-01-01 15:43:15 +01:00
2026-01-08 01:18:37 +01:00
Multi-account support: use `signal.accounts` with per-account config and optional `name` . See [`gateway/configuration` ](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts ) for the shared pattern.
2026-01-07 00:25:16 +01:00
## Access control (DMs + groups)
DMs:
- Default: `signal.dmPolicy = "pairing"` .
2026-01-07 05:06:04 +01:00
- Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour).
2026-01-07 00:25:16 +01:00
- Approve via:
2026-01-10 16:36:43 +01:00
- `clawdbot pairing list signal`
- `clawdbot pairing approve signal <CODE>`
2026-01-07 02:04:02 +01:00
- Pairing is the default token exchange for Signal DMs. Details: [Pairing ](/start/pairing )
2026-01-08 23:06:38 +00:00
- UUID-only senders (from `sourceUuid` ) are stored as `uuid:<id>` in `signal.allowFrom` .
2026-01-07 00:25:16 +01:00
Groups:
- `signal.groupPolicy = open | allowlist | disabled` .
- `signal.groupAllowFrom` controls who can trigger in groups when `allowlist` is set.
## How it works (behavior)
- `signal-cli` runs as a daemon; the gateway reads events via SSE.
- Inbound messages are normalized into the shared provider envelope.
- Replies always route back to the same number or group.
## Media + limits
2026-01-08 04:02:04 +01:00
- Outbound text is chunked to `signal.textChunkLimit` (default 4000).
2026-01-07 00:25:16 +01:00
- Attachments supported (base64 fetched from `signal-cli` ).
2026-01-08 04:02:04 +01:00
- Default media cap: `signal.mediaMaxMb` (default 8).
2026-01-07 00:25:16 +01:00
- Use `signal.ignoreAttachments` to skip downloading media.
2026-01-10 18:53:38 +01:00
- Group history context uses `signal.historyLimit` (or `signal.accounts.*.historyLimit` ), falling back to `messages.groupChat.historyLimit` . Set `0` to disable (default 50).
2026-01-07 00:25:16 +01:00
## Delivery targets (CLI/cron)
- DMs: `signal:+15551234567` (or plain E.164).
- Groups: `signal:group:<groupId>` .
- Usernames: `username:<name>` (if supported by your Signal account).
## Configuration reference (Signal)
2026-01-07 02:04:02 +01:00
Full configuration: [Configuration ](/gateway/configuration )
2026-01-07 00:25:16 +01:00
Provider options:
- `signal.enabled` : enable/disable provider startup.
- `signal.account` : E.164 for the bot account.
- `signal.cliPath` : path to `signal-cli` .
- `signal.httpUrl` : full daemon URL (overrides host/port).
- `signal.httpHost` , `signal.httpPort` : daemon bind (default 127.0.0.1:8080).
- `signal.autoStart` : auto-spawn daemon (default true if `httpUrl` unset).
- `signal.receiveMode` : `on-start | manual` .
- `signal.ignoreAttachments` : skip attachment downloads.
- `signal.ignoreStories` : ignore stories from the daemon.
- `signal.sendReadReceipts` : forward read receipts.
- `signal.dmPolicy` : `pairing | allowlist | open | disabled` (default: pairing).
2026-01-08 23:06:38 +00:00
- `signal.allowFrom` : DM allowlist (E.164 or `uuid:<id>` ). `open` requires `"*"` .
2026-01-07 00:25:16 +01:00
- `signal.groupPolicy` : `open | allowlist | disabled` (default: open).
- `signal.groupAllowFrom` : group sender allowlist.
2026-01-10 18:53:38 +01:00
- `signal.historyLimit` : max group messages to include as context (0 disables).
2026-01-07 00:25:16 +01:00
- `signal.textChunkLimit` : outbound chunk size (chars).
- `signal.mediaMaxMb` : inbound/outbound media cap (MB).
Related global options:
2026-01-09 12:44:23 +00:00
- `agents.list[].groupChat.mentionPatterns` (Signal does not support native mentions).
- `messages.groupChat.mentionPatterns` (global fallback).
2026-01-07 00:25:16 +01:00
- `messages.responsePrefix` .