An open-source Google Messages client with MCP support. Read and send SMS/RCS from Claude Code, a web UI, or any MCP-compatible tool.
Built on mautrix/gmessages (libgm) for the Google Messages protocol and mcp-go for the MCP server.
- Go 1.22+ (install)
- Google Messages on your Android phone
git clone https://github.com/MaxGhenis/openmessage.git
cd openmessage
go build -o openmessage ../openmessage pairBy default, a QR code appears in your terminal. On your phone, open Google Messages > Settings > Device pairing > Pair a device and scan it. The session saves to ~/.local/share/openmessage/session.json.
If Google only offers account pairing, you can also pair with Google account cookies copied from browser devtools:
pbpaste | ./openmessage pair --googleThe CLI accepts either a JSON cookie object or a full curl command for messages.google.com/web/config, then prompts you to confirm an emoji on your phone.
./openmessage serveThis starts both:
- Web UI at http://127.0.0.1:7007
- MCP SSE endpoint at
http://127.0.0.1:7007/mcp/sse
When serve is launched by an MCP client over pipes, it also serves MCP on stdio automatically.
Add to ~/.mcp.json:
{
"mcpServers": {
"openmessage": {
"command": "/path/to/openmessage",
"args": ["serve"]
}
}
}Restart Claude Code. The MCP tools appear automatically.
- Read messages — full conversation history, search, media
- Send messages — SMS and RCS, including replies
- Live WhatsApp sync — pair a local WhatsApp companion device from the web UI for live inbound messages, typing indicators, and text replies
- React to messages — emoji reactions on any message
- Image/media display — inline images with fullscreen viewer
- Web UI — real-time conversation view at localhost:7007
- MCP tools — conversation lookup, direct replies, media download, import helpers, and story/viz tools for Claude Code integration
- Local storage — SQLite database, your data stays on your machine
| Tool | Description |
|---|---|
get_messages |
Recent messages with filters (phone, date range, limit) |
get_conversation |
Messages in a specific conversation |
search_messages |
Full-text search across all messages |
send_message |
Send SMS/RCS to a phone number |
send_to_conversation |
Send a text reply directly to an existing conversation ID |
list_conversations |
List recent conversations |
list_contacts |
List/search contacts |
get_status |
Connection status and paired phone info |
The web UI runs at http://localhost:7007 when the server is started. It provides:
- Conversation list with search
- Message view with images, reactions, and reply threads
- Compose and send messages
- WhatsApp live-pairing control from the
WAbutton in the sidebar - React to messages (right-click)
- Reply to messages (double-click)
| Env var | Default | Purpose |
|---|---|---|
OPENMESSAGES_DATA_DIR |
~/.local/share/openmessage |
Data directory (DB + session) |
OPENMESSAGES_LOG_LEVEL |
info |
Log level (debug/info/warn/error/trace) |
OPENMESSAGES_PORT |
7007 |
Web UI port |
OPENMESSAGES_HOST |
127.0.0.1 |
Host/interface to bind the local web server to |
OPENMESSAGES_MY_NAME |
system user name | Display name for outgoing imported iMessage/WhatsApp messages |
OPENMESSAGES_STARTUP_BACKFILL |
auto |
Startup history sync mode: auto, shallow, deep, or off |
OPENMESSAGES_MACOS_NOTIFICATIONS |
interactive macOS serve sessions only |
Enable/disable native macOS notifications for fresh inbound live messages (1/0). Click-through opens the matching thread when terminal-notifier is available. |
- libgm handles the Google Messages protocol (pairing, encryption, long-polling)
- whatsmeow handles optional live WhatsApp pairing, text sending, and sync through a separate local session store
- SQLite (WAL mode, pure Go) stores messages, conversations, and contacts locally
- Real-time events from the phone are written to SQLite as they arrive
- WhatsApp Desktop import remains as a fallback when the live bridge is not active
- On first run, a deep backfill fetches full SMS/RCS history in the background; later runs do a lighter incremental sync by default
- MCP tool handlers read from SQLite for queries, call libgm for sends
- Auth tokens auto-refresh and persist to
session.json
go test ./... # Run all tests
go build . # Build binary
npm install # Install Playwright test runner
npx playwright install chromium
npm run test:e2e # Run browser-level web UI tests
./openmessage pair # Pair with phone
./openmessage serve # Start serverMIT