GroundEffect
Indexação local e ultrarrápida do Gmail e Google Agenda para o Claude Code, disponível como Skill ou MCP Server.
Documentação
GroundEffect
Indexação local ultra-rápida de Gmail e Google Agenda para Claude Code.
GroundEffect é um cliente local headless de IMAP/CalDav, skill do Claude Code e servidor MCP construído em Rust com LanceDB.
Recursos
- Busca Híbrida: Texto completo BM25 + busca semântica vetorial com Fusão de Rank Recíproco
- Embeddings Locais: Executa nomic-embed-text-v1.5 localmente via Candle com aceleração Metal
- Multi-Conta: Conecte contas ilimitadas de Gmail/GCal com sincronização independente
- Integração MCP: Expõe ferramentas de e-mail e agenda diretamente ao Claude Code
- Sincronização em Tempo Real: IMAP IDLE para notificações instantâneas de e-mail, polling CalDAV para agenda
- Extração de Texto HTML: Converte automaticamente e-mails HTML em texto simples usando
html2text - Armazenamento de Tokens Plugável: Baseado em arquivo (padrão) ou PostgreSQL com criptografia AES-256-GCM
Início Rápido
1. Instalar
brew tap jamiequint/groundeffect
brew install groundeffect
Isso automaticamente:
- Instala o daemon (inicia no login)
- Instala a skill do Claude Code
- Adiciona permissões para executar comandos do groundeffect
2. Configurar OAuth
Crie um projeto no Google Cloud com credenciais OAuth:
- Acesse o Google Cloud Console
- Crie um projeto e habilite a API Gmail e a API Google Calendar
- Vá em APIs & Services > Credentials
- Crie um ID de cliente OAuth (tipo Aplicativo de desktop)
- Adicione suas credenciais:
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. Adicionar uma Conta
groundeffect account add
Isso abre um navegador para OAuth do Google. Após a autenticação, o daemon sincroniza automaticamente.
É isso! Peça ao Claude Code para pesquisar seus e-mails e agenda.
Referência da CLI
Todos os comandos geram saída JSON por padrão. Adicione --human para saída legível.
Comandos de Conta
| Comando | Descrição |
|---|---|
account list | Lista todas as contas conectadas |
account show <account> | Mostra detalhes da conta e status de sincronização |
account add | Adiciona nova conta do Google via OAuth |
account reauth <account> | Reautentica uma conta existente via OAuth |
account delete <account> | Remove conta e todos os dados sincronizados |
account configure <account> | Atualiza configurações da conta (alias, anexos) |
Parâmetros para add:
| Parâmetro | Descrição | Padrão |
|---|---|---|
--years | Anos de histórico de e-mail para sincronizar (1-20 ou "all") | 1 |
--attachments | Habilita download automático de anexos | off |
--alias | Nome amigável para a conta | - |
Comandos de E-mail
| Comando | Descrição |
|---|---|
email search <query> | Busca híbrida BM25 + semântica |
email list | Lista e-mails recentes |
email show <id> | Mostra conteúdo completo do e-mail |
email thread <thread_id> | Mostra todos os e-mails em uma conversa |
email send | Redige e envia e-mail |
email attachment <id> | Obtém conteúdo de anexo |
email folders | Lista pastas IMAP |
Parâmetros para search:
| Parâmetro | Descrição | Padrão |
|---|---|---|
--account | Filtra para conta específica | all |
--limit | Máximo de resultados (máx: 100) | 10 |
--from | Filtra por remetente | - |
--to | Filtra por destinatário | - |
--date-from | Filtra após data (AAAA-MM-DD) | - |
--date-to | Filtra antes de data (AAAA-MM-DD) | - |
--has-attachment | Filtra e-mails com anexos | - |
Parâmetros para send:
| Parâmetro | Descrição |
|---|---|
--from | Conta para enviar (obrigatório) |
--to | Destinatário(s) (obrigatório) |
--subject | Assunto do e-mail (obrigatório) |
--body | Corpo do e-mail (obrigatório) |
--cc | Destinatários em CC |
--bcc | Destinatários em BCC |
--reply-to | ID do e-mail para responder (para conversas) |
--html | Força formato HTML (detectado automaticamente de markdown/URLs) |
--save-as-draft | Salva como rascunho em vez de enviar |
--confirm | Envia imediatamente (sem isso: apenas pré-visualização) |
Comandos de Rascunho
| Comando | Descrição |
|---|---|
email draft create | Cria um novo rascunho de e-mail |
email draft list | Lista todos os rascunhos de uma conta |
email draft show <id> | Mostra conteúdo completo do rascunho |
email draft update <id> | Atualiza um rascunho existente |
email draft send <id> | Envia um rascunho |
email draft delete <id> | Exclui um rascunho |
Parâmetros para draft create:
| Parâmetro | Descrição |
|---|---|
--from | Conta para criar rascunho (obrigatório) |
--to | Destinatário(s) |
--subject | Assunto do e-mail |
--body | Corpo do e-mail |
--cc | Destinatários em CC |
--bcc | Destinatários em BCC |
--html | Força formato HTML |
--reply-to | ID do e-mail para responder (para conversas) |
Comandos de Agenda
| Comando | Descrição |
|---|---|
calendar events | Lista eventos em um intervalo de datas (sem consulta necessária) |
calendar search <query> | Busca eventos com busca semântica |
calendar show <id> | Mostra detalhes do evento |
calendar create | Cria novo evento |
Parâmetros para events:
| Parâmetro | Descrição | Padrão |
|---|---|---|
--from | Data de início (AAAA-MM-DD) | hoje |
--to | Data de término (AAAA-MM-DD) | 7 dias a partir do início |
--account | Filtra para conta(s) específica(s) | all |
--limit | Máximo de resultados (máx: 200) | 50 |
--human | Saída legível agrupada por data | - |
Use calendar events para responder perguntas como "o que tenho na agenda amanhã" ou "mostre minhas reuniões na próxima semana" sem exigir uma consulta de busca.
Parâmetros para create:
| Parâmetro | Descrição | Padrão |
|---|---|---|
--account | Conta para criar evento (obrigatório) | - |
--summary | Título do evento (obrigatório) | - |
--start | Horário de início (ISO 8601) (obrigatório) | - |
--end | Horário de término (ISO 8601) (obrigatório) | - |
--description | Descrição do evento | - |
--location | Local do evento | - |
--attendees | E-mails dos participantes (repetível) | - |
--calendar | ID da agenda | primary |
Comandos de Sincronização
| Comando | Descrição |
|---|---|
sync status | Mostra status de sincronização de todas as contas |
sync reset --account <a> --confirm | Limpa todos os dados sincronizados |
sync extend --account <a> --target-date <d> | Sincroniza e-mails mais antigos até uma data |
sync resume-from --account <a> --target-date <d> | Força retomada da sincronização a partir de uma data |
sync download-attachments --account <a> | Baixa anexos pendentes |
Comandos do Daemon
| Comando | Descrição |
|---|---|
daemon install | Instala agente launchd (início automático no login) |
daemon uninstall | Remove agente launchd |
daemon status | Verifica se o daemon está em execução |
daemon restart | Reinicia o daemon |
Comandos de Configuração
| Comando | Descrição |
|---|---|
config settings | Visualiza/modifica configurações do daemon |
config add-permissions | Adiciona à lista de permissões do Claude Code |
config remove-permissions | Remove da lista de permissões do Claude Code |
Parâmetros para settings:
| Parâmetro | Descrição | Padrão |
|---|---|---|
--logging | Habilita/desabilita registro em arquivo | off |
--email-interval | Intervalo de polling de e-mail em segundos (60-3600) | 300 |
--calendar-interval | Intervalo de polling de agenda em segundos (60-3600) | 300 |
--max-fetches | Máximo de buscas simultâneas (1-50) | 10 |
--timezone | Fuso horário do usuário para análise de datas (ex.: America/Los_Angeles) | UTC |
--embedding-provider | Backend de embeddings: local, openrouter, remote | local |
--embedding-batch-size | Tamanho do lote de embeddings + busca IMAP (1-1024) | 128 |
--openrouter-model | ID do modelo de embeddings OpenRouter | openai/text-embedding-3-small |
--openrouter-api-key-env | Nome da variável de ambiente com a chave da API OpenRouter | OPENROUTER_API_KEY |
Exemplos de backends de embeddings:
# 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"
Integração MCP (Alternativa)
Se você preferir MCP em vez da skill CLI, adicione a ~/.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}"
}
}
}
}
A skill é mais rápida (chamadas CLI diretas vs. overhead JSON-RPC do MCP), mas o MCP funciona com outros clientes compatíveis com MCP.
Compilar a partir do Código-Fonte
git clone https://github.com/jamiequint/groundeffect.git
cd groundeffect
cargo build --release
Binários:
target/release/groundeffect- CLItarget/release/groundeffect-daemon- Daemon de sincronização em segundo planotarget/release/groundeffect-mcp- Servidor MCP
Instalar manualmente:
# 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
Armazenamento de Dados
~/.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
Armazenamento de Tokens
Por padrão, os tokens OAuth são armazenados em ~/.config/groundeffect/tokens/ como arquivos JSON criptografados.
Para implantações em servidores ou contêineres efêmeros, você pode armazenar tokens no PostgreSQL. Isso requer o recurso postgres.
Armazenamento de Tokens no PostgreSQL
-
Compile com o recurso postgres:
cargo build --release --features postgres -
Crie a tabela de tokens:
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 em
~/.config/groundeffect/config.toml:[tokens] provider = "postgres" database_url_env = "DATABASE_URL" encryption_key_env = "GE_TOKEN_ENCRYPTION_KEY" # table_name = "groundeffect_tokens" # optional -
Defina as variáveis de ambiente:
export DATABASE_URL="postgres://user:pass@localhost/mydb" export GE_TOKEN_ENCRYPTION_KEY="your-secret-key-here"
Os tokens são criptografados em repouso usando AES-256-GCM com uma chave derivada da sua chave de criptografia via HKDF-SHA256.
Solução de Problemas
"Token OAuth expirado"
Reautentique:
groundeffect account reauth <email-or-alias>
Daemon não está em execução
Verifique o status e reinicie:
groundeffect daemon status
groundeffect daemon restart
Ou verifique o launchd:
launchctl list | grep groundeffect
Ver registros
tail -f ~/.local/share/groundeffect/logs/daemon.log
Habilite o registro se estiver desabilitado:
groundeffect config settings --logging true
groundeffect daemon restart
Alto uso de memória
O modelo de embeddings usa cerca de 500MB-1GB durante a geração ativa de embeddings. Normal quando ocioso.
Arquitetura
┌──────────────┐ ┌──────────────────┐
│ Claude Code │─────►│ groundeffect-mcp │────────┐
│ (MCP Host) │stdio │ │ │
└──────────────┘ └──────────────────┘ │
▼
┌──────────────┐ ┌──────────────────┐ ┌─────────┐
│ Claude Code │─────►│ groundeffect │───►│ LanceDB │
│ (Skill/Bash) │ │ (CLI) │ └─────────┘
└──────────────┘ └──────────────────┘ ▲
│
┌──────────────────┐ │
│ groundeffect- │─────────┘
│ daemon │◄──── IMAP/CalDAV
└──────────────────┘
Licença
MIT