Crate notcoal

source ·
Expand description

This crate provides both a library as well as a standalone binary that can be used as an “initial tagging” system for the notmuch email system. As a standalone tool it integrates with the notmuch hooks and configuration files, while the library may be integrated into a bigger e-mail client that makes use of notmuch-rs.


notcoal reads JSON files with regex patterns, checks an incoming message’s respective header for a match. If an appropriate match is found, it is then able to add or remove tags, run an arbitrary binary for further processing, or delete the notmuch database entry and the corresponding file.

Rules can be combined with AND as well as OR.

§Example: a filter in a JSON file

    "name": "money",
    "desc": "Money stuff",
    "rules": [
        {"from": "@(real\\.bank|gig-economy\\.career)",
         "subject": ["report", "month" ]},
        {"from": "no-reply@trusted\\.bank",
         "subject": "statement"}
    "op": {
        "add": "€£$",
        "rm": ["inbox", "unread"],
        "run": ["any-binary-in-our-path-or-absolute-path", "--argument"]

The rules in this filter definition are equivalent to:

( from: ("" OR "") AND
  subject: ("report" AND "month") )
( from: "" AND
  subject: "statement" )

If if this filter is applied the operations will

  • add the tag €£$
  • remove the tags inbox and unread
  • run the equivalent of /bin/sh -c 'any-binary-in-our-path-or-absolute-path --argument' with 3 additional environment variables:

§What notcoal can match

Arbitrary headers! Matching from and subject are in no way a special case since all headers are treated equal (and case-insensitive). The mere existence of a header may be occasionally enough for classification, and while the Value enum also has a boolean field, it can not be used in rules.

In addition to arbitrary headers, notcoal also supports “special field checks”:

  • @tags: tags that have already been set by an filter that matched earlier
  • @path: the file system path of the message being processed
  • @attachment: any attachment file names
  • @body: the message body. The first (usually plain text) body part only.
  • @attachment-body: any attachments contents as long as the MIME type starts with text
  • @thread-tags: match on any tag in the thread that we belong to (e.g. mute).
    Please note, this applies to the entire thread, not only to the local branch.




  • Possible values for operations and rules


  • Apply all supplied filters to the corresponding matching messages
  • Returns how many matches there are as well as what Message-IDs have been matched by which filters, without running any of the operations
  • Deserialize filters from bytes
  • Deserialize a filters from file