Minimal multi-channel AI assistant with WhatsApp integration and queue-based architecture.
TinyClaw is a lightweight wrapper around Claude Code that:
- β Connects WhatsApp (via QR code)
- β Processes messages sequentially (no race conditions)
- β Maintains conversation context
- β Runs 24/7 in tmux
- β Ready for multi-channel (Telegram, etc.)
Key innovation: File-based queue system prevents race conditions and enables multi-channel support.
βββββββββββββββββββ
β WhatsApp ββββ
β Client β β
βββββββββββββββββββ β
ββββ Queue (incoming/)
βββββββββββββββββββ β β
β Telegram ββββ€ ββββββββββββββββ
β (future) β β β Queue β
βββββββββββββββββββ β β Processor β
β ββββββββββββββββ
Other Channels βββββββ β
claude --dangerously-skip-permissions -c -p
β
Queue (outgoing/)
β
βββββββββββββββββββ
β Channels send β
β responses β
βββββββββββββββββββ
ββββββββββββββββ¬βββββββββββββββ
β WhatsApp β Queue β
β Client β Processor β
ββββββββββββββββΌβββββββββββββββ€
β Heartbeat β Logs β
ββββββββββββββββ΄βββββββββββββββ
- macOS or Linux
- Claude Code installed
- Node.js v14+
- tmux
cd /Users/jliao/workspace/tinyclaw
# Install dependencies
npm install
# Make scripts executable
chmod +x *.sh *.js
# Start TinyClaw
./tinyclaw.sh startA QR code will appear in your terminal:
ββββββββββββββββββββββββββββββββββββββββ
WhatsApp QR Code
ββββββββββββββββββββββββββββββββββββββββ
[QR CODE HERE]
π± Scan with WhatsApp:
Settings β Linked Devices β Link a Device
Scan it with your phone. Done! π
Send a WhatsApp message to yourself from a different WhatsApp account:
"Hello Claude!"
You'll get a response! π€
# Start TinyClaw
./tinyclaw.sh start
# Check status
./tinyclaw.sh status
# Send manual message
./tinyclaw.sh send "What's the weather?"
# Reset conversation
./tinyclaw.sh reset
# View logs
./tinyclaw.sh logs whatsapp
./tinyclaw.sh logs queue
# Attach to tmux
./tinyclaw.sh attach
# Stop
./tinyclaw.sh stop- Connects to WhatsApp via QR code
- Writes incoming messages to queue
- Reads responses from queue
- Sends replies back
- Polls incoming queue
- Processes ONE message at a time
- Calls
claude -c -p - Writes responses to outgoing queue
- Runs every 5 minutes
- Sends heartbeat via queue
- Keeps conversation active
- Main orchestrator
- Manages tmux session
- CLI interface
WhatsApp message arrives
β
whatsapp-client.js writes to:
.tinyclaw/queue/incoming/whatsapp_<id>.json
β
queue-processor.js picks it up
β
Runs: claude -c -p "message"
β
Writes to:
.tinyclaw/queue/outgoing/whatsapp_<id>.json
β
whatsapp-client.js sends response
β
User receives reply
tinyclaw/
βββ .claude/ # Claude Code config
β βββ settings.json # Hooks config
β βββ hooks/ # Hook scripts
βββ .tinyclaw/ # TinyClaw data
β βββ queue/
β β βββ incoming/ # New messages
β β βββ processing/ # Being processed
β β βββ outgoing/ # Responses
β βββ logs/
β βββ whatsapp-session/
β βββ heartbeat.md
βββ tinyclaw.sh # Main script
βββ whatsapp-client.js # WhatsApp I/O
βββ queue-processor.js # Message processing
βββ heartbeat-cron.sh # Health checks
./tinyclaw.sh resetSend: !reset or /reset
Next message starts fresh (no conversation history).
Edit heartbeat-cron.sh:
INTERVAL=300 # seconds (5 minutes)Edit .tinyclaw/heartbeat.md:
Check for:
1. Pending tasks
2. Errors
3. Unread messages
Take action if needed.# WhatsApp activity
tail -f .tinyclaw/logs/whatsapp.log
# Queue processing
tail -f .tinyclaw/logs/queue.log
# Heartbeat checks
tail -f .tinyclaw/logs/heartbeat.log
# All logs
./tinyclaw.sh logs daemon# Incoming messages
watch -n 1 'ls -lh .tinyclaw/queue/incoming/'
# Outgoing responses
watch -n 1 'ls -lh .tinyclaw/queue/outgoing/'Messages processed sequentially, one at a time:
Message 1 β Process β Done
Message 2 β Wait β Process β Done
Message 3 β Wait β Process β Done
Add Telegram by creating telegram-client.js:
// Write to queue
fs.writeFileSync(
'.tinyclaw/queue/incoming/telegram_<id>.json',
JSON.stringify({ channel: 'telegram', message, ... })
);
// Read responses
// Same format as WhatsAppQueue processor handles it automatically!
Uses claude -c -p:
-c= continue conversation-p= print mode (clean output)- No tmux capture needed
WhatsApp session persists across restarts:
# First time: Scan QR code
./tinyclaw.sh start
# Subsequent starts: Auto-connects
./tinyclaw.sh restart- WhatsApp session stored locally in
.tinyclaw/whatsapp-session/ - Queue files are local (no network exposure)
- Each channel handles its own authentication
- Claude runs with your user permissions
# Check logs
./tinyclaw.sh logs whatsapp
# Re-authenticate
rm -rf .tinyclaw/whatsapp-session/
./tinyclaw.sh restart# Check queue processor
./tinyclaw.sh status
# Check queue
ls -la .tinyclaw/queue/incoming/
# View queue logs
./tinyclaw.sh logs queue# Use helper script
./show-qr.sh
# Or attach to tmux
tmux attach -t tinyclawsudo systemctl enable tinyclaw
sudo systemctl start tinyclawpm2 start tinyclaw.sh --name tinyclaw
pm2 save[program:tinyclaw]
command=/path/to/tinyclaw/tinyclaw.sh start
autostart=true
autorestart=trueYou: "Remind me to call mom"
Claude: "I'll remind you!"
[5 minutes later via heartbeat]
Claude: "Don't forget to call mom!"
You: "Review my code"
Claude: [reads files, provides feedback]
You: "Fix the bug"
Claude: [fixes and commits]
- WhatsApp on phone
- Telegram on desktop
- CLI for scripts All share the same Claude conversation!
- Inspired by OpenClaw by Peter Steinberger
- Built on Claude Code
- Uses whatsapp-web.js
MIT
TinyClaw - Small but mighty! π¦β¨