Eine Sprachnachricht auf WhatsApp: „Hey Claude, wie geht es meinem Server?" Antwort: Server gesund, 5 von 5 Containern laufen.
Das Problem dahinter ist unspektakulär. Einen eigenen Server zu betreiben bedeutet SSH. SSH bedeutet ein Terminal, und ein Terminal bedeutet, an einem Schreibtisch zu sitzen. Es gibt SSH-Clients fürs Telefon, ich habe sie benutzt. Ein systemctl-Kommando auf einem Touchscreen im Zug zu tippen ist kein Arbeitsablauf, das ist eine Strafe.
Die übliche Antwort darauf ist ein Dashboard — Grafana, Uptime Kuma, was auch immer. Dashboards sind in Ordnung. Sie zeigen Zahlen. Aber ein Dashboard kann nichts tun. Es sagt dir, dass ein Container unten ist. Es kann ihn nicht neu starten, es kann das Log nicht lesen, und es kann dir nicht sagen, warum.
Was ich eigentlich will, ist eine Frage in normaler Sprache zu stellen und eine Antwort von etwas zu bekommen, das auch handeln kann.
Was da läuft
Claude Code läuft auf diesem Server, seit dem Self-Hosting-Video. Gleiche Einrichtung, nichts Neues. Ich benutze also Claude Code, um das zu installieren, womit ich anschließend mit Claude Code rede.
Der Bot selbst ist ein eigenes Projekt und öffentlich auf GitHub. Er spricht Slack, Telegram und WhatsApp; hier läuft nur WhatsApp. Dazu gehören: PostgreSQL als Sitzungsgedächtnis, damit der Bot sich an den Gesprächsverlauf erinnert, und ein Router, der einfache Fragen an Haiku für eine schnelle Antwort schickt und schwere an Opus.
Zwei Punkte gehören vorweg, weil sie Geld beziehungsweise Risiko bedeuten:
- Sprachnachrichten laufen über OpenAI Whisper, eine getrennte kostenpflichtige Schnittstelle. Bruchteile eines Cents pro Nachricht, aber nicht umsonst.
- Die Nummer, die ich verbinde, ist eine Prepaid-SIM, eigens dafür gekauft. Nicht meine persönliche. Warum, steht weiter unten.
Phase 1 · Installation
Klone dieses Repository in mein Home-Verzeichnis und bring es auf diesem
Server zum Laufen.Zuerst npm install. Das zieht whatsapp-web.js, das zieht Puppeteer, das zieht einen vollständigen Chromium-Browser. Auf einem frischen Ubuntu-Server sind die Systembibliotheken, die Chromium braucht, nicht da.
Ein Ratschlag dazu, der fünfzehn Minuten spart: Rate die Paketliste nicht. Starte den Dienst, lies das Log, installiere genau das, was es benennt. Das sind zwei Minuten statt zwanzig.
Die 27 Pfade
Beim Durchsehen des Repositories hat Claude Code etwas gefunden, womit ich nicht gerechnet hatte: 27 hartkodierte Pfade. Jeder einzelne zeigte auf /home/damjan. Mein Benutzer auf diesem Server heißt anders. Auch der Pfad zur Claude-Binary war fest verdrahtet, direkt im Runner-Modul.
Ich habe dieses Projekt auf einer anderen Maschine geschrieben und es nie bemerkt, weil dort der Pfad stimmte.
Es gab zwei Auswege: einen Benutzer mit dem passenden Namen anlegen und weitermachen, oder die Pfade sauber umschreiben. Ich habe umschreiben lassen.
Das ist der ehrliche Grund, warum diese Phase im Video ist. Nicht weil npm install interessant wäre, sondern weil genau das passiert, wenn ein Projekt auf eine Maschine kommt, für die es nicht geschrieben wurde. Die Lehre ist banal und teuer: Schreib deine Pfade als Umgebungsvariablen. Ich habe es nicht getan, und es hat mich eine Phase dieses Videos gekostet.
Die Aufteilung
Claude Code kann kein sudo ausführen. Also schreibt es die Konfigurationen, und ich führe die privilegierten Befehle selbst aus.
Das ist kein Behelf, das ist die richtige Aufteilung. Der Agent schreibt, ich führe aus.
Phase 2 · Datenbank
PostgreSQL installieren und die Migrationen laufen lassen. Der erste Durchlauf hat einen Fehler zurückgegeben; ich habe den Fehler an Claude gegeben, es hat eine Migration nachgeschoben und die fehlenden Tabellen ergänzt, bis alle zwölf zu den Referenzen im Code passten.
Am Ende stand DB available: true — keine Abfrage hatte das Verfügbarkeitsflag ausgelöst. Danach die Testzeilen aus dem Rauchtest wieder entfernt.
Phase 3 · Kopplung
Der Bot startet, PostgreSQL ist verbunden, Slack sauber deaktiviert, WhatsApp initialisiert, das Dashboard läuft auf Port 3800.
Die Kopplung läuft über einen QR-Code. Er läuft in Sekunden ab, also lässt man ihn frisch erzeugen und scannt sofort: auf dem Telefon „Gerät verknüpfen", scannen, fertig. In WhatsApp erscheint danach eine Sitzung aus einem Chrome-Browser — das ist die Sitzung, die der Bot benutzt.
Die Sitzung wird in einem Ordner im Projekt abgelegt, ein Neustart kostet die Kopplung also nicht. Aber: Das Telefon muss etwa alle vierzehn Tage online kommen, sonst fällt die Verknüpfung und man scannt neu.
Der ehrliche Teil
Das ist nicht die offizielle WhatsApp Business API. Es ist Puppeteer, das einen kopflosen Browser fährt und sich als WhatsApp Web ausgibt. Metas Nutzungsbedingungen verbieten das, und Konten werden dafür gesperrt.
Genau deshalb hängt hier eine Prepaid-SIM und nicht meine eigene Nummer. Wenn sie gesperrt wird, verliere ich eine SIM-Karte und nicht meine Nachrichten. Wer das nachbaut, besorgt sich die SIM vorher, nicht hinterher. Zehn Euro, und es ist der Unterschied zwischen einem Projekt und einem Problem.
Phase 5 · Reden
Eine Testnachricht, und die Antwort kommt: Container laufen, Load 0,26, Platte bei 4 Prozent.
Auffällig ist die Reihenfolge. Eine kurze Antwort kommt fast sofort, eine längere folgt danach. Das ist der Router: Haiku klassifiziert die Nachricht. Ist sie einfach, antwortet Haiku direkt und die Sache ist erledigt. Ist sie komplex, schickt Haiku eine schnelle Empfangsbestätigung, damit man nicht ins Leere starrt, und Opus übernimmt dahinter.
Dieser zweistufige Aufbau ist der Unterschied zwischen „das fühlt sich an wie ein Chat" und „das fühlt sich an wie ein abgeschicktes Formular".

