Skip to content

MaximeGaudin/void

Void CLI

void banner

CI Release License: AGPL-3.0 Rust

One inbox for everything. void unifies WhatsApp, Telegram, Slack, Gmail, Google Calendar, LinkedIn, GitHub, Hacker News, Google News, and Reddit into a single local-first command-line tool — one inbox, one search index, one set of commands.

It is built for terminals, shell scripts, and AI agents:

  • One inboxvoid inbox shows every unprocessed message across all your accounts
  • Local-first — a background daemon syncs everything into SQLite; reads are instant and work offline
  • Full-text search — FTS5 across every message on every service
  • Inbox Zero — triage, act, archive; muted noise stays out of sight
  • Agent hooks — run Claude Code (or any agent CLI) on new messages or cron schedules
  • Remote mode — sync on a home server, drive it from any laptop over plain SSH

Start here: Install · Commands · Connector setup · Configuration · Hooks · Remote store

Install

# macOS (Homebrew) — recommended
brew install MaximeGaudin/tap/void

# macOS (Apple Silicon, direct)
curl -fsSL https://github.com/MaximeGaudin/void/releases/latest/download/void-darwin-arm64.tar.gz | sudo tar xz -C /usr/local/bin

# Linux (x86_64)
curl -fsSL https://github.com/MaximeGaudin/void/releases/latest/download/void-linux-amd64.tar.gz | sudo tar xz -C /usr/local/bin

macOS Intel, Linux ARM64, Windows, and build-from-source: see Install.

Quick start

void setup            # interactive wizard — connect WhatsApp, Slack, Gmail, ...
void sync --daemon    # start the background sync daemon

void inbox                                            # everything unprocessed, all services
void search "quarterly report"                        # full-text search across all of it
void reply <id> --message "On it — sending today."    # reply from where you are
void archive <id>                                     # done; on to the next one

WhatsApp and Telegram connect by scanning a QR code. Gmail and Calendar ship with built-in OAuth credentials — no Google Cloud project required. Per-service details: Connector setup.

The Inbox Zero loop

Void follows an Inbox Zero model: every unprocessed message from every service lands in a single inbox, and the goal is to empty it.

  1. Triagevoid inbox shows all unarchived messages across every connector
  2. Act — reply, react, forward, draft, or just read
  3. Archivevoid archive <id> marks the item as processed
  4. Done — when void inbox returns nothing, you're at Inbox Zero

Noise never reaches the inbox in the first place: void mute (or ignore_conversations in the config) silences groups and channels permanently. void inbox --all reviews what's been archived.

Everyday examples

Messaging

# Send anywhere through one interface
void send --via slack --to "#general" --message "Hello team"
void send --via whatsapp --to "Alice" --message "Running 5 min late"
void send --via telegram --to "Notes" --file ./screenshot.png

# Threads, reactions, edits, scheduled messages
void reply <id> --message "Agreed" --in-thread
void slack react <id> --emoji rocket
void slack schedule --channel "#standup" --message "OOO today" --at "2026-06-12 09:00"

# Bulk-archive an old backlog
void archive --before 2026-05-01 --connector slack

Gmail

Docs: commands · setup

void gmail search "from:boss newer_than:7d"
void gmail thread <id>

# Drafts only — void never sends email directly
void gmail draft create --reply-to <id> --subject "Re: Q3" --body "LGTM, approved."

# Archive in Gmail by removing the INBOX label, in bulk
void gmail batch-modify <id1> <id2> --remove INBOX

Calendar

Docs: commands

void calendar                       # today
void calendar week                  # this week
void calendar --day tomorrow
void calendar create --title "1:1 Alice" --start "2026-06-16T14:00" --meet   # ends +30min by default
void calendar availability --attendees alice@x.com,bob@x.com --from 2026-06-15T09:00 --to 2026-06-15T18:00
void calendar respond <id> --status accepted

Hacker News

Keyword-watched stories land in your inbox like any other message:

void hn keywords add "rust,local-first"
void hn min-score 100

Reddit

Keyword- and score-filtered posts from watched subreddits land in your inbox like any other message. Enable commenting during void setup to sync thread comments and reply from the CLI (browser OAuth, stores refresh_token).

void reddit subreddits add "rust,programming"
void reddit keywords add "ai,llm"
void reddit min-score 50
void reddit config
void reply <message-id> --message "Thanks!"

Google News

Keyword-watched articles from the public Google News RSS feed land in your inbox — one search per keyword, filtered by recency:

void gn keywords add "intelligence artificielle,startup"
void gn when 7d          # only articles from the last 7 days
void gn language fr      # hl parameter
void gn country FR       # gl parameter

Automation with hooks

Hooks run an AI agent on new messages or cron schedules — and since the agent can call void itself, it can triage, draft, and notify on your behalf. Docs: Hooks

# Get pinged on Telegram when an important email lands
void hook create --name email-triage --trigger new_message --connector gmail \
  --prompt 'New email: {message}. If important and actionable, send me a one-line summary on Telegram (chat "Notes") via void send. Otherwise do nothing.'

# Weekday-morning digest
void hook create --name digest --trigger schedule --cron "0 8 * * mon-fri" \
  --prompt-file ~/.config/void/prompts/digest.md --max-turns 10

How it works

A background daemon keeps a local SQLite database in sync with every connected service. Read commands hit the local database — instant, offline-capable. Write commands call the service APIs directly.

            reads (instant, offline)          writes (direct API)
  void ◄──────────► SQLite (FTS5) ◄────── sync daemon ──────► services
                                              │
        WhatsApp │ Telegram │ Slack ──── push (WebSocket / MTProto)
        Gmail │ Calendar │ LinkedIn │ GitHub │ HN │ Google News │ Reddit ──── polling
Crate Role
void-core Config, database, models, hooks, Connector trait, sync engine
void-cli The void binary: clap commands, output formatting
void-slack, void-gmail, void-calendar, void-whatsapp, void-telegram, void-hackernews, void-googlenews, void-linkedin, void-github, void-reddit One crate per connector

All data stays on your machine in ~/.local/share/void — no external database, no Docker, no cloud. Layout details: Configuration.

Two ways to run it

Local mode (default) Remote mode
Where sync runs your machine an always-on server
Setup nothing beyond void setup one server + a 4-line client config
When your laptop is off sync and hooks pause sync and hooks keep running 24/7
Multiple machines one database per machine any laptop, over plain SSH

Local mode is the zero-infrastructure default: daemon, database, and credentials all live on your machine. The only catch is that sync follows your laptop — closed lid means a stale inbox and silent hooks until it wakes.

Remote mode moves the daemon (and your credentials) to a home server or VPS. Your laptop keeps a cached snapshot for instant, offline-capable reads, and proxies writes to the server over plain SSH — no extra service, no open ports beyond SSH.

Details, trade-offs, and migration: Deployment modes · config reference: Remote store

Documentation

Development

./scripts/check.sh       # fmt + clippy + tests, same as CI
cargo build --release

Contributions welcome — read CONTRIBUTING.md, and Adding a connector is the best place to start. Security reports: SECURITY.md. Release notes: CHANGELOG.md.

License

Copyright (C) 2026 Maxime Gaudin

Free software under the GNU Affero General Public License v3.0. See LICENSE for the full text.

About

One inbox for everything — unified CLI for WhatsApp, Telegram, Slack, Gmail, Calendar, Drive, LinkedIn & Hacker News. Local-first, agent-ready.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages