GitHub - steipete/clawdis: Invoke actions on your machine when you get a WhatsApp message and send replies! Uses Twilio and TailScale. Great for connecting Claude Code with WhatsApp.

7 min read Original article β†—

🦞 CLAWDIS β€” WhatsApp & Telegram Gateway for AI Agents

CLAWDIS

EXFOLIATE! EXFOLIATE!

CI status GitHub release MIT License

CLAWDIS is a TypeScript/Node gateway that bridges WhatsApp (Web/Baileys) and Telegram (Bot API/grammY) to a local coding agent (Pi). It’s like having a genius lobster in your pocket 24/7 β€” but with a real control plane, companion apps, and a network model that won’t corrupt sessions.

WhatsApp / Telegram
        β”‚
        β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚          Gateway          β”‚  ws://127.0.0.1:18789 (loopback-only)
  β”‚     (single source)       β”‚  tcp://0.0.0.0:18790 (optional Bridge)
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚
              β”œβ”€ Pi agent (RPC)
              β”œβ”€ CLI (clawdis …)
              β”œβ”€ WebChat (loopback UI)
              β”œβ”€ macOS app (Clawdis.app)
              └─ iOS node (Iris) via Bridge + pairing

Why "CLAWDIS"?

CLAWDIS = CLAW + TARDIS

Because every space lobster needs a time-and-space machine. The Doctor has a TARDIS. Clawd has a CLAWDIS. Both are blue. Both are chaotic. Both are loved.

Features

  • πŸ“± WhatsApp Integration β€” Personal WhatsApp Web (Baileys)
  • ✈️ Telegram (Bot API) β€” DMs and groups via grammY
  • πŸ›°οΈ Gateway control plane β€” One long-lived gateway owns provider state; clients connect over WebSocket
  • πŸ€– Agent runtime β€” Pi only (Pi CLI in RPC mode), with tool streaming
  • πŸ’¬ Sessions β€” Direct chats collapse into main by default; groups are isolated
  • πŸ”” Heartbeats β€” Periodic check-ins for proactive AI
  • 🧭 Clawd Browser β€” Dedicated Chrome/Chromium profile with tabs + screenshot control (no interference with your daily browser)
  • πŸ‘₯ Group Chat Support β€” Mention-based triggering
  • πŸ“Ž Media Support β€” Images, audio, documents, voice notes
  • 🎀 Voice & transcription hooks β€” Voice Wake (macOS/iOS) + optional transcription pipeline
  • πŸ”§ Tool Streaming β€” Real-time display (πŸ’»πŸ“„βœοΈπŸ“)
  • πŸ–₯️ macOS Companion (Clawdis.app) β€” Menu bar controls, Voice Wake, WebChat, onboarding, remote gateway control
  • πŸ“± iOS Node (Iris) β€” Pairs as a node, exposes a Canvas surface, forwards voice wake transcripts

Only the Pi CLI is supported now; legacy Claude/Codex/Gemini paths have been removed.

Network model (the β€œnew reality”)

  • One Gateway per host. The Gateway is the only process allowed to own the WhatsApp Web session.
  • Loopback-first: the Gateway WebSocket listens on ws://127.0.0.1:18789 and is not exposed on the LAN.
  • Bridge for nodes: when enabled, the Gateway also exposes a bridge on tcp://0.0.0.0:18790 for paired nodes (Bonjour-discoverable). For tailnet-only setups, set bridge.bind: "tailnet" in ~/.clawdis/clawdis.json.
  • Remote control: use a VPN/tailnet or an SSH tunnel (ssh -N -L 18789:127.0.0.1:18789 user@host). The macOS app can drive this flow.
  • Wide-Area Bonjour (optional): for auto-discovery across networks (Vienna ⇄ London) over Tailscale, use unicast DNS-SD on clawdis.internal.; see docs/bonjour.md.

Codebase

  • TypeScript (ESM): CLI + Gateway live in src/ and run on Node β‰₯ 22.
  • macOS app (Swift): menu bar companion lives in apps/macos/.
  • iOS app (Swift): Iris node prototype lives in apps/ios/.

Quick Start

Runtime requirement: Node β‰₯22.0.0 (not bundled). The macOS app and CLI both use the host runtime; install via Homebrew or official installers before running clawdis.

# From source (recommended while the npm package is still settling)
pnpm install
pnpm build

# Link your WhatsApp (stores creds under ~/.clawdis/credentials)
pnpm clawdis login

# Start the gateway (WebSocket control plane)
pnpm clawdis gateway --port 18789 --verbose

# Send a WhatsApp message (WhatsApp sends go through the Gateway)
pnpm clawdis send --to +1234567890 --message "Hello from the CLAWDIS!"

# Talk to the agent (optionally deliver back to WhatsApp/Telegram)
pnpm clawdis agent --message "Ship checklist" --thinking high

# If the port is busy, force-kill listeners then start
pnpm clawdis gateway --force

Companion Apps

