Ein Koordinationsbus, der mehrere Claude-Code-Sessions (Linux, macOS, Windows) über eine bestehende
m1k1o/chat-Instanz zusammenschaltet. Jede Session hängt als normaler
Chat-Teilnehmer im selben Raum, adressiert die anderen Sessions direkt mit @nick, meldet ihren
Status selbst und kann blockierend auf die Zuarbeit einer anderen Session warten – ohne dass ein
Mensch zwischen den Rechnern hin- und herspringt.
user: @claude-linux bau Feature X
claude-linux: gepusht nach feature/x (abc123). @claude-win @claude-mac bitte bauen und testen
claude-win: Build ok, 12/12 Tests grün
claude-mac: Build bricht ab: fehlende Symbole in libfoo. @claude-linux Log: ...
claude-linux: Fix gepusht (def456). @claude-mac nochmal
Während claude-linux auf die Antwort wartet, blockiert es in wait_for_message – statt den Menschen
zu fragen – und wacht auf, sobald eine der anderen Sessions antwortet.
Ein Prozess pro Maschine (bridge.py), drei Bausteine in einem asyncio-Loop:
m1k1o/chat (z. B. chat-host:8484)
▲ Socket.IO
│
┌───────┴────────────────────────────────┐
│ bridge.py (Linux / macOS / Windows) │
│ ├─ ChatClient Socket.IO │
│ ├─ MCP-Server 127.0.0.1:8787 │◄── HTTP-MCP ──┐
│ ├─ Router @nick-Regeln │ │
│ └─ ClaudeSession Subprozess ───────┼──► claude -p ─┘
└────────────────────────────────────────┘ (stream-json)
- stdin-Injection weckt eine untätige Session (neuer Turn).
- MCP-Tools bedienen die arbeitende Session (senden / warten / Peers abfragen) mitten im Turn.
Eine Session reagiert nur, wenn sie mit @<ihr-nick>, @all oder @alle angesprochen wird.
Alle anderen Nachrichten liest sie nur mit und gibt sie beim nächsten eigenen Turn als Kontext weiter.
Zusätzlich greift nach HOP_LIMIT (Standard 12) aufeinanderfolgenden Bot→Bot-Runden ohne
menschliche Beteiligung eine Bremse; jede Nachricht eines Menschen oder /reset setzt sie zurück.
| Tool | Zweck |
|---|---|
chat_send_message(text, to=[…]) |
Nachricht posten; to setzt @nick-Präfixe |
chat_wait_for_message(from_nick, contains, timeout, addressed_only) |
blockierend auf Zuarbeit warten |
chat_get_messages(limit) |
letzte Nachrichten lesen, ohne zu warten |
chat_list_peers() |
wer ist online, mit letztem gemeldeten Status |
chat_set_status(state, detail) |
idle / working / blocked / done |
/status– Nick, Zustand, Session-ID, Queue, Wartende, Hops, Uptime, Peers (antwortet von jeder Session)/help– Kurzhilfe/reset– adressiert (@nick /reset): neue Claude-Session mit frischem Kontext/stop– adressiert: laufenden Turn abbrechen (Prozess neu, Kontext bleibt über--resume)
Der Bus braucht eine zentrale m1k1o/chat-Instanz im LAN, mit der
sich alle Sessions verbinden. Der Container lauscht intern auf Port 80; in dieser README wird er
nach außen auf 8484 gemappt (passend zu CHAT_URL=http://<host>:8484).
Schnellstart per Docker:
docker run -d --name chat --restart unless-stopped -p 8484:80 -e CACHE_SIZE=200 m1k1o/chat:latestOder per docker-compose.yml:
services:
chat:
image: m1k1o/chat:latest
restart: unless-stopped
ports:
- "8484:80"
environment:
CACHE_SIZE: 200 # Anzahl serverseitig gepufferter Nachrichten für neu verbundene Clients
healthcheck:
test: ["CMD", "curl", "http://localhost"]
interval: 60s
timeout: 10s
retries: 10
start_period: 5sdocker compose up -dCACHE_SIZE– wie viele letzte Nachrichten der Server puffert und einer neu verbundenen Session als Verlauf schickt. Standard 0 (kein Verlauf). Für den Bus sinnvoll (z. B. 200), damit eine neu gestartete Session den letzten Kontext sieht; nicht zu hoch, da auch Bilder gecacht werden.- Danach in jeder
config.envCHAT_URL=http://<host-ip>:8484setzen – die IP/den Hostnamen des Docker-Hosts (aus dem LAN erreichbar), nichtlocalhost, sonst finden die anderen Maschinen den Server nicht. - Prüfen:
curl http://<host-ip>:8484/sollteHTTP 200liefern.
⚠️ Sicherheit: m1k1o/chat hat keine Authentifizierung (siehe Abschnitt „Sicherheit — bitte lesen“). Den Port nur im vertrauenswürdigen LAN/VPN exponieren, niemals ins Internet.
Voraussetzungen: Python ≥ 3.10 und die Claude Code CLI (claude) im PATH.
git clone https://github.com/Catweazle74/claude-session-bus.git
cd claude-session-bus
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp config.example.env config.env # anpassen: CLAUDE_CWD, CHAT_NICK, ...# Falls kein echtes Python vorhanden ist (der Store-Alias "python" zählt nicht):
winget install --id Python.Python.3.12 --scope user
git clone https://github.com/Catweazle74/claude-session-bus.git
cd claude-session-bus
python -m venv .venv
.\.venv\Scripts\pip install -r requirements.txt
Copy-Item config.example.env config.env # anpassen: CLAUDE_CWD, CHAT_NICK, ...config.env bearbeiten – vor allem CLAUDE_CWD auf das gemeinsame Projekt-Repo setzen
(unter Windows als nativer Pfad, z. B. C:\Users\<user>\Sourcen\mein-projekt).
.venv/bin/python selftest.py # Windows: .venv\Scripts\python selftest.pyDeterministische Tests der Router-Logik (Adressierung, Pingpong-Bremse, wait/pending, Slash-Kommandos). Sollten alle mit „alle Selbsttests bestanden“ enden.
set -a; . ./config.env; set +a # Windows PowerShell: siehe unten
.venv/bin/python bridge.pyCHAT_URL ist Pflicht – ohne gesetzte Variable (oder --chat-url) bricht die Bridge mit einer
Meldung ab, statt still gegen eine Beispieladresse zu verbinden.
Der Nick ergibt sich, wenn nicht gesetzt, aus der Plattform: claude-linux / claude-mac /
claude-win. Overrides auch per CLI-Flag: .venv/bin/python bridge.py --nick claude-linux --cwd /pfad/zum/repo.
Windows (PowerShell):
Get-Content config.env | Where-Object { $_ -match '=' -and $_ -notmatch '^\s*#' } | ForEach-Object {
$k,$v = $_ -split '=',2; [Environment]::SetEnvironmentVariable($k.Trim(), $v.Trim())
}
.venv\Scripts\python bridge.py- Linux (systemd --user):
systemctl --user stop claude-session-bus - macOS (launchd):
launchctl unload ~/Library/LaunchAgents/claude-session-bus.plist - Windows:
Get-Process python | Where-Object Path -like '*claude-session-bus*' | Stop-Process - Direkt im Vordergrund gestartet: einfach
Strg+C.
.venv/bin/python test_client.py "@claude-linux liste die Dateien im Repo"
.venv/bin/python test_client.py --listen 120 # nur mitlesen-
Linux (systemd --user):
systemd/claude-session-bus.servicenach~/.config/systemd/user/kopieren, Pfade anpassen, dannsystemctl --user daemon-reload && systemctl --user enable --now claude-session-bus. -
macOS (launchd):
launchd/claude-session-bus.plistnach~/Library/LaunchAgents/kopieren, Pfade anpassen,launchctl load ~/Library/LaunchAgents/claude-session-bus.plist. -
Windows (Aufgabenplanung):
windows/install-task.ps1(Pfade anpassen) in einer als Administrator gestarteten PowerShell ausführen –Register-ScheduledTaskscheitert sonst mit „Zugriff verweigert“. Das Skript erzeugt dabeiwindows/run-bridge.ps1(maschinenspezifisch, nicht eingecheckt). Deinstallieren:Unregister-ScheduledTask -TaskName "claude-session-bus" -Confirm:$false.Adminfreie Alternative (kein Auto-Restart bei Absturz): einen versteckten Starter in den Autostart-Ordner legen (
shell:startup), derwindows/run-bridge.ps1aufruft, z. B. eineclaude-session-bus.vbs:Set sh = CreateObject("WScript.Shell") sh.Run "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File ""<pfad>\windows\run-bridge.ps1""", 0, False
Nur eine der beiden Varianten aktivieren, sonst startet die Bridge doppelt.
Der m1k1o-Chat hat keine Authentifizierung. Standardmäßig läuft die Bridge mit
PERMISSION_MODE=bypassPermissions. Das bedeutet: wer den Chat erreicht, kann ohne Rückfrage
Befehle auf allen angebundenen Maschinen ausführen und Dateien ändern. Deshalb:
- Port des Chats (z. B. 8484) niemals ins Internet exponieren – nur LAN oder VPN.
CLAUDE_CWDmöglichst eng auf das Projekt-Repo setzen, nicht auf$HOMEoder/.- Der MCP-Server bindet nur an
127.0.0.1– nicht öffentlich machen. - Restriktive Alternative (kein autonomes Schreiben/Ausführen):
Damit fragt Claude bei allem außerhalb der Whitelist zurück – was im Bus-Betrieb aber niemand bestätigen kann, die Session also effektiv blockiert. Für den unbeaufsichtigten Bus ist
PERMISSION_MODE=acceptEdits ALLOWED_TOOLS=Read Grep Glob Bash(git *)bypassPermissionsin einem vertrauenswürdigen LAN der praktikable Kompromiss.
Alle Optionen sind in config.example.env dokumentiert und zusätzlich als
CLI-Flags verfügbar (--help).
- ✅ Chat-Anbindung (Socket.IO),
@nick-Adressierung, Pingpong-Bremse, Slash-Kommandos - ✅ MCP-Tools für senden / blockierendes Warten / Peers / Status, in-process auf
127.0.0.1 - ✅ Claude-Session als Subprozess (
claude -p, stream-json) inklusive stdin-Injection und--resume - ✅ Autostart-Vorlagen für systemd (Linux), launchd (macOS), Aufgabenplanung (Windows)
- ✅ Offline-Selbsttests der Router-Logik (
selftest.py), in CI auf jedem Push ⚠️ Kein Auth-Konzept — die Sicherheit hängt vollständig am Netz, in dem der Chat läuft (siehe „Sicherheit — bitte lesen")
Bekannte Limitierungen:
bridge.pyliestconfig.envnicht selbst — die Variablen müssen vorher in die Umgebung (sourcen,EnvironmentFile=in systemd, Wrapper-Skript unter Windows/macOS).- Der Windows-Autostart per
Register-ScheduledTaskbraucht eine Administrator-PowerShell; ohne Adminrechte nur die Autostart-Ordner-Variante (kein Neustart bei Absturz). - m1k1o/chat bietet keine Authentifizierung — nur im vertrauenswürdigen LAN/VPN betreiben.
Bitte melden:
- Schritte zum Reproduzieren
- Erwartetes vs. tatsächliches Verhalten
- Plattform, Python-Version, Ausgabe von
/statusundselftest.py(falls möglich)
- Python ≥ 3.10
- Claude Code CLI (
claudeim PATH) - python-socketio[asyncio_client] ≥ 5.16, < 6 (Chat-Verbindung)
- mcp ≥ 2.0, < 3 (MCP-Server für die Session-Tools; mit 1.x nicht kompatibel)
- m1k1o/chat als zentrale Chat-Instanz im LAN (Docker)
MIT — siehe LICENSE.