beeperbox
Plug your AI agent into 50+ messengers (WhatsApp, iMessage, Signal, Telegram, Slack…) through one MCP endpoint. Two modes: a self-contained Docker container (headless Beeper bundled) or a lite npx MCP layer pointed at the Beeper you already run.
Links
README
From the repo.
╭──────────────────────────────────╮
│ ╔╗ ╔═╗╔═╗╔═╗╔═╗╦═╗╔╗ ╔═╗ ╦ ╦ │
│ ╠╩╗╠╣ ╠╣ ╠═╝╠╣ ╠╦╝╠╩╗║ ║ ╚╦╝ │
│ ╚═╝╚═╝╚═╝╩ ╚═╝╩╚═╚═╝╚═╝ ╩ ╩ │
│ one agent ──→ 50+ messengers │
╰──────────────────────────────────╯
Plug your AI agent into 50+ messengers through a single MCP endpoint — in Docker, or as a one-line npx.
WhatsApp, iMessage, Signal, Telegram, Discord, Slack, Messenger, Instagram, LinkedIn, Google Messages, Matrix — everything Beeper bridges, reachable from one HTTP or MCP endpoint instead of 50 per-platform SDKs, OAuth dances, and rate-limit quirks. If you only need Telegram, this is overkill — use openclaw or any BotFather library. If you need reach across many networks from one agent, keep reading.
Two ways to run
Same MCP server, same 12 tools, same serverInfo.version — by construction, because both modes run the same single file. Pick by where Beeper lives:
| Container | Lite (npx) | |
|---|---|---|
| Beeper Desktop | bundled, headless, in Docker | you supply it (already open on your machine) |
| Needs | Docker + compose | just Node 18+ |
| Start | docker compose up -d | npx beeperbox |
| Best for | always-on, VPS, headless | laptop users with Beeper already running |
| First-run login | noVNC at :6080 | already done in your local Beeper |
The container is the full appliance (headless Beeper + raw API + MCP). Lite mode is just the MCP verb layer pointed at a Beeper you already run — no Docker, no Electron, no Xvfb. New in v0.8.0.
Quick start (container)
Prereqs: Docker + compose plugin, ~1 GB disk, ~600 MB RAM, a Beeper account.
1. Pull and run
curl -LO https://raw.githubusercontent.com/hamr0/beeperbox/master/docker-compose.yml
docker compose up -d
Pulls the pre-built multi-arch image (ghcr.io/hamr0/beeperbox:latest, linux/amd64 + linux/arm64). No clone, no build. Pin a version with BEEPERBOX_IMAGE_TAG=0.8.0 docker compose up -d, or track master with :edge (may break).
2. Log in once
Open http://localhost:6080/vnc.html, sign into Beeper, then Settings → Developers → enable the API and create an access token. Save it:
echo "BEEPER_TOKEN=abc123..." > .env
docker compose up -d
Login and bridge state persist in a named volume — you won't log in again after restarts, and docker restart recovers cleanly (the entrypoint clears the stale display lock that used to wedge a restarted container).
3. Talk to it
# Raw Beeper Desktop API
curl -H "Authorization: Bearer $BEEPER_TOKEN" http://localhost:23373/v1/info
# MCP server (HTTP transport)
curl -X POST http://localhost:23375 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
For stdio MCP, point any MCP client at docker exec -i beeperbox node /opt/mcp/server.js --stdio. Works with Claude Code, Cursor, Cline, Continue, bareagent, or anything that speaks Model Context Protocol.
Done.
Ports
| Host | Purpose | Bound to |
|---|---|---|
6080 | noVNC web UI — first-run login only | 127.0.0.1 |
23373 | Raw Beeper Desktop HTTP API | 127.0.0.1 |
23375 | Opinionated 12-tool MCP server | 127.0.0.1 |
All three are env-overridable (BEEPERBOX_NOVNC_PORT, BEEPERBOX_HOST_PORT, BEEPERBOX_MCP_PORT) so you can run multiple instances on one VPS. For remote access use SSH tunnel, Tailscale, or a TLS reverse proxy — never drop the 127.0.0.1 prefix.
Lite mode (npx)
Lite mode runs only the MCP verb server against a Beeper Desktop you already run locally — no Docker, no Electron, no Xvfb. It's the same single file the container runs, so the tool surface and serverInfo.version are identical by construction.
Prereqs: Beeper Desktop running locally, with the Developer API enabled — Settings → Developers → enable the API and create an access token (the same token the container uses).
Run it:
BEEPER_TOKEN=your-token-here npx beeperbox
MCP HTTP server comes up on http://127.0.0.1:23375, pointed at the local Beeper API on http://127.0.0.1:23373. On boot it logs a one-line reachability verdict so a bad token or unreachable API is obvious immediately:
[beeperbox-mcp] preflight OK: http://127.0.0.1:23373 reachable, token accepted, 4 account(s)
For stdio transport (Claude Code, Cursor, Cline, Continue, bareagent), add --stdio:
BEEPER_TOKEN=your-token-here npx beeperbox --stdio
Env contract:
| Env | Meaning | Default |
|---|---|---|
BEEPER_API | Local Beeper Desktop API base | http://127.0.0.1:23373 |
BEEPER_TOKEN | Beeper dev token (Settings → Developers) | — (required) |
MCP_PORT | MCP HTTP port | 23375 |
MCP_AUTH_TOKEN | Optional bearer guard on the MCP endpoint | unset (open on loopback) |
MCP_ALLOWED_HOSTS | Host/Origin allowlist | localhost,127.0.0.1,::1 |
MCP_BIND_ADDR | Interface the MCP server binds | 127.0.0.1 (loopback) |
Security: lite mode binds loopback only (127.0.0.1) by default, so it's safe with no auth — only processes on your machine (your agent, Claude Code) can reach it. Do not just flip it to 0.0.0.0: a same-network attacker can spoof the Host header past the allowlist and reach the full tool surface (read every message, send across every network) unauthenticated. To expose it deliberately, set MCP_BIND_ADDR=0.0.0.0 and MCP_AUTH_TOKEN, and front it with a tunnel (SSH / Tailscale / TLS reverse proxy) — never raw on a public interface. (The container binds 0.0.0.0 on purpose because Docker publishes it on 127.0.0.1 — that loopback publish is its boundary; lite mode has no such layer, which is why its bind is loopback.)
Supervision: no Docker restart policy here — for an always-on lite setup, run it under systemd or pm2.
What lite mode is not: it does not bundle or headless-run Beeper (that's the container's job). No new verbs, no transport changes — it's the same server, packaged and safe to run standalone.
The MCP
Not a thin proxy over Beeper's raw API — an opinionated 12-tool verb layer built for an LLM to drive. Every tool returns one normalized Chat / Message schema (so the agent never learns a second shape), propagates chat_id + network onto every message (no second lookup to know where a hit came from), and is documented in-schema for the model. Reach across all 50+ networks; the agent never knows which bridge it's talking to.
Read / triage
| Tool | What it does |
|---|---|
list_accounts | Which networks are connected (WhatsApp, Telegram, Discord …) — slug + label + connection status + display name |
list_inbox | Most recently active chats, with unread counts and last-activity time |
list_unread | The "what needs me right now?" view — only chats with unread_count > 0 |
get_chat | One chat's current metadata by ID |
read_chat | Recent messages of a chat, chronological, normalized |
search_messages | Full-text search across every chat |
Write / act
| Tool | What it does |
|---|---|
send_message | The headline write — reply or initiate; markdown, reply_to_message_id, returns the new message ID |
note_to_self | The agent's private command/control channel — recorded, excluded from every inbox view |
react_to_message | Lightest "I saw it" — a unicode emoji, visible to the sender on every network |
archive_chat | The "done with this conversation" primitive (Beeper exposes no mark-as-read) |
Watch / reach — the last two releases
| Tool | What it does |
|---|---|
poll_messages | Read-only watch primitive: "what arrived since this cursor?" Seed once, persist the opaque cursor, poll with zero side effects. The cursor is restart-safe — survives a container/process restart with no missed or duplicated messages. Each message carries a source field ("api" for beeperbox's own sends, "external" otherwise) so a poll loop never answers itself. (v0.6.0) |
download_asset | The MCP-only way to reach attachment bytes (base64). Every Message now carries attachments[] ({type, file_name, mime_type, src_url, size, is_voice_note}); fetch by src_url or by chat_id+message_id. Byte-capped and timeout-bounded; a defense-in-depth guard refuses file:// paths outside Beeper's media cache. (v0.7.0) |
Reliable echo-suppression (source + the optional client_tag idempotency tag) means an agent on a poll loop can send and watch the same chat without mistaking its own messages for inbound — the wiring that lets multis drop its text-prefix hacks.
Build from source
Only if you're hacking on the image itself or running air-gapped:
git clone https://github.com/hamr0/beeperbox.git && cd beeperbox
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build
Docs
- docs/GUIDE.md — human walkthrough: first-run login, multi-instance VPS pattern, read-only vs read-write tokens, troubleshooting
- beeperbox.context.md — drop-in integration guide for AI assistants: MCP tools, schemas, wiring snippets for Claude Code / Cursor / Cline / bareagent, error codes
- CHANGELOG.md — version history and versioning policy. tl;dr MINOR = new runtime behavior (new MCP tool, new architecture, new transport), PATCH = bug fixes + packaging + docs.
MAJORheld at0until the MCP tool set and HTTP API are declared stable.
The bare ecosystem
Local-first, composable agent infrastructure. Same API patterns throughout — mix and match, each module works standalone.
Core — the brain, the gate, the memory.
- bareagent — the think→act→observe loop. Goal in → coordinated actions out. Replaces LangChain, CrewAI, AutoGen.
- bareguard — the single gate every action passes through. Action in → allow / deny / ask-a-human out. Replaces hand-rolled allowlists and scattered policy code.
- litectx — tree-sitter code + memory graph with activation decay, plus lightweight context engineering (write · select · compress · isolate). Query in → ranked context out.
Optional reach — give the agent hands.
- barebrowse — a real browser for agents. URL in → pruned snapshot out. Replaces Playwright, Selenium, Puppeteer.
- baremobile — Android + iOS device control. Screen in → pruned snapshot out. Replaces Appium, Espresso, XCUITest.
- beeperbox — 50+ messaging networks via one MCP server (headless Beeper Desktop in Docker). Chat in → unified message stream out. Replaces Twilio, per-platform bot APIs.
License
Apache-2.0. Independent wrapper around Beeper Desktop, no affiliation with Beeper / Automattic.
Related
- Beeper Desktop — upstream app this containerizes
- Beeper Desktop API — official API reference
- bareagent — lightweight agent orchestration that consumes beeperbox via MCP
- multis — personal-assistant project that drove beeperbox's extraction
Collected info
- ★ 27 stars
- ⎇ 2 forks
- Language: JavaScript
- Source updated: 9/20/2026
Config for your environment
Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.
Tool
OS
Config file: ~/.cursor/mcp.json
{
"mcpServers": {
"mcp-server": {
"url": "{MCP_ENDPOINT_URL}"
}
}
}Paste into mcpServers in the config file. Restart Cursor after saving.
If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.