macOS Companion (Clawdis.app)

  • A menu bar app that can start/stop the Gateway, show health/presence, and provide a local ops UI.
  • Instances UI shows friendly hardware model names (from the vendored MIT dataset under apps/macos/Sources/Clawdis/Resources/DeviceModels/).
  • Voice Wake (on-device speech recognition) and Push-to-talk overlay.
  • WebChat embed + debug tooling (logs, status, heartbeats, sessions).
  • Hosts PeekabooBridge for UI automation brokering (for clawd workflows).

Voice Wake reply routing

Voice Wake sends messages into the main session and replies on the last used surface:

  • WhatsApp: last direct message you sent/received.
  • Telegram: last DM chat id (bot mode).
  • WebChat: last WebChat thread you used.

If delivery fails (e.g. WhatsApp disconnected / Telegram token missing), Clawdis logs the error and you can still inspect the run via WebChat/session logs.

Build/run the mac app with ./scripts/restart-mac.sh (packages, installs, and launches), or swift build --package-path apps/macos && open dist/Clawdis.app.

iOS Node (Iris) (internal)

Iris is an internal/prototype iOS app that connects as a remote node:

  • Voice trigger: forwards transcripts into the Gateway (agent runs + wakeups).
  • Canvas screen: a WKWebView + <canvas> surface the agent can control (via screen.eval / screen.snapshot over node.invoke).
  • Discovery + pairing: finds the bridge via Bonjour (_clawdis-bridge._tcp) and uses Gateway-owned pairing (clawdis nodes pending|approve).

Runbook: docs/ios/connect.md

Configuration

Create ~/.clawdis/clawdis.json:

{
  inbound: {
    allowFrom: ["+1234567890"]
  }
}

Optional: enable/configure clawd’s dedicated browser control (defaults are already on):

{
  browser: {
    enabled: true,
    controlUrl: "http://127.0.0.1:18791",
    color: "#FF4500"
  }
}

Documentation

Clawd

CLAWDIS was built for Clawd, a space lobster AI assistant. See the full setup in docs/clawd.md.

Provider

If you’re running from source, use pnpm clawdis … instead of clawdis ….

WhatsApp Web

clawdis login      # scan QR, store creds
clawdis gateway    # run Gateway (WS on 127.0.0.1:18789)

Telegram (Bot API)

Bot-mode support (grammY only) shares the same main session as WhatsApp/WebChat, with groups kept isolated. Text/media sends work via clawdis send --provider telegram (reads TELEGRAM_BOT_TOKEN or telegram.botToken). Webhook mode is supported; see docs/telegram.md for setup and limits.

Commands

Command Description
clawdis login Link WhatsApp Web via QR
clawdis send Send a message (WhatsApp default; --provider telegram for bot mode). WhatsApp sends go via the Gateway WS; Telegram sends are direct.
clawdis agent Talk directly to the agent (no WhatsApp send)
clawdis browser ... Manage clawd’s dedicated browser (status/tabs/open/screenshot).
clawdis gateway Start the Gateway server (WS control plane). Params: --port, --token, --force, --verbose.
`clawdis gateway health status
clawdis wake Enqueue a system event and optionally trigger a heartbeat via the Gateway.
clawdis cron ... Manage scheduled jobs (via Gateway).
clawdis nodes ... Manage Gateway-owned node pairing.
clawdis status Web session health + session store summary
clawdis health Reports cached provider state from the running gateway.
clawdis webchat Start the loopback-only WebChat HTTP server

Gateway client params (WS only)

  • --url (default ws://127.0.0.1:18789)
  • --token (shared secret if set on the gateway)
  • --timeout <ms> (WS call timeout)

Send

  • --provider whatsapp|telegram (default whatsapp)
  • --media <path-or-url>
  • --json for machine-readable output

Health

  • Reads gateway/provider state (no direct Baileys socket from the CLI).

In chat, send /status to see if the agent is reachable, how much context the session has used, and the current thinking/verbose togglesβ€”no agent call required. /status also shows whether your WhatsApp web session is linked and how long ago the creds were refreshed so you know when to re-scan the QR.

Sessions, surfaces, and WebChat

  • Direct chats now share a canonical session key main by default (configurable via inbound.session.mainKey). Groups stay isolated as group:<jid>.
  • WebChat attaches to main and hydrates history from ~/.clawdis/sessions/<SessionId>.jsonl, so desktop view mirrors WhatsApp/Telegram turns.
  • Inbound contexts carry a Surface hint (e.g., whatsapp, webchat, telegram) for logging; replies still go back to the originating surface deterministically.
  • Every inbound message is wrapped for the agent as [Surface FROM HOST/IP TIMESTAMP] body:
    • WhatsApp: [WhatsApp +15551234567 2025-12-09 12:34] …
  • Telegram: [Telegram Ada Lovelace (@ada_bot) id:123456789 2025-12-09 12:34] …
    • WebChat: [WebChat my-mac.local 10.0.0.5 2025-12-09 12:34] … This keeps the model aware of the transport, sender, host, and time without relying on implicit context.

Credits

  • Peter Steinberger (@steipete) β€” Creator
  • Mario Zechner (@badlogicgames) β€” Pi, security testing
  • Clawd 🦞 β€” The space lobster who demanded a better name

License

MIT β€” Free as a lobster in the ocean.


"We're all just playing with our own prompts."

πŸ¦žπŸ’™