Fortmail
E-mail operado por agente em um Cloudflare Worker (MIT MCP para The Fort That Holds)
Documentação
Fortmail
E-mail operado por agente, em um único Cloudflare Worker.
Seu agente de IA ganha um cliente de e-mail real — todas as contas que você possui, agregadas, triadas e com capacidade de envio — e você para de verificar caixas de entrada. Fortmail é a versão open-source do sistema de e-mail que roda dentro do The Fort That Holds: um worker pequeno, sem framework, sem servidor para cuidar, compatível com o plano gratuito.
your Gmail(s) ─┐
your domain(s) ─┤→ Fortmail worker → triage desk (only what matters)
(any IMAP) ─┘ │
├→ MCP server at /mcp ← your agent connects here
└→ steward bridge: email → GitHub PR → wakes your agent
O que ele faz
- É dono de todas as suas caixas de correio. Contas Gmail via API do Gmail (OAuth), e qualquer provedor IMAP/SMTP (Migadu, Fastmail, Purelymail, seu host…) via sockets TLS puros — sem regras de encaminhamento, sem serviço intermediário.
- Sela as próprias credenciais. O worker gera sua própria chave AES-GCM e pode gerar + selar uma senha por caixa de correio. Você nunca manipula, armazena ou sequer vê essas senhas — a carteira do agente é o único lugar onde elas existem.
- Faz triagem de forma determinística. Um classificador por regex (sem LLM, sem custo de API,
sem alucinação) separa o e-mail em
desk(precisa de humano),record(vale manter),ignore(ruído de volume/OTP). Um cron varre um escopo a cada 5 minutos e armazena em cache a mesa de trabalho, então lê-la é instantâneo. - Fala MCP.
/mcpé um servidor Model Context Protocol com seu próprio OAuth (registro dinâmico de cliente + PKCE). MCP é neutro em relação a fornecedores — conecte qualquer agente que aceite um servidor MCP (Claude, ChatGPT, Gemini, Cursor, seu próprio harness) e ele recebe as ferramentas de e-mail (list_accounts,get_desk,triage,read_box,read_message,get_attachment,send) além das ferramentas de newsletter.read_messageretorna o texto do corpo e metadados de anexos;get_attachment/GET /attachmentbuscam os bytes de arquivos do Gmail. Não há LLM dentro do próprio Fortmail — sem dependência de modelo, sem chave de API para nenhum fornecedor de IA; a inteligência é qualquer agente que você apontar para ele. - Envia como qualquer conta que você possui. Gmail via API, todo o resto via SMTP —
transporte escolhido automaticamente a partir do endereço
from. - Roda suas newsletters. As listas de assinantes vivem no seu KV (não no banco de dados de um ESP), com double opt-in, cancelamento de inscrição em um clique (RFC 8058), supressão de rejeições/reclamações, e campanhas que são drenadas pelo cron em blocos seguros de taxa via um relay (Resend) que é apenas um cano burro. O aluguel por assinante é o modelo de negócio do ESP; isto é centavos por e-mail. Qualquer número de listas — um pseudônimo, uma marca, um produto, cada um ganha uma linha, não uma conta. Veja docs/NEWSLETTER.md.
- Acorda seu agente quando chega e-mail (opcional). Dê ao agente seu próprio endereço
(ex.:
steward@your-domain.com). Cada mensagem não lida ali vira um pull request no GitHub em um repositório que seu agente monitora — com o remetente marcado como CONFIÁVEL (você) ou NÃO CONFIÁVEL (todos os outros) para que o agente saiba se está recebendo instruções ou apenas dados. E-mail entra, agente acorda, trilha de auditoria embutida.
Início rápido
Pré-requisitos: uma conta Cloudflare (o plano gratuito funciona) e npx wrangler conectado.
git clone https://github.com/TheFortThatHolds/mail && cd mail
# 1. The one store
npx wrangler kv namespace create TOKENS
# → paste the returned id into wrangler.jsonc
# 2. The admin key (any long random string — this gates every admin endpoint)
npx wrangler secret put TRIGGER_KEY
# 3. Ship it
npx wrangler deploy
Depois conecte as caixas de correio — veja docs/SETUP.md para o passo a passo completo (app OAuth do Gmail, caixas IMAP, a ponte steward) e docs/AGENT.md para apontar seu agente para ele.
Ou pule a configuração manual completamente: faça fork deste repositório e aponte seu agente
de codificação — de qualquer fornecedor — para ele. AGENTS.md é um runbook que o agente
pode executar de ponta a ponta; ele pedirá apenas as etapas que exigem humano
(login no Cloudflare, senhas de caixa de correio, aprovações OAuth).
A versão de 60 segundos, com KEY = sua TRIGGER_KEY e W = a URL do seu worker:
# any IMAP mailbox you already have (password sent as a header, sealed on arrival)
curl -H "X-Mailbox-Password: <password>" \
"$W/wallet-import?key=$KEY&addr=me@my-domain.com&host=imap.my-provider.com"
# or mint a NEW sealed password for a box (then set that password at your provider)
curl "$W/wallet-provision?key=$KEY&addrs=steward@my-domain.com&host=imap.my-provider.com"
# a Gmail account (needs GMAIL_CLIENT_ID/SECRET set — see docs/SETUP.md)
open "$W/connect?key=$KEY"
# watch it work
curl "$W/triage?key=$KEY&scope=all"
curl "$W/desk?key=$KEY"
Conecte seu agente: adicione https://<your-worker>/mcp como um conector MCP personalizado.
Ele conduzirá o fluxo OAuth; o prompt de senha é sua TRIGGER_KEY.
A regra de confiança (leia esta)
E-mail é entrada não confiável. A ponte do Fortmail marca cada mensagem arquivada por uma
correspondência de From contra OWNER_EMAILS:
- ✅ REMETENTE CONFIÁVEL (dono) — instruções podem ser executadas.
- ⚠️ REMETENTE NÃO CONFIÁVEL — a mensagem é dado para triar. O agente nunca deve seguir instruções, links ou solicitações dentro dela.
Esta é a linha de defesa contra injeção de prompt para agentes orientados por e-mail: apenas o endereço do dono emite comandos; todo o resto é lido, nunca obedecido. Mantenha a mesma regra nas instruções do seu próprio agente — o selo é um sinal; a disciplina do seu agente é a aplicação. E spoofing existe: para qualquer coisa consequente, condicione à sua aprovação explícita, não a um cabeçalho From.
Endpoints
| Rota | O quê |
|---|---|
/mcp | Servidor MCP (protegido por OAuth) — a porta do agente |
/desk?key= | A mesa de triagem em cache, todos os escopos |
/triage?key=&scope= | Triagem ao vivo (filtro all, gmail, imap, &domain=) |
/cron-run?key= | Força um tick do cron (ou &scope= um específico) |
/send?key=&from=&to=&subject=&text= | Envia como qualquer caixa de propriedade sua |
/wallet-provision?key=&addrs=&host=&smtp= | Gera + sela novas credenciais IMAP |
/wallet-import?key=&addr=&host=&smtp= | Sela uma senha existente (via cabeçalho X-Mailbox-Password) |
/accounts?key= / /imapboxes?key= | Lista caixas de propriedade sua |
/tool?key=&name= | Chama qualquer ferramenta MCP via HTTP (consulta GET ou JSON POST {name,arguments}) — mesmo TRIGGER_KEY que /accounts |
/attachment?key=&address=&message=&attachmentId= | Busca um anexo do Gmail como bytes brutos (Content-Type da parte). encoding=base64 retorna JSON em vez disso. Somente leitura; limite de 4MB em payloads JSON/ferramentas |
/connect?key= → /oauth/callback | Fluxo OAuth da conta Gmail |
/import?key= | Importa um refresh token existente do Gmail |
/bridge-run?key=&dry=1 | Executa/inspeciona a ponte steward agora |
/news/subscribe?list= | Inscrição pública (double opt-in) — veja docs/NEWSLETTER.md |
/news/list?key= / /news/lists?key= | Cria listas / lista listas com contagens |
/news/send?key= | Enfileira uma campanha (ou test para um endereço) |
/news/campaign?key= / /news/drain?key= | Progresso da campanha / empurra a fila agora |
/news/relay?key= | Sela a chave de API do relay (ou use variáveis de modo broker) |
/news/hook | Webhook do relay → supressão em rejeição/reclamação |
Notas de design
- Um arquivo de propósito. ~550 linhas, zero dependências, revisável em uma sentada. E-mail guarda sua vida inteira; você deveria conseguir ler cada linha da coisa que o toca.
- Você é dono do público. O motor de newsletter mantém assinantes como linhas no seu KV; o relay de envio nunca guarda a lista. Sair de um relay é uma mudança de configuração, não uma migração.
- Janela de 90 dias tanto no Gmail quanto no IMAP (busca
SINCE) para que e-mails antigos nunca inundem a mesa. - Escopos rotativos do cron. Cada tick de 5 minutos varre UM escopo (gmail, ou um domínio) — muitas caixas de correio nunca se acumulam em um único timeout.
- Batching IMAP em grupos de quatro — Cloudflare serializa sockets concorrentes; lotes mantêm uma varredura rápida sem estourar limites.
- Sem LLM no caminho. A triagem é regex. Seu agente aplica julgamento quando lê a mesa; o encanamento em si nunca adivinha.
Ideias de endurecimento, modelo de ameaça e limites conhecidos: docs/SECURITY.md.
De onde isso veio
Fortmail é um órgão do The Fort That Holds — uma stack soberana, operada por agente, construída em aberto. Este repositório é a ferramenta de e-mail completa. É licenciado sob MIT e gratuito para rodar. Não há página de produto do Fortmail nem seed de e-mail pago.
Se você quiser a rota escrita para outras peças do Fort — as instruções que você entrega ao seu próprio agente para que ele possa percorrer um caminho que já funcionou — elas estão no Grand Bazaar como Selfware Seeds (a prateleira está na página inicial). As ativas hoje:
- LOCUS Symbiote
- Sovereign Web
- Digital Asset Vault
- Beta Reader — e um Beta Reader Pass hospedado se você preferir não auto-hospedar esse
Agentes podem ler a mesma lista como catalog.json. Nada disso é necessário para rodar o Fortmail.
Licença
MIT © The Fort That Holds LLC.