Add Carapace to Signal
Outcome
Connect Carapace to Signal so inbound direct messages trigger agent responses, with typing indicators and explicit read receipts.
Prerequisites
carainstalled.ANTHROPIC_API_KEYor another provider API key.- A running
signal-cli-rest-apicontainer with a registered phone number. - Docker installed (to run
signal-cli-rest-api).
1) Start signal-cli-rest-api
docker run -d -p 8080:8080 \
-v $HOME/.local/share/signal-api:/home/.local/share/signal-cli \
-e MODE=native \
bbernhard/signal-cli-rest-apiRegister or link your phone number via the signal-cli-rest-api documentation.
2) Create config
Generate a gateway token:
export CARAPACE_GATEWAY_TOKEN="$(openssl rand -hex 32)"Windows (PowerShell) alternative:
$bytes = [byte[]]::new(32)
[System.Security.Cryptography.RandomNumberGenerator]::Fill($bytes)
$env:CARAPACE_GATEWAY_TOKEN = [System.BitConverter]::ToString($bytes).Replace('-', '').ToLower(){
"gateway": {
"bind": "loopback",
"port": 18789,
"auth": {
"mode": "token",
"token": "${CARAPACE_GATEWAY_TOKEN}"
}
},
"agents": {
"defaults": {
"model": "anthropic:claude-sonnet-4-6"
}
},
"anthropic": {
"apiKey": "${ANTHROPIC_API_KEY}"
},
"signal": {
"baseUrl": "http://localhost:8080",
"phoneNumber": "+15551234567" // your registered Signal number
},
"channels": {
"signal": {
"features": {
"typing": {
"enabled": true
},
"readReceipts": {
"enabled": true
}
}
}
}
}
Replace +15551234567 with your actual registered Signal
phone number.
For non-loopback Signal API deployments, use https:// —
Carapace rejects non-HTTPS non-loopback Signal URLs.
3) Run commands
CARAPACE_CONFIG_PATH=./carapace.json5 caraOptional status check:
cara status --port 18789
curl -H "Authorization: Bearer ${CARAPACE_GATEWAY_TOKEN}" http://127.0.0.1:18789/health4) Verify
- Send a direct message to your Signal number from another device.
- Confirm Carapace logs show the inbound message.
- Confirm a typing indicator appears while the assistant generates a reply.
- Confirm the inbound message is marked as read in Signal at or before the assistant reply arrives. (See channel setup for the exact session-append ordering if you need to debug receipt timing.)
- Confirm the assistant reply arrives.
For reproducible live checks, use Channel Smoke Validation.
Next step
Common failures and fixes
- Symptom: No inbound messages in logs.
- Fix: Confirm signal-cli-rest-api is running and reachable at the
configured
baseUrl. Check thatphoneNumbermatches the registered number.
- Fix: Confirm signal-cli-rest-api is running and reachable at the
configured
- Symptom:
SSRF validation failederror.- Fix: Use
http://localhost:8080(loopback) orhttps://for non-loopback deployments. Carapace blocks non-HTTPS non-loopback URLs.
- Fix: Use
- Symptom: Messages arrive but sender shows as UUID instead of phone
number.
- Fix: This is expected when the sender has phone-number privacy
enabled. Carapace falls back to
sourceUuidas the sender identifier.
- Fix: This is expected when the sender has phone-number privacy
enabled. Carapace falls back to
- Symptom: Read receipts not sent.
- Fix: Confirm
channels.signal.features.readReceipts.enabledistrue. Unsupported messages (groups, non-text) remain unread by design.
- Fix: Confirm
- Symptom: No typing indicator.
- Fix: Confirm
channels.signal.features.typing.enabledistrue.
- Fix: Confirm