sessionmail
Mail for coding agents: message moves messages, pager alerts, memory
is the filesystem view - three commands over one maildir.
Quick start
claude plugin marketplace add sessionkit/sessionmail
claude plugin install sessionmail
uv tool install sessionmail # the commands the plugin calls
pager listen # blocks until mail arrives, then says so
Both of the first two lines need the repo and the release to be public: see Status, under Installation, before you copy them.
The last line is the point: an agent that runs pager listen in the
background can be reached while it is idle, instead of finding out on its
next manual check. Under an interactive Claude Code seat the plugin does
it for you: its pager monitor listens from launch, on by default (see
the pager monitor). The hand pager listen is for headless
(claude -p) seats, seats where the monitor is switched off, and clients
outside Claude Code.
message send NAME -s SUBJECT -f BODY.md # and list, tree, read, mark
pager listen # block until mail; page; exit
pager status # what would page you now
memory ls / | memory cat PATH # the box as a filesystem
Each command's own --help is the reference; <command> <verb> --help is
the page for a verb.
Installation
Two installs, and you need both. The plugin brings the skills, the two
hooks and the MCP servers; the package brings message, pager and
memory, which is what all of those call.
claude plugin install sessionmail # skills, hooks, MCP entries
uv tool install sessionmail # the three commands on PATH
On Claude Code 2.1.275 or later the plugin installs from its marketplace in one step, from inside a session:
/plugin install sessionmail --marketplace sessionkit/sessionmail
With only the plugin, the hooks exit quietly and the MCP servers do not start: you get skills describing commands the machine does not have. The hook says so once per session rather than leaving you to guess.
Same-host mail needs no mail server.
message sendwrites each copy straight into this host's maildirs: the file drop, the default. Mail to another host is refused by name.- Reading needs no server either:
message list,tree,readandmark,pagerandmemoryall read the maildir directly. - Mail across machines goes through postfix, which is opt-in: postfix configuration.
Then make the host ready with message setup: message
setup.
message setup --dry-run # print the plan; change nothing
message setup --box NAME # the mail root, the boxes, the notmuch profile
notmuch --config="$HOME/.config/notmuch/sessionkit/config" new # once, as setup says
message setup # again: it links the notmuch hook
- It makes the mail root, the operator's box and each
--box NAME(the file drop never makes a box), and sessionmail's own notmuch profile. It links notmuch's post-new hook into that profile's hook folder. It prints its whole plan before it applies any of it, and it is safe to re-run. - It never touches your own notmuch config, never edits postfix, and writes no settings key.
- Nothing runs
notmuch newfor you.message markandmemoryread an empty index until something does: launchd, cron, or by hand.
Status. sessionmail 0.0.1 on PyPI is a name reservation, not this
code - a 1.3 KB placeholder with no dependencies.
Until 0.2.0 ships, install from source instead of the uv tool install sessionmail line above:
uv tool install git+https://github.com/sessionkit/sessionmail # from the repo
make install # from a clone
message, pager and memory all run; the specs, in the git repository
(the release archive leaves them out), say what each verb is meant to do
and make progress counts how much of it is built.
Uninstall
claude plugin uninstall sessionmail # skills, hooks, MCP entries
uv tool uninstall sessionmail # the three commands
rm ~/.mail/.notmuch/hooks/post-new ~/.mail/.notmuch/hooks/post-insert # the linked hook (in notmuch's database.hook_dir)
notmuch --config="$HOME/.config/notmuch/sessionkit/config" config set sessionmail.post_new_command # the optional command, off
rm ~/.config/notmuch/sessionkit/config # sessionmail's notmuch profile (its index stays in ~/.mail/.notmuch)
Configuration
Which files, which environment variables, and where each one lives, one component at a time: configuration.
- sessionmail:
~/.sessionkit/mail/settings/mail.jsonfor the host, and one for a seat or a session if you want them. Its keys: settings. - postfix, only to send:
/etc/postfix/main.cf, root's and set once, and the two maps the generator writes as you, in/usr/local/etc/postfix-agents/. - notmuch, the index: sessionmail's own profile,
~/.config/notmuch/sessionkit/config. Your own~/.notmuch-configis never read. - Environment variables: each settings key has one (the
sendmailkey's isSESSIONMAIL_SENDMAIL). When it is set and not empty, it wins over the file.
Logs
sessionmail keeps four logs. Each is written only when it has something to record:
~/.session/sessions/<session-id>/log/mail/pager.jsonl: one row for each thing the pager put into an agent's context, sizes and Message-IDs only (the pager log). Past 16 MB it becomespager.1.jsonl.~/.session/sessions/<session-id>/log/settings.jsonl, and the same file under~/.session/seats/<seat>/: each settings change for that session or seat, such as a subscription or its address, with the command that made it.~/.mail/.state/regen-failures.log: each time the map generator refused to rewrite the alias map, and why.~/.sessionmail/post-new/log: the post-new command's runs and output, only once you set one. Past 1 MiB it becomeslog.1.
Follow one as it grows with tail -F, for example
tail -F ~/.mail/.state/regen-failures.log. pager status ends its
today: line with the path of this session's pager.jsonl.
- Health:
pager status, run by the agent.monitor: armed (pid N), or a handpager listennamed on that line, means something is listening for its mail;not armedoroffalone means nothing is. Exit 2 means it could not look (no session, or no box yet). It does not test sending:message sendexits 3 when the mail server did not take the message.
Docs
Everything else is in docs/, one subject per file:
- The pager, the model in one page; how
pager listenworks; the pager monitor; not running under Claude Code; what the pager injects. - Three hidden verbs:
message seat, a seat with no Claude session;message receipt, what another session recorded; andmessage setup, making a host ready. - Gating on
message verify --json: the verdict as one JSON object. - Delivery: where mail comes from, postfix configuration, the file drop.
- Configuration: the files you set up, by component;
settings, the keys of
mail.json. - Index: notmuch, notmuch settings, the post-new command.
- The plugin's three skills; development,
including
make test-latency, the wall-clock testsmake testleaves out.
Metadata
Release files for sessionmail 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| sessionmail-0.2.0.tar.gz | 628.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sessionmail-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.3 MB
Release files / sessionmail-0.2.0.tar.gz
| Download URL | sessionmail-0.2.0.tar.gz |
|---|---|
| Size | 628.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
44589b77ff00bf2a79390a5df1eec299e9313552bffcbe24385a7b9f1fefa90a
|
|
BLAKE2b-256 checksum How to use checksums |
20a84fe8aae9bafb19b047fc9ddbdc785dd41bb5fdc12382bd9b8bf87deec8ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.9 {"installer":{"name":"uv","version":"0.11.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / sessionmail-0.2.0-py3-none-any.whl
| Download URL | sessionmail-0.2.0-py3-none-any.whl |
|---|---|
| Size | 667.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9019aa16590f819e0d7107ea90cae9c8f2e8529a95f53140afc827c758233741
|
|
BLAKE2b-256 checksum How to use checksums |
5c1c4a555f51140d6c4d7c2c69d93b6405bfcd799a03b08c7656f9e25244b94d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.9 {"installer":{"name":"uv","version":"0.11.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for sessionmail 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.