1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# posta
> *[Read this in English](README.md)*
**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.
```console
$ 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_ACCOUNT` o un `default_account`.
- **Amigable para scripts** — todos los comandos imprimen JSON (canalizalo a
`jq`), con `--format table` para humanos.
- **Secretos a tu manera** — contraseñas literales (posta revisa los permisos
del archivo y te avisa si están flojos) o `password_cmd` para sacarlas de
`pass`, un keyring o cualquier comando.
- **Seguro por defecto** — leer nunca marca mensajes como leídos
(`BODY.PEEK` en todos lados); optás con `--mark-read` o `posta 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
```sh
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`):
```toml
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
```sh
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
- `send` guarda una copia en la carpeta de enviados vía IMAP (se omite con
`--no-record`).
- `move`/`delete` usan `UID MOVE` si el servidor lo soporta, con fallback a
`COPY` + `\Deleted` + `EXPUNGE`.
- TLS es siempre obligatorio; no hay conexiones en texto plano.
## Desarrollo
```sh
cargo test # tests unitarios + integración del CLI, sin servidor
cargo clippy --all-targets -- -D warnings
cargo fmt --check
```
## Licencia
[MIT](LICENSE)
|