Gmail Manager
Servidor MCP do Gmail (33 ferramentas) com lista de permissão opcional de destinatários e registro de auditoria local
Documentação
mcp-gmail-manager
Um servidor abrangente de Gmail Model Context Protocol: 35 ferramentas cobrindo envio/pré-visualização/confirmação, resposta, encaminhamento, rascunhos, busca, leitura, anexos, lixeira, rótulos, filtros, assinatura e respondedor de férias.
Recursos de defesa em profundidade que o diferenciam de outros MCPs de Gmail:
- Registro de auditoria à prova de adulteração (ativado por padrão) — toda operação de gravação/envio/modificação/download anexa uma linha JSON a
audit.jsonl, encadeada por SHA-256 para que adulterações parciais sejam detectáveis. Inclui rotação de logs, verificação de cadeia na inicialização, auditoria de leitura opcional e uma CLImcp-gmail-manager-verify-log. - Lista de permissões de destinatários (desativada por padrão) — quando habilitada, toda operação de saída (
send_email,create_draft,reply_to_message,forward_message,create_filtercom uma açãoforward, além de endereços incorporados na assinatura e no corpo de férias) verifica os destinatários em relação aos domínios configurados e endereços explícitos. - Lista de permissões e bloqueios de caminhos de anexos (bloqueio ativado por padrão) — o MCP se recusa a anexar ou sobrescrever arquivos de credenciais óbvios (
~/.ssh/,~/.aws/,id_rsa,.env,token.json, etc.), fechando o ataque de "LLM exfiltra chave SSH como anexo". Consulte Notas de segurança para o conjunto completo de bloqueios padrão. - Marcadores de conteúdo contaminado por injeção de prompt — ferramentas de leitura (
get_message,get_thread,search_threads,list_drafts) envolvem corpos de mensagens e trechos em tags<untrusted-email-content>...</untrusted-email-content>. As descrições das ferramentas instruem o LLM a tratar o conteúdo envolvido como dados, não instruções. - Varredura de conteúdo de saída (desativada por padrão) — detecção baseada em regex de segredos no assunto/corpo/assinatura/conteúdo de férias (chaves de acesso AWS, tokens Stripe/OpenAI/Anthropic/GitHub/GitLab/Google/Twilio, chaves privadas PEM, JWTs, credenciais incorporadas em URLs). Bloqueia o envio antes que ele chegue ao Gmail se um padrão corresponder.
- Fluxo de pré-visualização + confirmação de envio (desativado por padrão) —
preview_send_emailexecuta todas as salvaguardas e armazena a carga útil;confirm_send_email(preview_id)a entrega. Quandosend_confirmation.required=true, osend_emaildireto é desabilitado para que um LLM comprometido não possa "pré-visualizar X, depois enviar Y". - Limitação de taxa (desativada por padrão) — limite de envios de saída por hora para impedir que loops descontrolados de agentes queimem a cota do Gmail.
- Escopos OAuth de privilégio mínimo — solicita apenas
gmail.modify+gmail.settings.basic. NÃO solicitamail.google.com, portanto a exclusão permanente está intencionalmente indisponível.
Consulte examples/config.with-allowlist.json para uma configuração em modo institucional.
Ferramentas (33)
| Grupo | Ferramentas |
|---|---|
| Enviar / responder / encaminhar | send_email, preview_send_email, confirm_send_email, reply_to_message, forward_message |
| Rascunhos | create_draft, list_drafts, send_draft, update_draft, delete_draft |
| Ler / perfil | get_profile, get_message, search_threads, get_thread |
| Anexos | get_message_attachments, download_attachment |
| Lixeira | trash_message, untrash_message, trash_thread, untrash_thread |
| Rótulos | list_labels, create_label, update_label, delete_label, label_message, unlabel_message, label_thread, unlabel_thread |
| Filtros | list_filters, create_filter, delete_filter |
| Assinatura | get_signature, update_signature |
| Respondedor de férias | get_vacation_responder, set_vacation_responder |
Escopos OAuth solicitados: gmail.modify + gmail.settings.basic. Não solicita o escopo de superusuário https://mail.google.com/ — a exclusão permanente é intencionalmente não suportada.
Requisitos
- Python ≥ 3.10
- Um projeto Google Cloud com a API Gmail habilitada e um cliente OAuth 2.0 (tipo Desktop)
- Uma forma de encaminhar
localhost:8765para seu host de autenticação (normalmentessh -L 8765:localhost:8765 user@host)
Instalação
📖 Prefere um tutorial passo a passo com capturas de tela para cada etapa da configuração do Google Cloud? Consulte o Guia de Instalação. A seção abaixo cobre apenas a instalação do pacote; o guia completo aborda GCP, credenciais, OAuth, configuração de VM e registro no Claude Code.
Suportado em Linux, macOS e Windows. O caminho recomendado é pipx, que instala a CLI em um venv isolado e expõe os pontos de entrada em $PATH.
Linux (Debian / Ubuntu / Mint / Fedora / Arch)
sudo apt install pipx # Debian / Ubuntu / Mint
sudo dnf install pipx # Fedora
sudo pacman -S python-pipx # Arch
pipx ensurepath # adds ~/.local/bin to PATH
# reopen shell or: source ~/.bashrc
pipx install mcp-gmail-manager
macOS
brew install pipx # or: python3 -m pip install --user pipx
pipx ensurepath # adds ~/.local/bin to PATH
# reopen shell or: source ~/.zshrc
pipx install mcp-gmail-manager
Windows (PowerShell)
# If you don't have Python yet: winget install --id Python.Python.3.12
python -m pip install --user pipx
python -m pipx ensurepath
# close and reopen PowerShell
pipx install mcp-gmail-manager
Observações sobre Windows — tudo funciona, com três notas:
- Permissões do arquivo de token. No Linux/macOS, o MCP grava
token.jsoncomchmod 0o600. No Windows não há chmod POSIX, então o arquivo herda sua ACL%USERPROFILE%— protegido contra outras contas de usuário, mas qualquer processo executando como seu usuário pode lê-lo. Mesma postura efetiva da maioria das ferramentas CLI do Windows que armazenam tokens OAuth. - A lista de bloqueio de caminhos de anexos funciona. A partir da v0.3.2, a correspondência de bloqueio/permissão normaliza caminhos para o formato de barra invertida via
Path.as_posix(), então um caminho do Windows comoC:\Users\me\.ssh\id_rsaé corretamente capturado pelo padrão de bloqueio padrão~/.ssh/. Confirmado pela suíte de fumaça em ambas as plataformas. - A porta 8765 pode estar reservada pelo Windows. Hyper-V, WSL2 e Docker Desktop reservam faixas de portas dinâmicas que às vezes incluem 8765, resultando em
bind [127.0.0.1]:8765: Permission deniedna extremidade local de um encaminhamento SSH-L. Verifique comnetsh interface ipv4 show excludedportrange protocol=tcp. Se 8765 estiver reservada, definaGMAIL_MCP_AUTH_PORTpara uma porta livre em ambas as extremidades (v0.3.3+):set GMAIL_MCP_AUTH_PORT=18765no servidor antes de executarmcp-gmail-manager-auth, e encaminhe essa mesma porta:ssh -L 18765:localhost:18765 user@server.
Alternativa em qualquer SO — venv manual
python3 -m venv ~/.venv-mcp-gmail
~/.venv-mcp-gmail/bin/pip install mcp-gmail-manager
# Windows: python -m venv %USERPROFILE%\.venv-mcp-gmail
# Use the absolute path when registering with Claude Code (see below)
Por que não pip install simples em todo o sistema? Em distros modernas baseadas em Debian e no Python do Homebrew, isso falha com error: externally-managed-environment (PEP 668) — o SO protege seu Python. Os métodos pipx e venv acima são as soluções canônicas.
A partir do código-fonte:
git clone https://github.com/arthjhon/mcp-gmail-manager.git
cd mcp-gmail-manager
pipx install .
Configuração do Google Cloud (uma vez, ~10 minutos)
- Vá para Google Cloud Console e crie um novo projeto (ou escolha um existente).
- Habilite a API Gmail (não "Gmail MCP API" — essa é o MCP remoto do próprio Google; não é o que queremos).
- Configure a tela de consentimento OAuth:
- Tipo de usuário: Interno se sua conta faz parte de um Google Workspace (sem expiração de token); caso contrário, Externo em modo Teste (até 100 usuários, tokens de atualização expiram a cada 7 dias — consulte Expiração de token abaixo).
- Escopos: adicione
https://www.googleapis.com/auth/gmail.modifyehttps://www.googleapis.com/auth/gmail.settings.basic. Não adicione mais nada. - Usuários de teste (somente Externo): adicione o endereço Gmail com o qual você autenticará.
- Crie um ID de Cliente OAuth:
- Tipo de aplicativo: Aplicativo de desktop
- Baixe o JSON. Salve-o como
credentials.json.
Autenticação inicial
Mova suas credenciais para o diretório de configuração (padrão ~/.config/mcp-gmail-manager/):
mkdir -p ~/.config/mcp-gmail-manager
mv ~/Downloads/client_secret_*.json ~/.config/mcp-gmail-manager/credentials.json
chmod 600 ~/.config/mcp-gmail-manager/credentials.json
Execute o fluxo de autenticação:
mcp-gmail-manager-auth
Isso vincula a localhost:8765 e imprime uma URL de autorização do Google. Abra-a em um navegador em uma máquina que possa acessar localhost:8765 no host de autenticação:
- Desktop local: a URL impressa funciona diretamente.
- Servidor remoto / sem cabeça: encaminhe a porta do seu laptop primeiro:
Em seguida, executessh -L 8765:localhost:8765 user@your-servermcp-gmail-manager-authdentro dessa sessão SSH.
Autorize com a conta Google que será a proprietária do e-mail de saída. Em caso de sucesso, o script grava token.json e sai.
Expiração de token
A vida útil do token de atualização depende de como a tela de consentimento OAuth é configurada:
| Configuração | Vida útil do token de atualização | Reautenticação necessária? |
|---|---|---|
| Interno (Google Workspace) | Sem expiração | Nunca (até o usuário revogar) |
| Externo + Teste | 7 dias (política do Google para aplicativos não verificados) | Sim — semanalmente |
| Externo + Produção verificado | Sem expiração | Nunca, mas a verificação exige uma avaliação de segurança paga do Google |
Quando o token de atualização expira no modo Teste, você verá erros invalid_grant ou Token has been expired or revoked. Para recuperar:
rm ~/.config/mcp-gmail-manager/token.json
mcp-gmail-manager-auth
Leva ~30 segundos. Seu credentials.json não é afetado — apenas o token do usuário.
Como evitar a rotação semanal
- Usuários do Workspace: configure a tela de consentimento como Interno em vez de Externo. O token nunca expira.
- Usuários pessoais do Gmail: a reautenticação semanal é a única opção prática hoje. A verificação de produção para
gmail.modifyexige uma avaliação de segurança do Google (paga, semanas de processo) — não viável para a maioria dos projetos pessoais. - Defina um lembrete no calendário ou um cron job para lembrá-lo semanalmente. Uma versão futura pode adicionar avisos proativos na ferramenta antes da expiração.
Registrar com Claude Code
Se instalado via pipx:
claude mcp add gmail-manager -- mcp-gmail-manager
Se instalado em um venv manual que não está em $PATH:
claude mcp add gmail-manager -- ~/.venv-mcp-gmail/bin/mcp-gmail-manager
Reinicie sua sessão do Claude Code para que os novos esquemas de ferramentas sejam carregados.
Múltiplas contas Gmail
Cada instância do MCP lida com uma conta Gmail. Para usar várias contas na mesma sessão do Claude Code (ex.: pessoal + trabalho), registre o MCP uma vez por conta com um GMAIL_MCP_CONFIG_DIR distinto. Cada instância tem suas próprias credenciais, token, registro de auditoria e configuração — totalmente isoladas.
Configuração por conta
# 1. Dedicated config directory
mkdir -p ~/.config/mcp-gmail-<name> && chmod 700 ~/.config/mcp-gmail-<name>
# 2. Reuse the same OAuth client (one credentials.json works for any user in the same GCP project)
cp ~/.config/mcp-gmail-<other>/credentials.json ~/.config/mcp-gmail-<name>/
chmod 600 ~/.config/mcp-gmail-<name>/credentials.json
# 3. Authenticate with the target Gmail account
GMAIL_MCP_CONFIG_DIR=$HOME/.config/mcp-gmail-<name> mcp-gmail-manager-auth
# 4. Register with the env override
claude mcp add gmail-<name> -s user \
-e GMAIL_MCP_CONFIG_DIR=$HOME/.config/mcp-gmail-<name> \
-- mcp-gmail-manager
Reinicie o Claude Code. As ferramentas aparecem em namespaces separados:
mcp__gmail-personal__send_email→ envia da conta pessoalmcp__gmail-work__send_email→ envia da conta de trabalho
Você pode pedir ao Claude "enviar via gmail-work" e ele escolhe o namespace certo.
Configuração por conta
Cada <config_dir>/config.json é independente. Padrões úteis:
// ~/.config/mcp-gmail-work/config.json — strict allowlist
{
"allowlist": {
"enabled": true,
"domains": ["yourcompany.com"]
}
}
// ~/.config/mcp-gmail-personal/config.json — silence the audit log
{
"audit_log": { "enabled": false }
}
O comprometimento do token de uma conta não vaza o da outra — cada um vive em um diretório separado com chmod 600.
Configuração
~/.config/mcp-gmail-manager/config.json é opcional — se não existir, padrões sensatos são aplicados (sem lista de permissões, registro de auditoria habilitado). Dois exemplos prontos para copiar são fornecidos:
examples/config.example.json— padrões endurecidos (ponto de partida recomendado). Todas as salvaguardas ativadas; lista de permissões habilitada, mas vazia, então o aviso de inicialização apontará o que configurar primeiro.examples/config.with-allowlist.json— exemplo institucional totalmente preenchido com domínios de espaço reservado.examples/config.permissive.json— exclusão explícita para usuários que não querem salvaguardas (lista de permissões desativada, varredura de conteúdo desativada, limite de taxa desativado, sem confirmação de envio). Considere isso apenas se você entender o raio de impacto.
Referência do esquema:
{
"allowlist": {
"enabled": false,
"domains": [],
"emails": []
},
"audit_log": {
"enabled": true,
"include_reads": false,
"path": null
},
"attachments": {
"max_total_bytes": 20971520,
"allowed_paths": [],
"deny_patterns": [],
"use_default_deny_patterns": true
}
}
| Campo | Padrão | Significado |
|---|---|---|
allowlist.enabled | false | Quando false, qualquer destinatário é aceito. Ative explicitamente para uso institucional. |
allowlist.domains | [] | Sufixos de domínio em minúsculas aceitos como destinatários. |
allowlist.emails | [] | Endereços de e-mail explícitos em minúsculas aceitos independentemente do domínio. |
audit_log.enabled | true | Anexar toda gravação/envio/modificação ao JSONL. |
audit_log.include_reads | false | Também registrar operações de leitura (get_message, search_threads, get_thread, list_drafts, get_message_attachments). Útil para detectar reconhecimento silencioso. |
audit_log.path | null | null → <config_dir>/audit.jsonl. Substitua para centralizar os logs. |
audit_log.max_size_bytes | 10485760 (10 MB) | Rotacionar para audit.jsonl.1..N quando o arquivo atual exceder este tamanho. A cadeia é redefinida entre rotações; verifique cada arquivo separadamente com a CLI. |
audit_log.max_backups | 5 | Número de backups rotacionados a manter. Os mais antigos são sobrescritos. |
audit_log.verify_on_startup | false | Percorrer a cadeia na inicialização do servidor e emitir um aviso em stderr se estiver quebrada. Barato para logs de até alguns MB. |
attachments.max_total_bytes | 20971520 (20 MB) | Limite de tamanho combinado por envio. O limite rígido do Gmail é de 25 MB brutos. |
attachments.allowed_paths | [] | Quando preenchido, origens e destinos de anexos/download DEVEM estar sob uma dessas bases. Vazio = apenas padrões de negação se aplicam. |
attachments.deny_patterns | [] | Padrões regex extras para rejeitar (comparados ao caminho absoluto). Adicionados além dos padrões padrão. |
attachments.use_default_deny_patterns | true | Incluir o conjunto de negação embutido (~/.ssh/, ~/.aws/, id_rsa, .env, token.json, arquivos de credenciais, armazenamentos de navegador). |
rate_limit.enabled | false | Quando true, limitar envios de saída por hora por instância em execução. Janela deslizante em memória — redefine na reinicialização do servidor. |
rate_limit.sends_per_hour | 60 | Aplicado a send_email, reply_to_message, forward_message e send_draft combinados. |
content_scan.enabled | false | Quando true, verificar assuntos, corpos, assinaturas e conteúdo de férias de saída em busca de padrões de segredos. Correspondências bloqueiam a operação antes de chegar ao Gmail. |
content_scan.use_default_patterns | true | Incluir as regex de segredos embutidas (chaves de acesso AWS, tokens Stripe/OpenAI/Anthropic/GitHub/GitLab/Google/Twilio, chaves privadas PEM, JWTs, credenciais incorporadas em URLs). |
content_scan.patterns | [] | Padrões adicionais definidos pelo usuário. Cada entrada: {"name": "...", "regex": "..."}. Nomes aparecem em mensagens de erro para depuração. |
content_scan.scan_subject / scan_body / scan_signature / scan_vacation | true | Alternâncias por escopo. Útil para desativar um local enquanto mantém outros ativos. |
send_confirmation.required | false | Quando true, send_email direto é desativado — deve passar por preview_send_email → confirm_send_email(preview_id). |
send_confirmation.preview_ttl_seconds | 300 | Por quanto tempo uma prévia permanece válida antes de precisar ser reemitida. |
signature.auto_append | false | Quando true, busca a assinatura configurada nas Configurações do Gmail e a anexa a todo corpo de saída (enviar/responder/encaminhar/criar_rascunho/atualizar_rascunho/prévia). A interface web do próprio Gmail aplica assinaturas automaticamente; a API do Gmail NÃO — ative para corresponder. |
signature.cache_ttl_seconds | 3600 | Por quanto tempo armazenar em cache a assinatura buscada em memória antes de buscar novamente. |
signature.strip_html | true | O Gmail armazena assinaturas como HTML. Quando true, o MCP remove para texto simples (preservando quebras de linha) e envia uma mensagem somente text/plain. Quando false (v0.3.5+), o MCP envia multipart/alternative — uma parte em texto simples com a assinatura removida, mais uma parte text/html com a assinatura HTML original preservando imagens de logotipo, cores e layout. Defina para false se sua assinatura do Gmail tiver um logotipo ou formatação rica que você deseja manter. |
body.format | "plain" | Como o campo body das ferramentas de enviar/responder/encaminhar/rascunho é interpretado. "plain" (padrão): corpo é texto simples, enviado como text/plain (compatível com v0.3.5). "markdown" (v0.3.6+): corpo é Markdown; a parte de texto simples mantém o Markdown bruto, a parte HTML é renderizada — **bold**, *italic*, # H1, - lists, [links](url), `code` all render properly in email clients. "html": body is raw HTML; HTML part is passthrough, plain part is a stripped-to-text fallback. Enable markdown se você quiser que o Markdown natural do Claude seja renderizado como formatação rica. |
signature.send_as_email | null | Qual identidade sendAs terá sua assinatura usada. null = o e-mail principal. |
Verificando o log de auditoria
Execute mcp-gmail-manager-verify-log para percorrer a cadeia de hash e confirmar que nenhuma entrada foi editada ou removida:
mcp-gmail-manager-verify-log # verify the active log
mcp-gmail-manager-verify-log ~/.config/.../audit.jsonl.1 # verify a rotated backup
Códigos de saída: 0 OK, 1 log não encontrado, 2 JSON malformado, 3 cadeia quebrada.
Substituições por variáveis de ambiente
| Variável | Padrão |
|---|---|
GMAIL_MCP_CONFIG_DIR | $XDG_CONFIG_HOME/mcp-gmail-manager ou ~/.config/mcp-gmail-manager |
GMAIL_MCP_CREDENTIALS | <config_dir>/credentials.json |
GMAIL_MCP_TOKEN | <config_dir>/token.json |
Notas de segurança
- Modelo de ameaça: este MCP é principalmente endurecido contra um LLM com mau comportamento — injeção de prompt, destinatários alucinados, cenários de exfiltração induzida. NÃO substitui a segurança do host; um atacante com acesso local pode ler
token.jsone chamar o Gmail diretamente, contornando todas as proteções aqui. - Armazenamento de token:
token.jsoné gravadochmod 600. Trate-o como uma senha. - Sem atestação remota: este servidor roda inteiramente na sua máquina. Sem telemetria, sem chamadas de terceiros além de
googleapis.com. - Escopo OAuth é deliberadamente estreito:
gmail.modifycobre enviar/ler/rótulos/lixeira/rascunhos. NÃO solicitamail.google.com, então exclusão permanente não está disponível — exclusões vão para a Lixeira e podem ser desfeitas comuntrash_*. Se você só precisa enviar, faça um fork e substitua o escopo porgmail.send. - Proteções de destinatário cobrem encaminhamento em filtros:
create_filtercom umaction.forwarddirecionado a um endereço não permitido é rejeitado. Filtros eram um bypass comum de listas de permissão somente envio. - Ferramentas de leitura marcam conteúdo como não confiável: corpos e trechos são envolvidos em
<untrusted-email-content>...</untrusted-email-content>. Descrições de ferramentas instruem LLMs downstream a tratar conteúdo envolvido como dados. Qualquer ocorrência da tag de fechamento dentro de um corpo de mensagem é escapada para evitar quebra. - Conjunto de negação de anexos padrão (origem e destino) cobre caminhos comuns de credenciais/segredos:
~/.ssh/,~/.aws/,~/.gnupg/,~/.docker/config.json,~/.kube/,.env,.env.*,credentials.json,token.json,id_rsa/id_ed25519/id_ecdsa/id_dsa,.git-credentials,.netrc,wallet.dat,.bash_history,.zsh_history,~/.mozilla/*/logins.json,authorized_keys,known_hosts. Estenda viaattachments.deny_patternsou restrinja ainda mais viaattachments.allowed_paths. - Log de auditoria é à prova de adulteração, não à prova de violação: cada entrada inclui
prev_hash = sha256(previous line). Modificação parcial quebra a cadeia e é detectável. Uma reescrita completa do log por um atacante com permissão de escrita NÃO é impedida — combine com envio de log fora do host (roadmap) para garantias mais fortes. - O que NÃO é mitigado: limitação de taxa (um agente comprometido pode queimar a cota do Gmail rapidamente), varredura de padrões de conteúdo de saída (sem regex de segredos em corpos), phishing de assinatura/férias (a lista de permissão não cobre seu conteúdo), reescrita completa do log por um atacante local. Veja SECURITY.md para o modelo de ameaça atual e roadmap.
Limitações
- Verificação "Produção" do OAuth para
gmail.modifyrequer uma avaliação de segurança paga do Google. Permaneça em "Interno" (Workspace, sem expiração) ou "Teste" (≤ 100 usuários, rotação de token de atualização de 7 dias — veja Expiração de token) para evitar isso. - A composição de corpo de e-mail HTML não é exposta como um campo de primeira classe. Envie via
create_draft+ edição manual de HTML na interface do Gmail, ou estenda_build_mimeem um fork. - Notificações push (Pub/Sub
watch/stop) não implementadas — fora do escopo.
Contribuindo
Issues e PRs são bem-vindos. Mantenha as mudanças escopadas, documente qualquer nova ferramenta com um exemplo de esquema e adicione uma entrada de log de auditoria para qualquer coisa que altere o estado.
Licença
MIT — veja LICENSE.