mail-mcp
A maioria dos servidores MCP de e-mail apenas lê via IMAP. O mail-mcp faz tudo: 30 ferramentas para ler, pesquisar, enviar, responder, encaminhar e operações em lote através de IMAP, SMTP, Microsoft Graph API e Exchange Web Services. Multi-conta, OAuth2 nativo, construído em Rust. Funciona com Gmail, Microsoft 365, Hotmail/Outlook.com, Zoho e qualquer servidor IMAP/SMTP padrão.
Documentação
mail-mcp
Servidor MCP de e-mail pronto para produção para agentes de IA
IMAP + SMTP + EWS + Microsoft Graph API — construído em Rust
A maioria dos servidores MCP de e-mail só faz leituras via IMAP. Este faz tudo: ler, pesquisar, enviar, responder, encaminhar, operações em lote, Microsoft Graph API e Exchange Web Services — com suporte real a OAuth2, multi-contas e multi-provedores. Escrito em Rust para velocidade e segurança.
Novidades na v0.4.13
effective_from()auxiliar + validação deFROM_EMAILna inicialização por @arwack em #29 — o acompanhamento do #19 deles. O fallback defrom_email→useragora vive em um único lugar (SmtpAccountConfig::effective_from()), eMAIL_SMTP_<ID>_FROM_EMAILé validado quando o servidor inicia, em vez de falhar no primeiro envio.- Mudança de comportamento — leia antes de atualizar: um
FROM_EMAILmalformado (múltiplos@, espaços em branco, parte local vazia ou domínio sem ponto) agora impede o servidor de iniciar, para todas as contas. Observe que domínios sem ponto comouser@localhostoualerts@intranettambém são rejeitados atualmente; se você usa um endereço de relay interno assim, segure a atualização — um acompanhamento relaxando a regra do ponto está em discussão no #29. - Testes de formato de wire do APPEND endurecidos por @tordable em #28: aspas no nome da mailbox, tamanho literal anunciado e payload byte a byte agora são verificados em cada teste de append.
Novidades na v0.4.12
Versão da comunidade — ambas as mudanças vieram de contribuidores externos. Obrigado!
- Aliases de mailbox do iCloud + leituras não marcam mais mensagens como lidas por
@felipefdl em
#16. Nomes curtos de mailbox
agora resolvem para a pasta real de cada provedor (
Sent→Sent Messagesno iCloud /[Gmail]/Sent Mailno Gmail,Trash→Deleted Messages, e assim por diante, multilíngue) em busca, cópia e movimentação. Buscas de mensagens cruas agora usamBODY.PEEK[], então ler uma mensagem pelo MCP não define mais\Seencomo efeito colateral — com um fallback deBODY[]para servidores que rejeitamPEEK(o itemRFC822obsoleto, removido no #23, permanece fora). Validado contra uma mailbox real do iCloud pelo autor; inclui testes de resolução de alias e documentação de configuração do iCloud. - Dockerfile multi-estágio otimizado + docker-compose por
@monssefbaakka em
#5. Cache de camadas do cargo-chef,
cross-builds musl cientes de TARGETARCH (amd64/arm64) e uma imagem de runtime
scratch— 16,9 MB, abaixo dos 25,5 MB — verificada para responder a MCP initialize/tools-list via stdio. O pin da toolchain foi elevado para Rust 1.90 (os let-chains do código exigem >= 1.88).
Novidades na v0.4.11
Versão de correções da comunidade — ambas as correções vieram de contribuidores externos. Obrigado!
- Corrigido: salvar em Enviados falhava silenciosamente em servidores IMAP estritos (iCloud e
outros) por @dominikknafelj em
#26, relatado em
#25. A flag
\Seenintroduzida na v0.4.10 foi enviada sem a sintaxe de lista de flags entre parênteses do RFC 3501 (APPEND "Sent" \Seen …em vez deAPPEND "Sent" (\Seen) …), porqueasync-imapinterpola o argumento de flags literalmente. Servidores estritos rejeitaram o APPEND e a cópia enviada foi perdida — enquanto a ferramenta ainda relatavastatus: ok. As flags agora são normalizadas antes de irem para o wire, e as respostas desmtp_send_message/smtp_reply_message/smtp_forward_messageincluem um novo camposaved_to_sent(true/false, ounullquando salvar está desabilitado) para que chamadores possam detectar falhas de arquivamento. @tordable diagnosticou e corrigiu a mesma causa raiz simultaneamente em #24. - Corrigido: leituras de mensagens retornavam vazias no iCloud por
@tdabasinskas em
#23. Buscas de mensagens cruas
usavam o item
RFC822obsoleto, que o iCloud aceita mas deixa não populado. As buscas agora usam o itemBODY[]do IMAP4rev1 — mesmas semânticas de\Seen, funciona em todos os lugares — com um teste de regressão de servidor mock fixando o formato do wire.
Novidades na v0.4.10
Versão da comunidade — todas as três mudanças vieram de contribuidores externos. Obrigado!
- Compatibilidade com IMAP da NetEase (126.com / 163.com / yeah.net) por
@pep-27 em
#21. Servidores NetEase
rejeitam acesso à mailbox de clientes que não se identificam. O mail-mcp
agora envia o comando
IDdo RFC 2971 após a autenticação sempre que o servidor anuncia a capacidadeID. Inclui testes de regressão com servidor mock e documentação de configuração da NetEase emdocs/account-setup.md. MAIL_SMTP_<ID>_FROM_EMAIL— substituição do endereço do remetente por @arwack em #19. Para mailboxes compartilhadas/de grupo onde o SMTP autentica com uma conta pessoal, mas o endereço De deve ser o endereço do grupo. Aplica-se a enviar, responder (incluindo detecção de endereço próprio em responder a todos) e encaminhar; cai para_USERquando não definido.- Cópias de e-mails enviados agora são marcadas como
\Seenpor @ray-of-darkness em #9. As cópias que o MCP anexa à pasta Enviados após o envio via SMTP não aparecem mais como não lidas.
Novidades na v0.4.9
- Nova ferramenta
imap_get_attachment— baixar um único anexo para o disco. Até agora, as únicas maneiras de acessar os bytes de um anexo eramimap_get_message(que retorna metadados do anexo e texto PDF extraído opcional, nunca o binário) eimap_get_message_raw(limitado a 1 MB e codificado em base64 na resposta). Um e-mail de 7 MB com imagens de raio-X não podia ser recuperado de forma alguma — acima do limite, e despejá-lo na resposta explodiria o contexto do modelo de qualquer forma. - Como funciona: chame
imap_get_attachmentcom omessage_idmais um seletor — oupart_id(o valor queimap_get_messagerelata para cada anexo) oufilename. O servidor busca a mensagem completa (sem limite de tamanho no lado do servidor), extrai e decodifica apenas aquela parte, e a escreve no disco, retornando{ file_path, filename, content_type, part_id, size_bytes }. O binário nunca entra na resposta, então o contexto permanece pequeno. O caminho salvo alimenta diretamente um leitor local (por exemplo, uma ferramenta de descrição de imagem ou um leitor de PDF). - Onde os arquivos vão parar: argumento
output_dirse fornecido, senão a variável de ambienteMAIL_ATTACHMENT_DOWNLOAD_DIR, senão o diretório temporário do sistema. Os nomes de arquivo são sanitizados (apenas basename, caracteres de controle removidos) para prevenir path traversal, e prefixados com o UID da mensagem e o id da parte para evitar colisões. - Base64 inline opcional: defina
include_base64: truepara também obter os bytes na resposta, mas apenas quando o anexo tiver no máximomax_inline_bytes(padrão 256 KiB). Desativado por padrão.
Novidades na v0.4.8
SAVE_SENTagora é por conta com um padrão ciente do provedor. Anteriormente, salvar uma cópia do e-mail enviado na pasta Enviados via IMAP APPEND era controlado por uma única flag global,MAIL_SMTP_SAVE_SENT. O problema: provedores que já salvam e-mails enviados no servidor (Gmail, Zoho) acabavam com duas cópias idênticas em Enviados, enquanto um servidor SMTP genérico ou Office 365 (que não salvam automaticamente no envio via SMTP) perdiam a cópia completamente quando a flag estavafalse.- Padrão ciente do provedor (quando nada está configurado):
- Gmail (
smtp.gmail.com): salva no servidor e deduplica por Message-ID → o MCP não anexa (false). - Zoho (
smtp.zoho.com): salva no servidor, mas não deduplica → o MCP não anexa (false), evitando a duplicata. - Office 365 / SMTP genérico: não salvam automaticamente no envio via SMTP →
o MCP anexa (
true), ou a cópia enviada seria perdida.
- Gmail (
- Substituição por conta:
MAIL_SMTP_<ID>_SAVE_SENT=true|falsetem prioridade sobre tudo. A flag globalMAIL_SMTP_SAVE_SENTainda funciona como uma substituição grosseira (vence o padrão do provedor, perde para a substituição por conta). - Precedência: por conta → global → padrão ciente do provedor.
| Provedor | Salva automaticamente no servidor | Padrão do MCP |
|---|---|---|
| Gmail | Sim (com dedupe) | false |
| Zoho | Sim (sem dedupe) | false |
| Office 365 (SMTP) | Não | true |
| SMTP genérico / relays | Não | true |
Novidades na v0.4.7
- Correção crítica —
graph_send_messagedescartava silenciosamente anexos em respostas em thread. Quando chamado comin_reply_to+attachments, o fluxo decreateReply → PATCH → sendincluía os anexos no PATCH contra/me/messages/{id}. O Microsoft Graph trataMessage.attachmentscomo uma propriedade de navegação e descarta silenciosamente o campo no PATCH (resposta 2xx, sem erro), então a mensagem saía comotext/htmlde parte única sem arquivo. O MCP retornavastatus: oke o chamador assumia sucesso. Perda de dados invisível. - A correção: em
send_via_reply(), os anexos agora são enviados um a um paraPOST /me/messages/{draft_id}/attachmentsentre o PATCH e o envio. Arquivos < 3 MB vão inline (JSON com base64contentBytes); arquivos ≥ 3 MB usamcreateUploadSessioncom PUTs em blocos de 4 MB. O campoattachmentsfoi removido da structPatchDraftRequestpara que a regressão não possa ser reintroduzida por uma edição type-correct. - Nenhuma mudança nos fluxos que já funcionavam.
send_via_sendmail(novas mensagens semin_reply_to) usaPOST /me/sendMailcomattachmentsinline no JSON — o Graph ACEITA o campo nesse endpoint e nunca o descartou. Esse caminho está intocado. - Teste de regressão adicionado:
patch_draft_request_never_serializes_attachmentsfalha se alguém re-adicionar o campo à struct. - Referência:
BUG_GRAPH_ATTACHMENTS.mdna raiz do repositório documenta a reprodução completa, a causa raiz e as evidências empíricas por trás da correção.
Novidades na v0.4.6
- Aplicação no lado do servidor da REGRA RÍGIDA #1. Três versões de endurecimento
apenas por prompt (v0.4.3 → v0.4.4 → v0.4.5) ainda deixavam LLMs ocasionalmente vazando
marcação literal de
</body_text><parameter name="body_html">na caixa de entrada do destinatário. A v0.4.6 adiciona um validador real que rejeita a chamada de ferramenta antes de qualquer tentativa de SMTP / Graph / EWS sebody_textoubody_htmlcontiver sintaxe de wrapper de chamada de ferramenta. A verificação está conectada em todos os 5 caminhos de envio (smtp_send_message,smtp_reply_message,smtp_forward_message,graph_send_message,ews_send_message). - Os marcadores proibidos são insensíveis a maiúsculas/minúsculas e bem delimitados — apenas
as pseudo-tags que não têm uso legítimo em correspondência humana:
<body_text>,</body_text>,<body_html>,</body_html>,<function_calls>,</function_calls>,<invoke name=,</invoke>, e<parameter name="body_*">. Conteúdo técnico genérico que por acaso menciona<parameter>para um esquema XML ou<invoke>em um exemplo de código ainda passa. - Redação da REGRA RÍGIDA #1 atualizada para anunciar a rejeição no lado do servidor, para que o LLM saiba que é um contrato rígido — não uma sugestão que pode ignorar.
- Sem mudanças que quebrem chamadores limpos: mensagens bem comportadas enviam exatamente como antes.
Novidades na v0.4.5
serverInfoagora informaname="mail-mcp"+ o crateversion(o framework anteriormente retornava seu própriormcp 0.16.0, que nunca muda entre versões). Útil para verificar a versão ativa com/mcp, e assim qualquer cache do lado do cliente baseado em (servidor, versão) é invalidado a cada atualização.- Instruções do MCP reorganizadas: as 3 regras críticas anti-concatenação (que nas v0.4.3 e v0.4.4 ficavam no final do bloco e podiam ser perdidas por truncamento / atenção diluída) agora aparecem como REGRA RÍGIDA #1, #2, #3 no TOPO, logo após o título. Consolidadas em 3 parágrafos curtos (anteriormente 3 seções longas, ~1500 caracteres combinados).
- Nenhuma mudança funcional no servidor. Mesmo SMTP/IMAP/EWS/Graph, mesmo conjunto de ferramentas, mesmo comportamento. Apenas o texto exposto ao cliente mudou.
Importante para que essas regras tenham efeito
Clientes que retomam uma sessão com claude --continue (ou /resume) NÃO
atualizam o system_prompt do MCP — eles mantêm o da
primeira handshake daquela sessão. Se sua sessão for anterior à v0.4.5, as regras não
chegarão ao seu contexto mesmo que o binário em disco seja atualizado. Para recebê-las,
inicie uma NOVA sessão no projeto (não --continue).
O que há de novo na v0.4.4
-
Regra de higiene de pré-visualização no
instructionsdo MCP: quando o LLM mostra ao usuário a pré-visualização do e-mail antes de enviar, ele deve renderizar UMA versão limpa do corpo (marcadores estilo markdown, negrito, links como texto + URL) e declarar que a mensagem será multipart — mas NÃO deve despejar o código-fonte HTML bruto (<p>,<strong>,<a href>...) na pré-visualização. Dois motivos:- O revisor humano quer ler a mensagem, não auditar marcação — mostrar o HTML é ruído.
- Exibir tanto a string de texto simples QUANTO a string HTML lado a lado na pré-visualização é exatamente o contexto que historicamente levou LLMs a concatená-las na chamada de ferramenta eventual (o bug documentado na v0.4.3). Ocultar o código-fonte HTML da pré-visualização remove a tentação.
Complementa a regra PRÉ-VISUALIZAÇÃO NÃO É IGUAL A CHAMADA DE FERRAMENTA introduzida na v0.4.3.
O que há de novo na v0.4.3
- Orientação no servidor contra chamadas de ferramenta malformadas. O bloco
instructionsdo MCP agora diz explicitamente ao LLM chamador quebody_textebody_htmlsão DOIS CAMPOS JSON SEPARADOS e devem NUNCA ser concatenados. A redação anterior ("envie AMBOS body_text E body_html") era ambígua e alguns LLMs interpretaram como "concatene ambos com pseudo-tags<body_text>...</body_html>dentro de uma única stringbody_text". Quando isso acontece, o destinatário vê conteúdo duplicado e embaralhado, E qualquer sessão posterior do Claude que abrir a cópia salva via este MCP recebe um bloco de Política de Uso (o<invoke>...</invoke>vazado parece uma tentativa de injeção de prompt para filtros de segurança). A nova instrução mostra um exemplo CORRETO vs ERRADO e proíbe pseudo-tags / sintaxe de wrapper de chamada de ferramenta dentro de campos de e-mail.
O que há de novo na v0.4.2
- Pipeline de release corrigido: o job
publish-npmno fluxo de trabalho de release do CI foi desabilitado. Ele foi herdado do fork upstream e tentava publicar em@bradsjm/mail-imap-mcp-rs, um escopo que esta organização não possui — todo release estava retornando 404 nessa etapa. Veja "Releasing" abaixo para a explicação completa e como reativar a publicação npm se necessário. - Releases com acionamento automático em push de tag:
.github/workflows/release.ymlagora dispara empush: tags: ['v*'], então marcarvX.Y.Ze enviar é tudo o que é preciso para cortar um release.workflow_dispatché mantido como uma saída manual de emergência. - Limpeza: removido o fluxo de trabalho
init-npm-placeholder.ymlpendente (também referenciado o escopo npm do fork). - docs: o README ganha uma seção "Releasing" documentando o novo fluxo e a decisão sobre npm.
O que há de novo na v0.4.1
- Correção:
save_to_sent_folderagora arquiva os bytes RFC822 exatos que foram enviados (vialettre.formatted()), em vez de um stub somente texto feito à mão. A cópia na pasta Enviados mantém o corpo HTML, a estrutura multipart/alternative e o assunto codificado em RFC 2047 — sem mais???onde os acentos costumavam estar, e o HTML não é mais descartado silenciosamente. - Melhoria: detecção localizada da pasta Enviados —
Enviado[s],Elementos enviados,Enviadas,Itens enviados,Envoyés,Éléments envoyés,Gesendet,Posta inviata,Verzonden,Wysłane, além de variantes aninhadas. Anteriormente apenas nomes em inglês eram reconhecidos, então contas Zoho/IMAP localizadas caíam em uma pasta"Sent"inexistente. - Melhoria:
smtp_forward_messageaceitabody_html(antes era fixado em somente texto simples). - Melhoria: o envio via EWS ganha
bcc,in_reply_to,references(via<t:InternetMessageHeaders>), além de validação completa de destinatários + comprimento de assunto — agora em paridade com os caminhos de envio SMTP e Graph. - Melhoria: os fallbacks de threading da API Graph agora registram logs.
WARNquando a chamada HTTP de busca de mensagem falha (limite de taxa, 5xx, permissões) para que operadores vejam threading degradado devido a um erro real;DEBUGquando a mensagem original legitimamente não é encontrada. - Refatoração: a análise XML do EWS migrou de correspondência de substring para
quick-xml. Corrige um bug latente de colisão de namespace (<soap:Body>vs<t:Body>), decodifica corretamente entidades XML e CDATA, e lida com valores de atributos contendo=(comum em IDs de item EWS semelhantes a base64). - Limpeza: zero avisos em
cargo build --release. - Testes: 64 (acima de 47).
Por que este projeto
| mail-mcp | MCP de e-mail típico | |
|---|---|---|
| Leitura/escrita IMAP | 18 ferramentas | 3-5 ferramentas |
| Envio/resposta/encaminhamento SMTP | Sim | Não ou quebrado |
| API Microsoft Graph | Sim | Não |
| EWS (Exchange Web Services) | Sim | Não |
| OAuth2 (XOAUTH2) | Nativo | Não |
| Multi-contas | Sim | Conta única |
| Microsoft 365 + Hotmail | Ambos funcionam | Geralmente nenhum |
| Linguagem | Rust (rápido, seguro) | TypeScript/Python |
| Testes | 64 unitários + integração | Apenas mocks |
| Avisos no build de release | 0 | Varia |
Matriz de recursos
| Provedor | IMAP | SMTP | API Graph | EWS | OAuth2 | Multi-contas |
|---|---|---|---|---|---|---|
| Microsoft 365 (empresa) | Sim | Dependente do admin | Sim | Sim | Sim | Sim |
| Hotmail / Outlook.com | Sim | Bloqueado pela MS | Sim | Sim | Sim | Sim |
| Gmail | Sim | Sim | — | — | Sim | Sim |
| Apple iCloud | Sim | Sim | — | — | — | Sim |
| Zoho | Sim | Sim | — | — | — | Sim |
| Fastmail | Sim | Sim | — | — | — | Sim |
| Qualquer servidor IMAP/SMTP | Sim | Sim | — | — | — | Sim |
EWS é a maneira mais simples de adicionar contas Microsoft — um único token OAuth2 para leitura e envio. Funciona até em tenants que bloqueiam a API Graph e IMAP.
Início rápido — Deixe o Claude Code fazer isso
Copie e cole este prompt no Claude Code e ele instalará, compilará e configurará tudo para você:
Install and configure the mail-mcp MCP server from https://github.com/tecnologicachile/mail-mcp
1. Clone the repo, build with cargo build --release
2. Add the MCP server to .claude.json with the binary path
3. For Microsoft accounts: use EWS (simplest) — run device code flow with
client_id d3590ed6-52b3-4102-aeff-aad2292ab01c and scope
https://outlook.office365.com/EWS.AccessAsUser.All offline_access
Then configure MAIL_EWS_<ID>_USER and MAIL_EWS_<ID>_REFRESH_TOKEN
4. For Gmail: configure MAIL_IMAP + MAIL_SMTP with App Password from
https://myaccount.google.com/apppasswords
5. For Zoho: configure MAIL_IMAP + MAIL_SMTP with standard password
6. Enable write/send: MAIL_IMAP_WRITE_ENABLED=true, MAIL_SMTP_WRITE_ENABLED=true
My email accounts to configure:
- <your-email@example.com>
Substitua a última linha pelo(s) seu(s) e-mail(s). O Claude Code o guiará por cada etapa, incluindo o fluxo de código de dispositivo OAuth2 para contas Microsoft.
Configuração manual (2 minutos)
git clone https://github.com/tecnologicachile/mail-mcp.git
cd mail-mcp
cargo build --release
Adicione à configuração do seu cliente MCP (Claude Code, Cursor, etc.):
{
"mcpServers": {
"mail": {
"command": "./target/release/mail-mcp",
"env": {
"MAIL_IMAP_DEFAULT_HOST": "imap.gmail.com",
"MAIL_IMAP_DEFAULT_USER": "you@gmail.com",
"MAIL_IMAP_DEFAULT_PASS": "your-app-password",
"MAIL_SMTP_DEFAULT_HOST": "smtp.gmail.com",
"MAIL_SMTP_DEFAULT_PORT": "587",
"MAIL_SMTP_DEFAULT_USER": "you@gmail.com",
"MAIL_SMTP_DEFAULT_PASS": "your-app-password",
"MAIL_SMTP_DEFAULT_SECURE": "starttls",
"MAIL_IMAP_WRITE_ENABLED": "true",
"MAIL_SMTP_WRITE_ENABLED": "true"
}
}
}
}
É isso. Seu agente de IA agora pode ler, pesquisar, enviar, responder e gerenciar e-mails.
Conta Microsoft? Use a API Graph
A Microsoft bloqueia SMTP em contas pessoais. Use a API Graph em vez disso:
{
"env": {
"MAIL_IMAP_DEFAULT_HOST": "outlook.office365.com",
"MAIL_IMAP_DEFAULT_USER": "you@hotmail.com",
"MAIL_IMAP_DEFAULT_PASS": "your-app-password",
"MAIL_OAUTH2_DEFAULT_PROVIDER": "microsoft",
"MAIL_OAUTH2_DEFAULT_CLIENT_ID": "9e5f94bc-e8a4-4e73-b8be-63364c29d753",
"MAIL_OAUTH2_DEFAULT_CLIENT_SECRET": "none",
"MAIL_OAUTH2_DEFAULT_REFRESH_TOKEN": "<your-token>"
}
}
Obtenha seu token em 1 minuto com o fluxo de código de dispositivo. Veja Guia de configuração de conta.
31 Ferramentas MCP
Leitura (9 ferramentas)
| Ferramenta | O que faz |
|---|---|
list_all_accounts | Lista todas as contas com capacidades (IMAP, SMTP, Graph, EWS) |
imap_list_accounts | Lista contas IMAP |
imap_verify_account | Testa conectividade e autenticação |
imap_list_mailboxes | Lista pastas |
imap_mailbox_status | Contagens de mensagens |
imap_search_messages | Pesquisa com paginação por cursor |
imap_get_message | Mensagem analisada (texto, HTML, anexos) |
imap_get_message_raw | Fonte RFC822 |
imap_get_attachment | Baixa um anexo para o disco (ignora o limite de tamanho bruto) |
Escrita (11 ferramentas)
| Ferramenta | O que faz |
|---|---|
imap_update_message_flags | Adiciona/remove flags |
imap_copy_message | Copia (suporta entre contas) |
imap_move_message | Move para pasta |
imap_delete_message | Exclui com confirmação |
imap_create_mailbox | Cria pasta |
imap_delete_mailbox | Exclui pasta |
imap_rename_mailbox | Renomeia pasta |
imap_append_message | Acrescenta mensagem bruta |
imap_bulk_move | Move até 500 de uma vez |
imap_bulk_delete | Exclui até 500 de uma vez |
imap_bulk_update_flags | Marca até 500 de uma vez |
Envio (5 ferramentas)
| Ferramenta | O que faz |
|---|---|
smtp_send_message | Envia e-mail (texto/HTML, CC/CCO) |
smtp_reply_message | Responde com cabeçalhos de threading |
smtp_forward_message | Encaminha com original inline |
smtp_verify_account | Testa conectividade SMTP |
graph_send_message | Envia via API Microsoft Graph (com threading de resposta) |
EWS — Exchange Web Services (3 ferramentas)
| Ferramenta | O que faz |
|---|---|
ews_search_messages | Pesquisa e-mails via EWS (caixa de entrada, enviados, rascunhos, etc.) |
ews_get_message | Obtém conteúdo completo do e-mail via EWS |
ews_send_message | Envia e-mail via EWS |
Anexos
Envie arquivos com qualquer ferramenta de envio. Dois modos:
// Large files — MCP reads from disk (recommended)
"attachments": [{"file_path": "/path/to/report.pdf"}]
// Small files — inline base64
"attachments": [{"filename": "note.txt", "content_type": "text/plain", "content_base64": "SGVsbG8="}]
Nome do arquivo e tipo MIME são detectados automaticamente pelo caminho do arquivo. Responda com include_original_attachments: true para encaminhar anexos originais.
Baixando um anexo de uma mensagem recebida: use imap_get_attachment
com o message_id e um part_id (de imap_get_message) ou filename.
Ele grava o arquivo decodificado no disco e retorna o caminho — sem limite de tamanho, e o
binário fica fora da resposta. Defina o diretório de download padrão com
MAIL_ATTACHMENT_DOWNLOAD_DIR (usa o diretório temporário do sistema como fallback), ou passe
output_dir por chamada.
Operações em lote (2 ferramentas)
| Ferramenta | O que faz |
|---|---|
imap_search_and_move | Pesquisa + move correspondências |
imap_search_and_delete | Pesquisa + exclui correspondências |
Auxiliar de configuração (1 ferramenta)
| Ferramenta | O que faz |
|---|---|
get_setup_guide | Instruções de configuração específicas do provedor (Microsoft OAuth2, Senhas de aplicativo Gmail/iCloud, Zoho, etc.) |
Multi-contas
Configure quantas contas precisar:
# Gmail
MAIL_IMAP_GMAIL_HOST=imap.gmail.com
MAIL_IMAP_GMAIL_USER=me@gmail.com
MAIL_IMAP_GMAIL_PASS=app-password
# Apple iCloud (App-Specific Password from appleid.apple.com)
MAIL_IMAP_ICLOUD_HOST=imap.mail.me.com
MAIL_IMAP_ICLOUD_USER=you@icloud.com
MAIL_IMAP_ICLOUD_PASS=app-specific-password
MAIL_SMTP_ICLOUD_HOST=smtp.mail.me.com
MAIL_SMTP_ICLOUD_USER=you@icloud.com
MAIL_SMTP_ICLOUD_PASS=app-specific-password
MAIL_SMTP_ICLOUD_SECURE=starttls
# Microsoft 365
MAIL_IMAP_WORK_HOST=outlook.office365.com
MAIL_IMAP_WORK_USER=me@company.com
MAIL_OAUTH2_WORK_PROVIDER=microsoft
MAIL_OAUTH2_WORK_CLIENT_ID=your-client-id
MAIL_OAUTH2_WORK_CLIENT_SECRET=none
MAIL_OAUTH2_WORK_REFRESH_TOKEN=your-token
# Zoho
MAIL_IMAP_DEFAULT_HOST=imap.zoho.com
MAIL_IMAP_DEFAULT_USER=info@mydomain.com
MAIL_IMAP_DEFAULT_PASS=password
MAIL_SMTP_DEFAULT_HOST=smtp.zoho.com
MAIL_SMTP_DEFAULT_USER=info@mydomain.com
MAIL_SMTP_DEFAULT_PASS=password
MAIL_SMTP_DEFAULT_SECURE=starttls
Use account_id em chamadas de ferramenta: "account_id": "gmail", "account_id": "icloud", "account_id": "work", "account_id": "default".
Segurança
- TLS obrigatório em todas as conexões (exceto proxies localhost)
- Senhas em SecretString — nunca registradas em logs ou retornadas em respostas
- Operações de escrita protegidas — exigem
MAIL_IMAP_WRITE_ENABLED=trueexplícito - Operações de envio protegidas — exigem
MAIL_SMTP_WRITE_ENABLED=trueexplícito - Confirmação de exclusão — exige
confirm: true - HTML sanitizado com ammonia (previne XSS)
- Saídas limitadas — texto do corpo, HTML, anexos truncados para limites configuráveis
- Tokens OAuth2 em cache com margem de atualização de 10 minutos
- Sem segredos nas respostas — credenciais nunca expostas via ferramentas MCP
Referência de configuração
Referência completa de variáveis de ambiente
IMAP (por conta)
| Variável | Obrigatória | Padrão | Descrição |
|---|---|---|---|
MAIL_IMAP_<ID>_HOST | Sim | — | Servidor IMAP |
MAIL_IMAP_<ID>_PORT | Não | 993 | Porta IMAP |
MAIL_IMAP_<ID>_USER | Sim | — | Nome de usuário |
MAIL_IMAP_<ID>_PASS | Sim* | — | Senha (*opcional com OAuth2) |
MAIL_IMAP_<ID>_SECURE | Não | true | Usar TLS |
SMTP (por conta)
| Variável | Obrigatório | Padrão | Descrição |
|---|---|---|---|
MAIL_SMTP_<ID>_HOST | Sim | — | Servidor SMTP |
MAIL_SMTP_<ID>_PORT | Não | 587 | Porta SMTP |
MAIL_SMTP_<ID>_USER | Sim | — | Nome de usuário |
MAIL_SMTP_<ID>_PASS | Não | — | Senha (opcional com OAuth2) |
MAIL_SMTP_<ID>_SECURE | Não | starttls | starttls, tls ou plain |
MAIL_SMTP_<ID>_FROM_EMAIL | Não | = _USER | Endereço do remetente quando difere do nome de usuário de autenticação SMTP (ex.: caixas de correio compartilhadas/de grupo) |
OAuth2 (por conta)
| Variável | Obrigatório | Padrão | Descrição |
|---|---|---|---|
MAIL_OAUTH2_<ID>_PROVIDER | Sim | — | google ou microsoft |
MAIL_OAUTH2_<ID>_CLIENT_ID | Sim | — | ID do cliente OAuth2 |
MAIL_OAUTH2_<ID>_CLIENT_SECRET | Sim | — | Segredo do cliente (none para clientes públicos) |
MAIL_OAUTH2_<ID>_REFRESH_TOKEN | Sim | — | Token de atualização |
OAuth2 da Graph API (por conta)
| Variável | Obrigatório | Padrão | Descrição |
|---|---|---|---|
MAIL_GRAPH_<ID>_PROVIDER | Sim | — | microsoft |
MAIL_GRAPH_<ID>_CLIENT_ID | Sim | — | ID do cliente OAuth2 |
MAIL_GRAPH_<ID>_CLIENT_SECRET | Sim | — | Segredo do cliente (none para clientes públicos) |
MAIL_GRAPH_<ID>_REFRESH_TOKEN | Sim | — | Token de atualização (escopo Mail.Send) |
EWS — Exchange Web Services (por conta, mais simples para Microsoft)
| Variável | Obrigatório | Padrão | Descrição |
|---|---|---|---|
MAIL_EWS_<ID>_USER | Sim | — | Endereço de e-mail |
MAIL_EWS_<ID>_REFRESH_TOKEN | Sim | — | Token de atualização OAuth2 (escopo EWS) |
MAIL_EWS_<ID>_CLIENT_ID | Não | d3590ed6... (Microsoft Office) | ID do cliente OAuth2 |
MAIL_EWS_<ID>_CLIENT_SECRET | Não | none | Segredo do cliente |
Dica: EWS precisa apenas de 2 variáveis (USER + REFRESH_TOKEN). O ID do cliente usa como padrão o Microsoft Office, que tem todas as permissões pré-aprovadas.
Configurações Globais
| Variável | Padrão | Descrição |
|---|---|---|
MAIL_IMAP_WRITE_ENABLED | false | Ativar operações de escrita IMAP |
MAIL_SMTP_WRITE_ENABLED | false | Ativar operações de envio SMTP/Graph |
MAIL_SMTP_SAVE_SENT | false | Salvar e-mails enviados na pasta Enviados do IMAP (ative se seu provedor não salvar automaticamente no envio — ex.: Gmail salva, Zoho nem sempre) |
MAIL_SMTP_CONNECT_TIMEOUT_MS | 30000 | Timeout SMTP TCP/TLS/auth (fase de conexão) |
MAIL_SMTP_SEND_TIMEOUT_MS | 300000 | Timeout de transmissão SMTP DATA (5 min — acomoda anexos grandes) |
MAIL_SMTP_TIMEOUT_MS | (obsoleto) | Timeout único legado. Usado como fallback para MAIL_SMTP_SEND_TIMEOUT_MS. Prefira as variáveis separadas acima. |
MAIL_IMAP_CONNECT_TIMEOUT_MS | 30000 | Timeout de conexão TCP |
MAIL_IMAP_GREETING_TIMEOUT_MS | 15000 | Timeout TLS/saudação |
MAIL_IMAP_SOCKET_TIMEOUT_MS | 300000 | Timeout de I/O de socket |
Roadmap
- Operações de leitura IMAP (busca, recuperação, análise)
- Operações de escrita IMAP (copiar, mover, excluir, sinalizadores)
- Operações em lote IMAP (até 500 por chamada)
- Paginação baseada em cursor com TTL
- Envio, resposta e encaminhamento SMTP
- Microsoft Graph API (sendMail)
- OAuth2 XOAUTH2 (Google + Microsoft)
- Tokens separados da Graph API para empresas
- Multi-contas via variáveis de ambiente
- Extração de texto PDF de anexos
- Sanitização de HTML (ammonia)
- Documentação de configuração do provedor com links diretos
- Envio de anexos (SMTP/Graph)
- Responder com anexos originais
- Sanitização CDATA (correção de bug do Zoho)
- Protocolo de confirmação de e-mail (pré-visualização antes do envio)
- Instruções otimizadas para tokens (redução de 75%)
- Ferramenta de guia de configuração sob demanda
- EWS (Exchange Web Services) — token único para leitura + envio no Microsoft
- EWS com Microsoft Office Client ID (funciona em locatários restritos)
- Threading da Graph API — fluxo
createReplypara threading adequado de conversas - Orientação de formatação HTML — LLM prefere multipart (texto + HTML) para e-mails humanos
- Arquivamento na pasta Enviados preserva MIME completo — cópia byte-idêntica do que o destinatário recebeu (v0.4.1)
- Detecção localizada da pasta Enviados — espanhol / português / francês / alemão / italiano / holandês / polonês (v0.4.1)
- Paridade de recursos EWS com SMTP/Graph — BCC, cabeçalhos de threading, validação de destinatário (v0.4.1)
- Parser XML EWS via
quick-xml— tratamento correto de entidades/CDATA/namespaces (v0.4.1)
Próximo — Cache local com busca instantânea
- Cache local de e-mail SQLite + FTS5 — buscas instantâneas (<10ms vs 3-10s)
- Sincronização incremental — UIDVALIDITY + sincronização delta do último UID
- Pool de conexões — sessões IMAP persistentes por conta
- Busca entre contas — buscar em todas as contas de uma vez
- Estatísticas de e-mail — contagens, principais remetentes, atividade por data
Futuro
- Imagem Docker
- Distribuição npm/npx
- Gerenciamento de rascunhos
- Busca de contatos
- IMAP IDLE (notificações em tempo real)
- Site de documentação hospedado
Documentação
| Guia | Descrição |
|---|---|
| Configuração de Conta | Passo a passo por provedor, OAuth2, Senhas de App, Azure Client ID |
| Contrato de Ferramentas | Definições e esquemas completos das ferramentas |
| Formato de ID de Mensagem | Formato estável do identificador de mensagem |
| Paginação por Cursor | Comportamento e expiração da paginação |
| Segurança | Recursos de segurança e melhores práticas |
| Configuração Avançada | Timeouts e ajuste de desempenho |
Desenvolvimento
cargo test # 64 unit + integration tests
cargo fmt -- --check # formatting
cargo clippy --all-targets -- -D warnings # linting
Consulte AGENTS.md para diretrizes de contribuidores.
Lançamentos
Os lançamentos são automatizados via cargo-dist. Para publicar uma nova versão:
- Atualize
version = "X.Y.Z"emCargo.toml(o fluxo de trabalho de lançamento garante que isso corresponda à tag enviada). - Faça commit do incremento + quaisquer notas de versão em
main. - Crie a tag e envie:
git tag vX.Y.Z git push origin main --tags - O gatilho
push: tags: ['v*']em.github/workflows/release.ymlcompila binários para Linux / macOS (Intel + Apple Silicon) / Windows, gera scripts de instalação (.sh,.ps1), cria o GitHub Release e anexa todos os artefatos com somas SHA256. - Se algo falhar, você pode executar novamente o fluxo de trabalho manualmente na aba
Actions (o gatilho
workflow_dispatché preservado como saída de emergência).
A publicação no npm está intencionalmente desativada. O fork upstream foi
configurado para publicar como @bradsjm/mail-imap-mcp-rs, um escopo que esta
organização não possui, o que fazia cada lançamento retornar 404 no npm publish. O tarball npm ainda é gerado e anexado a cada GitHub
Release para que os usuários possam instalar via npm install ./mail-mcp-npm-package.tar.gz
manualmente. Para habilitar a publicação no registro npm para este fork: crie uma
org npm (ex.: @tecnologicachile), configure Trusted Publishing em
npmjs.com apontando para este repositório, defina publish-jobs = ["npm"] em
dist-workspace.toml e execute dist generate --allow-dirty para restaurar
o job publish-npm em release.yml.
Contribuindo
Contribuições são bem-vindas! Confira as issues para boas primeiras issues.
Licença
Licença MIT — consulte LICENSE para detalhes.