beeperbox 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +45 -11
  2. package/package.json +2 -2
  3. package/server.js +20 -6
package/README.md CHANGED
@@ -1,18 +1,28 @@
1
- # beeperbox (lite mode)
1
+ ```
2
+ ╭──────────────────────────────────╮
3
+ │ ╔╗ ╔═╗╔═╗╔═╗╔═╗╦═╗╔╗ ╔═╗ ╦ ╦ │
4
+ │ ╠╩╗╠╣ ╠╣ ╠═╝╠╣ ╠╦╝╠╩╗║ ║ ╚╦╝ │
5
+ │ ╚═╝╚═╝╚═╝╩ ╚═╝╩╚═╚═╝╚═╝ ╩ ╩ │
6
+ │ one agent ──→ 50+ messengers │
7
+ ╰──────────────────────────────────╯
8
+ ```
9
+
10
+ <p align="center">
11
+ <a href="https://www.npmjs.com/package/beeperbox"><img src="https://img.shields.io/npm/v/beeperbox?label=npm&color=2a4f8c" alt="npm version"></a>
12
+ <a href="https://github.com/hamr0/beeperbox"><img src="https://img.shields.io/badge/source-github-2a4f8c" alt="source on GitHub"></a>
13
+ <img src="https://img.shields.io/badge/license-Apache%202.0-2a4f8c" alt="license: Apache 2.0">
14
+ </p>
2
15
 
3
16
  **Run beeperbox's MCP verb server against a Beeper Desktop you already have open — no Docker, no Electron, no Xvfb.**
4
17
 
