Skip to main content
marsClaw

marsClaw

A personal chat agent β€” Telegram, Slack, WhatsApp on top of Claude or Gemini

git clone https://github.com/deBilla/marsclaw && cd marsclaw && bash setup.sh
πŸ›°οΈ

Two SDKs, one wire

Pick Claude or Gemini. Switch any time with bun run provider. Automatic Claude→Gemini failover when Claude is over-quota. The hardest 80% of building an agent — reasoning loop, tools, context — is delegated to the SDK so we own ~5k lines of glue.

πŸ’¬

Multi-channel

Telegram, Slack (Socket Mode), and WhatsApp (Baileys, QR auth) baked in. Enable any combination. Images go through vision; WhatsApp voice notes are transcribed locally and the agent can reply in synthesized speech.

πŸ›‘οΈ

Personal, hardened

Per-thread message serialization, sandboxed allowed_paths, a Bash denylist, inbound rate limits, daily USD budget cap, startup circuit-breaker, daily backups. Designed for one person; built like it runs unattended.

From clone to a running bot in ~2 minutes

1

Setup

bash setup.sh

Interactive: pick provider, log in (auto-detected if you already are), wire up channels.

2

Link WhatsApp (optional)

# scan the QR shown in
# the setup flow
# from your phone:
# Settings β†’ Linked devices

Or set TELEGRAM_BOT_TOKEN / Slack tokens β€” any combination of channels.

3

Start

bun run start

Or install as a launchd service: bun run service install. Message your bot.

Why it's small

The whole codebase is ~5k lines of TypeScript. The hardest parts of building an agent β€” the reasoning loop, context compaction, the built-in tools (shell, read/write/edit, glob, grep, web fetch/search), model selection, retry logic β€” are delegated to the Claude Agent SDK or the Gemini CLI core.

We own the chat-side glue: channel adapters, SQLite, an MCP server with channel-specific tools (send_message, send_file, speak, Gmail/Calendar/Drive/…), and ~5 files of context engineering.

When Anthropic or Google ship a better model or improved tool use, we get it for free.

Read the architecture β†’
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ channel adapter  β”‚ text ─▢ β”‚  handleMessage           β”‚
β”‚ Β· telegram       β”‚         β”‚  Β· persist to sqlite     β”‚
β”‚ Β· slack          β”‚         β”‚  Β· build prompt          β”‚
β”‚ Β· whatsapp       β”‚ audio?β–Ά β”‚  Β· gemini / claude SDK   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ whisper β”‚  Β· send reply            β”‚
        β–²           :9000    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                                β”‚
        β”‚                       speak()  β”‚  ← MCP
        β”‚                     kokoro     β”‚
        β”‚                     :9001      β–Ό
        └─ router.send ◀── outbox drain β”€β”˜