Skip to main content

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 send writes 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, read and mark, pager and memory all 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 new for you. message mark and memory read an empty index until something does: launchd, cron, or by hand.

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.json for 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-config is never read.
  • Environment variables: each settings key has one (the sendmail key's is SESSIONMAIL_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 becomes pager.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 becomes log.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 hand pager listen named on that line, means something is listening for its mail; not armed or off alone means nothing is. Exit 2 means it could not look (no session, or no box yet). It does not test sending: message send exits 3 when the mail server did not take the message.

Docs

Everything else is in docs/, one subject per file:

Metadata

Release files for sessionmail 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sessionmail 0.3.0
File Size Uploaded Provenance
sessionmail-0.3.0.tar.gz 657.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for sessionmail 0.3.0
File Interpreter ABI Platform
sessionmail-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.4 MB

Release files / sessionmail-0.3.0.tar.gz

Download URL sessionmail-0.3.0.tar.gz
Size 657.6 kB
Tags Source
SHA-256 checksum
How to use checksums
e17a0d74181309508eeb90c63323ec1cfaea9b3f7119fab49cbf3c9e51bb0979
BLAKE2b-256 checksum
How to use checksums
ff2706bb265590944c025baa192d6798fa14c9f970a3ea699b057324788e6173
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","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.3.0-py3-none-any.whl

Download URL sessionmail-0.3.0-py3-none-any.whl
Size 698.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8e4d9476d39b1170aaf79542f23b4ca6892b7481e9ab958d258a405a058f6bdf
BLAKE2b-256 checksum
How to use checksums
400a11acec345c7f5437ff8e5329a53b08d5a25fc3439352cca8ba709b729581
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","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.3.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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page