LABSCO SUMMARY
Your mail is indexed on your laptop, and the search model runs there too.
Mail and calendar land in a local LanceDB and the embedding model runs in-process, so a search never leaves the machine — the tradeoff is memory: the model uses roughly 500MB-1GB while it is actively embedding. Both a CLI skill and the MCP server front the same index; the skill is faster, the MCP server is what other clients can talk to.
What it is
A Rust daemon that syncs Gmail over IMAP and Google Calendar over CalDAV into a local LanceDB index, plus groundeffect-mcp, the server that exposes the email and calendar tools to your client.
What you get
- Hybrid mail search — BM25 full text and vector similarity, fused with Reciprocal Rank Fusion
- Embeddings computed locally with nomic-embed-text-v1.5 through Candle and Metal acceleration, or via OpenRouter if you prefer
- Calendar answers that need no search query — events in a date range, defaulting to the next 7 days
- Sending mail, drafts, threads, attachments and IMAP folders, across as many Gmail accounts as you connect
- Live sync — IMAP IDLE for instant mail, CalDAV polling for calendar
- HTML mail converted to clean plain text before it is indexed
Requirements
brew tap jamiequint/groundeffect && brew install groundeffect, which installs the daemon and starts it at login. You supply your own Google OAuth client — GROUNDEFFECT_GOOGLE_CLIENT_ID and GROUNDEFFECT_GOOGLE_CLIENT_SECRET, with the Gmail API and Google Calendar API enabled — then run groundeffect account add and authorise in the browser. Tokens are stored encrypted under ~/.config/groundeffect/tokens/.
Setup effort
Follow the published steps — brew tap jamiequint/groundeffect
USE CASES
01
Finding the thread you half-remember
Search by meaning and by keyword at once, filtered by sender, recipient, date range or whether there was an attachment.
02
Answering "what's on my calendar tomorrow"
List events over a date range directly — no search query needed, up to 200 results.
03
Drafting a reply in the same place you found the thread
Read the thread, then compose — preview by default, sent only when you confirm, or saved as a draft.
04
Keeping several accounts separate but searchable together
Connect each Gmail account with its own sync window and alias, then search across all of them or filter to one.
BEFORE YOU INSTALL
What to know first
Requires
- groundeffect-mcp on PATH
- GROUNDEFFECT_GOOGLE_CLIENT_ID in your environment
- GROUNDEFFECT_GOOGLE_CLIENT_SECRET in your environment
Where it runs
The documented client runs the server on your machine.
INSTALLATION
Connect your client
Server setup
TERMINAL
brew tap jamiequint/groundeffect
brew install groundeffectIn the Google Cloud Console, create a project, enable the Gmail API and Google Calendar API, and under APIs & Services > Credentials create an OAuth client ID (Desktop app type)
TERMINAL
echo 'export GROUNDEFFECT_GOOGLE_CLIENT_ID="<YOUR_CLIENT_ID>.apps.googleusercontent.com"' >> ~/.zshrc
echo 'export GROUNDEFFECT_GOOGLE_CLIENT_SECRET="<YOUR_GROUNDEFFECT_GOOGLE_CLIENT_SECRET>"' >> ~/.zshrc
source ~/.zshrc
groundeffect account addSign in to Google in the browser window that opens; after that the daemon syncs automatically
MCP Clients
Claude Code
CLAUDE CODE · JSON
{
"mcpServers": {
"groundeffect": {
"type": "stdio",
"command": "groundeffect-mcp",
"env": {
"GROUNDEFFECT_GOOGLE_CLIENT_ID": "${GROUNDEFFECT_GOOGLE_CLIENT_ID}",
"GROUNDEFFECT_GOOGLE_CLIENT_SECRET": "${GROUNDEFFECT_GOOGLE_CLIENT_SECRET}"
}
}
}
}~/.claude.json