Ravi is a daemon that runs Claude agents on WhatsApp, Telegram, and Discord. It handles sessions, queues messages, runs cron jobs, fires triggers, and manages outbound campaigns. Runs on your machine. No cloud. No SaaS.
$ ravi daemon start
├── nats-server :4222 (JetStream)
├── omni API :8882 (channel adapter)
│ ├── WhatsApp (Baileys)
│ ├── Telegram
│ └── Discord
└── ravi bot
├── OmniConsumer → pulls messages from JetStream
├── Claude SDK → runs agent sessions
├── OmniSender → sends replies back to channels
└── Runners → cron, heartbeat, triggers, outbound
One command starts everything. NATS and omni run as child processes.
WhatsApp via Baileys, Telegram, Discord. Multiple accounts, each routed to a different agent. Scan a QR code and go.
Each agent has its own CLAUDE.md, model, tools, and permissions. One handles sales, another monitors — same daemon.
Each contact, group, or thread gets its own session. Agents can also talk to each other across sessions.
"Every morning at 9, send a summary." Cron expressions, intervals, one-shot timers. Timezone-aware.
"When a contact is added, notify the team." Subscribe to any NATS topic, fire a prompt, with cooldowns and filters.
Queue up contacts, set follow-up intervals, track cold/warm/qualified. The agent writes the messages and handles replies.
The agent wakes up every N minutes, reads its HEARTBEAT.md, and acts on pending tasks. If nothing to do, stays quiet.
REBAC-based. Grant or deny access to tools, CLI commands, contacts, and sessions per agent. Closed by default.
Transcribes audio with Whisper, analyzes video with Gemini, generates images, sends files through any channel.
git clone https://github.com/filipexyz/ravi.git && cd ravi
bun install && bun run build && bun link
ravi setup
Downloads nats-server, asks for your Claude API key, creates the default agent.
ravi daemon start
Starts NATS, omni, and the bot. Everything in one process.
ravi whatsapp connect
Scan the QR code. That's it. Send a message to yourself on WhatsApp and Claude answers.
If a new message arrives while the agent is using a tool, it queues. When the tool finishes, the agent sees all queued messages at once.