Minimal multi-channel AI assistant with Discord, WhatsApp, and Telegram integration.
TinyClaw is a lightweight multi-provider AI assistant that:
- β Supports Anthropic Claude and OpenAI GPT models
- β Connects Discord, WhatsApp, and Telegram
- β Processes messages sequentially (no race conditions)
- β Maintains conversation context
- β Runs 24/7 in tmux
- β Extensible multi-channel architecture
Key innovation: File-based queue system prevents race conditions and enables seamless multi-channel support.
βββββββββββββββββββ
β Discord ββββ
β Client β β
βββββββββββββββββββ β
β
βββββββββββββββββββ β
β WhatsApp ββββ€
β Client β β
βββββββββββββββββββ ββββ Queue (incoming/)
β β
βββββββββββββββββββ β ββββββββββββββββ
β Telegram ββββ€ β Queue β
β Client β β β Processor β
βββββββββββββββββββ β ββββββββββββββββ
β β
β AI Provider
β (Claude or OpenAI)
β β
β Queue (outgoing/)
β β
βββ> Channels send
responses
- macOS or Linux
- Claude Code installed (for Anthropic provider)
- Codex CLI installed and authenticated (for OpenAI provider)
- Node.js v14+
- tmux
- Bash 4.0+ (macOS users:
brew install bash- system bash 3.2 won't work)
cd /path/to/tinyclaw
# Install dependencies
npm install
# Start TinyClaw (first run triggers setup wizard)
./tinyclaw.sh startOn first start, you'll see an interactive setup wizard:
ββββββββββββββββββββββββββββββββββββββββββ
TinyClaw - Setup Wizard
ββββββββββββββββββββββββββββββββββββββββββ
Which messaging channels do you want to enable?
Enable Discord? [y/N]: y
β Discord enabled
Enable WhatsApp? [y/N]: y
β WhatsApp enabled
Enable Telegram? [y/N]: y
β Telegram enabled
Enter your Discord bot token:
(Get one at: https://discord.com/developers/applications)
Token: YOUR_DISCORD_BOT_TOKEN_HERE
β Discord token saved
Enter your Telegram bot token:
(Create a bot via @BotFather on Telegram to get a token)
Token: YOUR_TELEGRAM_BOT_TOKEN_HERE
β Telegram token saved
Which AI provider?
1) Anthropic (Claude) (recommended)
2) OpenAI (Codex/GPT)
Choose [1-2]: 1
β Provider: anthropic
Which Claude model?
1) Sonnet (fast, recommended)
2) Opus (smartest)
Choose [1-2]: 1
β Model: sonnet
Heartbeat interval (seconds)?
(How often Claude checks in proactively)
Interval [default: 3600]: 3600
β Heartbeat interval: 3600s
β Configuration saved to .tinyclaw/settings.json
- Go to Discord Developer Portal
- Create a new application
- Go to "Bot" section and create a bot
- Copy the bot token
- Enable "Message Content Intent" in Bot settings
- Invite the bot to your server using OAuth2 URL Generator
- Open Telegram and search for @BotFather
- Send
/newbotand follow the prompts - Choose a name and username for your bot
- Copy the bot token provided by BotFather
- Start a chat with your bot or add it to a group
After starting, a QR code will appear if WhatsApp is enabled:
ββββββββββββββββββββββββββββββββββββββββ
WhatsApp QR Code
ββββββββββββββββββββββββββββββββββββββββ
[QR CODE HERE]
π± Scan with WhatsApp:
Settings β Linked Devices β Link a Device
Scan it with your phone. Done! π
Discord: Send a DM to your bot or mention it in a channel
WhatsApp: Send a message to the connected number
Telegram: Send a message to your bot
You'll get a response! π€
# Start TinyClaw
./tinyclaw.sh start
# Run setup wizard (change channels/model/heartbeat)
./tinyclaw.sh setup
# Check status
./tinyclaw.sh status
# Send manual message
./tinyclaw.sh send "What's the weather?"
# Reset conversation
./tinyclaw.sh reset
# Reset channel authentication
./tinyclaw.sh channels reset whatsapp # Clear WhatsApp session
./tinyclaw.sh channels reset discord # Shows Discord reset instructions
./tinyclaw.sh channels reset telegram # Shows Telegram reset instructions
# Switch AI provider (one-step command)
./tinyclaw.sh provider # Show current provider and model
./tinyclaw.sh provider anthropic --model sonnet # Switch to Anthropic with Sonnet
./tinyclaw.sh provider openai --model gpt-5.3-codex # Switch to OpenAI with GPT-5.3 Codex
./tinyclaw.sh provider openai --model gpt-4o # Switch to OpenAI with custom model
# Or switch provider/model separately
./tinyclaw.sh provider anthropic # Switch to Anthropic only
./tinyclaw.sh model sonnet # Then switch model
./tinyclaw.sh model opus # Switch to Claude Opus
./tinyclaw.sh model gpt-5.2 # Switch to OpenAI GPT-5.2
# View logs
./tinyclaw.sh logs whatsapp # WhatsApp activity
./tinyclaw.sh logs discord # Discord activity
./tinyclaw.sh logs telegram # Telegram activity
./tinyclaw.sh logs queue # Queue processing
./tinyclaw.sh logs heartbeat # Heartbeat checks
# Attach to tmux
./tinyclaw.sh attach
# Restart
./tinyclaw.sh restart
# Stop
./tinyclaw.sh stop- Interactive setup on first run
- Configures channels (Discord/WhatsApp/Telegram)
- Collects bot tokens for enabled channels
- Selects Claude model
- Writes to
.tinyclaw/settings.json
- Connects to Discord via bot token
- Listens for DMs and mentions
- Writes incoming messages to queue
- Reads responses from queue
- Sends replies back
- Connects to WhatsApp via QR code
- Writes incoming messages to queue
- Reads responses from queue
- Sends replies back
- Connects to Telegram via bot token
- Listens for messages
- Writes incoming messages to queue
- Reads responses from queue
- Sends replies back
- Polls incoming queue
- Processes ONE message at a time
- Routes to configured AI provider:
- Anthropic: Calls
claude -c -p(supports long-running agent tasks) - OpenAI: Calls
codex exec resume --last --jsonwith configured model - Parses JSONL output and extracts final agent message
- Anthropic: Calls
- Waits indefinitely for response
- Writes responses to outgoing queue
- Runs every 5 minutes
- Sends heartbeat via queue
- Keeps conversation active
- Main orchestrator
- Manages tmux session
- CLI interface
Message arrives (Discord/WhatsApp/Telegram)
β
Client writes to:
.tinyclaw/queue/incoming/{channel}_<id>.json
β
queue-processor.ts picks it up
β
Routes to AI provider:
- Claude: claude -c -p "message"
- Codex: codex exec resume --last --json "message"
β
Writes to:
.tinyclaw/queue/outgoing/{channel}_<id>.json
β
Client reads and sends response
β
User receives reply
tinyclaw/
βββ .claude/ # Claude Code config
β βββ settings.json # Hooks config
β βββ hooks/ # Hook scripts
βββ .tinyclaw/ # TinyClaw data
β βββ settings.json # Configuration (channel, model, tokens)
β βββ queue/
β β βββ incoming/ # New messages
β β βββ processing/ # Being processed
β β βββ outgoing/ # Responses
β βββ logs/
β β βββ discord.log
β β βββ whatsapp.log
β β βββ queue.log
β β βββ heartbeat.log
β βββ channels/ # Runtime channel data
β βββ whatsapp-session/
β βββ heartbeat.md
βββ src/
β βββ discord-client.ts # Discord I/O
β βββ whatsapp-client.ts # WhatsApp I/O
β βββ telegram-client.ts # Telegram I/O
β βββ queue-processor.ts # Message processing
βββ dist/ # TypeScript build output
βββ setup-wizard.sh # Interactive setup
βββ tinyclaw.sh # Main script
βββ heartbeat-cron.sh # Health checks
./tinyclaw.sh resetSend: !reset or /reset
Next message starts fresh (no conversation history).
All configuration is stored in .tinyclaw/settings.json:
Anthropic (Claude) example:
{
"channels": {
"enabled": ["telegram", "discord"],
"discord": {
"bot_token": "YOUR_DISCORD_TOKEN_HERE"
},
"telegram": {
"bot_token": "YOUR_TELEGRAM_TOKEN_HERE"
},
"whatsapp": {}
},
"models": {
"provider": "anthropic",
"anthropic": {
"model": "sonnet"
}
},
"monitoring": {
"heartbeat_interval": 3600
}
}OpenAI (Codex CLI) example:
{
"channels": {
"enabled": ["telegram", "discord"],
"discord": {
"bot_token": "YOUR_DISCORD_TOKEN_HERE"
},
"telegram": {
"bot_token": "YOUR_TELEGRAM_TOKEN_HERE"
},
"whatsapp": {}
},
"models": {
"provider": "openai",
"openai": {
"model": "gpt-5.3-codex"
}
},
"monitoring": {
"heartbeat_interval": 3600
}
}Note: Authentication is handled by the codex CLI. Make sure to run codex and authenticate before using the OpenAI provider.
To reconfigure, run:
./tinyclaw.sh setupThe heartbeat interval is in seconds (default: 3600s = 60 minutes). This controls how often Claude proactively checks in.
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
# Discord activity
tail -f .tinyclaw/logs/discord.log
# Telegram activity
tail -f .tinyclaw/logs/telegram.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
Discord, WhatsApp, and Telegram work seamlessly together. All channels share the same conversation context!
Adding more channels is easy:
// new-channel-client.ts
// Write to queue
fs.writeFileSync(
".tinyclaw/queue/incoming/channel_<id>.json",
JSON.stringify({
channel: "channel-name",
message,
sender,
timestamp,
}),
);
// Read responses from outgoing queue
// Same format as other channelsQueue processor handles all channels automatically!
Anthropic Claude:
- Sonnet (fast, recommended)
- Opus (smartest)
- Uses
claude -c -pCLI for conversation continuity
OpenAI Codex:
- GPT-5.3 Codex (recommended)
- GPT-5.2
- Uses
codex exec resume --lastfor conversation continuity - Parses JSONL output to extract agent messages
- Requires Codex CLI to be installed and authenticated
Switch providers and models in one command:
# One-step command (recommended)
./tinyclaw.sh provider openai --model gpt-5.3-codex
# Or two-step
./tinyclaw.sh provider openai
./tinyclaw.sh model gpt-5.3-codex
# Custom OpenAI model
./tinyclaw.sh provider openai --model gpt-4oWhatsApp 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
If you see:
Error: This script requires bash 4.0 or higher (you have 3.2.57)
macOS ships with bash 3.2 by default. Install a newer version:
# Install bash 5.x via Homebrew
brew install bash
# Add to your PATH (add this to ~/.zshrc or ~/.bash_profile)
export PATH="/opt/homebrew/bin:$PATH"
# Or run directly with the new bash
/opt/homebrew/bin/bash ./tinyclaw.sh start# Check logs
./tinyclaw.sh logs whatsapp
# Reset WhatsApp authentication
./tinyclaw.sh channels reset whatsapp
./tinyclaw.sh restart# Check logs
./tinyclaw.sh logs discord
# Update Discord bot token
./tinyclaw.sh setup# Check logs
./tinyclaw.sh logs telegram
# Update Telegram bot token
./tinyclaw.sh setup# Check queue processor
./tinyclaw.sh status
# Check queue
ls -la .tinyclaw/queue/incoming/
# View queue logs
./tinyclaw.sh logs queue# Attach to tmux to see the QR code
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
- Discord on desktop/mobile
- Telegram on any device
- CLI for scripts
All channels share the same Claude conversation!
- Inspired by OpenClaw by Peter Steinberger
- Built on Claude Code
- Uses discord.js
- Uses whatsapp-web.js
MIT
TinyClaw - Small but mighty! π¦β¨