posta
posta es un cliente de correo IMAP/SMTP chiquito y genérico para tu terminal. Un solo binario, salida JSON por defecto y cuentas con nombre en un archivo TOML — tu casilla queda tan scripteable como cualquier otra API.
El nombre viene de las postas: las estaciones de relevo del correo colonial sudamericano. Y en Argentina, la posta es también lo genuino, la verdad.
$ posta list --unread --max 3 --format table
UID DATE FROM SUBJECT
7121 ● Fri, 17 Jul 2026 17:0… "Proveedor" <facturas@isp.ex… Tu factura está lista
7120 ● Fri, 17 Jul 2026 15:0… Meetup <eventos@meetup.exam… 🚀 Inscripción abierta
7119 ● Fri, 17 Jul 2026 10:1… "banco@example.com" Aviso de tarjeta
$ posta search 'FROM banco UNSEEN' | jq .uids
[7119, 7118, 7117]
Características
- Funciona con cualquier proveedor — IMAP/SMTP con STARTTLS (
imap://,smtp://) o TLS implícito (imaps://,smtps://). Tu propio servidor, Gmail, Fastmail, lo que sea. - Múltiples cuentas — cuentas con nombre en un solo archivo, cambiadas
con
--account,$POSTA_ACCOUNTo undefault_account. - Amigable para scripts — todos los comandos imprimen JSON (canalizalo a
jq), con--format tablepara humanos. - Secretos a tu manera — contraseñas literales (posta revisa los permisos
del archivo y te avisa si están flojos) o
password_cmdpara sacarlas depass, un keyring o cualquier comando. - Seguro por defecto — leer nunca marca mensajes como leídos
(
BODY.PEEKen todos lados); optás con--mark-readoposta mark read. - Sin archivo de config si no querés — todo puede venir de variables de
entorno
POSTA_*, útil para CI y scripts sueltos.
Instalación
git clone https://git.all.ar/pub/posta.git
cd posta
cargo install --path .
Configuración
~/.config/posta/config.toml (o $POSTA_CONFIG, o --config ARCHIVO):
default_account = "personal"
[accounts.personal]
email = "alice@example.com"
display_name = "Alice Example"
imap_url = "imap://alice@example.com@mail.example.com:143"
smtp_url = "smtp://alice@example.com@mail.example.com:587"
password_cmd = "pass show mail/personal" # o: password = "..." (¡chmod 600!)
[accounts.trabajo]
email = "alice@work.example"
imap_url = "imaps://alice@imap.work.example" # TLS implícito, puerto 993
smtp_url = "smtps://alice@smtp.work.example" # TLS implícito, puerto 465
password_cmd = "secret-tool lookup mail trabajo"
sent_folder = "Sent Items"
trash_folder = "Deleted"
El usuario de la URL puede contener @
(imap://alice@example.com@mail.example.com); el host empieza después del
último. imap_password[_cmd] / smtp_password[_cmd] pisan la contraseña
compartida por protocolo cuando difieren.
Las variables de entorno pisan cualquier campo de la cuenta elegida:
POSTA_IMAP_URL, POSTA_SMTP_URL, POSTA_PASSWORD, POSTA_PASSWORD_CMD,
POSTA_IMAP_PASSWORD, POSTA_SMTP_PASSWORD, POSTA_EMAIL,
POSTA_DISPLAY_NAME, POSTA_SENT_FOLDER, POSTA_TRASH_FOLDER,
más POSTA_ACCOUNT y POSTA_CONFIG.
Uso
posta accounts # cuentas configuradas
posta status # totales y sin leer
posta folders # listar carpetas
posta list --unread # más recientes primero
posta list --query 'FROM banco SINCE 1-Jul-2026'
posta get 7119 # headers + cuerpo de texto, en JSON
posta get 7119 --html # preferir la parte HTML
posta get 7119 --raw > msg.eml # fuente RFC 822 crudo
posta send --to bob@example.com --subject 'Hola' --body '¡Hola!'
git log | posta send --to bob@example.com --subject 'Changelog'
posta mark read 7119 7120 # también: unread, flagged, unflagged
posta move 7119 --to Archives
posta delete 7119 # mueve a la papelera
posta search 'FROM banco UNSEEN' # IMAP SEARCH crudo, imprime UIDs
Flags globales: --account/-a NOMBRE, --config ARCHIVO,
--format json|table, y --folder en los comandos que operan sobre una
carpeta.
Cada comando abre una sesión nueva y cierra al terminar; no hay demonio, caché ni estado local.
Notas
sendguarda una copia en la carpeta de enviados vía IMAP (se omite con--no-record).move/deleteusanUID MOVEsi el servidor lo soporta, con fallback aCOPY+\Deleted+EXPUNGE.- TLS es siempre obligatorio; no hay conexiones en texto plano.
Desarrollo
cargo test # tests unitarios + integración del CLI, sin servidor
cargo clippy --all-targets -- -D warnings
cargo fmt --check