5
18
  This is the *lite* half of [beeperbox](https://github.com/hamr0/beeperbox). The full project ships a Docker image with a headless Beeper Desktop inside; lite mode is the same single-file, zero-dependency MCP server pointed at a Beeper Desktop **you** run on your laptop. Identical verb surface, identical version — you just supply Beeper.
6
19
 
7
- - **Always-on / VPS / no local Beeper?** Use the [Docker image](https://github.com/hamr0/beeperbox#quick-start).
20
+ - **Always-on / VPS / no local Beeper?** Use the [Docker image](https://github.com/hamr0/beeperbox#quick-start-container).
8
21
  - **Beeper already open on your machine?** Use this.
9
22
 
10
- ## Prerequisites
23
+ ## Quick start
11
24
 
12
- 1. **Beeper Desktop** running locally.
13
- 2. **Developer API enabled:** Beeper → **Settings → Developers** → enable the API and create an access token (the same token the container uses).
14
-
15
- ## Run
25
+ **Prereqs:** Beeper Desktop running locally, with the Developer API enabled — Beeper → **Settings → Developers** → enable the API and create an access token (the same token the container uses).
16
26
 
17
27
  ```sh
18
28
  BEEPER_TOKEN=your-token-here npx beeperbox
@@ -20,12 +30,22 @@ BEEPER_TOKEN=your-token-here npx beeperbox
20
30
 
21
31
  That starts the MCP HTTP server on `http://127.0.0.1:23375`, pointed at the local Beeper Desktop API on `http://127.0.0.1:23373`. On boot it logs a one-line reachability verdict (`preflight OK: … N account(s)` or `preflight FAIL: …`) so a misconfigured token or API is obvious immediately.
22
32
 
23
- For stdio transport (Claude Code, Cursor, Cline, Continue, bareagent):
33
+ For stdio transport (Claude Code, Cursor, Cline, Continue, [bareagent](https://npmjs.com/package/bare-agent)):
24
34
 
25
35
  ```sh
26
36
  BEEPER_TOKEN=your-token-here npx beeperbox --stdio
27
37
  ```
28
38
 
39
+ ## The 12 tools
40
+
41
+ One opinionated MCP verb layer over Beeper — every tool returns a normalized `Chat` / `Message` schema, propagates `chat_id` + `network` onto every message, and is documented in-schema for the model. Reach across all 50+ networks without knowing which bridge you're talking to.
42
+
43
+ - **Read / triage** — `list_accounts` · `list_inbox` · `list_unread` · `get_chat` · `read_chat` · `search_messages`
44
+ - **Write / act** — `send_message` · `note_to_self` · `react_to_message` · `archive_chat`
45
+ - **Watch / reach** — `poll_messages` (read-only watch primitive, restart-safe cursor, `source` echo-guard) · `download_asset` (attachment bytes; every message carries `attachments[]`)
46
+
47
+ Full schemas and usage in the [main README](https://github.com/hamr0/beeperbox#the-mcp).
48
+
29
49
  ## Config
30
50
 
31
51
  | Env | Meaning | Default |
@@ -35,15 +55,29 @@ BEEPER_TOKEN=your-token-here npx beeperbox --stdio
35
55
  | `MCP_PORT` | MCP HTTP port | `23375` |
36
56
  | `MCP_AUTH_TOKEN` | Optional bearer guard on the MCP endpoint | unset (open on loopback) |
37
57
  | `MCP_ALLOWED_HOSTS` | Host/Origin allowlist | `localhost,127.0.0.1,::1` |
58
+ | `MCP_BIND_ADDR` | Interface the MCP server binds | `127.0.0.1` (loopback) |
38
59
 
39
60
  ## Security
40
61
 
41
- The server binds `0.0.0.0` but is meant to stay loopback-only: it's safe on `127.0.0.1` with no auth. To expose it beyond your machine, set `MCP_AUTH_TOKEN` **and** `MCP_ALLOWED_HOSTS`, and put it behind a tunnel (SSH / Tailscale / TLS reverse proxy) — never raw on a public interface.
62
+ The server binds **loopback only** (`127.0.0.1`) by default, so it's safe with no auth — only processes on your own machine can reach it. Don't just set 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 put it behind a tunnel (SSH / Tailscale / TLS reverse proxy) — never raw on a public interface.
42
63
 
43
64
  ## Supervision
44
65
 
45
66
  There's no Docker restart policy in lite mode. For an always-on setup, run it under `systemd` or `pm2`.
46
67
 
47
- See the [full README](https://github.com/hamr0/beeperbox#lite-mode) and [docs/GUIDE.md](https://github.com/hamr0/beeperbox/blob/master/docs/GUIDE.md) for the complete tool reference and the container build.
68
+ See the [full README](https://github.com/hamr0/beeperbox#the-mcp) and [docs/GUIDE.md](https://github.com/hamr0/beeperbox/blob/master/docs/GUIDE.md) for the complete tool reference and the container build.
69
+
70
+ ## The bare ecosystem
71
+
72
+ Local-first, composable agent infrastructure. Same API patterns throughout — mix and match, each module works standalone.
73
+
74
+ - **[bareagent](https://npmjs.com/package/bare-agent)** — the think→act→observe loop. *Goal in → coordinated actions out.*
75
+ - **[bareguard](https://npmjs.com/package/bareguard)** — the single gate every action passes through. *Action in → allow / deny / ask-a-human out.*
76
+ - **[litectx](https://npmjs.com/package/litectx)** — code + memory graph with activation decay. *Query in → ranked context out.*
77
+ - **[barebrowse](https://npmjs.com/package/barebrowse)** — a real browser for agents. *URL in → pruned snapshot out.*
78
+ - **[baremobile](https://npmjs.com/package/baremobile)** — Android + iOS device control. *Screen in → pruned snapshot out.*
79
+ - **beeperbox** *(this)* — 50+ messaging networks via one MCP server. *Chat in → unified message stream out.*
80
+
81
+ ## License
48
82
 
49
- [Apache-2.0](https://github.com/hamr0/beeperbox/blob/master/LICENSE)
83
+ [Apache-2.0](https://github.com/hamr0/beeperbox/blob/master/LICENSE). Independent wrapper around Beeper Desktop, no affiliation with Beeper / Automattic.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beeperbox",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "Lite mode for beeperbox — the opinionated MCP verb server for Beeper Desktop, run standalone against a Beeper you already have open (no Docker, no Electron). The full headless-Beeper-in-Docker build lives at github.com/hamr0/beeperbox.",
5
5
  "bin": {
6
6
  "beeperbox": "server.js"
@@ -34,7 +34,7 @@
34
34
  "url": "git+https://github.com/hamr0/beeperbox.git",
35
35
  "directory": "mcp"
36
36
  },
37
- "homepage": "https://github.com/hamr0/beeperbox#lite-mode",
37
+ "homepage": "https://github.com/hamr0/beeperbox#lite-mode-npx",
38
38
  "bugs": "https://github.com/hamr0/beeperbox/issues",
39
39
  "author": "hamr0",
40
40
  "license": "Apache-2.0"
package/server.js CHANGED
@@ -22,6 +22,18 @@ const PORT = parseInt(process.env.MCP_PORT || '23375', 10);
22
22
  const BEEPER_API = process.env.BEEPER_API || 'http://127.0.0.1:23373';
23
23
  const BEEPER_TOKEN = process.env.BEEPER_TOKEN || '';
24
24
 
25
+ // Bind address. Defaults to LOOPBACK (127.0.0.1) — the safe default for lite
26
+ // mode (`npx beeperbox` on a laptop), where the process listens directly on the
27
+ // host with no Docker loopback publish in front of it. Binding 0.0.0.0 there
28
+ // would put the full tool surface (read every message, send across every
29
+ // network) on the LAN, reachable unauthenticated by anyone who can spoof the
30
+ // `Host` header — a non-browser attacker trivially can. The container needs
31
+ // 0.0.0.0 (a Docker published port can't reach a loopback-bound process) and
32
+ // sets MCP_BIND_ADDR=0.0.0.0 via the image ENV; there the loopback *publish*
33
+ // (`127.0.0.1:23375:23375`), not the bind, is the boundary. To expose lite mode
34
+ // deliberately, set MCP_BIND_ADDR=0.0.0.0 AND MCP_AUTH_TOKEN AND a tunnel.
35
+ const BIND_ADDR = process.env.MCP_BIND_ADDR || '127.0.0.1';
36
+
25
37
  // ─── http transport hardening ─────────────────────────────────────
26
38
  // The HTTP transport is the network-exposed surface (stdio is local-only).
27
39
  // Three guards, all configurable so they don't break the documented
@@ -34,10 +46,11 @@ const BEEPER_TOKEN = process.env.BEEPER_TOKEN || '';
34
46
  // Defaults to loopback; set it for reverse proxies.
35
47
  // MCP_MAX_BODY — max request body bytes (default 1 MiB) so a large
36
48
  // POST can't grow the in-memory buffer unbounded.
37
- // The listener stays bound to 0.0.0.0 ON PURPOSE: a Docker published port
38
- // is unreachable if the in-container process binds 127.0.0.1, so loopback
39
- // binding here would break `127.0.0.1:23375:23375`. Auth + Host/Origin
40
- // checks are the defense, not the bind address.
49
+ // The bind address is MCP_BIND_ADDR (see above): loopback by default (safe for
50
+ // lite mode), 0.0.0.0 in the container (where the loopback PUBLISH is the
51
+ // boundary). In the container, Auth + Host/Origin are the in-container defense;
52
+ // in lite mode the loopback BIND is, because a non-browser client can spoof the
53
+ // Host header past the allowlist.
41
54
  const MCP_AUTH_TOKEN = process.env.MCP_AUTH_TOKEN || '';
42
55
  const MCP_ALLOWED_HOSTS = new Set(
43
56
  (process.env.MCP_ALLOWED_HOSTS || 'localhost,127.0.0.1,::1,[::1]')
@@ -1217,8 +1230,8 @@ function startHttpTransport() {
1217
1230
  });
1218
1231
  });
1219
1232
 
1220
- server.listen(PORT, '0.0.0.0', () => {
1221
- console.log(`[beeperbox-mcp] listening on http://0.0.0.0:${PORT}`);
1233
+ server.listen(PORT, BIND_ADDR, () => {
1234
+ console.log(`[beeperbox-mcp] listening on http://${BIND_ADDR}:${PORT}${BIND_ADDR === '0.0.0.0' ? ' (all interfaces — rely on a loopback publish or set MCP_AUTH_TOKEN)' : ' (loopback only)'}`);
1222
1235
  console.log(`[beeperbox-mcp] beeper api: ${BEEPER_API}`);
1223
1236
  console.log(`[beeperbox-mcp] beeper token: ${BEEPER_TOKEN ? 'set' : 'NOT SET (set BEEPER_TOKEN env var)'}`);
1224
1237
  console.log(`[beeperbox-mcp] http auth: ${MCP_AUTH_TOKEN ? 'required (MCP_AUTH_TOKEN set)' : 'OPEN — set MCP_AUTH_TOKEN to require a bearer token'}`);
@@ -1288,6 +1301,7 @@ module.exports = {
1288
1301
  // version + tool names here is what guarantees the two builds can't drift.
1289
1302
  VERSION,
1290
1303
  TOOL_NAMES: TOOLS.map((t) => t.name),
1304
+ BIND_ADDR,
1291
1305
  ledgerPath,
1292
1306
  encodeCursor,
1293
1307
  decodeCursor,