Skip to content

v0.2.0: HTTP transport mode

Choose a tag to compare

@zach-source zach-source released this 25 Jul 06:18
· 32 commits to main since this release
v0.2.0
4e95661

HTTP transport mode + local-database bd mode

Adds a way to run this MCP server as a standalone, network-reachable service, in addition to its existing stdio mode (which is unchanged by default, zero config required).

New environment variables

  • MAILBOX_TRANSPORTstdio (default, unchanged) or http
  • MAILBOX_HTTP_HOST / MAILBOX_HTTP_PORT — bind address for HTTP mode (default 127.0.0.1:8000)
  • MAILBOX_GLOBAL1/true (default, unchanged: routes bd at the shared beads_global DB via --global) or 0/false/no (omits --global, so bd resolves a plain local project database under WORKSPACE via its default embedded engine)

Intended use case

Hosting one authoritative mailbox instance in a remote pod, backed by its own dedicated local database rather than the shared machine-wide one, reachable:

  • from a Claude Code session on a different machine, as an http-type MCP server entry
  • from a plain Python daemon (not a Claude session) as a regular MCP HTTP client

See the README's new "HTTP mode" section for the full env var table and a runnable example.

Known limitation

Proactive <channel> push notifications (peer DMs/requests/broadcasts interrupting a session) are best-effort and single-client only in HTTP mode. FastMCP's streamable-HTTP transport does give each connection its own session, but this server's per-session state (_State in server.py) is still a single process-global instance, so channel push only ever reaches whichever HTTP connection first captures a session — never a specific caller among several concurrent ones. Documented in channel.py and the README; pull-based tools (poll_inbox, read_channel) are unaffected and work correctly for every caller.

Testing

  • Existing stdio + global-mode test suite passes unchanged (32 passed, 1 skipped)
  • New tests/test_bd.py covers run_bd's argv with/without MAILBOX_GLOBAL, mocked at the subprocess.run seam
  • New tests/test_transport.py covers main()'s stdio/http dispatch, mocked at the mcp.run seam
  • Manually verified both bd init modes in a scratch directory (shared-server vs. plain embedded local DB), and a live HTTP smoke test: booted the server with MAILBOX_TRANSPORT=http + MAILBOX_GLOBAL=0 against a fresh local db and completed a real MCP initialize handshake over HTTP