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:

  1. Go to Google Cloud Console
  2. Create a project and enable Gmail API and Google Calendar API
  3. Go to APIs & Services > Credentials
  4. Create OAuth client ID (Desktop app type)
  5. 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

CommandDescription
account listList all connected accounts
account show <account>Show account details and sync status
account addAdd 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:

ParameterDescriptionDefault
--yearsYears of email history to sync (1-20 or "all")1
--attachmentsEnable automatic attachment downloadoff
--aliasFriendly name for the account-

Email Commands

CommandDescription
email search <query>Hybrid BM25 + semantic search
email listList recent emails
email show <id>Show full email content
email thread <thread_id>Show all emails in a thread
email sendCompose and send email
email attachment <id>Get attachment content
email foldersList IMAP folders

Parameters for search:

ParameterDescriptionDefault
--accountFilter to specific accountall
--limitMax results (max: 100)10
--fromFilter by sender-
--toFilter by recipient-
--date-fromFilter after date (YYYY-MM-DD)-
--date-toFilter before date (YYYY-MM-DD)-
--has-attachmentFilter emails with attachments-

Parameters for send:

ParameterDescription
--fromAccount to send from (required)
--toRecipient(s) (required)
--subjectEmail subject (required)
--bodyEmail body (required)
--ccCC recipients
--bccBCC recipients
--reply-toEmail ID to reply to (for threading)
--htmlForce HTML format (auto-detected from markdown/URLs)
--save-as-draftSave as draft instead of sending
--confirmSend immediately (without: preview only)

Draft Commands

CommandDescription
email draft createCreate a new email draft
email draft listList 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:

ParameterDescription
--fromAccount to create draft in (required)
--toRecipient(s)
--subjectEmail subject
--bodyEmail body
--ccCC recipients
--bccBCC recipients
--htmlForce HTML format
--reply-toEmail ID to reply to (for threading)

Calendar Commands

CommandDescription
calendar eventsList events in a date range (no query required)
calendar search <query>Search events with semantic search
calendar show <id>Show event details
calendar createCreate new event

Parameters for events:

ParameterDescriptionDefault
--fromStart date (YYYY-MM-DD)today
--toEnd date (YYYY-MM-DD)7 days from start
--accountFilter to specific account(s)all
--limitMax results (max: 200)50
--humanHuman-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:

ParameterDescriptionDefault
--accountAccount to create event in (required)-
--summaryEvent title (required)-
--startStart time (ISO 8601) (required)-
--endEnd time (ISO 8601) (required)-
--descriptionEvent description-
--locationEvent location-
--attendeesAttendee emails (repeatable)-
--calendarCalendar IDprimary

Sync Commands

CommandDescription
sync statusShow sync status for all accounts
sync reset --account <a> --confirmClear 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

CommandDescription
daemon installInstall launchd agent (auto-start at login)
daemon uninstallRemove launchd agent
daemon statusCheck if daemon is running
daemon restartRestart the daemon

Config Commands

CommandDescription
config settingsView/modify daemon settings
config add-permissionsAdd to Claude Code allowlist
config remove-permissionsRemove from Claude Code allowlist

Parameters for settings:

ParameterDescriptionDefault
--loggingEnable/disable file loggingoff
--email-intervalEmail poll interval in seconds (60-3600)300
--calendar-intervalCalendar poll interval in seconds (60-3600)300
--max-fetchesMax concurrent fetches (1-50)10
--timezoneUser timezone for date parsing (e.g., America/Los_Angeles)UTC
--embedding-providerEmbedding backend: local, openrouter, remotelocal
--embedding-batch-sizeEmbedding + IMAP fetch batch size (1-1024)128
--openrouter-modelOpenRouter embedding model IDopenai/text-embedding-3-small
--openrouter-api-key-envEnv var name with OpenRouter API keyOPENROUTER_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"

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 - CLI
  • target/release/groundeffect-daemon - Background sync daemon
  • target/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

  1. Build with the postgres feature:

    cargo build --release --features postgres
    
  2. 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()
    );
    
  3. 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
    
  4. 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 reauth <email-or-alias>

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

Máy chủ liên quan

NotebookLM Web Importer

Nhập trang web và video YouTube vào NotebookLM chỉ với một cú nhấp. Được tin dùng bởi hơn 200.000 người dùng.

Cài đặt tiện ích Chrome