{"id":"41357d0b-ae27-4574-a8cc-75ff1ac2e978","slug":"whatsrust","kind":"mcp","name":"whatsrust","summary":"WhatsApp in pure Rust. Single binary, 5 MB, 15 MB RAM. 54 API endpoints, 30 MCP tools, full protocol.","owner":"199-biotechnologies","repoUrl":"https://github.com/199-biotechnologies/whatsrust","license":"MIT","licenseTier":"permissive","trust":"community","stars":18,"match":null,"fewStars":false,"format":"mcp","createdAt":"2026-02-25T23:55:05.000Z","addedAt":"2026-10-14T05:05:15.920Z","logoUrl":"https://avatars.githubusercontent.com/u/174746481?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["communication","developer-tools","cloud-infra"],"tags":["automation","chatbot","messaging","rust","whatsapp","whatsapp-api","whatsapp-bot","whatsapp-web"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-17T08:30:47.826Z","sample":false,"url":"https://conduits.dev/tools/whatsrust","language":"Rust","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<div align=\"center\">\n\n# WhatsRust\n\n**WhatsApp in pure Rust. One 5 MB binary. 15 MB RAM. No Node.js required.**\n\n<br />\n\n[![Star this repo](https://img.shields.io/github/stars/199-biotechnologies/whatsrust?style=for-the-badge&logo=github&label=%E2%AD%90%20Star%20this%20repo&color=yellow)](https://github.com/199-biotechnologies/whatsrust/stargazers)\n&nbsp;&nbsp;\n[![Follow @longevityboris](https://img.shields.io/badge/Follow_%40longevityboris-000000?style=for-the-badge&logo=x&logoColor=white)](https://x.com/longevityboris)\n\n<br />\n\n[![Rust](https://img.shields.io/badge/Rust-stable-orange?style=for-the-badge&logo=rust)](https://www.rust-lang.org)\n&nbsp;\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue?style=for-the-badge)](LICENSE)\n&nbsp;\n[![54 API Endpoints](https://img.shields.io/badge/API-54_endpoints-green?style=for-the-badge)](https://github.com/199-biotechnologies/whatsrust#api)\n&nbsp;\n[![30 MCP Tools](https://img.shields.io/badge/MCP-30_tools-blueviolet?style=for-the-badge)](https://github.com/199-biotechnologies/whatsrust#mcp-server-for-ai-agents)\n&nbsp;\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen?style=for-the-badge)](https://github.com/199-biotechnologies/whatsrust/pulls)\n\n---\n\nA single Rust binary that handles the full WhatsApp Web protocol: text, images, audio, video, stickers, reactions, edits, polls, status stories, groups, and chat management. No npm. No Python. No Docker. Just `cargo build` and scan the QR code.\n\n[Install](#install) | [How It Works](#how-it-works) | [Features](#features) | [API](#api) | [MCP Tools](#mcp-server-for-ai-agents) | [Contributing](#contributing)\n\n</div>\n\n---\n\n## Why WhatsRust exists\n\nEvery WhatsApp automation library follows the same playbook: Node.js, Baileys, and a `node_modules` folder the size of a small country. It works until 3 AM when the process crashes, the memory leak finally wins, and you're reading someone else's JavaScript trying to figure out what went wrong.\n\nWe needed WhatsApp inside agent software and got tired of babysitting a Node sidecar. So we replaced it with one Rust binary.\n\n### Before vs After\n\n| | Node.js + Baileys | **WhatsRust** |\n|---|---------|-----------|\n| **Language** | JavaScript / Node.js | Rust |\n| **Install size** | ~200 MB with node_modules | **5 MB** single binary |\n| **Memory usage** | ~50-120 MB idle | **~15 MB** |\n| **Dependencies** | `npm install` + hope | `cargo build` |\n| **Crash recovery** | Roll your own | SQLite-backed queue + per-message backoff |\n| **API** | None built-in | **54 REST endpoints** + CLI + MCP server |\n| **Status/stories** | DIY | Text, image, video, revoke -- all built in |\n| **Chat management** | Manual API calls | **12 operations** (pin, mute, archive, star...) |\n| **Group management** | Manual | **12 methods**, full CRUD |\n| **Anti-ban protection** | None | Read receipt batching, typing sim, jitter |\n| **AI agent support** | None | **30 MCP tools** for Claude Code, etc. |\n\n---\n\n## Install\n\n```bash\ngit clone https://github.com/199-biotechnologies/whatsrust\ncd whatsrust && cargo run\n```\n\nScan the QR code with your phone. That's it.\n\n```bash\n# Phone number pairing instead of QR\nWHATSAPP_PAIR_PHONE=\"+1234567890\" cargo run\n\n# With sender allowlist + custom port\nWHATSAPP_ALLOWED=\"1234567890\" WHATSRUST_PORT=8080 cargo run\n```\n\n---\n\n## How it works\n\nWhatsRust runs as a daemon with a built-in REPL, REST API, and MCP server. Every outbound message goes through a durable SQLite queue -- messages survive crashes and restarts. Inbound messages are deduplicated with a generation-tracked concurrent map.\n\n```\nsrc/\n  bridge.rs          Core: events, messaging, queue, groups, chat management\n  outbound.rs        21 typed outbound ops, durable SQLite queue\n  bridge_events.rs   Broadcast event bus (tokio::sync::broadcast)\n  api.rs             REST API (54 endpoints) + SSE + CLI HTTP client\n  mcp.rs             MCP server (30 tools, JSON-RPC over stdio)\n  storage.rs         rusqlite Signal Protocol store + schema migrations\n  polls.rs           Poll crypto (HKDF-SHA256 + AES-256-GCM)\n  dedup.rs           Generation-tracked DashMap (concurrent-safe)\n  read_receipts.rs   Batched receipt scheduler\n  qr.rs              QR rendering (terminal/PNG/HTML/SVG)\n  instance_lock.rs   flock-based single-instance guard\n  main.rs            Daemon (REPL) + CLI (54 commands) + MCP mode\n  lib.rs             Library crate exports\n```\n\n~11,000 lines across 13 files. Built on [`whatsapp-rust`](https://github.com/jlucaso1/whatsapp-rust) (v0.5.0, MIT) for the protocol layer.\n\n### Four ways to run it\n\n| Mode | How |\n|------|-----|\n| **Daemon** | `cargo run` -- REPL with 54 commands |\n| **CLI** | `whatsrust send 15551234567 \"Hello\"` -- JSON to stdout |\n| **Library** | `WhatsAppBridge::start(config, tx, cancel)` -- embed in your Rust app |\n| **MCP server** | `whatsrust mcp` -- 30 tools for AI agents (Claude Code, etc.) |\n\n---\n\n## Features\n\n### Every WhatsApp message type\n\nText, image, audio/voice, video, document, sticker, location, contact card, reaction (add/remove), edit, revoke, reply/quote, forward, view-once (image/video), poll (create + encrypted vote decryption), status/story (text/image/video/revoke).\n\n### Chat management (12 operations)\n\nPin/unpin, mute/unmute, archive/unarchive, mark read/unread, delete chat, delete message for me, star/unstar. Direct app-state mutations that sync across all linked devices.\n\n### Full group management\n\nList groups, get info, create, rename, set description, add/remove/promote/demote participants, invite links. Group metadata cached with TTL and mutation invalidation.\n\n### Status/story posting\n\nText stories with custom background colors and fonts. Image and video stories. Revoke posted stories. Privacy controls (contacts, allowlist, denylist). All go through the durable outbound queue.\n\n### Stays alive\n\n- **Crash-safe outbound queue** in SQLite. Messages survive restarts.\n- **Atomic dedup** with generation-tracked DashMap. No double-processing under concurrent handlers.\n- **Per-message exponential backoff.** One stuck message doesn't block the rest.\n- **Graduated reconnect backoff** with jitter. Not the naive kind.\n- **Graceful shutdown.** Drains in-flight messages on SIGINT/SIGTERM.\n- **Single-instance flock.** Two bridges can't fight over one session.\n- **SQLite backup** on startup and shutdown. WAL mode, no corruption.\n\n### Doesn't get you banned\n\n- **Read receipt batching.** Groups message IDs per chat into single stanzas on a 200 ms coalesce.\n- **Flush-before-reply.** Marks messages as read before responding.\n- **Recording indicator** before voice notes.\n- **Configurable send pacing** with randomized jitter intervals.\n- **Auto presence management.** Available on connect, unavailable on shutdown.\n\n---\n\n## CLI\n\nWith the daemon running, use `whatsrust` as a one-shot CLI. Every command returns JSON to stdout:\n\n```bash\n# Messaging\nwhatsrust send 15551234567 \"Hello from the CLI\"\nwhatsrust image 15551234567 /tmp/photo.jpg \"Check this out\"\nwhatsrust video 15551234567 /tmp/clip.mp4\nwhatsrust react 15551234567 MSG_ID \"thumbsup\"\nwhatsrust poll 15551234567 1 \"Lunch?\" -- \"Pizza\" \"Sushi\" \"Tacos\"\n\n# Status/stories\nwhatsrust status-text 15551234567 \"Hello world\"\nwhatsrust status-image 15551234567 /tmp/photo.jpg\n\n# Chat management\nwhatsrust pin-chat 15551234567\nwhatsrust mute-chat 15551234567\nwhatsrust archive-chat 15551234567\nwhatsrust mark-read 15551234567\nwhatsrust delete-chat 15551234567\n\n# Groups\nwhatsrust groups\nwhatsrust group-info 120363012345678901@g.us\nwhatsrust group-create \"My Group\" 15551234567 15559876543\n```\n\nOutput:\n```json\n{\"ok\": true, \"id\": \"3EB0A1B2C3D4E5F6\"}\n```\n\n---\n\n## API\n\n54 REST endpoints on `localhost:7270`. JSON in, JSON out. No framework -- raw TCP for minimal overhead.\n\n### Messaging\n\n| Endpoint | Body |\n|----------|------|\n| `POST /api/send` | `{jid, text, mentions?, schedule_at?}` |\n| `POST /api/reply` | `{jid, id, sender, text}` |\n| `POST /api/edit` | `{jid, id, text}` |\n| `POST /api/react` | `{jid, id, emoji}` |\n| `POST /api/revoke` | `{jid, id}` |\n| `POST /api/image` | `{jid, data, mime?, caption?}` |\n| `POST /api/video` | `{jid, data, mime?, caption?}` |\n| `POST /api/audio` | `{jid, data}` |\n| `POST /api/poll` | `{jid, question, options, selectable_count}` |\n| `POST /api/forward` | `{jid, msg_id}` |\n\n### Status/stories\n\n| Endpoint | Body |\n|----------|------|\n| `POST /api/status-text` | `{recipients, text, background_argb?, font?}` |\n| `POST /api/status-image` | `{recipients, data, caption?}` |\n| `POST /api/status-video` | `{recipients, data, caption?}` |\n| `POST /api/status-revoke` | `{recipients, message_id}` |\n\n### Chat management\n\n| Endpoint | Body |\n|----------|------|\n| `POST /api/pin-chat` | `{jid}` |\n| `POST /api/mute-chat` | `{jid}` |\n| `POST /api/archive-chat` | `{jid}` |\n| `POST /api/mark-read` | `{jid}` |\n| `POST /api/delete-chat` | `{jid}` |\n| `POST /api/delete-for-me` | `{jid, id}` |\n| `POST /api/star` | `{jid, id}` |\n\nPlus: SSE streaming (`GET /api/events`), groups, presence, health check, QR.\n\nAsync sends return `{ok, job_id}`. Add `?sync=true` to wait for the WhatsApp message ID.\n\n---\n\n## MCP server for AI agents\n\nRun `whatsrust mcp` to start a Model Context Protocol server with 30 tools over JSON-RPC stdio. Connect it to Claude Code, Cursor, or any MCP-compatible AI agent and your agent can send messages, manage groups, post stories, and handle chat operations through WhatsApp.\n\nWorks out of the box with Claude Code -- just add it to your MCP config and your AI agent gets full WhatsApp access.\n\n---\n\n## Use as a library\n\nDesigned to be embedded. About 10 lines to wire up:\n\n```rust\nuse whatsrust::bridge::{BridgeConfig, WhatsAppBridge, WhatsAppInbound};\nuse tokio::sync::mpsc;\nuse tokio_util::sync::CancellationToken;\n\nlet (inbound_tx, mut inbound_rx) = mpsc::channel::<WhatsAppInbound>(256);\nlet cancel = CancellationToken::new();\n\nlet bridge = WhatsAppBridge::start(\n    BridgeConfig {\n        db_path: \"whatsapp.db\".into(),\n        health_port: 8080,\n        ..Default::default()\n    },\n    inbound_tx,\n    cancel.clone(),\n);\n\n// Send\nbridge.send_message_with_id(\"1234567890\", \"Hello from Rust\").await?;\n\n// Receive\nwhile let Some(msg) = inbound_rx.recv().await {\n    println!(\"{}: {}\", msg.sender, msg.content.display_text());\n}\n```\n\nInbound messages arrive as `WhatsAppInbound` with sender, JID, message ID, reply context, `MessageFlags` (forwarded, view-once), and typed content. Media arrives as raw bytes -- no second download step.\n\n---\n\n## Config\n\n| Variable | Default | What it does |\n|----------|---------|-------------|\n| `WHATSAPP_PAIR_PHONE` | *(QR mode)* | Phone number for pair-code linking |\n| `WHATSAPP_ALLOWED` | *(everyone)* | Comma-separated sender allowlist |\n| `WHATSRUST_PORT` | `7270` | API server port (0 = disabled) |\n| `WHATSRUST_BIND` | `127.0.0.1` | API bind address |\n| `WHATSRUST_API_TOKEN` | *(none)* | Bearer token for API auth |\n| `BACKUP_DIR` | `whatsapp.db.backups` | SQLite backup directory |\n| `RUST_LOG` | `info` | Log level (`debug` for protocol) |\n\n---\n\n## Contributing\n\nPRs welcome. Run `cargo test` and `cargo clippy` before submitting. See [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\n[MIT](LICENSE)\n\n---\n\n<div align=\"center\">\n\nBuilt by [Boris Djordjevic](https://github.com/longevityboris) at [199 Biotechnologies](https://github.com/199-biotechnologies) | [Paperfoot AI](https://paperfoot.ai)\n\n<br />\n\n**If this is useful to you:**\n\n[![Star this repo](https://img.shields.io/github/stars/199-biotechnologies/whatsrust?style=for-the-badge&logo=github&label=%E2%AD%90%20Star%20this%20repo&color=yellow)](https://github.com/199-biotechnologies/whatsrust/stargazers)\n&nbsp;&nbsp;\n[![Follow @longevityboris](https://img.shields.io/badge/Follow_%40longevityboris-000000?style=for-the-badge&logo=x&logoColor=white)](https://x.com/longevityboris)\n\n</div>\n"}