GroundEffect
Hyper-fast, local Gmail and Google Calendar indexing for Claude Code, available as a Skill or MCP Server.
GroundEffect
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.
Features
- 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
Quick Start
1. Install
brew tap jamiequint/groundeffect
brew install groundeffect
This automatically:
- Installs the daemon (starts at login)
- Installs the Claude Code skill
- Adds permissions to run groundeffect commands
2. Configure OAuth
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 ~/.zshrc
3. Add an Account
groundeffect account add
This opens a browser for Google OAuth. After authentication, the daemon syncs automatically.
That's it! Ask Claude Code to search your emails and calendar.
CLI Reference
All commands output JSON by default. Add --human for readable output.
Account Commands
| 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 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 | - |
Email Commands
| 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) |
Draft Commands
| 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) |
Calendar Commands
| 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 |
Sync Commands
| 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 |
Daemon Commands
| 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 |
Config Commands
| 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 |
MCP Integration (Alternative)
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.
Build from Source
git clone https://github.com/jamiequint/groundeffect.git
cd groundeffect
cargo build --release
Binaries:
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
Data Storage
~/.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
Token Storage
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.
PostgreSQL Token Storage
-
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.
Troubleshooting
"OAuth token expired"
Re-authenticate:
groundeffect account add
Daemon not running
Check status and restart:
groundeffect daemon status
groundeffect daemon restart
Or check launchd:
launchctl list | grep groundeffect
View logs
tail -f ~/.local/share/groundeffect/logs/daemon.log
Enable logging if disabled:
groundeffect config settings --logging true
groundeffect daemon restart
High memory usage
Embedding model uses ~500MB-1GB during active embedding. Normal when idle.
Architecture
┌──────────────┐ ┌──────────────────┐
│ Claude Code │─────►│ groundeffect-mcp │────────┐
│ (MCP Host) │stdio │ │ │
└──────────────┘ └──────────────────┘ │
▼
┌──────────────┐ ┌──────────────────┐ ┌─────────┐
│ Claude Code │─────►│ groundeffect │───►│ LanceDB │
│ (Skill/Bash) │ │ (CLI) │ └─────────┘
└──────────────┘ └──────────────────┘ ▲
│
┌──────────────────┐ │
│ groundeffect- │─────────┘
│ daemon │◄──── IMAP/CalDAV
└──────────────────┘
License
MIT
Related Servers
Shortcut
Manage your Shortcut projects, stories, and epics.
Hilanet MCP
Provides HR-related tools for a corporate dystopia.
Productboard MCP Server
Integrates with the Productboard API, offering 49 specialized tools to manage all major Productboard functionalities.
n8n
Provides AI assistants with direct access to the n8n automation platform.
early-mcp
Complete MCP server for Early (Timeular) time tracking - 46 tools for tracking, entries, activities, folders, tags, reports. Created with Claude
freee
Interact with the freee accounting API to manage financial data and business operations.
Fireflies.ai
Transcribe and analyze meetings using the Fireflies.ai API.
Docmost
An open-source collaborative wiki and documentation software with AI integration via MCP.
Taskeract
Official Taskeract MCP Server for integrating your Taskeract project tasks and load the context of your tasks into your MCP enabled app.
Norman Finance
MCP server for managing accounting and taxes with Norman Finance.