Signal mit OpenClaw verbinden: signal-cli, Pairing, Gruppen und Troubleshooting
So bindest du Signal per signal-cli an OpenClaw an, prüfst Pairing und Gruppenrouting und findest typische Fehler bei Container-, Daemon- und Bot-Setups.
Signal passt gut zu Agenten-Betrieb: vertraute App, Direktnachrichten, Gruppen und mobile Zustellung. In der Praxis scheitert das Setup aber selten am QR-Code allein, sondern an drei unscheinbaren Stellen: signal-cli läuft zwar, OpenClaw spricht aber den falschen Transport an; Direktnachrichten hängen noch im Pairing; Gruppen sind erlaubt, antworten aber nur bei Mentions oder gar nicht. Genau diese Lücken entscheidet man nicht mit Bauchgefühl, sondern mit einem klaren Diagnosepfad.
OpenClaw bindet Signal nicht über eine eingebaute libsignal-Integration an. Der Kanal läuft über signal-cli: OpenClaw spricht mit einem HTTP-Dienst, der entweder vom nativen signal-cli-Daemon oder vom Container bbernhard/signal-cli-rest-api bereitgestellt wird. Wenn du vorher andere Messenger angebunden hast, helfen die Grundlagen aus dem Telegram- und WhatsApp-Teil, dem Discord-Setup und dem Matrix-Guide beim Einordnen von Pairing, Allowlist und Gruppen.
Das ist der wichtigste Architekturpunkt. Signal ist kein reines „Schalter umlegen“-Feature, sondern ein kleiner Betriebsbaustein neben dem Gateway. Du brauchst eine laufende OpenClaw-Installation, ein Signal-Konto für den Bot und eine bewusste Entscheidung, ob OpenClaw den nativen Daemon selbst startet oder ob du einen externen Container betreibst. Die OpenClaw-Doku beschreibt den Linux-Pfad als auf Ubuntu 24 getestet; andere Umgebungen solltest du wie ein eigenes Deployment behandeln.
Woran Signal-Setups in der Praxis hängen
Vor dem eigentlichen Setup lohnt ein kurzer Reality-Abgleich zwischen Erwartung und Fehlerbild:
| Erwartet | Tatsächlich | Wahrscheinlicher Engpass |
|---|---|---|
| Der Bot ist gekoppelt und beantwortet eine Test-DM | Die DM bleibt still oder erzeugt nur einen Pairing-Code | dmPolicy, allowFrom oder offenes Pairing |
httpUrl zeigt auf einen gesunden Dienst | Der Kanal taucht in openclaw channels status --probe trotzdem nicht sauber auf | falscher Transportmodus, fehlendes WebSocket-/SSE-Receive |
| Die Gruppe ist erlaubt | In der Gruppe kommt nichts zurück oder nur bei @Mention | groupPolicy, groupAllowFrom, requireMention oder fehlende Mention-Patterns |
| Container läuft | Empfang bleibt leer, obwohl der Healthcheck grün ist | MODE=json-rpc fehlt oder apiMode passt nicht zum Ziel |
Wenn du genau eines dieser Symptome siehst, musst du nicht am ganzen Agenten-Stack zweifeln. Meist reicht es, den Transport, das Pairing oder die Gruppenregeln nacheinander zu prüfen.
Was du vorher entscheiden solltest
Für einen sauberen Start gibt es drei Entscheidungen:
- Bot-Konto: Nutzt du ein vorhandenes Signal-Konto per QR-Link oder eine eigene Bot-Nummer?
- Daemon-Modus: Nutzt du
signal-clinativ auf dem Host oder den Docker-Containerbbernhard/signal-cli-rest-api? - Zugriff: Dürfen nur gepairte Direktnachrichten rein oder zusätzlich bestimmte Gruppen?
Die Empfehlung für produktive Setups ist eindeutig: eigene Bot-Nummer, dmPolicy: "pairing", kleine Allowlist und Gruppen erst aktivieren, wenn Direktnachrichten zuverlässig funktionieren. Wenn du dein privates Signal-Konto als Bot verwendest, greift außerdem Loop-Schutz: Eigene Nachrichten werden ignoriert. Für „Ich schreibe dem Bot und er antwortet“ ist deshalb eine separate Bot-Nummer der robustere Weg.
Pfad A: vorhandenes Konto per QR-Link verbinden
Der QR-Link-Pfad ist der direkte Testweg. Er eignet sich, wenn du Signal zunächst als Kanal ausprobieren willst.
signal-cli link -n "OpenClaw"
Danach scannst du den QR-Code in Signal. Anschließend bekommt OpenClaw eine minimale channels.signal-Konfiguration:
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
account ist die Bot-Nummer im E.164-Format. cliPath zeigt auf signal-cli oder bleibt schlicht signal-cli, wenn das Binary im PATH liegt. dmPolicy: "pairing" sorgt dafür, dass unbekannte Absender erst einen Pairing-Code bekommen und nicht sofort Agentenarbeit auslösen. allowFrom begrenzt den DM-Zugriff auf Telefonnummern oder uuid:<id>-Werte.
Pfad B: eigene Bot-Nummer registrieren
Für produktive Nutzung ist die eigene Bot-Nummer sauberer. Du brauchst eine Nummer, die eine SMS oder Voice-Verifikation empfangen kann, und bei der Registrierung unter Umständen Zugriff auf signalcaptchas.org.
Auf Linux sieht der native Installationspfad laut OpenClaw-Doku so aus:
VERSION=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/AsamK/signal-cli/releases/latest | sed -e 's/^.*\/v//')
curl -L -O "https://github.com/AsamK/signal-cli/releases/download/v${VERSION}/signal-cli-${VERSION}-Linux-native.tar.gz"
sudo tar xf "signal-cli-${VERSION}-Linux-native.tar.gz" -C /opt
sudo ln -sf /opt/signal-cli /usr/local/bin/
signal-cli --version
Wenn du statt des Native-Builds den JVM-Build nutzt, brauchst du vorher eine passende Java-Laufzeit. Die Doku nennt JRE 25+ für den JVM-Build. Halte signal-cli aktuell; alte Releases können brechen, wenn sich Signal-Server-APIs ändern.
Die Registrierung läuft dann über signal-cli:
signal-cli -a +<BOT_PHONE_NUMBER> register
Falls Signal ein Captcha verlangt, öffnest du https://signalcaptchas.org/registration/generate.html, löst das Captcha, kopierst den signalcaptcha://...-Link und wiederholst die Registrierung direkt danach:
signal-cli -a +<BOT_PHONE_NUMBER> register --captcha '<SIGNALCAPTCHA_URL>'
signal-cli -a +<BOT_PHONE_NUMBER> verify <VERIFICATION_CODE>
Wichtig: Eine Nummer per signal-cli zu registrieren, kann die normale Signal-App-Session für diese Nummer abmelden. Genau deshalb ist eine getrennte Bot-Nummer mehr als Kosmetik.
Native Daemon oder Container?
Im nativen Modus startet OpenClaw den signal-cli-Daemon selbst, sofern du keinen externen Dienst konfigurierst. Dann reicht in vielen Setups cliPath, optional mit startupTimeoutMs, falls der Start langsam ist.
Wenn du signal-cli selbst betreiben willst, setzt du stattdessen eine externe URL und deaktivierst Auto-Start:
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
httpUrl: "http://127.0.0.1:8080",
autoStart: false,
apiMode: "native",
},
},
}
Der native Dienst nutzt JSON-RPC unter /api/v1/rpc und Events per SSE unter /api/v1/events. Der Container bbernhard/signal-cli-rest-api spricht dagegen REST und WebSocket. Für den Container brauchst du MODE=json-rpc, sonst sieht der Dienst zwar teilweise gesund aus, liefert aber kein brauchbares Receive-Streaming.
Ein minimales Compose-Beispiel:
services:
signal-cli:
image: bbernhard/signal-cli-rest-api:latest
environment:
MODE: json-rpc
ports:
- "8080:8080"
volumes:
- signal-cli-data:/home/.local/share/signal-cli
volumes:
signal-cli-data:
Dazu passt diese OpenClaw-Konfiguration:
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
httpUrl: "http://signal-cli:8080",
autoStart: false,
apiMode: "container",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
apiMode kann "auto", "native" oder "container" sein. auto probiert beide Varianten, native erzwingt den nativen JSON-RPC/SSE-Pfad, container erzwingt REST plus WebSocket. Wenn du weißt, worauf httpUrl zeigt, ist eine explizite Einstellung leichter zu debuggen.
Die praktische Faustregel lautet:
- Nutze
native, wenn OpenClaw den lokalensignal-cli-Daemon selbst ansprechen oder starten soll. - Nutze
container, wennhttpUrlsicher aufbbernhard/signal-cli-rest-apizeigt. - Lass
autonur dann stehen, wenn du die Umgebung wechselst oder noch nicht weißt, welcher Transport am Ende stabiler ist.
Damit vermeidest du das typische Fehlbild „Dienst antwortet, aber eingehende Nachrichten kommen nie bis zur Session durch“.
Gateway neu starten und prüfen
Nach der Konfiguration muss der Gateway neu gestartet werden. Bei einer User-systemd-Installation ist das zum Beispiel:
systemctl --user restart openclaw-gateway.service
Danach prüfst du nicht nur, ob der Prozess läuft, sondern ob OpenClaw den Kanal wirklich erkennt:
openclaw doctor
openclaw channels status --probe
Wenn dort Signal fehlt, ist meist channels.signal.enabled nicht gesetzt, die Konfiguration nicht geladen oder der Daemon nicht erreichbar.
Pairing für Direktnachrichten
Mit dmPolicy: "pairing" werden unbekannte Absender nicht sofort durchgelassen. Schick eine Test-DM an die Bot-Nummer. OpenClaw erzeugt einen Pairing-Code. Auf dem Server prüfst und bestätigst du ihn:
openclaw pairing list signal
openclaw pairing approve signal <PAIRING_CODE>
Pairing-Codes laufen laut Doku nach einer Stunde ab. Nach der Freigabe sollte eine weitere DM an den Bot beantwortet werden. Speichere die Bot-Nummer als Kontakt, damit Signal sie nicht als unbekannten Kontakt behandelt.
Wenn Direktnachrichten ignoriert werden, prüfe zuerst die Pairing-Liste, dann allowFrom. Bei UUID-only-Absendern speichert OpenClaw Einträge als uuid:<id>.
Gruppen erst danach aktivieren
Direktnachrichten und Gruppen sind in OpenClaw bewusst getrennt. Gruppen laufen in eigenem Gruppenkontext statt in deiner privaten DM-Session. Das ist sinnvoll, weil Gruppenkontext nicht automatisch in persönliche Agentengespräche laufen sollte.
Für Gruppen gibt es eigene Felder:
{
channels: {
signal: {
groupPolicy: "allowlist",
groupAllowFrom: ["signal:group:<GROUP_ID>"],
groups: {
"<GROUP_ID>": {
requireMention: true,
},
},
},
},
}
groupPolicy kann open, allowlist oder disabled sein. Für den Start ist allowlist die vernünftige Wahl. groupAllowFrom kann Gruppen-IDs, Telefonnummern, uuid:<id>-Werte oder * enthalten. Eine Allowlist bedeutet aber nicht automatisch, dass jede Gruppennachricht verarbeitet wird: Mention-Gating und Gruppen-Overrides bleiben relevant.
Der sichere Testablauf ist deshalb: erst DM-Pairing, dann eine kleine Testgruppe, dann groupAllowFrom, dann prüfen, ob requireMention und die globalen Mention-Patterns zum gewünschten Verhalten passen.
Medien, Reaktionen und Grenzen
Signal kann mehr als Text. OpenClaw unterstützt Attachments, Typing-Indikatoren, Read Receipts für erlaubte DMs, Reaktionen und Gruppenfunktionen. Für den Einstieg sind zwei Limits wichtig:
channels.signal.textChunkLimitbegrenzt ausgehende Textstücke; Standard laut Doku: 4000 Zeichen.channels.signal.mediaMaxMbbegrenzt Medien; Standard laut Doku: 8 MB.
Wenn du Medien zunächst ausschließen willst, setze ignoreAttachments. Für lange Antworten kann chunkMode: "newline" angenehmer sein, weil OpenClaw dann bevorzugt an Absatzgrenzen trennt.
Diagnose: erst die Leiter, dann Spezialfälle
Wenn Signal nicht antwortet, nicht raten. Arbeite diese Reihenfolge ab:
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe
openclaw pairing list signal
Damit prüfst du die drei Ebenen in der richtigen Reihenfolge:
- Gateway-Ebene:
openclaw status,openclaw gateway statusundopenclaw doctorzeigen, ob OpenClaw selbst läuft und die Konfiguration annimmt. - Kanal-Ebene:
openclaw channels status --probeprüft, ob der Signal-Kanal wirklich verbunden ist. - Gesprächs-Ebene:
openclaw pairing list signalzeigt, ob die Bot-Nummer zwar erreichbar ist, aber noch keinen freigegebenen Dialog hat.
Zusätzlich helfen diese Checks:
pgrep -af signal-cli
grep -i "signal" "/tmp/openclaw/openclaw-$(date +%Y-%m-%d).log" | tail -20
Wenn du an dieser Stelle nur einen einzigen Test machen willst, nimm openclaw channels status --probe. Dort trennt sich schnell, ob der Fehler im Gateway, im Transport oder erst im Chat-Routing steckt.
Typische Fehlerbilder:
- Daemon erreichbar, aber keine Antworten:
httpUrl,account,apiModeund Receive-Modus prüfen. - DMs werden ignoriert: Pairing steht noch aus oder der Absender fehlt in
allowFrom. - Gruppen reagieren nicht:
groupPolicy,groupAllowFrom, Gruppen-ID,requireMentionundmentionPatternsprüfen. - Config-Fehler nach Änderungen:
openclaw doctor --fixlaufen lassen. - Container wirkt gesund, aber Empfang fehlt:
MODE=json-rpcprüfen und bei BedarfapiMode: "container"explizit setzen.
Recovery: der kürzeste Weg zurück zu einem funktionierenden Kanal
Wenn Signal nach einer Änderung kippt, gehe nicht sofort auf Neuinstallation. Der robuste Recovery-Pfad ist kürzer:
- Letzte Änderung eingrenzen:
account,httpUrl,apiMode,allowFromundgroupAllowFromgegen die letzte funktionierende Version halten. - Gateway neu starten und danach nur den Signal-Kanal prüfen, nicht sofort mehrere Messenger parallel.
- Bei Container-Setups zuerst
MODE=json-rpcund die Konto-Verknüpfung im Container kontrollieren. - Bei Direktnachrichten immer noch einmal eine neue Test-DM senden und das Pairing explizit freigeben.
- Gruppen erst wieder aktivieren, wenn DMs zuverlässig laufen.
Das spart Zeit, weil du so nicht gleichzeitig Transport, Pairing und Gruppenkontext veränderst. Für generelle Kanalrechte und Server-/Raumlogik liefern auch der Discord-Guide und der Matrix-Guide gute Vergleichspunkte.
Sicherheitsbild für den Alltag
Signal fühlt sich privat an, ist für OpenClaw aber ein produktiver Eingabekanal. Alles, was dort durchgelassen wird, kann Agentenarbeit auslösen. Deshalb gehören diese Defaults in jedes ernsthafte Setup:
- separate Bot-Nummer statt privatem Hauptkonto,
dmPolicy: "pairing",- kleine
allowFrom-Liste, - Gruppen nur per
allowlist, - Backups des lokalen Signal-Zustands vor Servermigrationen,
- keine öffentlichen Logs mit Telefonnummern, UUIDs oder Pairing-Codes.
signal-cli speichert Kontoschlüssel lokal, typischerweise unter ~/.local/share/signal-cli/data/. Behandle diesen Zustand wie ein Secret. Wenn der Server neu gebaut oder migriert wird, brauchst du entweder ein Backup oder musst die Bot-Nummer erneut registrieren beziehungsweise verlinken.
Reality Check
Was belegt ist: Die OpenClaw-Dokumentation beschreibt Signal als externe signal-cli-Integration mit zwei Betriebswegen: nativer Daemon per JSON-RPC/SSE oder Container per REST/WebSocket. Belegt sind außerdem MODE=json-rpc für Container-Empfang, der Pairing-Ablauf für DMs, Gruppenregeln wie groupPolicy und requireMention sowie die diagnostischen OpenClaw-Kommandos für Kanalstatus und Pairing.
Was nicht vollständig belegt ist: Die verfügbaren Quellen liefern keine vollständige Matrix aller Signal-spezifischen Fehlermeldungen, keine garantierten Logzeilen für jeden Defekt und keine belastbare Aussage dazu, wie sich exotische Self-Hosting-Setups außerhalb des dokumentierten Linux-Pfads verhalten. Auch Rollback-Schritte für jede denkbare Container- oder JVM-Kombination bleiben offen.
Was du daraus ableiten solltest: Behandle Signal als Kanal mit eigener Runtime, nicht als austauschbaren Messenger-Schalter. Wenn der Kanal stumm bleibt, prüfe zuerst Transportmodus, Pairing und Gruppenregeln. Erst danach lohnt sich tieferes Debugging am restlichen Agenten-Stack oder an allgemeinen Groupchat-Regeln wie im Artikel zu OpenClaw-Gruppenchats, Commitments und Follow-ups.
Was du daraus mitnehmen solltest
Der sinnvolle Start ist klein: native oder Container-Variante wählen, eine Bot-Nummer anbinden, DM-Pairing testen, danach Gruppenrouting ergänzen. So wird Signal nicht zum Bastelchaos, sondern zu einem kontrollierten mobilen Eingang für OpenClaw.
Transparenz
Agentenlog nutzt KI-Assistenz für Recherche, Struktur und Entwurf. Inhaltliche Auswahl, Einordnung und Veröffentlichung liegen redaktionell bei Agentenlog; Quellen und Fakten werden vor Veröffentlichung geprüft.
Serie: Alle Kanäle verbinden
Das könnte dich auch interessieren
Slack mit OpenClaw verbinden: Bot, Mentions und Routing sauber einrichten
OpenClaw kann in Slack per Socket Mode oder HTTP Request URLs laufen. Entscheidend sind Bot-Setup, Gruppenzugriff, Mention-Gating und deterministisches Routing.
OpenClaw mit Mattermost verbinden: Bot, Channels und Self-Hosting ohne Blindflug
Wenn OpenClaw in Mattermost nur halb reagiert, prüfst du Runtime, Pairing, Chatmode, Callback-Erreichbarkeit und Routing.
OpenClaw mit Discord verbinden: Bot, Intents und Serverrechte ohne Blindflug
Wenn dein OpenClaw-Bot in Discord online ist, aber nicht antwortet, prüfst du Intents, Serverrechte, Pairing und Runtime in der richtigen Reihenfolge.