Skip to main content

Installation

msgbrowse installs with a single go install. The SQLite driver is pure Go (with FTS5 built in), so CGO_ENABLED=0 is the normal build — there is no C toolchain, no build tag, and no shared library to set up.

Install the binary​

Requires Go 1.25+ and nothing else:

go install github.com/joestump/msgbrowse/cmd/msgbrowse@latest

The binary lands in $(go env GOBIN) (or $(go env GOPATH)/bin) — make sure that directory is on your PATH:

export PATH="$PATH:$(go env GOPATH)/bin"
msgbrowse version

Install the exporters​

msgbrowse reads archives produced by three upstream tools. Install whichever sources you have — any subset (Signal-only, iMessage-only, …) works fine.

Signal — signal-export, installed with pipx:

pipx install signal-export
tip

The pip package is signal-export, but the console command it installs is sigexport — that is the binary msgbrowse export looks up on your PATH.

iMessage — imessage-exporter, installed with Homebrew on macOS:

brew install imessage-exporter

WhatsApp — whatsapp-chat-exporter, installed with pipx (the console command is wtsexporter):

pipx install whatsapp-chat-exporter

msgbrowse never auto-installs these tools and never touches the sensitive sources (the Signal database, the macOS Keychain, chat.db, ChatStorage.sqlite) itself — it only spawns your own, already-installed exporters at your explicit request.

Alternative: Docker​

Prefer containers? The repo ships a Dockerfile and a compose stack — the image is a fully static binary on a distroless base, running non-root with a read-only root filesystem and all capabilities dropped.

git clone https://github.com/joestump/msgbrowse.git
cd msgbrowse
cp .env.example .env
# edit .env:
# MSGBROWSE_ARCHIVE_HOST → your archive's absolute path
# MSGBROWSE_LLM_BASE_URL → your LiteLLM proxy (…/v1), MSGBROWSE_LLM_API_KEY → its key

make up # build + start msgbrowse (points at your external LiteLLM)
make signal-import # import the signal-export archive into the local DB
make embed # compute embeddings for semantic search (optional)
# open http://127.0.0.1:8787

make logs tails the server; make down stops the stack. The archive is mounted read-only (:ro), app data lives in a named volume, and the UI is published to host loopback only.

tip

No LLM proxy yet? Run the bundled, fully local LiteLLM with make up-bundled and set MSGBROWSE_LLM_BASE_URL=http://litellm:4000/v1. Until an endpoint is reachable, embed and the journal fail — browsing and keyword search work without any LLM.

About the LLM endpoint​

msgbrowse only ever talks to your own OpenAI-compatible endpoint — configure it with MSGBROWSE_LLM_BASE_URL (a …/v1 URL) and MSGBROWSE_LLM_API_KEY via env, config.yaml, or flags (see the configuration reference for all keys and their precedence). The default is a local proxy at http://127.0.0.1:4000/v1. This endpoint is the only network egress in the entire application, and it is optional: everything except embed, facts, semantic search, and the journal works without it. The security model documents exactly what is sent to it.

Next step​

With the binary and exporters installed, produce your first archives: Exporting your archives.