Skip to main content

Command-line client for Italian PEC (Posta Elettronica Certificata) — built for AI agents and developers.

Project description

pec-cli

Command-line client for PEC (Posta Elettronica Certificata — Italian certified email), built for both humans and AI agents. Designed to be context-efficient: the default output strips empty fields, and --json produces NDJSON suitable for piping into LLMs or jq.

Talks to the standard IMAP/SMTP endpoints exposed by Italian PEC providers (Aruba, Legalmail/InfoCert, Namirial, Register.it, Poste Italiane, Pec.it), all over SSL/TLS.

Part of MayAI CLI.

Requirements

  • Python 3.11+
  • A working PEC account from one of the supported providers

Installation

From PyPI (recommended):

pip install mayai-pec-cli

The package installs a single pec command on your PATH.

From source:

git clone https://github.com/mayai-it/pec-cli.git
cd pec-cli
make install

For local development (adds pytest, ruff):

make dev

Quick start

# 1. Authenticate (password prompted interactively, never passed as a flag)
pec auth login --address mia@pec.it --provider aruba

# 2. Verify
pec auth status

# 3. List the 20 most recent PECs in the inbox as NDJSON
pec --json list

# 4. Filter to unread, since a given date
pec --json list --unread --from 2025-01-01 --limit 50

# 5. Read a single message and save its attachments to ./attachments
pec get 1234 --save-attachments ./attachments

# 6. Inspect the parsed PEC certification (daticert.xml) for a message
pec get 1234 --cert --json

# 7. Trace the full receipt chain for an original message id
pec trace 'opec123.20260321102500.12345.67.1.1@pec.it'

# 8. Send a PEC with an attachment
pec send --to dest@pec.it --subject "Oggetto" --file body.txt --attach doc.pdf

Command reference

Command Description
pec auth login --address ADDR --provider P Prompt for password, verify via IMAP, save credentials in the system keyring (Fernet-encrypted file as fallback).
pec auth status Show whether credentials are present.
pec auth logout Delete saved credentials (keyring entry + any local encryption key).
pec list [--folder F] [--unread] [--from YYYY-MM-DD] [--limit N] List PEC messages (default folder inbox, default limit 20).
pec get <id> [--folder F] [--save-attachments DIR] [--cert] Fetch a single PEC by IMAP UID; --cert includes the parsed daticert.xml certification; --save-attachments writes attachments to DIR.
pec trace <message-id> [--folder F] [--limit N] Find every receipt in the folder whose daticert.xml references this message id, ordered chronologically (accettazionepresa-in-caricoavvenuta-consegna / errore-consegna).
`pec send --to ADDR --subject S (--body T --file F) [--attach F] [--cc ADDR] [--dry-run]`

Global flags

These work in any position (before or after the subcommand):

Flag Effect
--json Emit one JSON object per line (NDJSON).
--verbose Log IMAP/SMTP timings and certification metadata to stderr.
-h, --help Show help for the current command.

Exit codes

Code Meaning
0 Success
1 Application error (network, send failure, bad arguments)
2 Not authenticated — run pec auth login

Supported providers

Provider --provider IMAP SMTP
Aruba PEC aruba imaps.pec.aruba.it:993 smtps.pec.aruba.it:465
Legalmail (InfoCert) legalmail imapmail.legalmail.it:993 smtpmail.legalmail.it:465
Namirial namirial imap.namirialpec.it:993 smtp.namirialpec.it:465
Register.it register imap.pec.register.it:993 smtp.pec.register.it:465
Poste Italiane poste imappec.poste.it:993 smtppec.poste.it:465
Pec.it pec.it imap.pec.it:993 smtp.pec.it:465

All providers use implicit SSL/TLS (IMAPS:993 / SMTPS:465). Username is the full PEC address; the password is the one provided by the PEC provider.

Authentication

PEC is plain IMAP/SMTP with SSL — there's no OAuth. pec auth login:

  1. Prompts you for the password on stderr (never echoed, never on argv).
  2. Verifies it by opening an IMAP connection and logging in.
  3. Stores the password in the system keyring — macOS Keychain, Linux Secret Service, or Windows Credential Locker (DPAPI) — under the service name mayai-cli-pec and the PEC address as the username.
  4. Writes a small metadata file at ~/.config/mayai-cli/pec/credentials.json (mode 0600) recording the address, provider, and where the password lives.