Eine Sprachnachricht läuft denselben Weg: Das Audio geht an Whisper, kommt als Text zurück und durchläuft danach exakt dieselbe Kette, als hätte ich getippt. Die Grenze liegt bei 25 Megabyte, also mehreren Minuten Sprache — die trifft man nicht.
Und dann das, wofür ich es eigentlich gebaut habe: der Serverbericht. Docker-Container und ihr Status, Platte auf Root und Home, Speicher, nginx, Uptime. Das ist eine Snapshot-Funktion, die sechs Befehle auf der Maschine ausführt und das Ergebnis in die Zustandstabelle schreibt. Sie hält 24 Stunden Verlauf vor.
Was nicht lief
- 27 hartkodierte Pfade in einem Projekt, das ich selbst geschrieben habe. Umgebungsvariablen. Immer.
- Chromium-Systembibliotheken auf einem frischen Server. Vorhersehbar, nervig, fünf Minuten.
- Alle vierzehn Tage daran denken, das Prepaid-Telefon einzuschalten.
Drei Regeln
- Die Whitelist ist dein Sicherheitsmodell, kein Komfortmerkmal. Wer schreiben darf, darf handeln.
- Gib dem Agenten ein Arbeitsverzeichnis, nicht die ganze Platte. Die Konfiguration hat eine Einstellung dafür. Benutz sie.
- Alles, was Root braucht, führst du selbst aus. Der Agent schreibt die Konfiguration, du führst sie aus. Diese Trennung ist das, was den Aufbau sicher hält.
Fazit
Der Bot ist nicht der interessante Teil. Etwas Vergleichbares baut man mit Telegram an einem Nachmittag.
Was es zum Funktionieren bringt, ist, dass Claude Code ohnehin schon auf diesem Server lebt, mit echtem Zugriff. Die Messaging-App ist nur eine Tür — Telegram und Slack liegen bereits im selben Codebestand. Gleiche Maschine, andere Tür.
Die Schnittstelle zu deinem Server muss kein Terminal sein. Sie muss etwas sein, das du ohnehin offen hast.



