Hyper-fast, local Gmail and Google Calendar indexing for Claude Code.
GroundEffect is a local headless IMAP/CalDav client, Claude Code skill, and MCP server built in Rust with LanceDB.
- Hybrid Search: BM25 full-text + vector semantic search with Reciprocal Rank Fusion
- Local Embeddings: Runs nomic-embed-text-v1.5 locally via Candle with Metal acceleration
- Multi-Account: Connect unlimited Gmail/GCal accounts with independent sync
- MCP Integration: Exposes email and calendar tools directly to Claude Code
- Real-time Sync: IMAP IDLE for instant email notifications, CalDAV polling for calendar
- HTML Text Extraction: Automatically converts HTML emails to clean plain text using
html2text - Pluggable Token Storage: File-based (default) or PostgreSQL with AES-256-GCM encryption
brew tap jamiequint/groundeffect
brew install groundeffectThis automatically:
- Installs the daemon (starts at login)
- Installs the Claude Code skill
- Adds permissions to run groundeffect commands
Create a Google Cloud project with OAuth credentials:
- Go to Google Cloud Console
- Create a project and enable Gmail API and Google Calendar API
- Go to APIs & Services > Credentials
- Create OAuth client ID (Desktop app type)
- Add your credentials:
echo 'export GROUNDEFFECT_GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"' >> ~/.zshrc
echo 'export GROUNDEFFECT_GOOGLE_CLIENT_SECRET="your-client-secret"' >> ~/.zshrc
source ~/.zshrcgroundeffect account addThis opens a browser for Google OAuth. After authentication, the daemon syncs automatically.
That's it! Ask Claude Code to search your emails and calendar.
All commands output JSON by default. Add --human for readable output.
| Command | Description |
|---|---|
account list |
List all connected accounts |
account show <account> |
Show account details and sync status |
account add |
Add new Google account via OAuth |
account reauth <account> |
Re-authenticate an existing account via OAuth |
account delete <account> |
Remove account and all synced data |
account configure <account> |
Update account settings (alias, attachments) |
Parameters for add:
| Parameter | Description | Default |
|---|---|---|
--years |
Years of email history to sync (1-20 or "all") | 1 |
--attachments |
Enable automatic attachment download | off |
--alias |
Friendly name for the account | - |
| Command | Description |
|---|---|
email search <query> |
Hybrid BM25 + semantic search |
email list |
List recent emails |
email show <id> |
Show full email content |
email thread <thread_id> |
Show all emails in a thread |
email send |
Compose and send email |
email attachment <id> |
Get attachment content |
email folders |
List IMAP folders |
Parameters for search:
| Parameter | Description | Default |
|---|---|---|
--account |
Filter to specific account | all |
--limit |
Max results (max: 100) | 10 |
--from |
Filter by sender | - |
--to |
Filter by recipient | - |
--date-from |
Filter after date (YYYY-MM-DD) | - |
--date-to |
Filter before date (YYYY-MM-DD) | - |
--has-attachment |
Filter emails with attachments | - |
Parameters for send:
| Parameter | Description |
|---|---|
--from |
Account to send from (required) |
--to |
Recipient(s) (required) |
--subject |
Email subject (required) |
--body |
Email body (required) |
--cc |
CC recipients |
--bcc |
BCC recipients |
--reply-to |
Email ID to reply to (for threading) |
--html |
Force HTML format (auto-detected from markdown/URLs) |
--save-as-draft |
Save as draft instead of sending |
--confirm |
Send immediately (without: preview only) |
| Command | Description |
|---|---|
email draft create |
Create a new email draft |
email draft list |
List all drafts for an account |
email draft show <id> |
Show full draft content |
email draft update <id> |
Update an existing draft |
email draft send <id> |
Send a draft |
email draft delete <id> |
Delete a draft |
Parameters for draft create:
| Parameter | Description |
|---|---|
--from |
Account to create draft in (required) |
--to |
Recipient(s) |
--subject |
Email subject |
--body |
Email body |
--cc |
CC recipients |
--bcc |
BCC recipients |
--html |
Force HTML format |
--reply-to |
Email ID to reply to (for threading) |
| Command | Description |
|---|---|
calendar events |
List events in a date range (no query required) |
calendar search <query> |
Search events with semantic search |
calendar show <id> |
Show event details |
calendar create |
Create new event |
Parameters for events:
| Parameter | Description | Default |
|---|---|---|
--from |
Start date (YYYY-MM-DD) | today |
--to |
End date (YYYY-MM-DD) | 7 days from start |
--account |
Filter to specific account(s) | all |
--limit |
Max results (max: 200) | 50 |
--human |
Human-readable output grouped by date | - |
Use calendar events to answer questions like "what's on my calendar tomorrow" or "show me my meetings next week" without requiring a search query.
Parameters for create:
| Parameter | Description | Default |
|---|---|---|
--account |
Account to create event in (required) | - |
--summary |
Event title (required) | - |
--start |
Start time (ISO 8601) (required) | - |
--end |
End time (ISO 8601) (required) | - |
--description |
Event description | - |
--location |
Event location | - |
--attendees |
Attendee emails (repeatable) | - |
--calendar |
Calendar ID | primary |
| Command | Description |
|---|---|
sync status |
Show sync status for all accounts |
sync reset --account <a> --confirm |
Clear all synced data |
sync extend --account <a> --target-date <d> |
Sync older emails back to date |
sync resume-from --account <a> --target-date <d> |
Force sync to resume from date |
sync download-attachments --account <a> |
Download pending attachments |
| Command | Description |
|---|---|
daemon install |
Install launchd agent (auto-start at login) |
daemon uninstall |
Remove launchd agent |
daemon status |
Check if daemon is running |
daemon restart |
Restart the daemon |
| Command | Description |
|---|---|
config settings |
View/modify daemon settings |
config add-permissions |
Add to Claude Code allowlist |
config remove-permissions |
Remove from Claude Code allowlist |
Parameters for settings:
| Parameter | Description | Default |
|---|---|---|
--logging |
Enable/disable file logging | off |
--email-interval |
Email poll interval in seconds (60-3600) | 300 |
--calendar-interval |
Calendar poll interval in seconds (60-3600) | 300 |
--max-fetches |
Max concurrent fetches (1-50) | 10 |
--timezone |
User timezone for date parsing (e.g., America/Los_Angeles) | UTC |
--embedding-provider |
Embedding backend: local, openrouter, remote |
local |
--embedding-batch-size |
Embedding + IMAP fetch batch size (1-1024) | 128 |
--openrouter-model |
OpenRouter embedding model ID | openai/text-embedding-3-small |
--openrouter-api-key-env |
Env var name with OpenRouter API key | OPENROUTER_API_KEY |
Embeddings backend examples:
# Use local embeddings (default)
groundeffect config settings --embedding-provider local
# Use OpenRouter embeddings
export OPENROUTER_API_KEY="your-key"
groundeffect config settings --embedding-provider openrouter
# Set embedding + IMAP fetch batch size (128 recommended for Gmail/OpenRouter stability)
groundeffect config settings --embedding-batch-size 128
# Optional: set a different OpenRouter model
groundeffect config settings --openrouter-model "openai/text-embedding-3-large"If you prefer MCP over the CLI skill, add to ~/.claude.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}"
}
}
}
}The skill is faster (direct CLI calls vs MCP JSON-RPC overhead) but MCP works with other MCP-compatible clients.
git clone https://github.com/jamiequint/groundeffect.git
cd groundeffect
cargo build --releaseBinaries:
target/release/groundeffect- CLItarget/release/groundeffect-daemon- Background sync daemontarget/release/groundeffect-mcp- MCP server
Install manually:
# Install binaries
sudo cp target/release/groundeffect* /usr/local/bin/
# Install skill
cp -r skill ~/.claude/skills/groundeffect
# Install daemon
groundeffect daemon install
# Add permissions
groundeffect config add-permissions~/.config/groundeffect/
├── config.toml # Main configuration
├── daemon.toml # Daemon configuration
└── tokens/ # OAuth tokens (file provider)
~/.local/share/groundeffect/
├── lancedb/ # LanceDB database
├── attachments/ # Downloaded attachments
├── models/ # Embedding model files
├── logs/ # Log files
└── cache/
└── sync_state/ # Sync state
~/.claude/skills/groundeffect/ # Claude Code skill
By default, OAuth tokens are stored in ~/.config/groundeffect/tokens/ as encrypted JSON files.
For server deployments or ephemeral containers, you can store tokens in PostgreSQL instead. This requires the postgres feature.
-
Build with the postgres feature:
cargo build --release --features postgres
-
Create the tokens table:
CREATE TABLE IF NOT EXISTS groundeffect_tokens ( email VARCHAR(255) PRIMARY KEY, encrypted_tokens BYTEA NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() );
-
Configure in
~/.config/groundeffect/config.toml:[tokens] provider = "postgres" database_url_env = "DATABASE_URL" encryption_key_env = "GE_TOKEN_ENCRYPTION_KEY" # table_name = "groundeffect_tokens" # optional
-
Set environment variables:
export DATABASE_URL="postgres://user:pass@localhost/mydb" export GE_TOKEN_ENCRYPTION_KEY="your-secret-key-here"
Tokens are encrypted at rest using AES-256-GCM with a key derived from your encryption key via HKDF-SHA256.
Re-authenticate:
groundeffect account reauth <email-or-alias>Check status and restart:
groundeffect daemon status
groundeffect daemon restartOr check launchd:
launchctl list | grep groundeffecttail -f ~/.local/share/groundeffect/logs/daemon.logEnable logging if disabled:
groundeffect config settings --logging true
groundeffect daemon restartEmbedding model uses ~500MB-1GB during active embedding. Normal when idle.
┌──────────────┐ ┌──────────────────┐
│ Claude Code │─────►│ groundeffect-mcp │────────┐
│ (MCP Host) │stdio │ │ │
└──────────────┘ └──────────────────┘ │
▼
┌──────────────┐ ┌──────────────────┐ ┌─────────┐
│ Claude Code │─────►│ groundeffect │───►│ LanceDB │
│ (Skill/Bash) │ │ (CLI) │ └─────────┘
└──────────────┘ └──────────────────┘ ▲
│
┌──────────────────┐ │
│ groundeffect- │─────────┘
│ daemon │◄──── IMAP/CalDAV
└──────────────────┘
MIT