On headless boxes or CI where no keyring backend is available, the CLI transparently falls back to Fernet encryption: a 32-byte key at ~/.config/mayai-cli/pec/key.bin (mode 0600) encrypts the password inside credentials.json. Existing installs that still have a key.bin are migrated to the keyring on the next pec auth login (and key.bin is then removed).

pec auth logout clears the keyring entry and removes the on-disk files. The password is never written to plain disk and never accepted via a command-line flag.

Output format

  • Default — compact human-readable text. Empty / null fields are stripped so terminal output stays scannable.
  • --json — NDJSON. One object per line; lists stream one element per line so consumers can process incrementally.
  • --verbose — adds protocol timing lines on stderr (e.g. imap: connected to imaps.pec.aruba.it:993 as mia@pec.it (284ms)), and surfaces the PEC certification attachments (daticert.xml, postacert.eml, smime.p7s/p7m) that are normally hidden.

Errors always go to stderr, prefixed with error:.

What pec list returns

Each row carries the IMAP UID (id), a normalized ISO date, the sender, the subject, the PEC type (accettazione, consegna, errore, preavviso, …) when present, and read/attachment flags.

What pec get returns

The full message — from, to, cc, subject, date, plain-text body (HTML body too with --verbose), and the attachment list with each attachment's filename and size in bytes.

PEC messages that carry a daticert.xml certification (every receipt and every sent PEC) get an extra pec_cert_type field in the default output, e.g. "avvenuta-consegna". Pass --cert to also include the fully parsed certification (tipo, mittente, destinatari, data, identificativo, riferimento_message_id, oggetto, optional errore):

pec get 1234 --cert --json

By default the PEC certification files (daticert.xml, postacert.eml, smime.p7s, smime.p7m) are filtered out of both the listed attachments and the saved files; pass --verbose to include them. Use --save-attachments DIR to write attachments to disk under DIR (created if it doesn't exist).

What pec trace returns

pec trace <message-id> scans recent PECs in a folder (default inbox, --limit 200), reads each daticert.xml, and returns the chain whose riferimento_message_id matches the given id, sorted chronologically:

{
  "message_id": "opec123.20260321102500.12345.67.1.1@pec.it",
  "events": [
    {"id": "204", "tipo": "accettazione",     "data": "2026-03-21T10:25:00+01:00", "...": "..."},
    {"id": "205", "tipo": "presa-in-carico",  "data": "2026-03-21T10:25:04+01:00", "...": "..."},
    {"id": "206", "tipo": "avvenuta-consegna","data": "2026-03-21T10:25:07+01:00", "...": "..."}
  ],
  "count": 3
}

The argument is the certified identificativo of the original message — the same value pec get --cert returns under pec_cert.identificativo. Surround or strip <...> brackets as you wish; the CLI normalizes them.

Development

make dev       # install with dev extras
make test      # run pytest
make lint      # run ruff
make clean     # remove caches and build artifacts

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mayai_pec_cli-0.1.0.tar.gz (22.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mayai_pec_cli-0.1.0-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

File details

Details for the file mayai_pec_cli-0.1.0.tar.gz.

File metadata

  • Download URL: mayai_pec_cli-0.1.0.tar.gz
  • Upload date:
  • Size: 22.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for mayai_pec_cli-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c755d21a2c1f9f76c2bddf17a86a03c66f933aa68edf6bb041c252e526585b80
MD5 ae5dd4936320f563f54b0ce8f7cbdcd6
BLAKE2b-256 0594c77f217fa981a1ee9116108981868a7d805ecd30a03ba2d703dd814ffedb

See more details on using hashes here.

File details

Details for the file mayai_pec_cli-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mayai_pec_cli-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 24.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for mayai_pec_cli-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bc98e1a584fe16e9d284d8ad44ee399ade1a74a39eef2ba845e2af3be271bddf
MD5 d1c6828c71e21061d1d3af58adcce276
BLAKE2b-256 a50c893c3e893b9dcd332a703aeca9fbe5bf93432027bf9115652efe5a754565

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page